diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml deleted file mode 100644 index 5b5e5fecb..000000000 --- a/.github/workflows/gh-pages.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: github pages -on: - push: - branches: - - main # Set a branch to deploy - pull_request: - branches: - - main - workflow_dispatch: - -jobs: - deploy: - permissions: - contents: write - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v3 - with: - submodules: true # Fetch Hugo themes (true OR recursive) - fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod - - - name: Setup Hugo - uses: peaceiris/actions-hugo@v2 - with: - hugo-version: 0.121.2 - extended: true - - - name: Install Dependencies - run: npm install autoprefixer postcss postcss-cli - - - name: Build - run: hugo --minify - - - name: Deploy - uses: peaceiris/actions-gh-pages@v3 - if: github.ref == 'refs/heads/main' - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./public - cname: protobuf.dev \ No newline at end of file diff --git a/content/reference/php/api-docs/opensearch.xml b/.nojekyll similarity index 100% rename from content/reference/php/api-docs/opensearch.xml rename to .nojekyll diff --git a/404.html b/404.html new file mode 100644 index 000000000..551fdf665 --- /dev/null +++ b/404.html @@ -0,0 +1,4 @@ +404 Page not found | Protocol Buffers Documentation +

Not found

Oops! This page doesn't exist. Try going back to the home page.

\ No newline at end of file diff --git a/CNAME b/CNAME index 0003f2fa4..07e91d7e1 100644 --- a/CNAME +++ b/CNAME @@ -1 +1 @@ -protobuf.dev \ No newline at end of file +protobuf.dev diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 3abd08301..000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,28 +0,0 @@ -# How to Contribute - -We'd love to accept your patches and contributions to this project. There are -just a few small guidelines you need to follow. - -## Contributor License Agreement - -Contributions to this project must be accompanied by a Contributor License -Agreement. You (or your employer) retain the copyright to your contribution; -this simply gives us permission to use and redistribute your contributions as -part of the project. Head over to to see -your current agreements on file or to sign a new one. - -You generally only need to submit a CLA once, so if you've already submitted one -(even if it was for a different project), you probably don't need to do it -again. - -## Code Reviews - -All submissions, including submissions by project members, require review. We -use GitHub pull requests for this purpose. Consult -[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more -information on using pull requests. - -## Community Guidelines - -This project follows [Google's Open Source Community -Guidelines](https://opensource.google/conduct/). \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 740f1a055..000000000 --- a/LICENSE +++ /dev/null @@ -1,32 +0,0 @@ -Copyright 2021 Google Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Code generated by the Protocol Buffer compiler is owned by the owner -of the input file used when generating it. This code is not -standalone and requires a support library to be linked with it. This -support library is itself covered by the above license. diff --git a/README.md b/README.md deleted file mode 100644 index e36457ebe..000000000 --- a/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# Protocol Buffers - Google's data interchange format - -Copyright 2008 Google Inc. - -https://protobuf.dev - -## Overview - -Protocol Buffers (a.k.a., protobuf) are Google's language-neutral, -platform-neutral, extensible mechanism for serializing structured data. This -site holds Protocol Buffers documentation. - -## Protocol Buffers Repository - -The Protocol Buffers GitHub repository is -https://github.com/protocolbuffers/protobuf. - -## Developer Community - -To be alerted to upcoming changes in Protocol Buffers and connect with protobuf -developers and users, -[join the Google Group](https://groups.google.com/g/protobuf). diff --git a/best-practices/1-1-1/index.html b/best-practices/1-1-1/index.html new file mode 100644 index 000000000..7ee30d2a5 --- /dev/null +++ b/best-practices/1-1-1/index.html @@ -0,0 +1,114 @@ +1-1-1 Best Practice | Protocol Buffers Documentation +

1-1-1 Best Practice

All proto definitions should have one top-level element and build target per file.

The “1-1-1” best practice advocates structuring definitions with one top-level +entity (message, enum, or extension) per .proto file, corresponding to a +single proto_library build rule. This approach promotes small, modular proto +definitions. Key benefits include simplified refactoring, potentially improved +build times, and smaller binary sizes due to minimized transitive dependencies.

Rationale

The 1-1-1 best practice is to keep every proto_library and .proto file as small +as is reasonable, with the ideal being:

  • One proto_library build rule
  • One source .proto file
  • One top-level entity (message, enum, or extension)

Having the fewest number of message, enum, extension, and services as you +reasonably can makes refactoring easier. Moving files when they’re separated is +much easier than extracting messages from a file with other messages.

Following this practice can help build times and binary size by reducing the +size of your transitive dependencies in practice: when some code only needs to +use one enum, under a 1-1-1 design it can depend just on the .proto file that +defines that enum and avoid incidentally pulling in a large set of transitive +dependencies that may only be used by another message defined in the same file.

There are cases where the 1-1-1 ideal is not possible (circular dependencies), +not ideal (extremely conceptually coupled messages which have readability +benefits by being co-located), or where some of the downsides don’t apply (when +a .proto file has no imports, then there are no technical concerns about the +size of transitive dependencies). As with any best practice, use good judgment +for when to diverge from the guideline.

One place that modularity of proto schema files is important is when creating +gRPC +definitions. The following set of proto files shows modular structure.

student_id.proto

edition = "2023";
+
+package my.package;
+
+message StudentId {
+  string value = 1;
+}
+

full_name.proto

edition = "2023";
+
+package my.package;
+
+message FullName {
+  string family_name = 1;
+  string given_name = 2;
+}
+

student.proto

edition = "2023";
+
+package my.package;
+
+import "student_id.proto";
+import "full_name.proto";
+
+message Student {
+  StudentId id = 1;
+  FullName name = 2;
+}
+

create_student_request.proto

edition = "2023";
+
+package my.package;
+
+import "full_name.proto";
+
+message CreateStudentRequest {
+  FullName name = 1;
+}
+

create_student_response.proto

edition = "2023";
+
+package my.package;
+
+import "student.proto";
+
+message CreateStudentResponse {
+  Student student = 1;
+}
+

get_student_request.proto

edition = "2023";
+
+package my.package;
+
+import "student_id.proto";
+
+message GetStudentRequest {
+  StudentId id = 1;
+}
+

get_student_response.proto

edition = "2023";
+
+package my.package;
+
+import "student.proto";
+
+message GetStudentResponse {
+  Student student = 1;
+}
+

student_service.proto

edition = "2023";
+
+package my.package;
+
+import "create_student_request.proto";
+import "create_student_response.proto";
+import "get_student_request.proto";
+import "get_student_response.proto";
+
+service StudentService {
+  rpc CreateStudent(CreateStudentRequest) returns (CreateStudentResponse);
+  rpc GetStudent(GetStudentRequest) returns (GetStudentResponse);
+}
+

The service definition and each of the message definitions are each in their own +file, and you use includes to give access to the messages from other schema +files.

In this example, Student, StudentId, and FullName are domain types that +are reusable across requests and responses. The top-level request and response +protos are unique to each service+method.

If you later need to add a middle_name field to the FullName message, you +won’t need to update every individual top-level message with that new field. +Likewise, if you need to update Student with more information, all the +requests and responses get the update. Further, StudentId might update to be a +multi-part ID.

Lastly, having even simple types like StudentId wrapped as a message means +that you have created a type that has semantics and consolidated documentation. +For something like FullName you’ll need to be careful with where this PII gets +logged; this is another advantage of not repeating these fields in multiple +top-level messages. You can tag those fields in one place as sensitive +and exclude them from logging.

\ No newline at end of file diff --git a/best-practices/dos-donts/index.html b/best-practices/dos-donts/index.html new file mode 100644 index 000000000..c75c57f07 --- /dev/null +++ b/best-practices/dos-donts/index.html @@ -0,0 +1,167 @@ +Proto Best Practices | Protocol Buffers Documentation +

Proto Best Practices

Shares vetted best practices for authoring Protocol Buffers.

Clients and servers are never updated at exactly the same time - even when you +try to update them at the same time. One or the +other may get rolled back. Don’t assume that you can make a breaking change and +it’ll be okay because the client and server are in sync.

Don’t Re-use a Tag Number

Never re-use a tag number. It messes up deserialization. Even if you think no +one is using the field, don’t re-use a tag number. If the change was live ever, +there could be serialized versions of your proto in a log +somewhere. Or there could be old code in another server that will break.

Do Reserve Tag Numbers for Deleted Fields

When you delete a field that’s no longer used, reserve its tag number so that no +one accidentally re-uses it in the future. Just reserved 2, 3; is enough. No +type required (lets you trim dependencies!). You can also reserve names to avoid +recycling now-deleted field names: reserved foo, bar;. See the docs on +reserved field numbers +and +reserved field names.

Do Reserve Numbers for Deleted Enum Values

When you delete an enum value that’s no longer used, reserve its number so that +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;. See also +enum reserved values

Do Put New 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), 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

Almost never change the type of a field; it’ll mess up deserialization, same as +re-using a tag number. The +protobuf docs +outline a small number of cases that are okay (for example, going between +int32, uint32, int64 and bool). However, changing a field’s message type +will break unless the new message is a superset of the old one.

Don’t Add a Required Field

Never add a required field, instead add // required to document the API +contract. Required fields are considered harmful by so many they were +removed from proto3 completely. Make all fields +optional or repeated. You never know how long a message type is going to last +and whether someone will be forced to fill in your required field with an empty +string or zero in four years when it’s no longer logically required but the +proto still says it is.

For proto3 there are no required fields, so this advice does not apply.

Don’t Make a Message with Lots of Fields

Don’t make a message with “lots” (think: hundreds) of fields. In C++ every field +adds roughly 65 bits to the in-memory object size whether it’s populated or not +(8 bytes for the pointer and, if the field is declared as optional, another bit +in a bitfield that keeps track of whether the field is set). When your proto +grows too large, the generated code may not even compile (for example, in Java +there is a hard limit on the size of a method +).

Do Include an Unspecified Value in an Enum

Enums should include a default FOO_UNSPECIFIED value as the first value in the +declaration. +When new values are added to an enum, old clients will see the field as unset +and the getter will return the default value or the first-declared value if no +default exists . For consistent behavior with proto enums, +the first declared enum value should be a default FOO_UNSPECIFIED value and +should use tag 0. It may be tempting to declare this default as a semantically +meaningful value but as a general rule, do not, to aid in the evolution of your +protocol as new enum values are added over time. All enum values declared under +a container message are in the same C++ namespace, so prefix the unspecified +value with the enum’s name to avoid compilation errors. If you’ll never need +cross-language constants, an int32 will preserve unknown values and generates +less code. Note that proto enums require the first value to be +zero and can round-trip (deserialize, serialize) an unknown enum value.

Don’t Use C/C++ Macro Constants for Enum Values

Using words that have already been defined by the C++ language - specifically, +in its headers such as math.h, may cause compilation errors if the #include +statement for one of those headers appears before the one for .proto.h. Avoid +using macro constants such as “NULL,” “NAN,” and “DOMAIN” as enum values.

Do prefer extensions over Any where possible

If you plan to use Any, first double-check if extensions can satisfy the use +case instead. If yes, prefer using extensions.

Any was created in Proto3 to replace extensions. However, it has a number of +design flaws. For most use cases, prefer using extensions.

The main use case that Any fulfills is the uncommon scenario in which +horizontal infrastructure needs to propagate completely arbitrary messages, and +declaring an extension for each possible legal types would be infeasible.

In the future, Protobuf may introduce a new concept that would satisfy the Any +use cases without the design flaws, but we have no concrete plans at this time.

Do Use Well-Known Types and Common Types

Using the following common, shared types is strongly encouraged. E.g., do not +use int32 timestamp_seconds_since_epoch or int64 timeout_millis in your code +when a perfectly suitable common type already exists!

  • duration +is a signed, fixed-length span of time (for example, 42s).
  • timestamp +is a point in time independent of any time zone or calendar (for example, +2017-01-15T01:30:15.01Z).
  • interval +is a time interval independent of time zone or calendar (for example, +2017-01-15T01:30:15.01Z - 2017-01-16T02:30:15.01Z).
  • date +is a whole calendar date (for example, 2005-09-19).
  • month +is a month of year (for example, April).
  • dayofweek +is a day of week (for example, Monday).
  • timeofday +is a time of day (for example, 10:42:23).
  • field_mask +is a set of symbolic field paths (for example, f.b.d).
  • postal_address +is a postal address (for example, 1600 Amphitheatre Parkway Mountain View, +CA 94043 USA).
  • money +is an amount of money with its currency type (for example, 42 USD).
  • latlng +is a latitude/longitude pair (for example, 37.386051 latitude and +-122.083855 longitude).
  • color +is a color in the RGBA color space.

Note: While the “Well-Known Types” (such as Duration and Timestamp) are +included with the Protocol Buffers compiler, the “Common Types” (such as Date +and Money) are not. To use the Common Types, you may need to add a dependency +on the googleapis repository.

Do Define Message Types in Separate Files

When defining a proto schema, you should have a single message, enum, extension, +service, or group of cyclic dependencies per file. This makes refactoring +easier. Moving files when they’re separated is much easier than extracting +messages from a file with other messages. Following this practice also helps to +keep the proto schema files smaller, which enhances maintainability.

If they will be widely used outside of your project, consider putting them in +their own file with no dependencies. Then it’s easy for anyone to use those +types without introducing the transitive dependencies in your other proto files.

For more on this topic, see +1-1-1 Rule.

Don’t Change the Default Value of a Field

Almost never change the default value of a proto field. This causes version skew +between clients and servers. A client reading an unset value will see a +different result than a server reading the same unset value when their builds +straddle the proto change. Proto3 removed the ability to +set default values.

Don’t Go from Repeated to Scalar

Although it won’t cause crashes, you’ll lose data. For JSON, a mismatch in +repeatedness will lose the whole message. For numeric proto3 fields and proto2 +packed fields, going from repeated to scalar will lose all data in that +field. For non-numeric proto3 fields and un-annotated proto2 fields, going +from repeated to scalar will result in the last deserialized value “winning.”

Going from scalar to repeated is OK in proto2 and in proto3 with +[packed=false] because for binary serialization the scalar value becomes a +one-element list.

Do Follow the Style Guide for Generated Code

Proto generated code is referred to in normal code. Ensure that options in +.proto file do not result in generation of code which violate the style guide. +For example:

Don’t use Text Format Messages for Interchange

Text-based serialization formats like text format and +JSON represent fields and enum values as strings. As a result, deserialization +of protocol buffers in these formats using old code will fail when a field or +enum value is renamed, or when a new field or enum value or extension is added. +Use binary serialization when possible for data interchange, and use text format +for human editing and debugging only.

If you use protos converted to JSON in your API or for storing data, you may not +be able to safely rename fields or enums at all.

Never Rely on Serialization Stability Across Builds

The stability of proto serialization is not guaranteed across binaries or across +builds of the same binary. Do not rely on it when, for example, building cache +keys.

Don’t Generate Java Protos in the Same Java Package as Other Code

Generate Java proto sources into a separate package from your hand-written Java +sources. The package, java_package and java_alt_api_package options +control +where the generated Java sources are emitted. +Make sure hand-written Java source code does not also live in that same package. +A common practice is to generate your protos into a proto subpackage in your +project that only contains those protos (that is, no hand-written source +code).

Do Derive Java Package from the .proto Package (if overridden)

Setting the java_package can introduce fully-qualified name collisions in +generated code that did not exist in the .proto semantics. For example, these +two files may create collisions in the generated code despite the +fully-qualified names not colliding in the original schema:

package x;
+option java_package = "com.example.proto";
+message Abc {}
+
package y;
+option java_package = "com.example.proto";
+message Abc {}
+

To avoid these problems, you should never set the same java_package in two +files that have different .proto packages set.

The best practice is to establish a local naming pattern where the package name +is derived from the .proto package. For example, a best practice file with +package y might consistently set option java_package = "com.example.proto.y".

This guidance also applies to any other language-specific options where package +overrides are possible.

Avoid Using Language Keywords for Field Names

If the name of a message, field, enum, or enum value is a keyword in the +language that reads from/writes to that field, then protobuf may change the +field name, and may have different ways to access them than normal fields. For +example, see +this warning about Python.

You should also avoid using keywords in your file paths, as this can also cause +problems.

Do Use Different Messages For RPC APIs and Storage

Reusing the same messages for APIs and long-term storage may seem convenient, +reducing boilerplate and overhead of conversion between messages.

However, the needs of long-term storage and live RPC services tend to later +diverge. Using separate types even if they are largely duplicative initially +gives freedom to change your storage format without impacting your external +clients. Layer your code so that modules deal either with client protos, storage +protos, or translation.

There is a cost in maintaining the translation layer, but it quickly pays off +once you have clients and have to do your first storage changes.

Don’t Use Booleans for Something That Has Two States Now, but Might Have More Later

If you are using boolean for a field, make sure that the field is indeed +describing just two possible states (for all time, not just now and the near +future). The future flexibility of using an enum is often worth it, even if it +only has two values when it is first introduced.

message Photo {
+  // Bad: True if it's a GIF.
+  optional bool gif;
+
+  // Good: File format of the referenced photo (for example, GIF, WebP, PNG).
+  optional PhotoType type;
+}
+

Do Use java_outer_classname (before Edition 2024)

Every proto schema definition file should set option java_outer_classname to +the .proto file name converted to TitleCase with the ‘.’ removed. For example, +the file student_record_request.proto should set:

option java_outer_classname = "StudentRecordRequestProto";
+

The default behavior of Edition 2024 files has been aligned with this +recommendation, so no option should be set when using Edition 2024 or later.

\ No newline at end of file diff --git a/best-practices/index.html b/best-practices/index.html new file mode 100644 index 000000000..712bebddf --- /dev/null +++ b/best-practices/index.html @@ -0,0 +1,9 @@ +Proto Best Practices | Protocol Buffers Documentation +

Proto Best Practices

An overview of best practices topics.

Best practices content for defining and using protos exists in the following +topics:

\ No newline at end of file diff --git a/best-practices/index.xml b/best-practices/index.xml new file mode 100644 index 000000000..b796e1d84 --- /dev/null +++ b/best-practices/index.xml @@ -0,0 +1,4 @@ +Proto Best Practices on Protocol Buffers Documentationhttps://protobuf.dev/best-practices/Recent content in Proto Best Practices on Protocol Buffers DocumentationHugoenAvoid Cargo Cultinghttps://protobuf.dev/best-practices/no-cargo-cults/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/best-practices/no-cargo-cults/Do not cargo cult settings in proto files. If you are creating a new proto file based on existing schema definitions, don’t apply option settings except for those that you understand the need for. +Best Practices Specific to Editions Avoid applying editions features except when they’re actually necessary. Features in .proto files signal the use of either experimental future behaviors or deprecated past behaviors. Best practices for the latest edition will always be the default.Proto Best Practiceshttps://protobuf.dev/best-practices/dos-donts/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/best-practices/dos-donts/Clients and servers are never updated at exactly the same time - even when you try to update them at the same time. One or the other may get rolled back. Don’t assume that you can make a breaking change and it’ll be okay because the client and server are in sync. +Don’t Re-use a Tag Number Never re-use a tag number. It messes up deserialization. Even if you think no one is using the field, don’t re-use a tag number.1-1-1 Best Practicehttps://protobuf.dev/best-practices/1-1-1/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/best-practices/1-1-1/The “1-1-1” best practice advocates structuring definitions with one top-level entity (message, enum, or extension) per .proto file, corresponding to a single proto_library build rule. This approach promotes small, modular proto definitions. Key benefits include simplified refactoring, potentially improved build times, and smaller binary sizes due to minimized transitive dependencies. +Rationale The 1-1-1 best practice is to keep every proto_library and .proto file as small as is reasonable, with the ideal being: \ No newline at end of file diff --git a/best-practices/no-cargo-cults/index.html b/best-practices/no-cargo-cults/index.html new file mode 100644 index 000000000..81a395b0f --- /dev/null +++ b/best-practices/no-cargo-cults/index.html @@ -0,0 +1,18 @@ +Avoid Cargo Culting | Protocol Buffers Documentation +

Avoid Cargo Culting

Avoid using features where they are not needed.

Do not +cargo cult +settings in proto files. If you are creating a new proto file based on existing +schema definitions, don’t apply option settings except for those that you +understand the need for.

Best Practices Specific to Editions

Avoid applying editions features +except when they’re actually necessary. Features in .proto files signal the +use of either experimental future behaviors or deprecated past behaviors. Best +practices for the latest edition will always be the default. New proto schema +definition content should remain feature-free, except if you want to early-adopt +a feature for future behavior that’s being rolled out.

Copying-forward feature settings without understanding why they are set can lead +to unexpected behaviors in your code.

\ No newline at end of file diff --git a/categories/index.html b/categories/index.html new file mode 100644 index 000000000..93032aa24 --- /dev/null +++ b/categories/index.html @@ -0,0 +1,4 @@ +Categories | Protocol Buffers Documentation +

Categories

\ No newline at end of file diff --git a/categories/index.xml b/categories/index.xml new file mode 100644 index 000000000..b63040b34 --- /dev/null +++ b/categories/index.xml @@ -0,0 +1 @@ +Categories on Protocol Buffers Documentationhttps://protobuf.dev/categories/Recent content in Categories on Protocol Buffers DocumentationHugoen \ No newline at end of file diff --git a/config.toml b/config.toml deleted file mode 100644 index 2949c9ad6..000000000 --- a/config.toml +++ /dev/null @@ -1,190 +0,0 @@ -baseURL = 'https://protobuf.dev' -languageCode = 'en-us' -title = 'Protocol Buffers Documentation' - -# Theme -[module] - [module.hugoVersion] - extended = true - min = "0.75.0" - [[module.imports]] - path = "github.com/google/docsy" - disable = false - [[module.imports]] - path = "github.com/google/docsy/dependencies" - disable = false - -# Language settings -contentDir = "content" -defaultContentLanguage = "en" -defaultContentLanguageInSubdir = false -enableMissingTranslationPlaceholders = true -enableRobotsTXT = true -enableGitInfo = false - -[taxonomies] -tag = "tags" -category = "categories" - -[params.taxonomy] -# set taxonomyCloud = [] to hide taxonomy clouds -taxonomyCloud = ["tags", "categories"] - -# Highlighting config -pygmentsCodeFences = true -pygmentsUseClasses = false -# Use the new Chroma Go highlighter in Hugo. -pygmentsUseClassic = false -#pygmentsOptions = "linenos=table" -# See https://help.farbox.com/pygments.html -pygmentsStyle = "tango" - -# Configure how URLs look like per section. -[permalinks] -blog = "/:section/:year/:month/:day/:slug/" - -## Configuration for BlackFriday markdown parser: https://github.com/russross/blackfriday -[blackfriday] -plainIDAnchors = true -hrefTargetBlank = true -angledQuotes = false -latexDashes = true -smartypants = false - -# Image processing configuration. -[imaging] -resampleFilter = "CatmullRom" -quality = 75 -anchor = "smart" - -[services] -[services.googleAnalytics] -id = "G-5L8P8GRN4Y" - -# Language configuration - -[languages] -[languages.en] -title = "Protocol Buffers Documentation" -languageName ="English" -# Weight used for sorting. -weight = 1 - - -[markup] - [markup.goldmark] - [markup.goldmark.renderer] - unsafe = true - [markup.highlight] - # See a complete list of available styles at https://xyproto.github.io/splash/docs/all.html - style = "tango" - # Uncomment if you want your chosen highlight style used for code blocks without a specified language - guessSyntax = "true" - -# Everything below this are Site Params - -# Comment out if you don't want the "print entire section" link enabled. -# [outputs] -# section = ["HTML", "print", "RSS"] - -[params] -description = "Protocol buffers is a language-neutral, platform-neutral extensible mechanism for serializing structured data." -copyright = "Google LLC" -privacy_policy = "https://policies.google.com/privacy" - -# First one is picked as the Twitter card image if not set on page. -# images = ["images/project-illustration.png"] - -# Menu title if your navbar has a versions selector to access old versions of your site. -# This menu appears only if you have at least one [params.versions] set. -version_menu = "Releases" - -# Flag used in the "version-banner" partial to decide whether to display a -# banner on every page indicating that this is an archived version of the docs. -# Set this flag to "true" if you want to display the banner. -archived_version = false - -# The version number for the version of the docs represented in this doc set. -# Used in the "version-banner" partial to display a version number for the -# current doc set. -version = "1.0" - -# A link to latest version of the docs. Used in the "version-banner" partial to -# point people to the main doc site. -url_latest_version = "https://protobuf.dev" - -# Repository configuration (URLs for in-page links to opening issues and suggesting changes) -github_repo = "https://github.com/protocolbuffers/protocolbuffers.github.io" -# An optional link to a related project repo. For example, the sibling repository where your product code lives. -github_project_repo = "https://github.com/protocolbuffers/protobuf" - -# Uncomment this if you have a newer GitHub repo with "main" as the default branch, -# or specify a new value if you want to reference another branch in your GitHub links -# github_branch= "main" - -# Google Custom Search Engine ID. Remove or comment out to disable search. -gcs_engine_id = "e39860f6782624f0b" - -# Enable Algolia DocSearch -algolia_docsearch = false - -# Enable Lunr.js offline search -offlineSearch = false - -# Enable syntax highlighting and copy buttons on code blocks with Prism -prism_syntax_highlighting = false - -# User interface configuration -[params.ui] -# Set to true to disable breadcrumb navigation. -breadcrumb_disable = false -# Set to true to disable the About link in the site footer -footer_about_disable = false -# Set to false if you don't want to display a logo (/assets/icons/logo.svg) in the top navbar -navbar_logo = false -# Set to true if you don't want the top navbar to be translucent when over a `block/cover`, like on the homepage. -navbar_translucent_over_cover_disable = false -# Enable to show the side bar menu in its compact state. -sidebar_menu_compact = false -# Set to true to hide the sidebar search box (the top nav search box will still be displayed if search is enabled) -sidebar_search_disable = true - -# ui.sidebar_menu_compact = true -ui.ul_show = 2 -ui.sidebar_menu_foldable = true - - -# Adds a H2 section titled "Feedback" to the bottom of each doc. The responses are sent to Google Analytics as events. -# This feature depends on [services.googleAnalytics] and will be disabled if "services.googleAnalytics.id" is not set. -# If you want this feature, but occasionally need to remove the "Feedback" section from a single page, -# add "hide_feedback: true" to the page's front matter. -[params.ui.feedback] -enable = false -# The responses that the user sees after clicking "yes" (the page was helpful) or "no" (the page was not helpful). -yes = 'Glad to hear it! Please tell us how we can improve.' -no = 'Sorry to hear that. Please tell us how we can improve.' - -# Adds a reading time to the top of each doc. -# If you want this feature, but occasionally need to remove the Reading time from a single page, -# add "hide_readingtime: true" to the page's front matter -[params.ui.readingtime] -enable = false - -[params.links] -# End user relevant links. These will show up on left side of footer and in the community page if you have one. -[[params.links.user]] - name = "Stack Overflow" - url = "https://stackoverflow.com/questions/tagged/protocol-buffers" - icon = "fab fa-stack-overflow" - desc = "Practical questions and curated answers" -# Developer relevant links. These will show up on right side of footer and in the community page if you have one. -[[params.links.developer]] - name = "GitHub" - url = "https://github.com/protocolbuffers/protobuf" - icon = "fab fa-github" - desc = "Source code, issues, and other details are stored here." -[[params.links.developer]] - name = "Developer mailing list" - url = "https://groups.google.com/g/protobuf" - icon = "fa fa-envelope" - desc = "Discuss development issues around the project" \ No newline at end of file diff --git a/content/_index.md b/content/_index.md deleted file mode 100644 index 471fe8375..000000000 --- a/content/_index.md +++ /dev/null @@ -1,81 +0,0 @@ -+++ -title = "Protocol Buffers" -weight = 5 -toc_hide = "true" -description = "Protocol Buffers are language-neutral, platform-neutral extensible mechanisms for serializing structured data." -type = "docs" -no_list = "true" -+++ - -## What Are Protocol Buffers? - -Protocol buffers are Google's language-neutral, platform-neutral, extensible -mechanism for serializing structured data – think XML, but smaller, faster, and -simpler. You define how you want your data to be structured once, then you can -use special generated source code to easily write and read your structured data -to and from a variety of data streams and using a variety of languages. - -## Pick Your Favorite Language - -Protocol buffers support generated code in C++, C#, Dart, Go, Java, -Kotlin, -Objective-C, Python, Rust, and Ruby. With proto3, you can also work with PHP. - -## Example Implementation - -```proto -edition = "2024"; - -message Person { - string name = 1; - int32 id = 2; - string email = 3; -} -``` - -**Figure 1.** A proto definition. - -```java -// Java code -Person john = Person.newBuilder() - .setId(1234) - .setName("John Doe") - .setEmail("jdoe@example.com") - .build(); -output = new FileOutputStream(args[0]); -john.writeTo(output); -``` - -**Figure 2.** Using a generated class to persist data. - -```cpp -// C++ code -Person john; -fstream input(argv[1], - ios::in | ios::binary); -john.ParseFromIstream(&input); -id = john.id(); -name = john.name(); -email = john.email(); -``` - -**Figure 3.** Using a generated class to parse persisted data. - -## How Do I Start? - -
    - -
  1. - Download - and install the protocol buffer compiler. -
  2. - -
  3. - Read the - overview. -
  4. -
  5. - Try the tutorial for your - chosen language. -
  6. -
diff --git a/content/best-practices/1-1-1.md b/content/best-practices/1-1-1.md deleted file mode 100644 index f5c1ae9c1..000000000 --- a/content/best-practices/1-1-1.md +++ /dev/null @@ -1,180 +0,0 @@ -+++ -title = "1-1-1 Best Practice" -weight = 105 -linkTitle = "1-1-1 Best Practice" -description = "All proto definitions should have one top-level element and build target per file." -type = "docs" -aliases = "/programming-guides/1-1-1" -+++ - -The "1-1-1" best practice advocates structuring definitions with one top-level -entity (message, enum, or extension) per `.proto` file, corresponding to a -single `proto_library` build rule. This approach promotes small, modular proto -definitions. Key benefits include simplified refactoring, potentially improved -build times, and smaller binary sizes due to minimized transitive dependencies. - -## Rationale - -The 1-1-1 best practice is to keep every proto_library and .proto file as small -as is reasonable, with the ideal being: - -* One `proto_library` build rule -* One source `.proto` file -* One top-level entity (message, enum, or extension) - -Having the fewest number of message, enum, extension, and services as you -reasonably can makes refactoring easier. Moving files when they're separated is -much easier than extracting messages from a file with other messages. - -Following this practice can help build times and binary size by reducing the -size of your transitive dependencies in practice: when some code only needs to -use one enum, under a 1-1-1 design it can depend just on the .proto file that -defines that enum and avoid incidentally pulling in a large set of transitive -dependencies that may only be used by another message defined in the same file. - -There are cases where the 1-1-1 ideal is not possible (circular dependencies), -not ideal (extremely conceptually coupled messages which have readability -benefits by being co-located), or where some of the downsides don't apply (when -a .proto file has no imports, then there are no technical concerns about the -size of transitive dependencies). As with any best practice, use good judgment -for when to diverge from the guideline. - -One place that modularity of proto schema files is important is when creating -gRPC -definitions. The following set of proto files shows modular structure. - -**student_id.proto** - -```proto -edition = "2023"; - -package my.package; - -message StudentId { - string value = 1; -} -``` - -**full_name.proto** - -```proto -edition = "2023"; - -package my.package; - -message FullName { - string family_name = 1; - string given_name = 2; -} -``` - -**student.proto** - -```proto -edition = "2023"; - -package my.package; - -import "student_id.proto"; -import "full_name.proto"; - -message Student { - StudentId id = 1; - FullName name = 2; -} -``` - -**create_student_request.proto** - -```proto -edition = "2023"; - -package my.package; - -import "full_name.proto"; - -message CreateStudentRequest { - FullName name = 1; -} -``` - -**create_student_response.proto** - -```proto -edition = "2023"; - -package my.package; - -import "student.proto"; - -message CreateStudentResponse { - Student student = 1; -} -``` - -**get_student_request.proto** - -```proto -edition = "2023"; - -package my.package; - -import "student_id.proto"; - -message GetStudentRequest { - StudentId id = 1; -} -``` - -**get_student_response.proto** - -```proto -edition = "2023"; - -package my.package; - -import "student.proto"; - -message GetStudentResponse { - Student student = 1; -} -``` - -**student_service.proto** - -```proto -edition = "2023"; - -package my.package; - -import "create_student_request.proto"; -import "create_student_response.proto"; -import "get_student_request.proto"; -import "get_student_response.proto"; - -service StudentService { - rpc CreateStudent(CreateStudentRequest) returns (CreateStudentResponse); - rpc GetStudent(GetStudentRequest) returns (GetStudentResponse); -} -``` - -The service definition and each of the message definitions are each in their own -file, and you use includes to give access to the messages from other schema -files. - -In this example, `Student`, `StudentId`, and `FullName` are domain types that -are reusable across requests and responses. The top-level request and response -protos are unique to each service+method. - -If you later need to add a `middle_name` field to the `FullName` message, you -won't need to update every individual top-level message with that new field. -Likewise, if you need to update `Student` with more information, all the -requests and responses get the update. Further, `StudentId` might update to be a -multi-part ID. - -Lastly, having even simple types like `StudentId` wrapped as a message means -that you have created a type that has semantics and consolidated documentation. -For something like `FullName` you'll need to be careful with where this PII gets -logged; this is another advantage of not repeating these fields in multiple -top-level messages. You can tag those fields in one place as sensitive -and exclude them from logging. diff --git a/content/best-practices/_index.md b/content/best-practices/_index.md deleted file mode 100644 index caf73bea8..000000000 --- a/content/best-practices/_index.md +++ /dev/null @@ -1,14 +0,0 @@ -+++ -title = "Proto Best Practices" -weight = 90 -description = "An overview of best practices topics." -type = "docs" -no_list = "true" -+++ - -Best practices content for defining and using protos exists in the following -topics: - -* [Proto Best Practices](/best-practices/dos-donts) -* [1-1-1 Rule](/best-practices/1-1-1) -* [Avoid Cargo Culting](/best-practices/no-cargo-cults) diff --git a/content/best-practices/dos-donts.md b/content/best-practices/dos-donts.md deleted file mode 100644 index 9128809c5..000000000 --- a/content/best-practices/dos-donts.md +++ /dev/null @@ -1,378 +0,0 @@ -+++ -title = "Proto Best Practices" -weight = 90 -description = "Shares vetted best practices for authoring Protocol Buffers." -type = "docs" -aliases = "/programming-guides/dos-donts" -+++ - -Clients and servers are never updated at exactly the same time - even when you -try to update them at the same time. One or the -other may get rolled back. Don’t assume that you can make a breaking change and -it'll be okay because the client and server are in sync. - - - -## **Don't** Re-use a Tag Number {#reuse-number} - -Never re-use a tag number. It messes up deserialization. Even if you think no -one is using the field, don’t re-use a tag number. If the change was live ever, -there could be serialized versions of your proto in a log -somewhere. Or there could be old code in another server that will break. - - - -## **Do** Reserve Tag Numbers for Deleted Fields {#reserve-tag-numbers} - -When you delete a field that's no longer used, reserve its tag number so that no -one accidentally re-uses it in the future. Just `reserved 2, 3;` is enough. No -type required (lets you trim dependencies!). You can also reserve names to avoid -recycling now-deleted field names: `reserved foo, bar;`. See the docs on -[reserved field numbers](/programming-guides/editions#fieldreserved) -and -[reserved field names](/programming-guides/editions#reserved-field-names). - - - -## **Do** Reserve Numbers for Deleted Enum Values {#reserve-deleted-numbers} - -When you delete an enum value that's no longer used, reserve its number so that -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;`. See also -[enum reserved values](/programming-guides/editions#reserved) - - - -## **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} - -Almost never change the type of a field; it'll mess up deserialization, same as -re-using a tag number. The -[protobuf docs](/programming-guides/editions#updating) -outline a small number of cases that are okay (for example, going between -`int32`, `uint32`, `int64` and `bool`). However, changing a field’s message type -**will break** unless the new message is a superset of the old one. - - - -## **Don't** Add a Required Field {#add-required} - -Never add a required field, instead add `// required` to document the API -contract. Required fields are considered harmful by so many they were -removed from proto3 completely. Make all fields -optional or repeated. You never know how long a message type is going to last -and whether someone will be forced to fill in your required field with an empty -string or zero in four years when it’s no longer logically required but the -proto still says it is. - -For proto3 there are no `required` fields, so this advice does not apply. - - - -## **Don't** Make a Message with Lots of Fields {#lots-of-fields} - -Don't make a message with “lots” (think: hundreds) of fields. In C++ every field -adds roughly 65 bits to the in-memory object size whether it’s populated or not -(8 bytes for the pointer and, if the field is declared as optional, another bit -in a bitfield that keeps track of whether the field is set). When your proto -grows too large, the generated code may not even compile (for example, in Java -there is a hard limit on the size of a method -). - - - -## **Do** Include an Unspecified Value in an Enum {#unspecified-enum} - -Enums should include a default `FOO_UNSPECIFIED` value as the first value in the -declaration. -When new values are added to an enum, old clients will see the field as unset -and the getter will return the default value or the first-declared value if no -default exists . For consistent behavior with [proto enums][proto-enums], -the first declared enum value should be a default `FOO_UNSPECIFIED` value and -should use tag 0. It may be tempting to declare this default as a semantically -meaningful value but as a general rule, do not, to aid in the evolution of your -protocol as new enum values are added over time. All enum values declared under -a container message are in the same C++ namespace, so prefix the unspecified -value with the enum’s name to avoid compilation errors. If you'll never need -cross-language constants, an `int32` will preserve unknown values and generates -less code. Note that [proto enums][proto-enums] require the first value to be -zero and can round-trip (deserialize, serialize) an unknown enum value. - -[example-unspecified]: http://cs/#search/&q=file:proto%20%22_UNSPECIFIED%20=%200%22&type=cs -[proto-enums]: /programming-guides/editions#enum - - - -## **Don't** Use C/C++ Macro Constants for Enum Values {#macro-constants} - -Using words that have already been defined by the C++ language - specifically, -in its headers such as `math.h`, may cause compilation errors if the `#include` -statement for one of those headers appears before the one for `.proto.h`. Avoid -using macro constants such as "`NULL`," "`NAN`," and "`DOMAIN`" as enum values. - - - -## **Do** prefer extensions over `Any` where possible {#avoid-any} - -If you plan to use `Any`, first double-check if extensions can satisfy the use -case instead. If yes, prefer using extensions. - -`Any` was created in Proto3 to replace extensions. However, it has a number of -design flaws. For most use cases, prefer using extensions. - -The main use case that `Any` fulfills is the uncommon scenario in which -horizontal infrastructure needs to propagate completely arbitrary messages, and -declaring an extension for each possible legal types would be infeasible. - -In the future, Protobuf may introduce a new concept that would satisfy the `Any` -use cases without the design flaws, but we have no concrete plans at this time. - - - -## **Do** Use Well-Known Types and Common Types {#well-known-common} - -Using the following common, shared types is strongly encouraged. E.g., do not -use `int32 timestamp_seconds_since_epoch` or `int64 timeout_millis` in your code -when a perfectly suitable common type already exists! - - - -* [`duration`](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/duration.proto) - is a signed, fixed-length span of time (for example, 42s). -* [`timestamp`](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/timestamp.proto) - is a point in time independent of any time zone or calendar (for example, - 2017-01-15T01:30:15.01Z). -* [`interval`](https://github.com/googleapis/googleapis/blob/master/google/type/interval.proto) - is a time interval independent of time zone or calendar (for example, - 2017-01-15T01:30:15.01Z - 2017-01-16T02:30:15.01Z). -* [`date`](https://github.com/googleapis/googleapis/blob/master/google/type/date.proto) - is a whole calendar date (for example, 2005-09-19). -* [`month`](https://github.com/googleapis/googleapis/blob/master/google/type/month.proto) - is a month of year (for example, April). -* [`dayofweek`](https://github.com/googleapis/googleapis/blob/master/google/type/dayofweek.proto) - is a day of week (for example, Monday). -* [`timeofday`](https://github.com/googleapis/googleapis/blob/master/google/type/timeofday.proto) - is a time of day (for example, 10:42:23). -* [`field_mask`](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/field_mask.proto) - is a set of symbolic field paths (for example, f.b.d). -* [`postal_address`](https://github.com/googleapis/googleapis/blob/master/google/type/postal_address.proto) - is a postal address (for example, 1600 Amphitheatre Parkway Mountain View, - CA 94043 USA). -* [`money`](https://github.com/googleapis/googleapis/blob/master/google/type/money.proto) - is an amount of money with its currency type (for example, 42 USD). -* [`latlng`](https://github.com/googleapis/googleapis/blob/master/google/type/latlng.proto) - is a latitude/longitude pair (for example, 37.386051 latitude and - -122.083855 longitude). -* [`color`](https://github.com/googleapis/googleapis/blob/master/google/type/color.proto) - is a color in the RGBA color space. - -**Note:** While the "Well-Known Types" (such as `Duration` and `Timestamp`) are -included with the Protocol Buffers compiler, the "Common Types" (such as `Date` -and `Money`) are not. To use the Common Types, you may need to add a dependency -on the [googleapis repository](https://github.com/googleapis/googleapis). - - - -## **Do** Define Message Types in Separate Files {#separate-files} - -When defining a proto schema, you should have a single message, enum, extension, -service, or group of cyclic dependencies per file. This makes refactoring -easier. Moving files when they're separated is much easier than extracting -messages from a file with other messages. Following this practice also helps to -keep the proto schema files smaller, which enhances maintainability. - -If they will be widely used outside of your project, consider putting them in -their own file with no dependencies. Then it's easy for anyone to use those -types without introducing the transitive dependencies in your other proto files. - -For more on this topic, see -[1-1-1 Rule](/best-practices/1-1-1). - - - -## **Don't** Change the Default Value of a Field {#change-default-value} - -Almost never change the default value of a proto field. This causes version skew -between clients and servers. A client reading an unset value will see a -different result than a server reading the same unset value when their builds -straddle the proto change. Proto3 removed the ability to -set default values. - - - -## **Don't** Go from Repeated to Scalar {#repeated-to-scalar} - -Although it won't cause crashes, you'll lose data. For JSON, a mismatch in -repeatedness will lose the whole *message*. For numeric proto3 fields and proto2 -`packed` fields, going from repeated to scalar will lose all data in that -*field*. For non-numeric proto3 fields and un-annotated proto2 fields, going -from repeated to scalar will result in the last deserialized value "winning." - -Going from scalar to repeated is OK in proto2 and in proto3 with -`[packed=false]` because for binary serialization the scalar value becomes a -one-element list. - - - -## **Do** Follow the Style Guide for Generated Code {#follow-style-guide} - -Proto generated code is referred to in normal code. Ensure that options in -`.proto` file do not result in generation of code which violate the style guide. -For example: - -* `java_outer_classname` should follow - https://google.github.io/styleguide/javaguide.html#s5.2.2-class-names - -* `java_package` and `java_alt_package` should follow - https://google.github.io/styleguide/javaguide.html#s5.2.1-package-names - -* `package`, although used for Java when `java_package` is not present, always - directly corresponds to C++ namespace and thus should follow - https://google.github.io/styleguide/cppguide.html#Namespace_Names. - If these style guides conflict, use `java_package` for Java. - -* `ruby_package` should be in the form `Foo::Bar::Baz` rather than - `Foo.Bar.Baz`. - - - -## **Don't** use Text Format Messages for Interchange {#text-format-interchange} - -Text-based serialization formats like text format and -JSON represent fields and enum values as strings. As a result, deserialization -of protocol buffers in these formats using old code will fail when a field or -enum value is renamed, or when a new field or enum value or extension is added. -Use binary serialization when possible for data interchange, and use text format -for human editing and debugging only. - -If you use protos converted to JSON in your API or for storing data, you may not -be able to safely rename fields or enums at all. - - - -## **Never** Rely on Serialization Stability Across Builds {#serialization-stability} - -The stability of proto serialization is not guaranteed across binaries or across -builds of the same binary. Do not rely on it when, for example, building cache -keys. - - - -## **Don't** Generate Java Protos in the Same Java Package as Other Code {#generate-java-protos} - -Generate Java proto sources into a separate package from your hand-written Java -sources. The `package`, `java_package` and `java_alt_api_package` options -control -[where the generated Java sources are emitted](/reference/java/java-generated#package). -Make sure hand-written Java source code does not also live in that same package. -A common practice is to generate your protos into a `proto` subpackage in your -project that **only** contains those protos (that is, no hand-written source -code). - -## **Do** Derive Java Package from the .proto Package (if overridden) {#derive-java-package} - -Setting the `java_package` can introduce fully-qualified name collisions in -generated code that did not exist in the .proto semantics. For example, these -two files may create collisions in the generated code despite the -fully-qualified names not colliding in the original schema: - -```proto -package x; -option java_package = "com.example.proto"; -message Abc {} -``` - -```proto -package y; -option java_package = "com.example.proto"; -message Abc {} -``` - -To avoid these problems, you should never set the same `java_package` in two -files that have different .proto packages set. - -The best practice is to establish a local naming pattern where the package name -is derived from the .proto package. For example, a best practice file with -`package y` might consistently set `option java_package = -"com.example.proto.y"`. - -This guidance also applies to any other language-specific options where package -overrides are possible. - -## Avoid Using Language Keywords for Field Names {#avoid-keywords} - -If the name of a message, field, enum, or enum value is a keyword in the -language that reads from/writes to that field, then protobuf may change the -field name, and may have different ways to access them than normal fields. For -example, see -[this warning about Python](/reference/python/python-generated#keyword-conflicts). - -You should also avoid using keywords in your file paths, as this can also cause -problems. - -## **Do** Use Different Messages For RPC APIs and Storage {#separate-types-for-storage} - -Reusing the same messages for APIs and long-term storage may seem convenient, -reducing boilerplate and overhead of conversion between messages. - -However, the needs of long-term storage and live RPC services tend to later -diverge. Using separate types even if they are largely duplicative initially -gives freedom to change your storage format without impacting your external -clients. Layer your code so that modules deal either with client protos, storage -protos, or translation. - -There is a cost in maintaining the translation layer, but it quickly pays off -once you have clients and have to do your first storage changes. - -## **Don't** Use Booleans for Something That Has Two States Now, but Might Have More Later {#bad-bools} - -If you are using boolean for a field, make sure that the field is indeed -describing just two possible states (for all time, not just now and the near -future). The future flexibility of using an enum is often worth it, even if it -only has two values when it is first introduced. - -``` -message Photo { - // Bad: True if it's a GIF. - optional bool gif; - - // Good: File format of the referenced photo (for example, GIF, WebP, PNG). - optional PhotoType type; -} -``` - -## **Do** Use java_outer_classname (before Edition 2024) {#java-outer-classname} - -Every proto schema definition file should set option `java_outer_classname` to -the `.proto` file name converted to TitleCase with the '.' removed. For example, -the file `student_record_request.proto` should set: - -```java -option java_outer_classname = "StudentRecordRequestProto"; -``` - -The default behavior of Edition 2024 files has been aligned with this -recommendation, so no option should be set when using Edition 2024 or later. diff --git a/content/best-practices/no-cargo-cults.md b/content/best-practices/no-cargo-cults.md deleted file mode 100644 index 8f63daf4e..000000000 --- a/content/best-practices/no-cargo-cults.md +++ /dev/null @@ -1,24 +0,0 @@ -+++ -title = "Avoid Cargo Culting" -weight = 90 -description = "Avoid using features where they are not needed." -type = "docs" -+++ - -Do not -[cargo cult](https://en.wikipedia.org/wiki/Cargo_cult_programming) -settings in proto files. If you are creating a new proto file based on existing -schema definitions, don't apply option settings except for those that you -understand the need for. - -## Best Practices Specific to Editions {#editions} - -Avoid applying [editions features](/editions/features) -except when they're actually necessary. Features in `.proto` files signal the -use of either experimental future behaviors or deprecated past behaviors. Best -practices for the latest edition will always be the default. New proto schema -definition content should remain feature-free, except if you want to early-adopt -a feature for future behavior that's being rolled out. - -Copying-forward feature settings without understanding why they are set can lead -to unexpected behaviors in your code. diff --git a/content/design-decisions/_index.md b/content/design-decisions/_index.md deleted file mode 100644 index 2e1468b22..000000000 --- a/content/design-decisions/_index.md +++ /dev/null @@ -1,17 +0,0 @@ -+++ -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/design-decisions/nullable-getters-setters.md b/content/design-decisions/nullable-getters-setters.md deleted file mode 100644 index ec22b6f32..000000000 --- a/content/design-decisions/nullable-getters-setters.md +++ /dev/null @@ -1,90 +0,0 @@ -+++ -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 -getters/setters in their null-friendly language of choice (particularly Kotlin, -C#, and Rust). While this does seem to be a helpful feature for folks using -those languages, the design choice has tradeoffs which have led to the Protobuf -team choosing not to implement them. - -Explicit presence is not a concept that directly maps to the traditional notion -of nullability. It is subtle, but explicit presence philosophy is closer to "the -fields are not nullable, but you can detect if the field was explicitly assigned -a value or not. Normal access will see some default value if it is not assigned, -but you can check if the field was actively written to or not, when needed." - -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 -message Msg { Child child = 1; } -message Child { Grandchild grandchild = 1; } -message Grandchild { int32 foo = 1 [default = 72]; } -``` - -and corresponding Kotlin getters: - -```kotlin -// With our API where getters are always non-nullable: -msg.child.grandchild.foo == 72 - -// With nullable submessages the ?. operator fails to get the default value: -msg?.child?.grandchild?.foo == null - -// Or verbosely duplicating the default value at the usage site: -(msg?.child?.grandchild?.foo ?: 72) -``` - -and corresponding Rust getters: - -```rust -// With our API: -msg.child().grandchild().foo() // == 72 - -// Where every getter is an Option, verbose and no default observed -msg.child().map(|c| c.grandchild()).map(|gc| gc.foo()) // == Option::None - -// For the rare situations where code may want to observe both the presence and -// value of a field, the _opt() accessor which returns a custom Optional type -// can also be used here (the Optional type is similar to Option except can also -// be aware of the default value): -msg.child().grandchild().foo_opt() // Optional::Unset(72) -``` - -If a nullable getter existed, it would necessarily ignore the user-specified -defaults (to return null instead) which would lead to surprising and -inconsistent behavior. If users of nullable getters want to access the default -value of the field, they would have to write their own custom handling to use -the default if null is returned, which removes the supposed benefit of -cleaner/easier code with null getters. - -Similarly, we do not provide nullable setters as the behavior would be -unintuitive. Performing a set and then get would not always give the same value -back, and calling a set would only sometimes affect the has-bit for the field. - -Note that message-typed fields are always explicit presence fields (with -hazzers). Proto3 defaults to scalar fields having implicit presence (without -hazzers) unless they are explicitly marked `optional`, while Proto2 does not -support implicit presence. With -[Editions](/editions/features#field_presence), explicit -presence is the default behavior unless an implicit presence feature is used. -With the forward expectation that almost all fields will have explicit presence, -the ergonomic concerns that come with nullable getters are expected to be more -of a concern than they may have been for Proto3 users. - -Due to these issues, nullable setters/getters would radically change the way -default values can be used. While we understand the possible utility, we have -decided it’s not worth the inconsistencies and difficulty it introduces. diff --git a/content/downloads.md b/content/downloads.md deleted file mode 100644 index 757d79504..000000000 --- a/content/downloads.md +++ /dev/null @@ -1,25 +0,0 @@ -+++ -title = "Downloads" -weight = 1000 -description = "The downloads page for protocol buffers." -type = "docs" -+++ - -## Release Packages - -### Latest Version - -The latest release of Protocol Buffers can be found on the -[release page](https://github.com/protocolbuffers/protobuf/releases/latest). - -### Old Versions - -Older versions are available in our historical releases -[on GitHub](https://github.com/protocolbuffers/protobuf/releases). - -## Source Code - -### GitHub Repository - -Protocol Buffers source code is hosted on -[GitHub](https://github.com/protocolbuffers/protobuf). diff --git a/content/editions/_index.md b/content/editions/_index.md deleted file mode 100644 index 6819f57da..000000000 --- a/content/editions/_index.md +++ /dev/null @@ -1,10 +0,0 @@ -+++ -title = "Protobuf Editions" -weight = 41 -description = "Topics related to the Protobuf Editions functionality." -type = "docs" -+++ - -* [Protobuf Editions Overview](/editions/overview) -* [Feature Settings for Editions](/editions/features) -* [Implementing Editions Support](/editions/implementation) diff --git a/content/editions/features.md b/content/editions/features.md deleted file mode 100644 index b025baab0..000000000 --- a/content/editions/features.md +++ /dev/null @@ -1,1190 +0,0 @@ -+++ -title = "Feature Settings for Editions" -weight = 43 -description = "Protobuf Editions features and how they affect protobuf behavior." -type = "docs" -+++ - -This topic provides an overview of the features that are included in the -released edition versions. Subsequent editions' features will be added to this -topic. We announce new editions in -[the News section](/news). - -Before configuring feature settings in your new schema definition content, make -sure you understand why you are using them. Avoid -[cargo-culting](/best-practices/no-cargo-cults) with -features. - -## Prototiller {#prototiller} - -Prototiller is a command-line tool that updates proto schema configuration files -between syntax versions and editions. It hasn't been released yet, but is -referenced throughout this topic. - -## Features {#features} - -The following sections include all of the behaviors that are configurable using -features in editions. [Preserving proto2 or proto3 Behavior](#preserving) shows -how to override the default behaviors so that your proto definition files act -like proto2 or proto3 files. For more information on how editions and features -work together to set behavior, see -[Protobuf Editions Overview](/editions/overview). - - Feature settings apply at different levels: - -**File-level:** These settings apply to all elements (messages, fields, enums, -and so on) that don't have an overriding setting. - -**Non-nested:** Messages, enums, and services can override settings made at the -file level. They apply to everything within them (message fields, enum values) -that aren't overridden, but don't apply to other parallel messages and enums. - -**Nested:** Oneofs, messages, and enums can override settings from the message -they're nested in. - -**Lowest-level:** Fields, extensions, enum values, extension ranges, and methods -are the lowest level at which you can override settings. - -Each of the following sections has a comment that states what scope the feature -can be applied to. The following sample shows a mock feature applied to each -scope: - -```proto -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 this example, the setting "`GRAULT"` in the lowest-level scope feature -definition overrides the non-nested-scope "`QUUX`" setting. And within the -Garply message, "`WALDO`" overrides "`QUUX`." - -### `features.default_symbol_visibility` {#symbol-vis} - -This feature enables setting the default visibility for messages and enums, -making them available or unavailable when imported by other protos. Use of this -feature will reduce dead symbols in order to create smaller binaries. - -In addition to setting the defaults for the entire file, you can use the `local` -and `export` keywords to set per-field behavior. Read more about this at -[`export` / `local` Keywords](/editions/overview#export-local). - -**Values available:** - -* `EXPORT_ALL`: This is the default prior to Edition 2024. All messages and - enums are exported by default. -* `EXPORT_TOP_LEVEL`: All top-level symbols default to export; nested default - to local. -* `LOCAL_ALL`: All symbols default to local. -* `STRICT`: All symbols local by default. Nested types cannot be exported, - except for a special-case caveat for `message { enum {} reserved 0 to max; - }`. This will become the default in a future edition. - -**Applicable to the following scope:** file - -**Added in:** Edition 2024 - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | ------------------ -2024 | `EXPORT_TOP_LEVEL` -2023 | `EXPORT_ALL` -proto3 | `EXPORT_ALL` -proto2 | `EXPORT_ALL` - -**Note:** Feature settings on different schema elements -[have different scopes](#cascading). - -The following sample shows how you can apply the feature to elements in your -proto schema definition files: - -```proto -// 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` {#enforce_naming} - -Introduced in Edition 2024, this feature enables strict naming style enforcement -as defined in -[the style guide](/programming-guides/style) to ensure -protos are round-trippable by default with a feature value to opt-out to use - -**Values available:** - -* `STYLE2024`: Enforces strict adherence to the style guide for naming. -* `STYLE_LEGACY`: Applies the pre-Edition 2024 level of style guide - enforcement. - -**Applicable to the following scopes:** file, extension range, message, field, -oneof, enum, enum value, service, method - -**Added in:** Edition 2024 - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | -------------- -2024 | `STYLE2024` -2023 | `STYLE_LEGACY` -proto3 | `STYLE_LEGACY` -proto2 | `STYLE_LEGACY` - -**Note:** Feature settings on different schema elements -[have different scopes](#cascading). - -The following code sample shows an Edition 2023 file: - -Edition 2023 defaults to `STYLE_LEGACY`, so a non-conformant field name is fine: - -```proto -edition = "2023"; - -message Foo { - // A non-conforming field name is not a problem - int64 bar_1 = 1; -} -``` - -Edition 2024 defaults to `STYLE2024`, so an override is needed to keep the -non-conformant field name: - -```proto -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` {#enum_type} - -This feature sets the behavior for how enum values that aren't contained within -the defined set are handled. See -[Enum Behavior](/programming-guides/enum) for more -information on open and closed enums. - -This feature doesn't impact proto3 files, so this section doesn't have a before -and after of a proto3 file. - -**Values available:** - -* `CLOSED:` Closed enums store enum values that are out of range in the - unknown field set. -* `OPEN:` Open enums parse out of range values into their fields directly. - -**Applicable to the following scopes:** file, enum - -**Added in:** Edition 2023 - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | -------- -2024 | `OPEN` -2023 | `OPEN` -proto3 | `OPEN` -proto2 | `CLOSED` - -**Note:** Feature settings on different schema elements -[have different scopes](#cascading). - -The following code sample shows a proto2 file: - -```proto -syntax = "proto2"; - -enum Foo { - A = 2; - B = 4; - C = 6; -} -``` - -After running [Prototiller](#prototiller), the equivalent code might look like -this: - -```proto -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` {#field_presence} - -This feature sets the behavior for tracking field presence, or the notion of -whether a protobuf field has a value. - -**Values available:** - -* `LEGACY_REQUIRED`: The field is required for parsing and serialization. - Any explicitly-set value is - serialized onto the wire (even if it is the same as the default value). -* `EXPLICIT`: The field has explicit presence tracking. Any explicitly-set - value is serialized onto the wire (even if it is the same as the default - value). For singular primitive fields, `has_*` functions are generated for - fields set to `EXPLICIT`. -* `IMPLICIT`: The field has no presence tracking. The default value is not - serialized onto the wire (even if it is explicitly set). `has_*` functions - are not generated for fields set to `IMPLICIT`. - -**Applicable to the following scopes:** file, field - -**Added in:** Edition 2023 - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | ----------- -2024 | `EXPLICIT` -2023 | `EXPLICIT` -proto3 | `IMPLICIT`* -proto2 | `EXPLICIT` - -\* proto3 is `IMPLICIT` unless the field has the `optional` label, in which case -it behaves like `EXPLICIT`. See -[Presence in Proto3 APIs](/programming-guides/field_presence#presence-proto3) -for more information. - -**Note:** Feature settings on different schema elements -[have different scopes](#cascading). - -The following code sample shows a proto2 file: - -```proto -syntax = "proto2"; - -message Foo { - required int32 x = 1; - optional int32 y = 2; - repeated int32 z = 3; -} -``` - -After running Prototiller, the equivalent code might look like this: - -```proto -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; -} -``` - -The following shows a proto3 file: - -```proto -syntax = "proto3"; - -message Bar { - int32 x = 1; - optional int32 y = 2; - repeated int32 z = 3; -} -``` - -After running Prototiller, the equivalent code might look like this: - -```proto -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; -} -``` - -Note that the `required` and `optional` labels no longer exist in Editions, as -the corresponding behavior is set explicitly with the `field_presence` feature. - -### `features.json_format` {#json_format} - -This feature sets the behavior for JSON parsing and serialization. - -This feature doesn't impact proto3 files, so this section doesn't have a before -and after of a proto3 file. Editions behavior matches the behavior in proto3. - -**Values available:** - -* `ALLOW`: A runtime must allow JSON parsing and serialization. Checks are - applied at the proto level to make sure that there is a well-defined mapping - to JSON. -* `LEGACY_BEST_EFFORT`: A runtime does the best it can to parse and serialize - JSON. Certain protos are allowed that can result in unspecified behavior at - runtime (such as many:1 or 1:many mappings). - -**Applicable to the following scopes:** file, message, enum - -**Added in:** Edition 2023 - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | -------------------- -2024 | `ALLOW` -2023 | `ALLOW` -proto3 | `ALLOW` -proto2 | `LEGACY_BEST_EFFORT` - -**Note:** Feature settings on different schema elements -[have different scopes](#cascading). - -The following code sample shows a proto2 file: - -```proto -syntax = "proto2"; - -message Foo { - // Warning only - string bar = 1; - string bar_ = 2; -} -``` - -After running Prototiller, the equivalent code might look like this: - -```proto -edition = "2024"; -option features.json_format = LEGACY_BEST_EFFORT; - -message Foo { - string bar = 1; - string bar_ = 2; -} -``` - -### `features.message_encoding` {#message_encoding} - -This feature sets the behavior for encoding fields when serializing. - -This feature doesn't impact proto3 files, so this section doesn't have a before -and after of a proto3 file. - -Depending on the language, fields that are "group-like" may have some unexpected -capitalization in generated code and in text-format, in order to provide -backwards compatibility with proto2. Message fields are "group-like" if all of -the following conditions are met: - -* Has `DELIMITED` message encoding specified -* Message type is defined in the same scope as the field -* Field name is exactly the lowercased type name - -**Values available:** - -* `LENGTH_PREFIXED`: Fields are encoded using the LEN wire type described in - [Message Structure](/programming-guides/encoding#structure). -* `DELIMITED`: Message-typed fields are encoded as - [groups](/programming-guides/proto2#groups). - -**Applicable to the following scopes:** file, field - -**Added in:** Edition 2023 - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | ----------------- -2024 | `LENGTH_PREFIXED` -2023 | `LENGTH_PREFIXED` -proto3 | `LENGTH_PREFIXED` -proto2 | `LENGTH_PREFIXED` - -**Note:** Feature settings on different schema elements -[have different scopes](#cascading). - -The following code sample shows a proto2 file: - -```proto -syntax = "proto2"; - -message Foo { - group Bar = 1 { - optional int32 x = 1; - repeated int32 y = 2; - } -} -``` - -After running Prototiller, the equivalent code might look like this: - -```proto -edition = "2024"; - -message Foo { - message Bar { - int32 x = 1; - repeated int32 y = 2; - } - Bar bar = 1 [features.message_encoding = DELIMITED]; -} -``` - -### `features.repeated_field_encoding` {#repeated_field_encoding} - -This feature is what the proto2/proto3 -[`packed` option](/programming-guides/encoding#packed) -for `repeated` fields has been migrated to in Editions. - -**Values available:** - -* `PACKED`: `Repeated` fields of a primitive type are encoded as a single LEN - record that contains each element concatenated. -* `EXPANDED`: `Repeated` fields are each encoded with the field number for - each value. - -**Applicable to the following scopes:** file, field - -**Added in:** Edition 2023 - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | ---------- -2024 | `PACKED` -2023 | `PACKED` -proto3 | `PACKED` -proto2 | `EXPANDED` - -**Note:** Feature settings on different schema elements -[have different scopes](#cascading). - -The following code sample shows a proto2 file: - -```proto -syntax = "proto2"; - -message Foo { - repeated int32 bar = 6 [packed=true]; - repeated int32 baz = 7; -} -``` - -After running Prototiller, the equivalent code might look like this: - -```proto -edition = "2024"; -option features.repeated_field_encoding = EXPANDED; - -message Foo { - repeated int32 bar = 6 [features.repeated_field_encoding=PACKED]; - repeated int32 baz = 7; -} -``` - -The following shows a proto3 file: - -```proto -syntax = "proto3"; - -message Foo { - repeated int32 bar = 6; - repeated int32 baz = 7 [packed=false]; -} -``` - -After running Prototiller, the equivalent code might look like this: - -```proto -edition = "2024"; - -message Foo { - repeated int32 bar = 6; - repeated int32 baz = 7 [features.repeated_field_encoding=EXPANDED]; -} -``` - -### `features.utf8_validation` {#utf8_validation} - -This feature sets how strings are validated. It applies to all languages except -where there's a language-specific `utf8_validation` feature that overrides it. -See [`features.(pb.java).utf8_validation`](#java-utf8_validation) for the -Java-language-specific feature. - -This feature doesn't impact proto3 files, so this section doesn't have a before -and after of a proto3 file. - -**Values available:** - -* `VERIFY`: The runtime should verify UTF-8. This is the default proto3 - behavior. -* `NONE`: The field behaves like an unverified `bytes` field on the wire. - Parsers may handle this type of field in an unpredictable way, such as - replacing invalid characters. This is the default proto2 behavior. - -**Applicable to the following scopes:** file, field - -**Added in:** Edition 2023 - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | -------- -2024 | `VERIFY` -2023 | `VERIFY` -proto3 | `VERIFY` -proto2 | `NONE` - -**Note:** Feature settings on different schema elements -[have different scopes](#cascading). - -The following code sample shows a proto2 file: - -```proto -syntax = "proto2"; - -message MyMessage { - string foo = 1; -} -``` - -After running Prototiller, the equivalent code might look like this: - -```proto -edition = "2024"; - -message MyMessage { - string foo = 1 [features.utf8_validation = NONE]; -} -``` - -## Language-specific Features {#lang-specific} - -Some features apply to specific languages, and not to the same protos in other -languages. Using these features requires you to import the corresponding -*_features.proto file from the language's runtime. The examples in the following -sections show these imports. - -### `features.(pb.go).api_level` {#go-api_level} - -**Languages:** Go - -The `api_level` feature enables you to select which API version the Go protobuf -plugin should generate code for. The Opaque API is the latest version of the -Protocol Buffers implementation for the Go programming language. The previous -version is now called Open Struct API. See the -[Go Protobuf: Releasing the Opaque API](https://go.dev/blog/protobuf-opaque) -blog post for an introduction. - -**Values available:** - -* `API_OPEN`: The Open Struct API generates struct types that are open to - direct access. -* `API_HYBRID`: Hybrid is a step between Open and Opaque: The Hybrid API also - includes accessor methods (so you can update your code), but still exports - the struct fields as before. There is no performance difference; this API - level only helps with the migration. -* `API_OPAQUE`: With the Opaque API, the struct fields are hidden and can no - longer be directly accessed. Instead, the new accessor methods allow for - getting, setting, or clearing a field. - -**Applicable to the following scopes:** message, file - -**Added in:** Edition 2023 - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | ------------ -2023 | `API_OPEN` -2024 | `API_OPAQUE` - -**Note:** Feature settings on different schema elements -[have different scopes](#cascading). - -You can set the `api_level` feature starting in edition 2023: - -```proto -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; -``` - -See also: -[Opaque API: Migration](/reference/go/opaque-migration) - -### `features.(pb.cpp).enum_name_uses_string_view` {#enum-name-string-view} - -**Languages:** C++ - -Before Edition 2024, all generated enum types provide the following function to -obtain the label out of an enum value, which has some overhead to construct the -`std::string` instances at runtime: - -```cpp -const std::string& Foo_Name(int); -``` - -The default feature value in Edition 2024 changes this signature to return -`absl::string_view` to allow for better storage decoupling and potential -memory/CPU savings. If you aren't ready to migrate, yet, you can override this -to set it back to its previous behavior. See -[string_view return type](/support/migration#string_view-return-type) -in the migration guide for more on this topic. - -**Values available:** - -* `true`: The enum uses `string_view` for its values. -* `false`: The enum uses `std::string` for its values. - -**Applicable to the following scopes:** file, enum - -**Added in:** Edition 2024 - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | ------- -2024 | `true` -2023 | `false` -proto3 | `false` -proto2 | `false` - -**Note:** Feature settings on different schema elements -[have different scopes](#cascading). - -### `features.(pb.java).large_enum` {#java-large_enum} - -**Languages:** Java - -This language-specific feature enables you to adopt new functionality that -handles large enums in Java without causing compiler errors. Note that this -feature replicates enum-like behavior but has some notable differences. For -example, switch statements are not supported. - -**Values available:** - -* `true`: Java enums will use the new functionality. -* `false`: Java enums will continue to use Java enums. - -**Applicable to the following scopes:** file, enum - -**Added in:** Edition 2024 - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | ------- -2024 | `false` -2023 | `false` -proto3 | `false` -proto2 | `false` - -**Note:** Feature settings on different schema elements -[have different scopes](#cascading). - -### `features.(pb.cpp/pb.java).legacy_closed_enum` {#legacy_closed_enum} - -**Languages:** C++, Java - -This feature determines whether a field with an open enum type should be behave -as if it was a closed enum. This allows editions to reproduce -[non-conformant behavior](/programming-guides/enum) in -Java and C++ from proto2 and proto3. - -This feature doesn't impact proto3 files, and so this section doesn't have a -before and after of a proto3 file. - -**Values available:** - -* `true`: Treats the enum as closed regardless of [`enum_type`](#enum_type). -* `false`: Respect whatever is set in the `enum_type`. - -**Applicable to the following scopes:** file, field - -**Added in:** Edition 2023 - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | ------- -2024 | `false` -2023 | `false` -proto3 | `false` -proto2 | `true` - -**Note:** Feature settings on different schema elements -[have different scopes](#cascading). - -The following code sample shows a proto2 file: - -```proto -syntax = "proto2"; - -import "myproject/proto3file.proto"; - -message Msg { - myproject.proto3file.Proto3Enum name = 1; -} -``` - -After running Prototiller, the equivalent code might look like this: - -```proto -edition = "2024"; - -import "myproject/proto3file.proto"; - -import "google/protobuf/cpp_features.proto"; -import "google/protobuf/java_features.proto"; - -message Msg { - myproject.proto3file.Proto3Enum name = 1 [ - features.(pb.cpp).legacy_closed_enum = true, - features.(pb.java).legacy_closed_enum = true - ]; -} -``` - -### `features.(pb.java).nest_in_file_class` {#java-nest_in_file} - -**Languages:** Java - -This feature controls whether the Java generator will nest the generated class -in the Java generated file class. Setting this option to `NO` is the equivalent -of setting `java_multiple_files = true` in proto2/proto3/edition 2023. - -The default outer classname is also updated to always be the camel-cased .proto -filename suffixed with Proto by default (for example, `foo/bar_baz.proto` -becomes `BarBazProto`). You can still override this using the -`java_outer_classname` file option and replace the pre-Edition 2024 default of -`BarBaz` or `BarBazOuterClass` depending on the presence of conflicts. - -**Values available:** - -* `NO`: Do not nest the generated class in the file class. -* `YES`: Nest the generated class in the file class. -* Legacy: Nesting behavior controlled by `java_multiple_files` option (see - go/java-proto-names#immutable-api-message-names). - -**Applicable to the following scopes:** message, enum, service - -**Added in:** Edition 2024 - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | ------- -2024 | `NO` -2023 | Legacy -proto3 | Legacy -proto2 | Legacy - -**Note:** Feature settings on different schema elements -[have different scopes](#cascading). - -### `features.(pb.cpp).string_type` {#string_type} - -**Languages:** C++ - -This feature determines how generated code should treat string fields. This -replaces the `ctype` option from proto2 and proto3, and offers a new -`string_type` feature. In Edition 2023, you can specify either `ctype` or -`string_type` on a field, but not both. In Edition 2024, the `ctype` option is -removed. - -**Values available:** - -* `VIEW`: Generates `string_view` accessors for the field. -* `CORD`: Generates `Cord` accessors for the field. Not supported on extension - fields. -* `STRING`: Generates `string` accessors for the field. - -**Applicable to the following scopes:** file, field - -**Added in:** Edition 2023 - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | -------- -2024 | `VIEW` -2023 | `STRING` -proto3 | `STRING` -proto2 | `STRING` - -**Note:** Feature settings on different schema elements -[have different scopes](#cascading). - -The following code sample shows a proto2 file: - -```proto -syntax = "proto2"; - -message Foo { - optional string bar = 6; - optional string baz = 7 [ctype = CORD]; -} -``` - -After running Prototiller, the equivalent code might look like this: - -```proto -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]; -} -``` - -The following shows a proto3 file: - -```proto -syntax = "proto3" - -message Foo { - string bar = 6; - string baz = 7 [ctype = CORD]; -} -``` - -After running Prototiller, the equivalent code might look like this: - -```proto -edition = "2024"; - -import "google/protobuf/cpp_features.proto"; - -message Foo { - string bar = 6 [features.(pb.cpp).string_type = STRING]; - string baz = 7 [features.(pb.cpp).string_type = CORD]; -} -``` - -### `features.(pb.java).utf8_validation` {#java-utf8_validation} - -**Languages:** Java - -This language-specific feature enables you to override the file-level settings -at the field level for Java only. - -This feature doesn't impact proto3 files, and so this section doesn't have a -before and after of a proto3 file. - -**Values available:** - -* `DEFAULT`: The behavior matches that set by - [`features.utf8_validation`](#utf8_validation). -* `VERIFY`: Overrides the file-level `features.utf8_validation` setting to - force it to `VERIFY` for Java only. - -**Applicable to the following scopes:** file, field - -**Added in:** Edition 2023 - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | --------- -2024 | `DEFAULT` -2023 | `DEFAULT` -proto3 | `DEFAULT` -proto2 | `DEFAULT` - -**Note:** Feature settings on different schema elements -[have different scopes](#cascading). - -The following code sample shows a proto2 file: - -```proto -syntax = "proto2"; - -option java_string_check_utf8=true; - -message MyMessage { - string foo = 1; - string bar = 2; -} -``` - -After running Prototiller, the equivalent code might look like this: - -```proto -edition = "2024"; - -import "google/protobuf/java_features.proto"; - -option features.utf8_validation = NONE; -option features.(pb.java).utf8_validation = VERIFY; -message MyMessage { - string foo = 1; - string bar = 2; -} -``` - -### `features.(pb.go).strip_enum_prefix` {#go-strip_enum_prefix} - -**Languages:** Go - -Enum values are not scoped by their containing enum name, so -[prefixing every value with the enum name is recommended](/programming-guides/style#enums): - -```proto -edition = "2024"; - -enum Strip { - STRIP_ZERO = 0; - STRIP_ONE = 1; -} -``` - -However, the generated Go code will now contain two prefixes! - -```go -type Strip int32 - -const ( - Strip_STRIP_ZERO Strip = 0 - Strip_STRIP_ONE Strip = 1 -) -``` - -The language-specific `strip_enum_prefix` feature determines whether the Go code -generator strips the repetitive prefix or not. - -**Values available:** - -* `STRIP_ENUM_PREFIX_KEEP`: Keep the name as-is, even if repetitive. -* `STRIP_ENUM_PREFIX_GENERATE_BOTH`: Generate both, a full name and a stripped - name (to help with migrating your Go code). -* `STRIP_ENUM_PREFIX_STRIP`: Strip the enum name prefix from enum value names. - -**Applicable to the following scopes:** file, enum, enum value - -**Added in:** Edition 2024 - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | ------------------------ -2024 | `STRIP_ENUM_PREFIX_KEEP` - -**Note:** Feature settings on different schema elements -[have different scopes](#cascading). - -You can set the `strip_enum_prefix` feature in edition 2024 (or newer) .proto -files: - -```proto -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; -} -``` - -The generated Go code will now strip the `STRIP` prefix: - -```go -type Strip int32 - -const ( - Strip_ZERO Strip = 0 - Strip_ONE Strip = 1 -) -``` - -## Preserving proto2 or proto3 Behavior in Edition 2023 {#preserving} - -You may want to move to the editions format but not deal with updates to the way -that generated code behaves yet. This section shows the changes that the -Prototiller tool makes to your .proto files to make edition-2023-based protos -behave like a proto2 or proto3 file. - -After these changes are made at the file level, you get the proto2 or proto3 -defaults. You can override at lower levels (message level, field level) to -consider additional behavior differences (such as -[required, proto3 optional](#caveats)) or if you want your definition to only be -*mostly* like proto2 or proto3. - -We recommend using Prototiller unless you have a specific reason not to. To -manually apply all of these instead of using Prototiller, add the content from -the following sections to the top of your .proto file. - -### Proto2 Behavior {#proto2-behavior} - -The following shows the settings to replicate proto2 behavior with Edition 2023. - -```proto -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 Behavior {#proto3-behavior} - -The following shows the settings to replicate proto3 behavior with Edition 2023. - -```proto -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 to 2024 {#2023-2024} - -The following shows the settings to replicate Edition 2023 behavior with Edition -2024. - -```proto -// 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; -} -``` - -### Caveats and Exceptions {#caveats} - -This section shows the changes that you'll need to make manually if you choose -not to use Prototiller. - -Setting the file-level defaults shown in the previous section sets the default -behaviors in most cases, but there are a few exceptions. - -**Edition 2023 and later** - -* `optional`: Remove all instances of the `optional` label and change the - [`features.field_presence`](#field_presence) to `EXPLICIT` if the file - default is `IMPLICIT`. -* `required`: Remove all instances of the `required` label and add the - [`features.field_presence=LEGACY_REQUIRED`](#field_presence) option at the - field level. -* `groups`: Unwrap the `groups` into a separate message and add the - `features.message_encoding = DELIMITED` option at the field level. See - [`features.message_encoding`](#message_encoding) for more on this. -* `java_string_check_utf8`: Remove this file option and replace it with the - [`features.(pb.java).utf8_validation`](#java-utf8_validation). You'll need - to import Java features, as covered in - [Language-specific Features](#lang-specific). -* `packed`: For proto2 files converted to editions format, remove the `packed` - field option and add `[features.repeated_field_encoding=PACKED]` at the - field level when you don't want the `EXPANDED` behavior that you set in - [Proto2 Behavior](#proto2-behavior). For proto3 files converted to editions - format, add `[features.repeated_field_encoding=EXPANDED]` at the field level - when you don't want the default proto3 behavior. - -**Edition 2024 and later** - -* (C++) `ctype`: Remove all instances of the `ctype` option and set the - [`features.(pb.cpp).string_type`](#string_type) value. -* (C++ and Go) `weak`: Remove weak - importsimports.. Use - [`import option`](/editions/overview#import-option) - instead. -* (Java) `java_multiple_files`: Remove `java_multiple_files` and use - [`features.(pb.java).nest_in_file_class`](#java-nest_in_file) instead. diff --git a/content/editions/implementation.md b/content/editions/implementation.md deleted file mode 100644 index 478f2d9cf..000000000 --- a/content/editions/implementation.md +++ /dev/null @@ -1,444 +0,0 @@ -+++ -title = "Implementing Editions Support" -weight = 43 -description = "Instructions for implementing Editions support in runtimes and plugins." -type = "docs" -+++ - -This topic explains how to implement editions in new runtimes and generators. - -## Overview {#overview} - -### Edition 2023 {#edition-2023} - -The first edition released is Edition 2023, which is designed to unify proto2 -and proto3 syntax. The features we’ve added to cover the difference in behaviors -are detailed in -[Feature Settings for Editions](/editions/features). - -### Feature Definition {#feature-definition} - -In addition to *supporting* editions and the global features we've defined, you -may want to define your own features to leverage the infrastructure. This will -allow you to define arbitrary features that can be used by your generators and -runtimes to gate new behaviors. The first step is to claim an extension number -for the `FeatureSet` message in descriptor.proto above 9999. You can send a -pull-request to us in GitHub, and it will be included in our next release (see, -for example, [#15439](https://github.com/protocolbuffers/protobuf/pull/15439)). - -Once you have your extension number, you can create your features proto (similar -to -[cpp_features.proto](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/cpp_features.proto)). -These will typically look something like: - -```proto -edition = "2023"; - -package foo; - -import "google/protobuf/descriptor.proto"; - -extend google.protobuf.FeatureSet { - MyFeatures features = ; -} - -message MyFeatures { - enum FeatureValue { - FEATURE_VALUE_UNKNOWN = 0; - VALUE1 = 1; - VALUE2 = 2; - } - - FeatureValue feature_value = 1 [ - targets = TARGET_TYPE_FIELD, - targets = TARGET_TYPE_FILE, - feature_support = { - edition_introduced: EDITION_2023, - edition_deprecated: EDITION_2024, - deprecation_warning: "Feature will be removed in 2025", - edition_removed: EDITION_2025, - }, - edition_defaults = { edition: EDITION_LEGACY, value: "VALUE1" }, - edition_defaults = { edition: EDITION_2024, value: "VALUE2" } - ]; -} -``` - -Here we’ve defined a new enum feature `foo.feature_value` (currently only -boolean and enum types are supported). In addition to defining the values it can -take, you also need to specify how it can be used: - -* **Targets** - specifies the type of proto descriptors this feature can be - attached to. This controls where users can explicitly specify the feature. - Every type must be explicitly listed. -* **Feature support** - specifies the lifetime of this feature relative to - edition. You must specify the edition it was introduced in, and it will not - be allowed before then. You can optionally deprecate or remove the feature - in later editions. -* **Edition defaults** - specifies any changes to the default value of the - feature. This must cover every supported edition, but you can leave out any - edition where the default didn’t change. Note that `EDITION_PROTO2` and - `EDITION_PROTO3` can be specified here to provide defaults for the “legacy” - editions (see [Legacy Editions](#legacy_editions)). - -#### What is a Feature? {#what-feature} - -Features are designed to provide a mechanism for ratcheting down bad behavior -over time, on edition boundaries. While the timeline for actually removing a -feature may be years (or decades) in the future, the desired goal of any feature -should be eventual removal. When a bad behavior is identified, you can introduce -a new feature that guards the fix. In the next edition (or possibly later), you -would flip the default value while still allowing users to retain their old -behavior when upgrading. At some point in the future you would mark the feature -deprecated, which would trigger a custom warning to any users overriding it. In -a later edition, you would then mark it removed, preventing users from -overriding it anymore (but the default value would still apply). Until support -for that last edition is dropped in a breaking release, the feature will remain -usable for protos stuck on older editions, giving them time to migrate. - -Flags that control optional behaviors you have no intention of removing are -better implemented as -[custom options](/programming-guides/proto2/#customoptions). -This is related to the reason we’ve restricted features to be either boolean or -enum types. Any behavior controlled by a (relatively) unbounded number of values -probably isn’t a good fit for the editions framework, since it’s not realistic -to eventually turn down that many different behaviors. - -One caveat to this is behaviors related to wire boundaries. Using -language-specific features to control serialization or parsing behavior can be -dangerous, since any other language could be on the other side. Wire-format -changes should always be controlled by global features in `descriptor.proto`, -which can be respected by every runtime uniformly. - -### Generators {#generators} - -Generators written in C++ get a lot for free, because they use the C++ runtime. -They don’t need to handle [Feature Resolution](#feature_resolution) themselves, -and if they need any feature extensions they can register them in -`GetFeatureExtensions` in their CodeGenerator. They can generally use -`GetResolvedSourceFeatures` for access to resolved features for a descriptor in -codegen and `GetUnresolvedSourceFeatures` for access to their own unresolved -features. - -Plugins written in the same language as the runtime they generate code for may -need some custom bootstrapping for their feature definitions. - -#### Explicit Support {#explicit-support} - -Generators must specify exactly which editions they support. This allows you to -safely add support for an edition after it’s been released, on your own -schedule. Protoc will reject any editions protos sent to generators that don’t -include `FEATURE_SUPPORTS_EDITIONS` in the `supported_features` field of their -`CodeGeneratorResponse`. Additionally, we have `minimum_edition` and -`maximum_edition` fields for specifying your precise support window. Once you’ve -defined all of the code and feature changes for a new edition, you can bump -`maximum_edition` to advertise this support. - -#### Codegen Tests {#codegen-tests} - -We have a set of codegen tests that can be used to lock down that Edition 2023 -produces no unexpected functional changes. These have been very useful in -languages like C++ and Java, where a significant amount of the functionality is -in gencode. On the other hand, in languages like Python, where the gencode is -basically just a collection of serialized descriptors, these are not quite as -useful. - -This infrastructure is not reusable yet, but is planned to be in a future -release. At that point you will be able to use them to verify that migrating to -editions doesn’t have any unexpected codegen changes. - -### Runtimes {#runtimes} - -Runtimes without reflection or dynamic messages should not need to do anything -to implement Editions. All of that logic should be handled by the code -generator. - -Languages *with* reflection but *without* dynamic messages need resolved -features, but may optionally choose to handle it in their generator only. This -can be done by passing both resolved and unresolved feature sets to the runtime -during codegen. This avoids re-implementing -[Feature Resolution](#feature_resolution) in the runtime with the main downside -being efficiency, since it will create a unique feature set for every -descriptor. - -Languages with dynamic messages must fully implement Editions, because they need -to be able to build descriptors at runtime. - -#### Syntax Reflection {#syntax_reflection} - -The first step in implementing Editions in a runtime with reflection is to -remove all direct checks of the `syntax` keyword. All of these should be moved -to finer-grained feature helpers, which can continue to use `syntax` if -necessary. - -The following feature helpers should be implemented on descriptors, with -language-appropriate naming: - -* `FieldDescriptor::has_presence` - Whether or not a field has explicit - presence - * Repeated fields *never* have presence - * Message, extension, and oneof fields *always* have explicit presence - * Everything else has presence iff `field_presence` is not `IMPLICIT` -* `FieldDescriptor::is_required` - Whether or not a field is required -* `FieldDescriptor::requires_utf8_validation` - Whether or not a field should - be checked for utf8 validity -* `FieldDescriptor::is_packed` - Whether or not a repeated field has packed - encoding -* `FieldDescriptor::is_delimited` - Whether or not a message field has - delimited encoding -* `EnumDescriptor::is_closed` - Whether or not a field is closed - -{{% alert title="Note" color="note" %}} In -most languages, the message encoding feature is still currently signaled by -`TYPE_GROUP` and required fields still have `LABEL_REQUIRED` set. This is not -ideal, and was done to make downstream migrations easier. Eventually, these -should be migrated to the appropriate helpers and -`TYPE_MESSAGE/LABEL_OPTIONAL`.{{% /alert %}} - -Downstream users should migrate to these new helpers instead of using syntax -directly. The following class of existing descriptor APIs should ideally be -deprecated and eventually removed, since they leak syntax information: - -* `FileDescriptor` syntax -* Proto3 optional APIs - * `FieldDescriptor::has_optional_keyword` - * `OneofDescriptor::is_synthetic` - * `Descriptor::*real_oneof*` - should be renamed to just “oneof” and the - existing “oneof” helpers should be removed, since they leak information - about synthetic oneofs (which don’t exist in editions). -* Group type - * The `TYPE_GROUP` enum value should be removed, replaced with the - `is_delimited` helper. -* Required label - * The `LABEL_REQUIRED` enum value should be removed, replaced with the - `is_required` helper. - -There are many classes of user code where these checks exist but *aren’t* -hostile to editions. For example, code that needs to handle proto3 `optional` -specially because of its synthetic oneof implementation won’t be hostile to -editions as long as the polarity is something like `syntax == "proto3"` (rather -than checking `syntax != "proto2"`). - -If it’s not possible to remove these APIs entirely, they should be deprecated -and discouraged. - -#### Feature Visibility {#visibility} - -As discussed in -[editions-feature-visibility](https://github.com/protocolbuffers/protobuf/blob/main/docs/design/editions/editions-feature-visibility.md), -feature protos should remain an internal detail of any Protobuf implementation. -The *behaviors* they control should be exposed via descriptor methods, but the -protos themselves should not. Notably, this means that any options that are -exposed to the users need to have their `features` fields stripped out. - -The one case where we permit features to leak out is when serializing -descriptors. The resulting descriptor protos should be a faithful representation -of the original proto files, and should contain *unresolved features* inside of -the options. - -#### Legacy Editions {#legacy_editions} - -As discussed more in -[legacy-syntax-editions](https://github.com/protocolbuffers/protobuf/blob/main/docs/design/editions/legacy-syntax-editions.md), -a great way to get early coverage of your editions implementation is to unify -proto2, proto3, and editions. This effectively migrates proto2 and proto3 to -editions under the hood, and makes all of the helpers implemented in -[Syntax Reflection](#syntax_reflection) use features exclusively (instead of -branching on syntax). This can be done by inserting a *feature inference* phase -into [Feature Resolution](#feature_resolution), where various aspects of the -proto file can inform what features are appropriate. These features can then be -merged into the parent’s features to get the resolved feature set. - -While we provide reasonable defaults for proto2/proto3 already, for edition 2023 -the following additional inferences are required: - -* required - we infer `LEGACY_REQUIRED` presence when a field has - `LABEL_REQUIRED` -* groups - we infer `DELIMITED` message encoding when a field has `TYPE_GROUP` -* packed - we infer `PACKED` encoding when the `packed` option is true -* expanded - we infer `EXPANDED` encoding when a proto3 field has `packed` - explicitly set to false - -#### Conformance Tests {#conformance-tests} - -Editions-specific conformance tests have been added, but need to be opted-in to. -A `--maximum_edition 2023` flag can be passed to the runner to enable these. You -will need to configure your testee binary to handle the following new message -types: - -* `protobuf_test_messages.editions.proto2.TestAllTypesProto2` - Identical to - the old proto2 message, but transformed to edition 2023 -* `protobuf_test_messages.editions.proto3.TestAllTypesProto3` - Identical to - the old proto3 message, but transformed to edition 2023 -* `protobuf_test_messages.editions.TestAllTypesEdition2023` - Used to cover - edition-2023-specific test cases - -### Feature Resolution {#feature-resolution} - -Editions use lexical scoping to define features, meaning that any non-C++ code -that needs to implement editions support will need to reimplement our *feature -resolution* algorithm. However, the bulk of the work is handled by protoc -itself, which can be configured to output an intermediate `FeatureSetDefaults` -message. This message contains a “compilation” of a set of feature definition -files, laying out the default feature values in every edition. - -For example, the feature definition above would compile to the following -defaults between proto2 and edition 2025 (in text-format notation): - -``` -defaults { - edition: EDITION_PROTO2 - overridable_features { [foo.features] {} } - fixed_features { - // Global feature defaults… - [foo.features] { feature_value: VALUE1 } - } -} -defaults { - edition: EDITION_PROTO3 - overridable_features { [foo.features] {} } - fixed_features { - // Global feature defaults… - [foo.features] { feature_value: VALUE1 } - } -} -defaults { - edition: EDITION_2023 - overridable_features { - // Global feature defaults… - [foo.features] { feature_value: VALUE1 } - } -} -defaults { - edition: EDITION_2024 - overridable_features { - // Global feature defaults… - [foo.features] { feature_value: VALUE2 } - } -} -defaults { - edition: EDITION_2025 - overridable_features { - // Global feature defaults… - } - fixed_features { [foo.features] { feature_value: VALUE2 } } -} -minimum_edition: EDITION_PROTO2 -maximum_edition: EDITION_2025 - -``` - -Global feature defaults are left out for compactness, but they would also be -present. This object contains an ordered list of every edition with a unique set -of defaults (some editions may end up not being present) within the specified -range. Each set of defaults is split into *overridable* and *fixed* features. -The former are supported features for the edition that can be freely overridden -by users. The fixed features are those which haven’t yet been introduced or have -been removed, and can’t be overridden by users. - -We provide a Bazel rule for compiling these intermediate objects: - -``` -load("@com_google_protobuf//editions:defaults.bzl", "compile_edition_defaults") - -compile_edition_defaults( - name = "my_defaults", - srcs = ["//some/path:lang_features_proto"], - maximum_edition = "PROTO2", - minimum_edition = "2024", -) -``` - -The output `FeatureSetDefaults` can be embedded into a raw string literal in -whatever language you need to do feature resolution in. We also provide an -`embed_edition_defaults` macro to do this: - -``` -embed_edition_defaults( - name = "embed_my_defaults", - defaults = ":my_defaults", - output = "my_defaults.h", - placeholder = "DEFAULTS_DATA", - template = "my_defaults.h.template", -) -``` - -Alternatively, you can invoke protoc directly (outside of Bazel) to generate -this data: - -``` -protoc --edition_defaults_out=defaults.binpb --edition_defaults_minimum=PROTO2 --edition_defaults_maximum=2023 -``` - -Once the defaults message is hooked up and parsed by your code, feature -resolution for a file descriptor at a given edition follows a simple algorithm: - -1. Validate that the edition is in the appropriate range [`minimum_edition`, - `maximum_edition`] -2. Binary-search the ordered `defaults` field for the highest entry less than - or equal to the edition -3. Merge `overridable_features` into `fixed_features` from the selected - defaults -4. Merge any explicit features set on the descriptor (the `features` field in - the file options) - -From there, you can recursively resolve features for all other descriptors: - -1. Initialize to the parent descriptor’s feature set -2. Merge any explicit features set on the descriptor (the `features` field in - the options) - -For determining the “parent” descriptor, you can reference our -[C++ implementation](https://github.com/protocolbuffers/protobuf/blob/27.x/src/google/protobuf/descriptor.cc#L1129). -This is straightforward in most cases, but extensions are a bit surprising -because their parent is the enclosing scope rather than the extendee. Oneofs -also need to be considered as the parent of their fields. - -#### Conformance Tests {#conformance-tests} - -In a future release, we plan to add conformance tests to verify feature -resolution cross-language. Until then, our regular -[conformance tests](#conformance_tests) do give partial coverage, and our -[example inheritance unit tests](https://github.com/protocolbuffers/protobuf/blob/27.x/python/google/protobuf/internal/descriptor_test.py#L1386) -can be ported to provide more comprehensive coverage. - -### Examples {#examples} - -Below are some real examples of how we implemented editions support in our -runtimes and plugins. - -#### Java {#java} - -* [#14138](https://github.com/protocolbuffers/protobuf/pull/14138) - Bootstrap - compiler with C++ gencode for Java features proto -* [#14377](https://github.com/protocolbuffers/protobuf/pull/14377) - Use - features in Java, Kotlin, and Java Lite code generators, including codegen - tests -* [#15210](https://github.com/protocolbuffers/protobuf/pull/15210) - Use - features in Java full runtimes covering Java features bootstrap, feature - resolution, and legacy editions, along with unit-tests and conformance - testing - -#### Pure Python {#python} - -* [#14546](https://github.com/protocolbuffers/protobuf/pull/14546) - Setup - codegen tests in advance -* [#14547](https://github.com/protocolbuffers/protobuf/pull/14547) - Fully - implements editions in one shot, along with unit-tests and conformance - testing - -#### 𝛍pb {#upb} - -* [#14638](https://github.com/protocolbuffers/protobuf/pull/14638) - First - pass at editions implementation covering feature resolution and legacy - editions -* [#14667](https://github.com/protocolbuffers/protobuf/pull/14667) - Added - more complete handling of field label/type, support for upb’s code - generator, and some tests -* [#14678](https://github.com/protocolbuffers/protobuf/pull/14678) - Hooks up - upb to the Python runtime, with more unit tests and conformance tests - -#### Ruby {#ruby} - -* [#16132](https://github.com/protocolbuffers/protobuf/pull/16132) - Hook up - upb/Java to all four Ruby runtimes for full editions support diff --git a/content/editions/overview.md b/content/editions/overview.md deleted file mode 100644 index 7586cca02..000000000 --- a/content/editions/overview.md +++ /dev/null @@ -1,474 +0,0 @@ -+++ -title = "Protobuf Editions Overview" -linkTitle = "Overview" -weight = 42 -description = "An overview of the Protobuf Editions functionality." -type = "docs" -+++ - -Protobuf Editions replace the proto2 and proto3 designations that we have used -for Protocol Buffers. Instead of adding `syntax = "proto2"` or `syntax = -"proto3"` at the top of proto definition files, you use an edition number, such -as `edition = "2024"`, to specify the default behaviors your file will have. -Editions enable the language to evolve incrementally over time. - -Instead of the hardcoded behaviors that older versions have had, editions -represent a collection of [features](/editions/features) -with a default value (behavior) per feature. Features are options on a file, -message, field, enum, and so on, that specify the behavior of protoc, the code -generators, and protobuf runtimes. You can explicitly override a behavior at -those different levels (file, message, field, ...) when your needs don't match -the default behavior for the edition you've selected. You can also override your -overrides. The [section later in this topic on lexical scoping](#scoping) goes -into more detail on that. - -**NOTE:** The latest released edition is 2024. - -## Lifecycle of a Feature {#lifecycles} - -Editions provide the fundamental increments for the lifecycle of a feature. -Features have an expected lifecycle: introducing -it, changing its default behavior, deprecating it, and then removing it. For -example: - -1. Edition 2031 creates `feature.amazing_new_feature` with a default value of - `false`. This value maintains the same behavior as all earlier editions. - That is, it defaults to no impact. Not all new features will default to the - no-op option, but for the sake of this example, `amazing_new_feature` does. - -2. Developers update their .proto files to `edition = "2031"`. - -3. A later edition, such as edition 2033, switches the default of - `feature.amazing_new_feature` from `false` to `true`. This is the desired - behavior for all protos, and the reason that the protobuf team created the - feature. - - Using the Prototiller tool to migrate earlier versions of proto files to - edition 2033 adds explicit `feature.amazing_new_feature = false` entries as - needed to continue to retain the previous behavior. Developers remove these - newly-added settings when they want the new behavior to apply to their - .proto files. - - - -4. At some point, `feature.amazing_new_feature` is marked deprecated in an - edition and removed in a later one. - - When a feature is removed, the code generators for that behavior and the - runtime libraries that support it may also be removed. The timelines will be - generous, though. Following the example in the earlier steps of the - lifecycle, the deprecation might happen in edition 2034 but not be removed - until edition 2036, roughly two years later. Removing a feature will always - initiate a major version bump. - - - -You will have the full -window of the Google migration plus the deprecation window to upgrade your code. - -The preceding lifecycle example used boolean values for the features, but -features may also use enums. For example, `features.field_presence` has values -`LEGACY_REQUIRED`, `EXPLICIT`, and `IMPLICIT.` - -## Migrating to Protobuf Editions {#migrating} - -Editions won't break existing binaries and don't change a message's binary, -text, or JSON serialization format. Edition 2023 was as minimally disruptive as -possible. It established the baseline and combined proto2 and proto3 definitions -into a new single definition format. - -As more editions are released, default behaviors for features may change. You -can have Prototiller do a no-op transformation of your .proto file or you can -choose to accept some or all of the new behaviors. Editions are planned to be -released roughly once a year. - -### Proto2 to Editions {#proto2-migration} - -This section shows a proto2 file, and what it might look like after running the -Prototiller tool to change the definition files to use Protobuf Editions syntax. - -
- -#### Proto2 Syntax {.new-tab} - -```proto -// proto2 file -syntax = "proto2"; - -package com.example; - -message Player { - // in proto2, optional fields have explicit presence - optional string name = 1 [default = "N/A"]; - // proto2 still supports the problematic "required" field rule - required int32 id = 2; - // in proto2 this is not packed by default - repeated int32 scores = 3; - - enum Handed { - HANDED_UNSPECIFIED = 0; - HANDED_LEFT = 1; - HANDED_RIGHT = 2; - HANDED_AMBIDEXTROUS = 3; - } - - // in proto2 enums are closed - optional Handed handed = 4; - - reserved "gender"; -} -``` - -#### Editions Syntax {.new-tab} - -```proto -// Edition version of proto2 file -edition = "2024"; - -package com.example; - -option features.utf8_validation = NONE; -option features.enforce_naming_style = STYLE_LEGACY; -option features.default_symbol_visibility = EXPORT_ALL; - -// Sets the default behavior for C++ strings -option features.(pb.cpp).string_type = STRING; - -message Player { - // fields have explicit presence, so no explicit setting needed - string name = 1 [default = "N/A"]; - // to match the proto2 behavior, LEGACY_REQUIRED is set at the field level - int32 id = 2 [features.field_presence = LEGACY_REQUIRED]; - // to match the proto2 behavior, EXPANDED is set at the field level - repeated int32 scores = 3 [features.repeated_field_encoding = EXPANDED]; - - export enum Handed { - // this overrides the default editions behavior, which is OPEN - option features.enum_type = CLOSED; - HANDED_UNSPECIFIED = 0; - HANDED_LEFT = 1; - HANDED_RIGHT = 2; - HANDED_AMBIDEXTROUS = 3; - } - - Handed handed = 4; - - reserved gender; -} -``` - -
- -### Proto3 to Editions {#proto3-migration} - -This section shows a proto3 file, and what it might look like after running the -Prototiller tool to change the definition files to use Protobuf Editions syntax. - -
- -#### Proto3 Syntax {.new-tab} - -```proto -// proto3 file -syntax = "proto3"; - -package com.example; - -message Player { - // in proto3, optional fields have explicit presence - optional string name = 1; - // in proto3 no specified field rule defaults to implicit presence - int32 id = 2; - // in proto3 this is packed by default - repeated int32 scores = 3; - - enum Handed { - HANDED_UNSPECIFIED = 0; - HANDED_LEFT = 1; - HANDED_RIGHT = 2; - HANDED_AMBIDEXTROUS = 3; - } - - // in proto3 enums are open - optional Handed handed = 4; - - reserved "gender"; -} -``` - -#### Editions Syntax {.new-tab} - -```proto -// Editions version of proto3 file -edition = "2024"; - -package com.example; - -option features.utf8_validation = NONE; -option features.enforce_naming_style = STYLE_LEGACY; -option features.default_symbol_visibility = EXPORT_ALL; - -// Sets the default behavior for C++ strings -option features.(pb.cpp).string_type = STRING; - -message Player { - // fields have explicit presence, so no explicit setting needed - string name = 1 [default = "N/A"]; - // to match the proto3 behavior, IMPLICIT is set at the field level - int32 id = 2 [features.field_presence = IMPLICIT]; - // PACKED is the default state, and is provided just for illustration - repeated int32 scores = 3 [features.repeated_field_encoding = PACKED]; - - export enum Handed { - HANDED_UNSPECIFIED = 0; - HANDED_LEFT = 1; - HANDED_RIGHT = 2; - HANDED_AMBIDEXTROUS = 3; - } - - Handed handed = 4; - - reserved gender; -} -``` - -
- - - -### Lexical Scoping {#scoping} - -Editions syntax supports lexical scoping, with a per-feature list of allowed -targets. For example, in Edition 2023, features can be specified at only the -file level or the lowest level of granularity. The implementation of lexical -scoping enables you to set the default behavior for a feature across an entire -file, and then override that behavior at the message, field, enum, enum value, -oneof, service, or method level. Settings made at a higher level (file, message) -apply when no setting is made within the same scope (field, enum value). Any -features not explicitly set conform to the behavior defined in the edition -version used for the .proto file. - -The following code sample shows some features being set at the file, field, and -enum level. - -```proto {highlight="lines:3,7,16"} -edition = "2024"; - -option features.enum_type = CLOSED; - -message Person { - string name = 1; - int32 id = 2 [features.field_presence = IMPLICIT]; - - enum Pay_Type { - PAY_TYPE_UNSPECIFIED = 1; - PAY_TYPE_SALARY = 2; - PAY_TYPE_HOURLY = 3; - } - - enum Employment { - option features.enum_type = OPEN; - EMPLOYMENT_UNSPECIFIED = 0; - EMPLOYMENT_FULLTIME = 1; - EMPLOYMENT_PARTTIME = 2; - } - Employment employment = 4; -} -``` - -In the preceding example, the presence feature is set to `IMPLICIT`; it would -default to `EXPLICIT` if it wasn't set. The `Pay_Type` `enum` will be `CLOSED`, -as it applies the file-level setting. The `Employment` `enum`, though, will be -`OPEN`, as it is set within the enum. - -### Prototiller {#prototiller} - -When the Prototiller tool is launched, we will -provide both a migration guide and migration tooling to ease the migration to -and between editions. The tool will enable you to: - -* convert proto2 and proto3 definition files to the new editions syntax, at - scale -* migrate files from one edition to another -* manipulate proto files in other ways - -### Backward Compatibility {#compatibility} - -We are building Protobuf Editions to be as minimally disruptive as possible. For -example, you can import proto2 and proto3 definitions into editions-based -definition files, and vice versa: - -```proto -// file myproject/foo.proto -syntax = "proto2"; - -enum Employment { - EMPLOYMENT_UNSPECIFIED = 0; - EMPLOYMENT_FULLTIME = 1; - EMPLOYMENT_PARTTIME = 2; -} -``` - -```proto -// file myproject/edition.proto -edition = "2024"; - -import "myproject/foo.proto"; -``` - -While the generated code changes when you move from proto2 or proto3 to -editions, the wire format does not. You'll still be able to access proto2 and -proto3 data files or file streams using your editions-syntax proto definitions. - -### Grammar Changes {#syntax} - -There are some grammar changes in editions compared to proto2 and proto3. - -#### Syntax Description {#syntax-descrip} - -Instead of the `syntax` element, you use an `edition` element: - -```proto -syntax = "proto2"; -syntax = "proto3"; -edition = "2028"; -``` - -#### Reserved Names {#reserved-names} - -You no longer put field names and enum value names in quotation marks when -reserving them: - -```proto -reserved foo, bar; -``` - -#### Group Syntax {#group-syntax} - -Group syntax, available in proto2, is removed in editions. The special -wire-format that groups used is still available by using `DELIMITED` message -encoding. - -#### Required Label {#required-label} - -The `required` label, available only in proto2, is unavailable in editions. The -underlying functionality is still available -by using `features.field_presence=LEGACY_REQUIRED`. - -#### `import option` {#import-option} - -Edition 2024 added support for option imports using the syntax `import option`. - -Option imports must come after any other `import` statements. - -Unlike normal `import` statements, `import option` only imports custom options -defined in a `.proto` file, without importing other symbols. - -This means that messages and enums are excluded from the option import. In the -following example, the `Bar` message cannot be used as a field type in -`foo.proto`, but options with type `Bar` can still be set. - -```proto -// bar.proto -edition = "2024"; - -import "google/protobuf/descriptor.proto"; - -message Bar { - bool bar = 1; -} - -extend proto2.FileOptions { - bool file_opt1 = 5000; - Bar file_opt2 = 5001; -} - -// foo.proto: -edition = "2024"; - -import option "bar.proto"; - -option (file_opt1) = true; -option (file_opt2) = {bar: true}; - -message Foo { - // Bar bar = 1; // This is not allowed -} -``` - -Option imports do not require generated code for its symbols and should thus be -provided as `option_deps` in `proto_library` instead of `deps`. This avoids -generating unreachable code. - -```proto -proto_library( - name = "foo", - srcs = ["foo.proto"], - option_deps = [":custom_option_proto"] -) -``` - -Option imports and `option_deps` are strongly recommended when importing -protobuf language features and other custom options to avoid generating -unnecessary code. - -This replaces `import weak`, which was removed in Edition 2024. - -#### `export` / `local` Keywords {#export-local} - -`export` and `local` keywords were added in Edition 2024 as modifiers for the -symbol visibility of importable symbols, from the default behavior specified by -[`features.default_symbol_visibility`](/editions/features#symbol-vis). - -This controls which symbols can be imported from other proto files, but does not -affect code-generation. - -In Edition 2024, these can be set on all `message` and `enum` symbols by -default. However, some values of the `default_symbol_visibility` feature further -restrict which symbols are exportable. - -Example: - -```proto -// Top-level symbols are exported by default in Edition 2024 -message LocalMessage { - int32 baz = 1; - // Nested symbols are local by default in Edition 2024; applying the `export` - // keyword overrides this - export enum ExportedNestedEnum { - UNKNOWN_EXPORTED_NESTED_ENUM_VALUE = 0; - } -} - -// The `local` keyword overrides the default behavior of exporting messages -local message AnotherMessage { - int32 foo = 1; -} -``` - -#### `import weak` and Weak Field Option {#import-weak} - -As of Edition 2024, weak imports are no longer allowed. - -If you previously relied on `import weak` to declare a "weak -dependency"—to import custom options without generated code for C++ and -Go—you should instead migrate to use `import option`. - -See [`import option`](/editions/overview#import-option) -for more details. - -#### `ctype` Field Option {#ctype} - -As of Edition 2024, `ctype` field option is no longer allowed. Use the -`string_type` feature instead. - -See -[`features.(pb.cpp).string_type`](/editions/features#string_type) -for more details. - -#### `java_multiple_files` File Option {#java-mult-files} - -As of Edition 2024, the `java_multiple_files` file option no longer available. -Use the -[`features.(pb.java).nest_in_file_class`](/editions/features#java-nest_in_file) -Java feature, instead. diff --git a/content/forum-link.md b/content/forum-link.md deleted file mode 100644 index 1d743b80f..000000000 --- a/content/forum-link.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "Forum" -manualLink: "https://groups.google.com/g/protobuf" -manualLinkTarget: "_blank" -weight: 1040 ---- \ No newline at end of file diff --git a/content/getting-started/_index.md b/content/getting-started/_index.md deleted file mode 100644 index 7ca41d2fb..000000000 --- a/content/getting-started/_index.md +++ /dev/null @@ -1,14 +0,0 @@ - - -+++ -title = "Tutorials" -weight = 200 -description = "Each tutorial in this section shows you how to implement a simple application using protocol buffers in your favourite language, introducing you to the language's protocol buffer API as well as showing you the basics of creating and using .proto files." -type = "docs" -+++ - -The complete sample code for each application is also provided. - -The tutorials don't assume that you know anything about protocol buffers, but do -assume that you are comfortable writing code in your chosen language, including -using file I/O. diff --git a/content/getting-started/cpptutorial.md b/content/getting-started/cpptutorial.md deleted file mode 100644 index 403d4bf5c..000000000 --- a/content/getting-started/cpptutorial.md +++ /dev/null @@ -1,629 +0,0 @@ -+++ -title = "Protocol Buffer Basics: C++" -weight = 210 -linkTitle = "C++" -description = "A basic C++ programmers introduction to working with protocol buffers." -type = "docs" -+++ - -This tutorial provides a basic C++ programmers introduction to working with -protocol buffers. By walking through creating a simple example application, it -shows you how to - -- Define message formats in a `.proto` file. -- Use the protocol buffer compiler. -- Use the C++ protocol buffer API to write and read messages. - -This isn't a comprehensive guide to using protocol buffers in C++. For more -detailed reference information, see the -[Protocol Buffer Language Guide](/programming-guides/editions), -the [C++ API Reference](/reference/cpp/api-docs), the -[C++ Generated Code Guide](/reference/cpp/cpp-generated), -and the -[Encoding Reference](/programming-guides/encoding). - -## The Problem Domain {#problem-domain} - -The example we're going to use is a very simple "address book" application that -can read and write people's contact details to and from a file. Each person in -the address book has a name, an ID, an email address, and a contact phone -number. - -How do you serialize and retrieve structured data like this? There are a few -ways to solve this problem: - -- The raw in-memory data structures can be sent/saved in binary form. Over - time, this is a fragile approach, as the receiving/reading code must be - compiled with exactly the same memory layout, endianness, etc. Also, as - files accumulate data in the raw format and copies of software that are - wired for that format are spread around, it's very hard to extend the - format. -- You can invent an ad-hoc way to encode the data items into a single - string -- such as encoding 4 ints as "12:3:-23:67". This is a simple and - flexible approach, although it does require writing one-off encoding and - parsing code, and the parsing imposes a small run-time cost. This works best - for encoding very simple data. -- Serialize the data to XML. This approach can be very attractive since XML is - (sort of) human readable and there are binding libraries for lots of - languages. This can be a good choice if you want to share data with other - applications/projects. However, XML is notoriously space intensive, and - encoding/decoding it can impose a huge performance penalty on applications. - Also, navigating an XML DOM tree is considerably more complicated than - navigating simple fields in a class normally would be. - -Instead of these options, you can use protocol buffers. Protocol buffers are the -flexible, efficient, automated solution to solve exactly this problem. With -protocol buffers, you write a `.proto` description of the data structure you -wish to store. From that, the protocol buffer compiler creates a class that -implements automatic encoding and parsing of the protocol buffer data with an -efficient binary format. The generated class provides getters and setters for -the fields that make up a protocol buffer and takes care of the details of -reading and writing the protocol buffer as a unit. Importantly, the protocol -buffer format supports the idea of extending the format over time in such a way -that the code can still read data encoded with the old format. - -## Where to Find the Example Code {#example-code} - -The example code is included in the source code package, under the -["examples" directory](https://github.com/protocolbuffers/protobuf/tree/main/examples). - -## Defining Your Protocol Format {#protocol-format} - -To create your address book application, you'll need to start with a `.proto` -file. The definitions in a `.proto` file are simple: you add a *message* for -each data structure you want to serialize, then specify a name and a type for -each field in the message. Here is the `.proto` file that defines your messages, -`addressbook.proto`. - -```proto -edition = "2023"; - -package tutorial; - -message Person { - string name = 1; - int32 id = 2; - string email = 3; - - enum PhoneType { - PHONE_TYPE_UNSPECIFIED = 0; - PHONE_TYPE_MOBILE = 1; - PHONE_TYPE_HOME = 2; - PHONE_TYPE_WORK = 3; - } - - message PhoneNumber { - string number = 1; - PhoneType type = 2; - } - - repeated PhoneNumber phones = 4; -} - -message AddressBook { - repeated Person people = 1; -} - -``` - -As you can see, the syntax is similar to C++ or Java. Let's go through each part -of the file and see what it does. - -The `.proto` file starts with an `edition` declaration. Editions replace the -older `syntax = "proto2"` and `syntax = "proto3"` declarations and provide a -more flexible way to evolve the language over time. - -Next is a package declaration, which helps to prevent naming conflicts between -different projects. In C++, your generated classes will be placed in a namespace -matching the package name. - -Following the package declaration are your message definitions. A message is -just an aggregate containing a set of typed fields. Many standard simple data -types are available as field types, including `bool`, `int32`, `float`, -`double`, and `string`. You can also add further structure to your messages by -using other message types as field types -- in the above example the `Person` -message contains `PhoneNumber` messages, while the `AddressBook` message -contains `Person` messages. You can even define message types nested inside -other messages -- as you can see, the `PhoneNumber` type is defined inside -`Person`. You can also define enum types if you want one of your fields to have -one of a predefined list of values -- here you want to specify that a phone -number can be one of several types. - -The " = 1", " = 2" markers on each element identify the unique field number that -field uses in the binary encoding. Field numbers 1-15 require one less byte to -encode than higher numbers, so as an optimization you can decide to use those -numbers for the commonly used or repeated elements, leaving field numbers 16 and -higher for less-commonly used elements. - -Fields can be one of the following: - -* singular: By default, fields are optional, meaning the field may or may not - be set. If a singular field is not set, a type-specific default is used: - zero for numeric types, the empty string for strings, false for bools, and - the first defined enum value for enums (which must be 0). Note that you - cannot explicitly set a field to `singular`. This is a description of a - non-repeated field. - -* **`repeated`**: The field may be repeated any number of times (including - zero). The order of the repeated values will be preserved. Think of repeated - fields as dynamically sized arrays. - -In older versions of protobuf, a `required` keyword existed, but it has been -found to be brittle and is not supported in modern protobufs (though editions -does have a feature you can use to enable it, for backward compatibility). - -You'll find a complete guide to writing `.proto` files -- including all the -possible field types -- in the -[Protocol Buffer Language Guide](/programming-guides/editions). -Don't go looking for facilities similar to class inheritance, though -- protocol -buffers don't do that. - -## Compiling Your Protocol Buffers {#compiling-protocol-buffers} - -Now that you have a `.proto`, the next thing you need to do is generate the -classes you'll need to read and write `AddressBook` (and hence `Person` and -`PhoneNumber`) messages. To do this, you need to run the protocol buffer -compiler `protoc` on your `.proto`: - -1. If you haven't installed the compiler, follow the instructions in - [Protocol Buffer Compiler Installation](/installation/). - -2. Now run the compiler, specifying the source directory (where your - application's source code lives -- the current directory is used if you - don't provide a value), the destination directory (where you want the - generated code to go; often the same as `$SRC_DIR`), and the path to your - `.proto`. In this case: - - ```shell - protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto - ``` - - Because you want C++ classes, you use the `--cpp_out` option -- similar - options are provided for other supported languages. - -This generates the following files in your specified destination directory: - -- `addressbook.pb.h`, the header which declares your generated classes. -- `addressbook.pb.cc`, which contains the implementation of your classes. - -## The Protocol Buffer API {#protobuf-api} - -Let's look at some of the generated code and see what classes and functions the -compiler has created for you. If you look in `addressbook.pb.h`, you can see -that you have a class for each message you specified in `addressbook.proto`. -Looking closer at the `Person` class, you can see that the compiler has -generated accessors for each field. For example, for the `name`, `id`, `email`, -and `phones` fields, you have these methods: - -```cpp - // name - bool has_name() const; // Only for explicit presence - void clear_name(); - const ::std::string& name() const; - void set_name(const ::std::string& value); - ::std::string* mutable_name(); - - // id - bool has_id() const; - void clear_id(); - int32_t id() const; - void set_id(int32_t value); - - // email - bool has_email() const; - void clear_email(); - const ::std::string& email() const; - void set_email(const ::std::string& value); - ::std::string* mutable_email(); - - // phones - int phones_size() const; - void clear_phones(); - const ::google::protobuf::RepeatedPtrField< ::tutorial::Person_PhoneNumber >& phones() const; - ::google::protobuf::RepeatedPtrField< ::tutorial::Person_PhoneNumber >* mutable_phones(); - const ::tutorial::Person_PhoneNumber& phones(int index) const; - ::tutorial::Person_PhoneNumber* mutable_phones(int index); - ::tutorial::Person_PhoneNumber* add_phones(); -``` - -As you can see, the getters have exactly the name as the field in lowercase, and -the setter methods begin with `set_`. There are also `has_` methods for singular -fields that have explicit presence tracking, which return true if that field has -been set. Finally, each field has a `clear_` method that un-sets the field back -to its default state. - -While the numeric `id` field just has the basic accessor set described above, -the `name` and `email` fields have a couple of extra methods because they're -strings -- a `mutable_` getter that lets you get a direct pointer to the string, -and an extra setter. Note that you can call `mutable_email()` even if `email` is -not already set; it will be initialized to an empty string automatically. If you -had a repeated message field in this example, it would also have a `mutable_` -method but not a `set_` method. - -Repeated fields also have some special methods -- if you look at the methods for -the repeated `phones` field, you'll see that you can - -- check the repeated field's `_size` (in other words, how many phone numbers - are associated with this `Person`). -- get a specified phone number using its index. -- update an existing phone number at the specified index. -- add another phone number to the message which you can then edit (repeated - scalar types have an `add_` that just lets you pass in the new value). - -For more information on exactly what members the protocol compiler generates for -any particular field definition, see the -[C++ generated code reference](/reference/cpp/cpp-generated). - -### Enums and Nested Classes {#enums-nested-classes} - -The generated code includes a `PhoneType` enum that corresponds to your `.proto` -enum. You can refer to this type as `Person::PhoneType` and its values as -`Person::PHONE_TYPE_MOBILE`, `Person::PHONE_TYPE_HOME`, and -`Person::PHONE_TYPE_WORK` (the implementation details are a little more -complicated, but you don't need to understand them to use the enum). - -The compiler has also generated a nested class for you called -`Person::PhoneNumber`. If you look at the code, you can see that the "real" -class is actually called `Person_PhoneNumber`, but a typedef defined inside -`Person` allows you to treat it as if it were a nested class. The only case -where this makes a difference is if you want to forward-declare the class in -another file -- you cannot forward-declare nested types in C++, but you can -forward-declare `Person_PhoneNumber`. - -### Standard Message Methods {#standard-message-methods} - -Each message class also contains a number of other methods that let you check or -manipulate the entire message, including: - -- `bool IsInitialized() const;`: checks if all required fields have been set. -- `string DebugString() const;`: returns a human-readable representation of - the message, particularly useful for debugging. -- `void CopyFrom(const Person& from);`: overwrites the message with the given - message's values. -- `void Clear();`: clears all the elements back to the empty state. - -These and the I/O methods described in the following section implement the -`Message` interface shared by all C++ protocol buffer classes. For more info, -see the -[complete API documentation for `Message`](/reference/cpp/api-docs/google.protobuf.message#Message). - -### Parsing and Serialization {#parsing-serialization} - -Finally, each protocol buffer class has methods for writing and reading messages -of your chosen type using the protocol buffer -[binary format](/programming-guides/encoding). These -include: - -- `bool SerializeToString(string* output) const;`: serializes the message and - stores the bytes in the given string. Note that the bytes are binary, not - text; we only use the `string` class as a convenient container. -- `bool ParseFromString(const string& data);`: parses a message from the given - string. -- `bool SerializeToOstream(ostream* output) const;`: writes the message to the - given C++ `ostream`. -- `bool ParseFromIstream(istream* input);`: parses a message from the given - C++ `istream`. - -These are just a couple of the options provided for parsing and serialization. -See the -[`Message` API reference](/reference/cpp/api-docs/google.protobuf.message#Message) -for a complete list. - -{{% alert title="Important" color="warning" %}} **Protocol Buffers and Object Oriented Design** -Protocol buffer classes are basically data holders (like structs in C) that -don't provide additional functionality; they don't make good first class -citizens in an object model. If you want to add richer behavior to a generated -class, the best way to do this is to wrap the generated protocol buffer class in -an application-specific class. Wrapping protocol buffers is also a good idea if -you don't have control over the design of the .proto file (if, say, you're -reusing one from another project). In that case, you can use the wrapper class -to craft an interface better suited to the unique environment of your -application: hiding some data and methods, exposing convenience functions, etc. -**You cannot add behavior to the generated classes by inheriting from them**, as -they are final. This prevents breaking internal mechanisms and is not good -object-oriented practice anyway. - - {{% /alert %}} - -## Writing a Message {#writing-a-message} - -Now let's try using your protocol buffer classes. The first thing you want your -address book application to be able to do is write personal details to your -address book file. To do this, you need to create and populate instances of your -protocol buffer classes and then write them to an output stream. - -Here is a program that reads an `AddressBook` from a file, adds one new `Person` -to it based on user input, and writes the new `AddressBook` back out to the file -again. The parts which directly call or reference code generated by the protocol -compiler are highlighted. - -```cpp -#include -#include -#include -#include "addressbook.pb.h" -using namespace std; - -// This function fills in a Person message based on user input. -void PromptForAddress(tutorial::Person& person) { - cout << "Enter person ID number: "; - int id; - cin >> id; - person.set_id(id); - cin.ignore(256, '\n'); - - cout << "Enter name: "; - getline(cin, *person.mutable_name()); - - cout << "Enter email address (blank for none): "; - string email; - getline(cin, email); - if (!email.empty()) { - person.set_email(email); - } - - while (true) { - cout << "Enter a phone number (or leave blank to finish): "; - string number; - getline(cin, number); - if (number.empty()) { - break; - } - - tutorial::Person::PhoneNumber* phone_number = person.add_phones(); - phone_number->set_number(number); - - cout << "Is this a mobile, home, or work phone? "; - string type; - getline(cin, type); - if (type == "mobile") { - phone_number->set_type(tutorial::Person::PHONE_TYPE_MOBILE); - } else if (type == "home") { - phone_number->set_type(tutorial::Person::PHONE_TYPE_HOME); - } else if (type == "work") { - phone_number->set_type(tutorial::Person::PHONE_TYPE_WORK); - } else { - cout << "Unknown phone type. Using default." << endl; - } - } -} - -// Main function: Reads the entire address book from a file, -// adds one person based on user input, then writes it back out to the same -// file. -int main(int argc, char* argv[]) { - // Verify that the version of the library that we linked against is - // compatible with the version of the headers we compiled against. - GOOGLE_PROTOBUF_VERIFY_VERSION; - - if (argc != 2) { - cerr << "Usage: " << argv[0] << " ADDRESS_BOOK_FILE" << endl; - return -1; - } - - tutorial::AddressBook address_book; - - { - // Read the existing address book. - fstream input(argv[1], ios::in | ios::binary); - if (!input) { - cout << argv[1] << ": File not found. Creating a new file." << endl; - } else if (!address_book.ParseFromIstream(&input)) { - cerr << "Failed to parse address book." << endl; - return -1; - } - } - - // Add an address. - PromptForAddress(*address_book.add_people()); - - { - // Write the new address book back to disk. - fstream output(argv[1], ios::out | ios::trunc | ios::binary); - if (!address_book.SerializeToOstream(&output)) { - cerr << "Failed to write address book." << endl; - return -1; - } - } - - // Optional: Delete all global objects allocated by libprotobuf. - google::protobuf::ShutdownProtobufLibrary(); - - return 0; -} -``` - -Notice the `GOOGLE_PROTOBUF_VERIFY_VERSION` macro. It is good practice -- though -not strictly necessary -- to execute this macro before using the C++ Protocol -Buffer library. It verifies that you have not accidentally linked against a -version of the library which is incompatible with the version of the headers you -compiled with. If a version mismatch is detected, the program will abort. Note -that every `.pb.cc` file automatically invokes this macro on startup. - -Also notice the call to `ShutdownProtobufLibrary()` at the end of the program. -All this does is delete any global objects that were allocated by the Protocol -Buffer library. This is unnecessary for most programs, since the process is just -going to exit anyway and the OS will take care of reclaiming all of its memory. -However, if you use a memory leak checker that requires that every last object -be freed, or if you are writing a library which may be loaded and unloaded -multiple times by a single process, then you may want to force Protocol Buffers -to clean up everything. - -## Reading a Message {#reading-a-message} - -Of course, an address book wouldn't be much use if you couldn't get any -information out of it! This example reads the file created by the above example -and prints all the information in it. - -```cpp -#include -#include -#include -#include "addressbook.pb.h" -using namespace std; - -// Iterates though all people in the AddressBook and prints info about them. -void ListPeople(const tutorial::AddressBook& address_book) { - for (const tutorial::Person& person : address_book.people()) { - cout << "Person ID: " << person.id() << endl; - cout << " Name: " << person.name() << endl; - if (!person.has_email()) { - cout << " E-mail address: " << person.email() << endl; - } - - for (const tutorial::Person::PhoneNumber& phone_number : person.phones()) { - switch (phone_number.type()) { - case tutorial::Person::PHONE_TYPE_MOBILE: - cout << " Mobile phone #: "; - break; - case tutorial::Person::PHONE_TYPE_HOME: - cout << " Home phone #: "; - break; - case tutorial::Person::PHONE_TYPE_WORK: - cout << " Work phone #: "; - break; - case tutorial::Person::PHONE_TYPE_UNSPECIFIED: - default: - cout << " Phone #: "; - break; - } - cout << phone_number.number() << endl; - } - } -} - -// Main function: Reads the entire address book from a file and prints all -// the information inside. -int main(int argc, char* argv[]) { - // Verify that the version of the library that we linked against is - // compatible with the version of the headers we compiled against. - GOOGLE_PROTOBUF_VERIFY_VERSION; - - if (argc != 2) { - cerr << "Usage: " << argv[0] << " ADDRESS_BOOK_FILE" << endl; - return -1; - } - - tutorial::AddressBook address_book; - - { - // Read the existing address book. - fstream input(argv[1], ios::in | ios::binary); - if (!address_book.ParseFromIstream(&input)) { - cerr << "Failed to parse address book." << endl; - return -1; - } - } - - ListPeople(address_book); - - // Optional: Delete all global objects allocated by libprotobuf. - google::protobuf::ShutdownProtobufLibrary(); - - return 0; -} -``` - -## Extending a Protocol Buffer {#extending-a-protobuf} - -Sooner or later after you release the code that uses your protocol buffer, you -will undoubtedly want to "improve" the protocol buffer's definition. If you want -your new buffers to be backwards-compatible, and your old buffers to be -forward-compatible -- and you almost certainly do want this -- then there are -some rules you need to follow. In the new version of the protocol buffer: - -* you *must not* change the field numbers of any existing fields. -* you *may* delete singular or repeated fields. -* you *may* add new singular or repeated fields but you must use fresh field - numbers (that is, field numbers that were never used in this protocol - buffer, not even by deleted fields). - -(There are -[some exceptions](/programming-guides/editions#updating) -to these rules, but they are rarely used.) - -If you follow these rules, old code will happily read new messages and simply -ignore any new fields. To the old code, fields that were deleted will simply -have their default value, and deleted repeated fields will be empty. New code -will also transparently read old messages. However, keep in mind that new fields -will not be present in old messages, so you will need to check for their -presence by checking if they have the default value (e.g., an empty string) -before use. - -## Optimization Tips {#optimization} - -The C++ Protocol Buffers library is extremely heavily optimized. However, proper -usage can improve performance even more. Here are some tips for squeezing every -last drop of speed out of the library: - -- **Use Arenas for memory allocation.** When you create many protocol buffer - messages in a short-lived operation (like parsing a single request), the - system's memory allocator can become a bottleneck. Arenas are designed to - mitigate this. By using an arena, you can perform many allocations with low - overhead, and a single deallocation for all of them at once. This can - significantly improve performance in message-heavy applications. - - To use arenas, you allocate messages on a `google::protobuf::Arena` object: - - ```cpp - google::protobuf::Arena arena; - tutorial::Person* person = google::protobuf::Arena::Create(&arena); - // ... populate person ... - ``` - - When the arena object is destroyed, all messages allocated on it are freed. - For more details, see the [Arenas guide](/arenas). - -- **Reuse non-arena message objects when possible.** Messages try to keep - around any memory they allocate for reuse, even when they are cleared. Thus, - if you are handling many messages with the same type and similar structure - in succession, it is a good idea to reuse the same message object each time - to take load off the memory allocator. However, objects can become bloated - over time, especially if your messages vary in "shape" or if you - occasionally construct a message that is much larger than usual. You should - monitor the sizes of your message objects by calling the `SpaceUsed` method - and delete them once they get too big. - - Reusing arena messages can lead to unbounded memory growth. Reusing heap - messages is safer. Even with heap message, though, you can still experience - issues with the high water mark of fields. For example, if you see messages: - - ```none - a: [1, 2, 3, 4] - b: [1] - ``` - - and - - ```none - a: [1] - b: [1, 2, 3, 4] - ``` - - and reuse the messages, then both fields will have enough memory for the - largest they have seen. So if each input only had 5 elements, the reused - message will have memory for 8. - -- Your system's memory allocator may not be well-optimized for allocating lots - of small objects from multiple threads. Try using - [Google's TCMalloc](https://github.com/google/tcmalloc) instead. - -## Advanced Usage {#advanced-usage} - -Protocol buffers have uses that go beyond simple accessors and serialization. Be -sure to explore the [C++ API reference](/reference/cpp) -to see what else you can do with them. - -One key feature provided by protocol message classes is *reflection*. You can -iterate over the fields of a message and manipulate their values without writing -your code against any specific message type. One very useful way to use -reflection is for converting protocol messages to and from other encodings, such -as XML or JSON. A more advanced use of reflection might be to find differences -between two messages of the same type, or to develop a sort of "regular -expressions for protocol messages" in which you can write expressions that match -certain message contents. If you use your imagination, it's possible to apply -Protocol Buffers to a much wider range of problems than you might initially -expect! - -Reflection is provided by the -[`Message::Reflection` interface](/reference/cpp/api-docs/google.protobuf.message#Reflection). diff --git a/content/getting-started/csharptutorial.md b/content/getting-started/csharptutorial.md deleted file mode 100644 index 5b0be8257..000000000 --- a/content/getting-started/csharptutorial.md +++ /dev/null @@ -1,342 +0,0 @@ -+++ -title = "Protocol Buffer Basics: C#" -weight = 220 -linkTitle = "C#" -description = "A basic C# programmers introduction to working with protocol buffers." -type = "docs" -+++ - -This tutorial provides a basic C# programmer's introduction to working with -protocol buffers, using the -[proto3](/programming-guides/proto3) version of the -protocol buffers language. By walking through creating a simple example -application, it shows you how to - -- Define message formats in a `.proto` file. -- Use the protocol buffer compiler. -- Use the C# protocol buffer API to write and read messages. - -This isn't a comprehensive guide to using protocol buffers in C#. For more -detailed reference information, see the -[Protocol Buffer Language Guide](/programming-guides/proto3), -the [C# API Reference](/reference/csharp/api-docs), the -[C# Generated Code Guide](/reference/csharp/csharp-generated), -and the -[Encoding Reference](/programming-guides/encoding). - -## The Problem Domain {#problem-domain} - -The example we're going to use is a very simple "address book" application that -can read and write people's contact details to and from a file. Each person in -the address book has a name, an ID, an email address, and a contact phone -number. - -How do you serialize and retrieve structured data like this? There are a few -ways to solve this problem: - -- Use .NET binary serialization with - `System.Runtime.Serialization.Formatters.Binary.BinaryFormatter` and - associated classes. This ends up being very fragile in the face of changes, - expensive in terms of data size in some cases. It also doesn't work very - well if you need to share data with applications written for other - platforms. -- You can invent an ad-hoc way to encode the data items into a single - string -- such as encoding 4 ints as "12:3:-23:67". This is a simple and - flexible approach, although it does require writing one-off encoding and - parsing code, and the parsing imposes a small run-time cost. This works best - for encoding very simple data. -- Serialize the data to XML. This approach can be very attractive since XML is - (sort of) human readable and there are binding libraries for lots of - languages. This can be a good choice if you want to share data with other - applications/projects. However, XML is notoriously space intensive, and - encoding/decoding it can impose a huge performance penalty on applications. - Also, navigating an XML DOM tree is considerably more complicated than - navigating simple fields in a class normally would be. - -Protocol buffers are the flexible, efficient, automated solution to solve -exactly this problem. With protocol buffers, you write a `.proto` description of -the data structure you wish to store. From that, the protocol buffer compiler -creates a class that implements automatic encoding and parsing of the protocol -buffer data with an efficient binary format. The generated class provides -getters and setters for the fields that make up a protocol buffer and takes care -of the details of reading and writing the protocol buffer as a unit. -Importantly, the protocol buffer format supports the idea of extending the -format over time in such a way that the code can still read data encoded with -the old format. - -## Where to Find the Example Code {#example-code} - -Our example is a command-line application for managing an address book data -file, encoded using protocol buffers. The command `AddressBook` (see: -[Program.cs](//github.com/protocolbuffers/protobuf/blob/master/csharp/src/AddressBook/Program.cs)) -can add a new entry to the data file or parse the data file and print the data -to the console. - -You can find the complete example in the -[examples directory](https://github.com/protocolbuffers/protobuf/tree/master/examples) -and -[`csharp/src/AddressBook` directory](https://github.com/protocolbuffers/protobuf/tree/master/csharp/src/AddressBook) -of the GitHub repository. - -## Defining Your Protocol Format {#protocol-format} - -To create your address book application, you'll need to start with a `.proto` -file. The definitions in a `.proto` file are simple: you add a *message* for -each data structure you want to serialize, then specify a name and a type for -each field in the message. In our example, the `.proto` file that defines the -messages is -[`addressbook.proto`](https://github.com/protocolbuffers/protobuf/blob/master/examples/addressbook.proto). - -The `.proto` file starts with a package declaration, which helps to prevent -naming conflicts between different projects. - -```proto -syntax = "proto3"; -package tutorial; - -import "google/protobuf/timestamp.proto"; -``` - -In C#, your generated classes will be placed in a namespace matching the -`package` name if `csharp_namespace` is not specified. In our example, the -`csharp_namespace` option has been specified to override the default, so the -generated code uses a namespace of `Google.Protobuf.Examples.AddressBook` -instead of `Tutorial`. - -```csharp -option csharp_namespace = "Google.Protobuf.Examples.AddressBook"; -``` - -Next, you have your message definitions. A message is just an aggregate -containing a set of typed fields. Many standard simple data types are available -as field types, including `bool`, `int32`, `float`, `double`, and `string`. You -can also add further structure to your messages by using other message types as -field types. - -```proto -message Person { - string name = 1; - int32 id = 2; // Unique ID number for this person. - string email = 3; - - enum PhoneType { - PHONE_TYPE_UNSPECIFIED = 0; - PHONE_TYPE_MOBILE = 1; - PHONE_TYPE_HOME = 2; - PHONE_TYPE_WORK = 3; - } - - message PhoneNumber { - string number = 1; - PhoneType type = 2; - } - - repeated PhoneNumber phones = 4; - - google.protobuf.Timestamp last_updated = 5; -} - -// Our address book file is just one of these. -message AddressBook { - repeated Person people = 1; -} -``` - -In the above example, the `Person` message contains `PhoneNumber` messages, -while the `AddressBook` message contains `Person` messages. You can even define -message types nested inside other messages -- as you can see, the `PhoneNumber` -type is defined inside `Person`. You can also define `enum` types if you want -one of your fields to have one of a predefined list of values -- here you want -to specify that a phone number can be one of `PHONE_TYPE_MOBILE`, -`PHONE_TYPE_HOME`, or `PHONE_TYPE_WORK`. - -The " = 1", " = 2" markers on each element identify the unique "tag" that field -uses in the binary encoding. Tag numbers 1-15 require one less byte to encode -than higher numbers, so as an optimization you can decide to use those tags for -the commonly used or repeated elements, leaving tags 16 and higher for -less-commonly used optional elements. Each element in a repeated field requires -re-encoding the tag number, so repeated fields are particularly good candidates -for this optimization. - -If a field value isn't set, a -[default value](/programming-guides/proto3#default) is -used: zero for numeric types, the empty string for strings, false for bools. For -embedded messages, the default value is always the "default instance" or -"prototype" of the message, which has none of its fields set. Calling the -accessor to get the value of a field which has not been explicitly set always -returns that field's default value. - -If a field is `repeated`, the field may be repeated any number of times -(including zero). The order of the repeated values will be preserved in the -protocol buffer. Think of repeated fields as dynamically sized arrays. - -You'll find a complete guide to writing `.proto` files -- including all the -possible field types -- in the -[Protocol Buffer Language Guide](/programming-guides/proto3). -Don't go looking for facilities similar to class inheritance, though -- protocol -buffers don't do that. - -## Compiling Your Protocol Buffers {#compiling-protocol-buffers} - -Now that you have a `.proto`, the next thing you need to do is generate the -classes you'll need to read and write `AddressBook` (and hence `Person` and -`PhoneNumber`) messages. To do this, you need to run the protocol buffer -compiler `protoc` on your `.proto`: - -1. If you haven't installed the compiler, - [download the package](/downloads) and follow the - instructions in the README. - -2. Now run the compiler, specifying the source directory (where your - application's source code lives -- the current directory is used if you - don't provide a value), the destination directory (where you want the - generated code to go; often the same as `$SRC_DIR`), and the path to your - `.proto`. In this case, you would invoke: - - ```shell - protoc -I=$SRC_DIR --csharp_out=$DST_DIR $SRC_DIR/addressbook.proto - ``` - - Because you want C# code, you use the `--csharp_out` option -- similar - options are provided for other supported languages. - -This generates `Addressbook.cs` in your specified destination directory. To -compile this code, you'll need a project with a reference to the -`Google.Protobuf` assembly. - -## The Addressbook Classes {#addressbook-classes} - -Generating `Addressbook.cs` gives you five useful types: - -- A static `Addressbook` class that contains metadata about the protocol - buffer messages. -- An `AddressBook` class with a read-only `People` property. -- A `Person` class with properties for `Name`, `Id`, `Email` and `Phones`. -- A `PhoneNumber` class, nested in a static `Person.Types` class. -- A `PhoneType` enum, also nested in `Person.Types`. - -You can read more about the details of exactly what's generated in the -[C# Generated Code guide](/reference/csharp/csharp-generated), -but for the most part you can treat these as perfectly ordinary C# types. One -point to highlight is that any properties corresponding to repeated fields are -read-only. You can add items to the collection or remove items from it, but you -can't replace it with an entirely separate collection. The collection type for -repeated fields is always `RepeatedField`. This type is like `List` but -with a few extra convenience methods, such as an `Add` overload accepting a -collection of items, for use in collection initializers. - -Here's an example of how you might create an instance of Person: - -```csharp -Person john = new Person -{ - Id = 1234, - Name = "John Doe", - Email = "jdoe@example.com", - Phones = { new Person.Types.PhoneNumber { Number = "555-4321", Type = Person.Types.PhoneType.Home } } -}; -``` - -Note that with C# 6, you can use `using static` to remove the `Person.Types` -ugliness: - -```csharp -// Add this to the other using directives -using static Google.Protobuf.Examples.AddressBook.Person.Types; -... -// The earlier Phones assignment can now be simplified to: -Phones = { new PhoneNumber { Number = "555-4321", Type = PhoneType.HOME } } -``` - -## Parsing and Serialization {#parsing-serialization} - -The whole purpose of using protocol buffers is to serialize your data so that it -can be parsed elsewhere. Every generated class has a -`WriteTo(CodedOutputStream)` method, where `CodedOutputStream` is a class in the -protocol buffer runtime library. However, usually you'll use one of the -extension methods to write to a regular `System.IO.Stream` or convert the -message to a byte array or `ByteString`. These extension messages are in the -`Google.Protobuf.MessageExtensions` class, so when you want to serialize you'll -usually want a `using` directive for the `Google.Protobuf` namespace. For -example: - -```csharp -using Google.Protobuf; -... -Person john = ...; // Code as before -using (var output = File.Create("john.dat")) -{ - john.WriteTo(output); -} -``` - -Parsing is also simple. Each generated class has a static `Parser` property -which returns a `MessageParser` for that type. That in turn has methods to -parse streams, byte arrays and `ByteString`s. So to parse the file we've just -created, we can use: - -```csharp -Person john; -using (var input = File.OpenRead("john.dat")) -{ - john = Person.Parser.ParseFrom(input); -} -``` - -A full example program to maintain an addressbook (adding new entries and -listing existing ones) using these messages is available -[in the Github repository](https://github.com/protocolbuffers/protobuf/tree/master/csharp/src/AddressBook). - -## Extending a Protocol Buffer {#extending-a-protobuf} - -Sooner or later after you release the code that uses your protocol buffer, you -will undoubtedly want to "improve" the protocol buffer's definition. If you want -your new buffers to be backwards-compatible, and your old buffers to be -forward-compatible -- and you almost certainly do want this -- then there are -some rules you need to follow. In the new version of the protocol buffer: - -- you *must not* change the tag numbers of any existing fields. -- you *may* delete fields. -- you *may* add new fields but you must use fresh tag numbers (i.e. tag - numbers that were never used in this protocol buffer, not even by deleted - fields). - -(There are -[some exceptions](/programming-guides/proto3#updating) to -these rules, but they are rarely used.) - -If you follow these rules, old code will happily read new messages and simply -ignore any new fields. To the old code, singular fields that were deleted will -simply have their default value, and deleted repeated fields will be empty. New -code will also transparently read old messages. - -However, keep in mind that new fields will not be present in old messages, so -you will need to do something reasonable with the default value. A type-specific -[default value](/programming-guides/proto3#default) is -used: for strings, the default value is the empty string. For booleans, the -default value is false. For numeric types, the default value is zero. - -## Reflection {#reflection} - -Message descriptors (the information in the `.proto` file) and instances of -messages can be examined programmatically using the reflection API. This can be -useful when writing generic code such as a different text format or a smart diff -tool. Each generated class has a static `Descriptor` property, and the -descriptor for any instance can be retrieved using the `IMessage.Descriptor` -property. As a quick example of how these can be used, here is a short method to -print the top-level fields of any message. - -```csharp -public void PrintMessage(IMessage message) -{ - var descriptor = message.Descriptor; - foreach (var field in descriptor.Fields.InDeclarationOrder()) - { - Console.WriteLine( - "Field {0} ({1}): {2}", - field.FieldNumber, - field.Name, - field.Accessor.GetValue(message); - } -} -``` diff --git a/content/getting-started/darttutorial.md b/content/getting-started/darttutorial.md deleted file mode 100644 index 2d66ea7ee..000000000 --- a/content/getting-started/darttutorial.md +++ /dev/null @@ -1,375 +0,0 @@ -+++ -title = "Protocol Buffer Basics: Dart" -weight = 230 -linkTitle = "Dart" -description = "A basic Dart programmers introduction to working with protocol buffers." -type = "docs" -+++ - -This tutorial provides a basic Dart programmer's introduction to working with -protocol buffers, using the -[proto3](/programming-guides/proto3) version of the -protocol buffers language. By walking through creating a simple example -application, it shows you how to - -- Define message formats in a `.proto` file. -- Use the protocol buffer compiler. -- Use the Dart protocol buffer API to write and read messages. - -This isn't a comprehensive guide to using protocol buffers in Dart . For more -detailed reference information, see the -[Protocol Buffer Language Guide](/programming-guides/proto3), -the -[Dart Language Tour,](https://www.dartlang.org/guides/language/language-tour) -the [Dart API Reference](https://pub.dartlang.org/documentation/protobuf), the -[Dart Generated Code Guide](/reference/dart/dart-generated), -and the -[Encoding Reference](/programming-guides/encoding). - -## The Problem Domain {#problem-domain} - -The example we're going to use is a very simple "address book" application that -can read and write people's contact details to and from a file. Each person in -the address book has a name, an ID, an email address, and a contact phone -number. - -How do you serialize and retrieve structured data like this? There are a few -ways to solve this problem: - -- You can invent an ad-hoc way to encode the data items into a single - string -- such as encoding 4 ints as "12:3:-23:67". This is a simple and - flexible approach, although it does require writing one-off encoding and - parsing code, and the parsing imposes a small run-time cost. This works best - for encoding very simple data. -- Serialize the data to XML. This approach can be very attractive since XML is - (sort of) human readable and there are binding libraries for lots of - languages. This can be a good choice if you want to share data with other - applications/projects. However, XML is notoriously space intensive, and - encoding/decoding it can impose a huge performance penalty on applications. - Also, navigating an XML DOM tree is considerably more complicated than - navigating simple fields in a class normally would be. - -Protocol buffers are the flexible, efficient, automated solution to solve -exactly this problem. With protocol buffers, you write a `.proto` description of -the data structure you wish to store. From that, the protocol buffer compiler -creates a class that implements automatic encoding and parsing of the protocol -buffer data with an efficient binary format. The generated class provides -getters and setters for the fields that make up a protocol buffer and takes care -of the details of reading and writing the protocol buffer as a unit. -Importantly, the protocol buffer format supports the idea of extending the -format over time in such a way that the code can still read data encoded with -the old format. - -## Where to Find the Example Code {#example-code} - -Our example is a set of command-line applications for managing an address book -data file, encoded using protocol buffers. The command `dart add_person.dart` -adds a new entry to the data file. The command `dart list_people.dart` parses -the data file and prints the data to the console. - -You can find the complete example in the -[examples directory](https://github.com/protocolbuffers/protobuf/tree/master/examples) -of the GitHub repository. - -## Defining Your Protocol Format {#protocol-format} - -To create your address book application, you'll need to start with a `.proto` -file. The definitions in a `.proto` file are simple: you add a *message* for -each data structure you want to serialize, then specify a name and a type for -each field in the message. In our example, the `.proto` file that defines the -messages is -[`addressbook.proto`](https://github.com/protocolbuffers/protobuf/blob/master/examples/addressbook.proto). - -The `.proto` file starts with a package declaration, which helps to prevent -naming conflicts between different projects. - -```proto -syntax = "proto3"; -package tutorial; - -import "google/protobuf/timestamp.proto"; -``` - -Next, you have your message definitions. A message is just an aggregate -containing a set of typed fields. Many standard simple data types are available -as field types, including `bool`, `int32`, `float`, `double`, and `string`. You -can also add further structure to your messages by using other message types as -field types. - -```proto -message Person { - string name = 1; - int32 id = 2; // Unique ID number for this person. - string email = 3; - - enum PhoneType { - PHONE_TYPE_UNSPECIFIED = 0; - PHONE_TYPE_MOBILE = 1; - PHONE_TYPE_HOME = 2; - PHONE_TYPE_WORK = 3; - } - - message PhoneNumber { - string number = 1; - PhoneType type = 2; - } - - repeated PhoneNumber phones = 4; - - google.protobuf.Timestamp last_updated = 5; -} - -// Our address book file is just one of these. -message AddressBook { - repeated Person people = 1; -} -``` - -In the above example, the `Person` message contains `PhoneNumber` messages, -while the `AddressBook` message contains `Person` messages. You can even define -message types nested inside other messages -- as you can see, the `PhoneNumber` -type is defined inside `Person`. You can also define `enum` types if you want -one of your fields to have one of a predefined list of values -- here you want -to specify that a phone number can be one of `PHONE_TYPE_MOBILE`, -`PHONE_TYPE_HOME`, or `PHONE_TYPE_WORK`. - -The " = 1", " = 2" markers on each element identify the unique "tag" that field -uses in the binary encoding. Tag numbers 1-15 require one less byte to encode -than higher numbers, so as an optimization you can decide to use those tags for -the commonly used or repeated elements, leaving tags 16 and higher for -less-commonly used optional elements. Each element in a repeated field requires -re-encoding the tag number, so repeated fields are particularly good candidates -for this optimization. - -If a field value isn't set, a -[default value](/programming-guides/proto3#default) is -used: zero for numeric types, the empty string for strings, false for bools. For -embedded messages, the default value is always the "default instance" or -"prototype" of the message, which has none of its fields set. Calling the -accessor to get the value of a field which has not been explicitly set always -returns that field's default value. - -If a field is `repeated`, the field may be repeated any number of times -(including zero). The order of the repeated values will be preserved in the -protocol buffer. Think of repeated fields as dynamically sized arrays. - -You'll find a complete guide to writing `.proto` files -- including all the -possible field types -- in the -[Protocol Buffer Language Guide](/programming-guides/proto3). -Don't go looking for facilities similar to class inheritance, though -- protocol -buffers don't do that. - -## Compiling Your Protocol Buffers {#compiling-protocol-buffers} - -Now that you have a `.proto`, the next thing you need to do is generate the -classes you'll need to read and write `AddressBook` (and hence `Person` and -`PhoneNumber`) messages. To do this, you need to run the protocol buffer -compiler `protoc` on your `.proto`: - -1. If you haven't installed the compiler, - [download the package](/downloads) and follow the - instructions in the README. - -2. Install the Dart Protocol Buffer plugin as described in - [its README](https://github.com/google/protobuf.dart/tree/master/protoc_plugin#how-to-build). - The executable `bin/protoc-gen-dart` must be in your `PATH` for the protocol - buffer `protoc` to find it. - -3. Now run the compiler, specifying the source directory (where your - application's source code lives -- the current directory is used if you - don't provide a value), the destination directory (where you want the - generated code to go; often the same as `$SRC_DIR`), and the path to your - `.proto`. In this case, you would invoke: - - ```shell - protoc -I=$SRC_DIR --dart_out=$DST_DIR $SRC_DIR/addressbook.proto - ``` - - Because you want Dart code, you use the `--dart_out` option -- similar - options are provided for other supported languages. - -This generates `addressbook.pb.dart` in your specified destination directory. - -## The Protocol Buffer API {#protobuf-api} - -Generating `addressbook.pb.dart` gives you the following useful types: - -- An `AddressBook` class with a `List get people` getter. -- A `Person` class with accessor methods for `name`, `id`, `email` and - `phones`. -- A `Person_PhoneNumber` class, with accessor methods for `number` and `type`. -- A `Person_PhoneType` class with static fields for each value in the - `Person.PhoneType` enum. - -You can read more about the details of exactly what's generated in the -[Dart Generated Code guide](/reference/dart/dart-generated). - -## Writing a Message {#writing-a-message} - -Now let's try using your protocol buffer classes. The first thing you want your -address book application to be able to do is write personal details to your -address book file. To do this, you need to create and populate instances of your -protocol buffer classes and then write them to an output stream. - -Here is a program which reads an `AddressBook` from a file, adds one new -`Person` to it based on user input, and writes the new `AddressBook` back out to -the file again. The parts which directly call or reference code generated by the -protocol compiler are highlighted. - -```dart -import 'dart:io'; - -import 'dart_tutorial/addressbook.pb.dart'; - -// This function fills in a Person message based on user input. -Person promptForAddress() { - Person person = Person(); - - print('Enter person ID: '); - String input = stdin.readLineSync(); - person.id = int.parse(input); - - print('Enter name'); - person.name = stdin.readLineSync(); - - print('Enter email address (blank for none) : '); - String email = stdin.readLineSync(); - if (email.isNotEmpty) { - person.email = email; - } - - while (true) { - print('Enter a phone number (or leave blank to finish): '); - String number = stdin.readLineSync(); - if (number.isEmpty) break; - - Person_PhoneNumber phoneNumber = Person_PhoneNumber(); - - phoneNumber.number = number; - print('Is this a mobile, home, or work phone? '); - - String type = stdin.readLineSync(); - switch (type) { - case 'mobile': - phoneNumber.type = Person_PhoneType.PHONE_TYPE_MOBILE; - break; - case 'home': - phoneNumber.type = Person_PhoneType.PHONE_TYPE_HOME; - break; - case 'work': - phoneNumber.type = Person_PhoneType.PHONE_TYPE_WORK; - break; - default: - print('Unknown phone type. Using default.'); - } - person.phones.add(phoneNumber); - } - - return person; -} - -// Reads the entire address book from a file, adds one person based -// on user input, then writes it back out to the same file. -main(List arguments) { - if (arguments.length != 1) { - print('Usage: add_person ADDRESS_BOOK_FILE'); - exit(-1); - } - - File file = File(arguments.first); - AddressBook addressBook; - if (!file.existsSync()) { - print('File not found. Creating new file.'); - addressBook = AddressBook(); - } else { - addressBook = AddressBook.fromBuffer(file.readAsBytesSync()); - } - addressBook.people.add(promptForAddress()); - file.writeAsBytes(addressBook.writeToBuffer()); -} -``` - -## Reading a Message {#reading-a-message} - -Of course, an address book wouldn't be much use if you couldn't get any -information out of it! This example reads the file created by the above example -and prints all the information in it. - -```dart -import 'dart:io'; - -import 'dart_tutorial/addressbook.pb.dart'; -import 'dart_tutorial/addressbook.pbenum.dart'; - -// Iterates though all people in the AddressBook and prints info about them. -void printAddressBook(AddressBook addressBook) { - for (Person person in addressBook.people) { - print('Person ID: ${ person.id}'); - print(' Name: ${ person.name}'); - if (person.hasEmail()) { - print(' E-mail address:${ person.email}'); - } - - for (Person_PhoneNumber phoneNumber in person.phones) { - switch (phoneNumber.type) { - case Person_PhoneType.PHONE_TYPE_MOBILE: - print(' Mobile phone #: '); - break; - case Person_PhoneType.PHONE_TYPE_HOME: - print(' Home phone #: '); - break; - case Person_PhoneType.PHONE_TYPE_WORK: - print(' Work phone #: '); - break; - default: - print(' Unknown phone #: '); - break; - } - print(phoneNumber.number); - } - } -} - -// Reads the entire address book from a file and prints all -// the information inside. -main(List arguments) { - if (arguments.length != 1) { - print('Usage: list_person ADDRESS_BOOK_FILE'); - exit(-1); - } - - // Read the existing address book. - File file = new File(arguments.first); - AddressBook addressBook = new AddressBook.fromBuffer(file.readAsBytesSync()); - printAddressBook(addressBook); -} -``` - -## Extending a Protocol Buffer {#extending-a-protobuf} - -Sooner or later after you release the code that uses your protocol buffer, you -will undoubtedly want to "improve" the protocol buffer's definition. If you want -your new buffers to be backwards-compatible, and your old buffers to be -forward-compatible -- and you almost certainly do want this -- then there are -some rules you need to follow. In the new version of the protocol buffer: - -- you *must not* change the tag numbers of any existing fields. -- you *may* delete fields. -- you *may* add new fields but you must use fresh tag numbers (i.e. tag - numbers that were never used in this protocol buffer, not even by deleted - fields). - -(There are -[some exceptions](/programming-guides/proto3#updating) to -these rules, but they are rarely used.) - -If you follow these rules, old code will happily read new messages and simply -ignore any new fields. To the old code, singular fields that were deleted will -simply have their default value, and deleted repeated fields will be empty. New -code will also transparently read old messages. - -However, keep in mind that new fields will not be present in old messages, so -you will need to do something reasonable with the default value. A type-specific -[default value](/programming-guides/proto3#default) is -used: for strings, the default value is the empty string. For booleans, the -default value is false. For numeric types, the default value is zero. diff --git a/content/getting-started/gotutorial.md b/content/getting-started/gotutorial.md deleted file mode 100644 index f295167d4..000000000 --- a/content/getting-started/gotutorial.md +++ /dev/null @@ -1,313 +0,0 @@ -+++ -title = "Protocol Buffer Basics: Go" -weight = 240 -linkTitle = "Go" -description = "A basic Go programmers introduction to working with protocol buffers." -type = "docs" -+++ - -This tutorial provides a basic Go programmer's introduction to working with -protocol buffers, using the -[proto3](/programming-guides/proto3) version of the -protocol buffers language. By walking through creating a simple example -application, it shows you how to - -- Define message formats in a `.proto` file. -- Use the protocol buffer compiler. -- Use the Go protocol buffer API to write and read messages. - -This isn't a comprehensive guide to using protocol buffers in Go. For more -detailed reference information, see the -[Protocol Buffer Language Guide](/programming-guides/proto3), -the [Go API Reference](https://pkg.go.dev/google.golang.org/protobuf/proto), the -[Go Generated Code Guide](/reference/go/go-generated), -and the -[Encoding Reference](/programming-guides/encoding). - -## The Problem Domain {#problem-domain} - -The example we're going to use is a very simple "address book" application that -can read and write people's contact details to and from a file. Each person in -the address book has a name, an ID, an email address, and a contact phone -number. - -How do you serialize and retrieve structured data like this? There are a few -ways to solve this problem: - -- Use [gobs](//golang.org/pkg/encoding/gob/) to serialize Go data structures. - This is a good solution in a Go-specific environment, but it doesn't work - well if you need to share data with applications written for other - platforms. -- You can invent an ad-hoc way to encode the data items into a single - string -- such as encoding 4 ints as "12:3:-23:67". This is a simple and - flexible approach, although it does require writing one-off encoding and - parsing code, and the parsing imposes a small run-time cost. This works best - for encoding very simple data. -- Serialize the data to XML. This approach can be very attractive since XML is - (sort of) human readable and there are binding libraries for lots of - languages. This can be a good choice if you want to share data with other - applications/projects. However, XML is notoriously space intensive, and - encoding/decoding it can impose a huge performance penalty on applications. - Also, navigating an XML DOM tree is considerably more complicated than - navigating simple fields in a class normally would be. - -Protocol buffers are the flexible, efficient, automated solution to solve -exactly this problem. With protocol buffers, you write a `.proto` description of -the data structure you wish to store. From that, the protocol buffer compiler -creates a class that implements automatic encoding and parsing of the protocol -buffer data with an efficient binary format. The generated class provides -getters and setters for the fields that make up a protocol buffer and takes care -of the details of reading and writing the protocol buffer as a unit. -Importantly, the protocol buffer format supports the idea of extending the -format over time in such a way that the code can still read data encoded with -the old format. - -## Where to Find the Example Code {#example-code} - -Our example is a set of command-line applications for managing an address book -data file, encoded using protocol buffers. The command `add_person_go` adds a -new entry to the data file. The command `list_people_go` parses the data file -and prints the data to the console. - -You can find the complete example in the -[examples directory](https://github.com/protocolbuffers/protobuf/tree/master/examples) -of the GitHub repository. - -## Defining Your Protocol Format {#protocol-format} - -To create your address book application, you'll need to start with a `.proto` -file. The definitions in a `.proto` file are simple: you add a *message* for -each data structure you want to serialize, then specify a name and a type for -each field in the message. In our example, the `.proto` file that defines the -messages is -[`addressbook.proto`](https://github.com/protocolbuffers/protobuf/blob/master/examples/addressbook.proto). - -The `.proto` file starts with a package declaration, which helps to prevent -naming conflicts between different projects. - -```proto -syntax = "proto3"; -package tutorial; - -import "google/protobuf/timestamp.proto"; -``` - -The `go_package` option defines the import path of the package which will -contain all the generated code for this file. The Go package name will be the -last path component of the import path. For example, our example will use a -package name of "tutorialpb". - -```proto -option go_package = "github.com/protocolbuffers/protobuf/examples/go/tutorialpb"; -``` - -Next, you have your message definitions. A message is just an aggregate -containing a set of typed fields. Many standard simple data types are available -as field types, including `bool`, `int32`, `float`, `double`, and `string`. You -can also add further structure to your messages by using other message types as -field types. - -```proto -message Person { - string name = 1; - int32 id = 2; // Unique ID number for this person. - string email = 3; - - message PhoneNumber { - string number = 1; - PhoneType type = 2; - } - - repeated PhoneNumber phones = 4; - - google.protobuf.Timestamp last_updated = 5; -} - -enum PhoneType { - PHONE_TYPE_UNSPECIFIED = 0; - PHONE_TYPE_MOBILE = 1; - PHONE_TYPE_HOME = 2; - PHONE_TYPE_WORK = 3; -} - -// Our address book file is just one of these. -message AddressBook { - repeated Person people = 1; -} -``` - -In the above example, the `Person` message contains `PhoneNumber` messages, -while the `AddressBook` message contains `Person` messages. You can even define -message types nested inside other messages -- as you can see, the `PhoneNumber` -type is defined inside `Person`. You can also define `enum` types if you want -one of your fields to have one of a predefined list of values -- here you want -to specify that a phone number can be one of `PHONE_TYPE_MOBILE`, -`PHONE_TYPE_HOME`, or `PHONE_TYPE_WORK`. - -The " = 1", " = 2" markers on each element identify the unique "tag" that field -uses in the binary encoding. Tag numbers 1-15 require one less byte to encode -than higher numbers, so as an optimization you can decide to use those tags for -the commonly used or repeated elements, leaving tags 16 and higher for -less-commonly used optional elements. Each element in a repeated field requires -re-encoding the tag number, so repeated fields are particularly good candidates -for this optimization. - -If a field value isn't set, a -[default value](/programming-guides/proto3#default) is -used: zero for numeric types, the empty string for strings, false for bools. For -embedded messages, the default value is always the "default instance" or -"prototype" of the message, which has none of its fields set. Calling the -accessor to get the value of a field which has not been explicitly set always -returns that field's default value. - -If a field is `repeated`, the field may be repeated any number of times -(including zero). The order of the repeated values will be preserved in the -protocol buffer. Think of repeated fields as dynamically sized arrays. - -You'll find a complete guide to writing `.proto` files -- including all the -possible field types -- in the -[Protocol Buffer Language Guide](/programming-guides/proto3). -Don't go looking for facilities similar to class inheritance, though -- protocol -buffers don't do that. - -## Compiling Your Protocol Buffers {#compiling-protocol-buffers} - -Now that you have a `.proto`, the next thing you need to do is generate the -classes you'll need to read and write `AddressBook` (and hence `Person` and -`PhoneNumber`) messages. To do this, you need to run the protocol buffer -compiler `protoc` on your `.proto`: - -1. If you haven't installed the compiler, - [download the package](/downloads) and follow the - instructions in the README. - -2. Run the following command to install the Go protocol buffers plugin: - - ```shell - go install google.golang.org/protobuf/cmd/protoc-gen-go@latest - ``` - - The compiler plugin `protoc-gen-go` will be installed in `$GOBIN`, - defaulting to `$GOPATH/bin`. It must be in your `$PATH` for the protocol - compiler `protoc` to find it. - -3. Now run the compiler, specifying the source directory (where your - application's source code lives -- the current directory is used if you - don't provide a value), the destination directory (where you want the - generated code to go; often the same as `$SRC_DIR`), and the path to your - `.proto`. In this case, you would invoke: - - ```shell - protoc -I=$SRC_DIR --go_out=$DST_DIR $SRC_DIR/addressbook.proto - ``` - - Because you want Go code, you use the `--go_out` option -- similar options - are provided for other supported languages. - -This generates -`github.com/protocolbuffers/protobuf/examples/go/tutorialpb/addressbook.pb.go` -in your specified destination directory. - -## The Protocol Buffer API {#protobuf-api} - -Generating `addressbook.pb.go` gives you the following useful types: - -- An `AddressBook` structure with a `People` field. -- A `Person` structure with fields for `Name`, `Id`, `Email` and `Phones`. -- A `Person_PhoneNumber` structure, with fields for `Number` and `Type`. -- The type `Person_PhoneType` and a value defined for each value in the - `Person.PhoneType` enum. - -You can read more about the details of exactly what's generated in the -[Go Generated Code guide](/reference/go/go-generated), -but for the most part you can treat these as perfectly ordinary Go types. - -Here's an example from the -[`list_people` command's unit tests](https://github.com/protocolbuffers/protobuf/blob/master/examples/go/cmd/list_people/list_people_test.go) -of how you might create an instance of Person: - -```go -p := pb.Person{ - Id: 1234, - Name: "John Doe", - Email: "jdoe@example.com", - Phones: []*pb.Person_PhoneNumber{ - {Number: "555-4321", Type: pb.PhoneType_PHONE_TYPE_HOME}, - }, -} -``` - -## Writing a Message {#writing-a-message} - -The whole purpose of using protocol buffers is to serialize your data so that it -can be parsed elsewhere. In Go, you use the `proto` library's -[Marshal](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#Marshal) -function to serialize your protocol buffer data. A pointer to a protocol buffer -message's `struct` implements the `proto.Message` interface. Calling -`proto.Marshal` returns the protocol buffer, encoded in its wire format. For -example, we use this function in the -[`add_person` command](https://github.com/protocolbuffers/protobuf/blob/master/examples/go/cmd/add_person/add_person.go): - -```go -book := &pb.AddressBook{} -// ... - -// Write the new address book back to disk. -out, err := proto.Marshal(book) -if err != nil { - log.Fatalln("Failed to encode address book:", err) -} -if err := ioutil.WriteFile(fname, out, 0644); err != nil { - log.Fatalln("Failed to write address book:", err) -} -``` - -## Reading a Message {#reading-a-message} - -To parse an encoded message, you use the `proto` library's -[Unmarshal](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#Unmarshal) -function. Calling this parses the data in `in` as a protocol buffer and places -the result in `book`. So to parse the file in the -[`list_people` command](https://github.com/protocolbuffers/protobuf/blob/master/examples/go/cmd/list_people/list_people.go), -we use: - -```go -// Read the existing address book. -in, err := ioutil.ReadFile(fname) -if err != nil { - log.Fatalln("Error reading file:", err) -} -book := &pb.AddressBook{} -if err := proto.Unmarshal(in, book); err != nil { - log.Fatalln("Failed to parse address book:", err) -} -``` - -## Extending a Protocol Buffer {#extending-a-protobuf} - -Sooner or later after you release the code that uses your protocol buffer, you -will undoubtedly want to "improve" the protocol buffer's definition. If you want -your new buffers to be backwards-compatible, and your old buffers to be -forward-compatible -- and you almost certainly do want this -- then there are -some rules you need to follow. In the new version of the protocol buffer: - -- you *must not* change the tag numbers of any existing fields. -- you *may* delete fields. -- you *may* add new fields but you must use fresh tag numbers (i.e. tag - numbers that were never used in this protocol buffer, not even by deleted - fields). - -(There are -[some exceptions](/programming-guides/proto3#updating) to -these rules, but they are rarely used.) - -If you follow these rules, old code will happily read new messages and simply -ignore any new fields. To the old code, singular fields that were deleted will -simply have their default value, and deleted repeated fields will be empty. New -code will also transparently read old messages. - -However, keep in mind that new fields will not be present in old messages, so -you will need to do something reasonable with the default value. A type-specific -[default value](/programming-guides/proto3#default) is -used: for strings, the default value is the empty string. For booleans, the -default value is false. For numeric types, the default value is zero. diff --git a/content/getting-started/javatutorial.md b/content/getting-started/javatutorial.md deleted file mode 100644 index 237a53526..000000000 --- a/content/getting-started/javatutorial.md +++ /dev/null @@ -1,622 +0,0 @@ -+++ -title = "Protocol Buffer Basics: Java" -weight = 250 -linkTitle = "Java" -description = "A basic Java programmers introduction to working with protocol buffers." -type = "docs" -+++ - -This tutorial provides a basic Java programmer's introduction to working with -protocol buffers. By walking through creating a simple example application, it -shows you how to - -- Define message formats in a `.proto` file. -- Use the protocol buffer compiler. -- Use the Java protocol buffer API to write and read messages. - -This isn't a comprehensive guide to using protocol buffers in Java. For more -detailed reference information, see the -[Protocol Buffer Language Guide (proto2)](/programming-guides/proto2), -the -[Protocol Buffer Language Guide (proto3)](/programming-guides/proto3), -the -[Java API Reference](/reference/java/api-docs/overview-summary.html), -the -[Java Generated Code Guide](/reference/java/java-generated), -and the -[Encoding Reference](/programming-guides/encoding). - -## The Problem Domain {#problem-domain} - -The example we're going to use is a very simple "address book" application that -can read and write people's contact details to and from a file. Each person in -the address book has a name, an ID, an email address, and a contact phone -number. - -How do you serialize and retrieve structured data like this? There are a few -ways to solve this problem: - -- Use Java Serialization. This is the default approach since it's built into - the language, but it has a host of well-known problems (see Effective Java, - by Josh Bloch pp. 213), and also doesn't work very well if you need to share - data with applications written in C++ or Python. -- You can invent an ad-hoc way to encode the data items into a single - string -- such as encoding 4 ints as "12:3:-23:67". This is a simple and - flexible approach, although it does require writing one-off encoding and - parsing code, and the parsing imposes a small run-time cost. This works best - for encoding very simple data. -- Serialize the data to XML. This approach can be very attractive since XML is - (sort of) human readable and there are binding libraries for lots of - languages. This can be a good choice if you want to share data with other - applications/projects. However, XML is notoriously space intensive, and - encoding/decoding it can impose a huge performance penalty on applications. - Also, navigating an XML DOM tree is considerably more complicated than - navigating simple fields in a class normally would be. - -Instead of these options, you can use protocol buffers. Protocol buffers are the -flexible, efficient, automated solution to solve exactly this problem. With -protocol buffers, you write a `.proto` description of the data structure you -wish to store. From that, the protocol buffer compiler creates a class that -implements automatic encoding and parsing of the protocol buffer data with an -efficient binary format. The generated class provides getters and setters for -the fields that make up a protocol buffer and takes care of the details of -reading and writing the protocol buffer as a unit. Importantly, the protocol -buffer format supports the idea of extending the format over time in such a way -that the code can still read data encoded with the old format. - -## Where to Find the Example Code {#example-code} - -The example code is included in the source code package, under the "examples" -directory. [Download it here.](/downloads) - -## Defining Your Protocol Format {#protocol-format} - -To create your address book application, you'll need to start with a `.proto` -file. The definitions in a `.proto` file are simple: you add a *message* for -each data structure you want to serialize, then specify a name and a type for -each field in the message. Here is the `.proto` file that defines your messages, -`addressbook.proto`. - -```proto -syntax = "proto2"; - -package tutorial; - -option java_multiple_files = true; -option java_package = "com.example.tutorial.protos"; -option java_outer_classname = "AddressBookProtos"; - -message Person { - optional string name = 1; - optional int32 id = 2; - optional string email = 3; - - enum PhoneType { - PHONE_TYPE_UNSPECIFIED = 0; - PHONE_TYPE_MOBILE = 1; - PHONE_TYPE_HOME = 2; - PHONE_TYPE_WORK = 3; - } - - message PhoneNumber { - optional string number = 1; - optional PhoneType type = 2 [default = PHONE_TYPE_HOME]; - } - - repeated PhoneNumber phones = 4; -} - -message AddressBook { - repeated Person people = 1; -} -``` - -As you can see, the syntax is similar to C++ or Java. Let's go through each part -of the file and see what it does. - -The `.proto` file starts with a package declaration, which helps to prevent -naming conflicts between different projects. In Java, the package name is used -as the Java package unless you have explicitly specified a `java_package`, as we -have here. Even if you do provide a `java_package`, you should still define a -normal `package` as well to avoid name collisions in the Protocol Buffers name -space as well as in non-Java languages. - -After the package declaration, you can see three options that are Java-specific: -`java_multiple_files`, `java_package`, and `java_outer_classname`. -`java_package` specifies in what Java package name your generated classes should -live. If you don't specify this explicitly, it simply matches the package name -given by the `package` declaration, but these names usually aren't appropriate -Java package names (since they usually don't start with a domain name). The -`java_outer_classname` option defines the class name of the wrapper class which -will represent this file. If you don't give a `java_outer_classname` explicitly, -it will be generated by converting the file name to upper camel case. For -example, "my_proto.proto" would, by default, use "MyProto" as the wrapper class -name. The `java_multiple_files = true` option enables generating a separate -`.java` file for each generated class (instead of the legacy behavior of -generating a single `.java` file for the wrapper class, using the wrapper class -as an outer class, and nesting all the other classes inside the wrapper class). - -Next, you have your message definitions. A message is just an aggregate -containing a set of typed fields. Many standard simple data types are available -as field types, including `bool`, `int32`, `float`, `double`, and `string`. You -can also add further structure to your messages by using other message types as -field types -- in the above example the `Person` message contains `PhoneNumber` -messages, while the `AddressBook` message contains `Person` messages. You can -even define message types nested inside other messages -- as you can see, the -`PhoneNumber` type is defined inside `Person`. You can also define `enum` types -if you want one of your fields to have one of a predefined list of values -- -here you want to specify that a phone number can be one of the following phone -types: `PHONE_TYPE_MOBILE`, `PHONE_TYPE_HOME`, or `PHONE_TYPE_WORK`. - -The " = 1", " = 2" markers on each element identify the unique "tag" that field -uses in the binary encoding. Tag numbers 1-15 require one less byte to encode -than higher numbers, so as an optimization you can decide to use those tags for -the commonly used or repeated elements, leaving tags 16 and higher for -less-commonly used optional elements. Each element in a repeated field requires -re-encoding the tag number, so repeated fields are particularly good candidates -for this optimization. - -Each field must be annotated with one of the following modifiers: - -- `optional`: the field may or may not be set. If an optional field value - isn't set, a default value is used. For simple types, you can specify your - own default value, as we've done for the phone number `type` in the example. - Otherwise, a system default is used: zero for numeric types, the empty - string for strings, false for bools. For embedded messages, the default - value is always the "default instance" or "prototype" of the message, which - has none of its fields set. Calling the accessor to get the value of an - optional (or required) field which has not been explicitly set always - returns that field's default value. -- `repeated`: the field may be repeated any number of times (including zero). - The order of the repeated values will be preserved in the protocol buffer. - Think of repeated fields as dynamically sized arrays. -- `required`: a value for the field must be provided, otherwise the message - will be considered "uninitialized". Trying to build an uninitialized message - will throw a `RuntimeException`. Parsing an uninitialized message will throw - an `IOException`. Other than this, a required field behaves exactly like an - optional field. - -{{% alert title="Important" color="warning" %}} **Required Is Forever** -You should be very careful about marking fields as `required`. If at some point -you wish to stop writing or sending a required field, it will be problematic to -change the field to an optional field -- old readers will consider messages -without this field to be incomplete and may reject or drop them unintentionally. -You should consider writing application-specific custom validation routines for -your buffers instead. Within Google, `required` fields are strongly disfavored; -most messages defined in proto2 syntax use `optional` and `repeated` only. -(Proto3 does not support `required` fields at all.) -{{% /alert %}} - -You'll find a complete guide to writing `.proto` files -- including all the -possible field types -- in the -[Protocol Buffer Language Guide](/programming-guides/proto2). -Don't go looking for facilities similar to class inheritance, though -- protocol -buffers don't do that. - -## Compiling Your Protocol Buffers {#compiling-protocol-buffers} - -Now that you have a `.proto`, the next thing you need to do is generate the -classes you'll need to read and write `AddressBook` (and hence `Person` and -`PhoneNumber`) messages. To do this, you need to run the protocol buffer -compiler `protoc` on your `.proto`: - -1. If you haven't installed the compiler, - [download the package](/downloads) and follow the - instructions in the README. - -1. Now run the compiler, specifying the source directory (where your - application's source code lives -- the current directory is used if you - don't provide a value), the destination directory (where you want the - generated code to go; often the same as `$SRC_DIR`), and the path to your - `.proto`. In this case, you...: - - ```shell - protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/addressbook.proto - ``` - - Because you want Java classes, you use the `--java_out` option -- similar - options are provided for other supported languages. - -This generates a `com/example/tutorial/protos/` subdirectory in your specified -destination directory, containing a few generated `.java` files. - -## The Protocol Buffer API {#protobuf-api} - -Let's look at some of the generated code and see what classes and methods the -compiler has created for you. If you look in `com/example/tutorial/protos/`, you -can see that it contains `.java` files defining a class for each message you -specified in `addressbook.proto`. Each class has its own `Builder` class that -you use to create instances of that class. You can find out more about builders -in the [Builders vs. Messages](#builders-messages) section below. - -Both messages and builders have auto-generated accessor methods for each field -of the message; messages have only getters while builders have both getters and -setters. Here are some of the accessors for the `Person` class (implementations -omitted for brevity): - -```java -// required string name = 1; -public boolean hasName(); -public String getName(); - -// required int32 id = 2; -public boolean hasId(); -public int getId(); - -// optional string email = 3; -public boolean hasEmail(); -public String getEmail(); - -// repeated .tutorial.Person.PhoneNumber phones = 4; -public List getPhonesList(); -public int getPhonesCount(); -public PhoneNumber getPhones(int index); -``` - -Meanwhile, `Person.Builder` has the same getters plus setters: - -```java -// required string name = 1; -public boolean hasName(); -public String getName(); -public Builder setName(String value); -public Builder clearName(); - -// required int32 id = 2; -public boolean hasId(); -public int getId(); -public Builder setId(int value); -public Builder clearId(); - -// optional string email = 3; -public boolean hasEmail(); -public String getEmail(); -public Builder setEmail(String value); -public Builder clearEmail(); - -// repeated .tutorial.Person.PhoneNumber phones = 4; -public List getPhonesList(); -public int getPhonesCount(); -public PhoneNumber getPhones(int index); -public Builder setPhones(int index, PhoneNumber value); -public Builder addPhones(PhoneNumber value); -public Builder addAllPhones(Iterable value); -public Builder clearPhones(); -``` - -As you can see, there are simple JavaBeans-style getters and setters for each -field. There are also `has` getters for each singular field which return true if -that field has been set. Finally, each field has a `clear` method that un-sets -the field back to its empty state. - -Repeated fields have some extra methods -- a `Count` method (which is just -shorthand for the list's size), getters and setters which get or set a specific -element of the list by index, an `add` method which appends a new element to the -list, and an `addAll` method which adds an entire container full of elements to -the list. - -Notice how these accessor methods use camel-case naming, even though the -`.proto` file uses lowercase-with-underscores. This transformation is done -automatically by the protocol buffer compiler so that the generated classes -match standard Java style conventions. You should always use -lowercase-with-underscores for field names in your `.proto` files; this ensures -good naming practice in all the generated languages. See the -[style guide](/programming-guides/style) for more on good -`.proto` style. - -For more information on exactly what members the protocol compiler generates for -any particular field definition, see the -[Java generated code reference](/reference/java/java-generated). - -### Enums and Nested Classes {#enums-nested-classes} - -The generated code includes a `PhoneType` Java 5 enum, nested within `Person`: - -```java -public static enum PhoneType { - PHONE_TYPE_UNSPECIFIED(0, 0), - PHONE_TYPE_MOBILE(1, 1), - PHONE_TYPE_HOME(2, 2), - PHONE_TYPE_WORK(3, 3), - ; - ... -} -``` - -The nested type `Person.PhoneNumber` is generated, as you'd expect, as a nested -class within `Person`. - -### Builders vs. Messages {#builders-messages} - -The message classes generated by the protocol buffer compiler are all -*immutable*. Once a message object is constructed, it cannot be modified, just -like a Java `String`. To construct a message, you must first construct a -builder, set any fields you want to set to your chosen values, then call the -builder's `build()` method. - -You may have noticed that each method of the builder which modifies the message -returns another builder. The returned object is actually the same builder on -which you called the method. It is returned for convenience so that you can -string several setters together on a single line of code. - -Here's an example of how you would create an instance of `Person`: - -```java -Person john = - Person.newBuilder() - .setId(1234) - .setName("John Doe") - .setEmail("jdoe@example.com") - .addPhones( - Person.PhoneNumber.newBuilder() - .setNumber("555-4321") - .setType(Person.PhoneType.PHONE_TYPE_HOME) - .build()); - .build(); -``` - -### Standard Message Methods {#standard-message-methods} - -Each message and builder class also contains a number of other methods that let -you check or manipulate the entire message, including: - -- `isInitialized()`: checks if all the required fields have been set. -- `toString()`: returns a human-readable representation of the message, - particularly useful for debugging. -- `mergeFrom(Message other)`: (builder only) merges the contents of `other` - into this message, overwriting singular scalar fields, merging composite - fields, and concatenating repeated fields. -- `clear()`: (builder only) clears all the fields back to the empty state. - -These methods implement the `Message` and `Message.Builder` interfaces shared by -all Java messages and builders. For more information, see the -[complete API documentation for `Message`](/reference/java/api-docs/com/google/protobuf/Message.html). - -### Parsing and Serialization {#parsing-serialization} - -Finally, each protocol buffer class has methods for writing and reading messages -of your chosen type using the protocol buffer -[binary format](/programming-guides/encoding). These -include: - -- `byte[] toByteArray();`: serializes the message and returns a byte array - containing its raw bytes. -- `static Person parseFrom(byte[] data);`: parses a message from the given - byte array. -- `void writeTo(OutputStream output);`: serializes the message and writes it - to an `OutputStream`. -- `static Person parseFrom(InputStream input);`: reads and parses a message - from an `InputStream`. - -These are just a couple of the options provided for parsing and serialization. -Again, see the -[`Message` API reference](/reference/java/api-docs/com/google/protobuf/Message.html) -for a complete list. - -{{% alert title="Important" color="warning" %}} **Protocol Buffers and Object Oriented Design** -Protocol buffer classes are basically data holders (like structs in C) that -don't provide additional functionality; they don't make good first class -citizens in an object model. If you want to add richer behavior to a generated -class, the best way to do this is to wrap the generated protocol buffer class in -an application-specific class. Wrapping protocol buffers is also a good idea if -you don't have control over the design of the `.proto` file (if, say, you're -reusing one from another project). In that case, you can use the wrapper class -to craft an interface better suited to the unique environment of your -application: hiding some data and methods, exposing convenience functions, etc. -**You should never add behavior to the generated classes by inheriting from -them**. This will break internal mechanisms and is not good object-oriented -practice anyway. {{% /alert %}} - -## Writing a Message {#writing-a-message} - -Now let's try using your protocol buffer classes. The first thing you want your -address book application to be able to do is write personal details to your -address book file. To do this, you need to create and populate instances of your -protocol buffer classes and then write them to an output stream. - -Here is a program which reads an `AddressBook` from a file, adds one new -`Person` to it based on user input, and writes the new `AddressBook` back out to -the file again. The parts which directly call or reference code generated by the -protocol compiler are highlighted. - -```java -import com.example.tutorial.protos.AddressBook; -import com.example.tutorial.protos.Person; -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.InputStreamReader; -import java.io.IOException; -import java.io.PrintStream; - -class AddPerson { - // This function fills in a Person message based on user input. - static Person PromptForAddress(BufferedReader stdin, - PrintStream stdout) throws IOException { - Person.Builder person = Person.newBuilder(); - - stdout.print("Enter person ID: "); - person.setId(Integer.valueOf(stdin.readLine())); - - stdout.print("Enter name: "); - person.setName(stdin.readLine()); - - stdout.print("Enter email address (blank for none): "); - String email = stdin.readLine(); - if (email.length() > 0) { - person.setEmail(email); - } - - while (true) { - stdout.print("Enter a phone number (or leave blank to finish): "); - String number = stdin.readLine(); - if (number.length() == 0) { - break; - } - - Person.PhoneNumber.Builder phoneNumber = - Person.PhoneNumber.newBuilder().setNumber(number); - - stdout.print("Is this a mobile, home, or work phone? "); - String type = stdin.readLine(); - if (type.equals("mobile")) { - phoneNumber.setType(Person.PhoneType.PHONE_TYPE_MOBILE); - } else if (type.equals("home")) { - phoneNumber.setType(Person.PhoneType.PHONE_TYPE_HOME); - } else if (type.equals("work")) { - phoneNumber.setType(Person.PhoneType.PHONE_TYPE_WORK); - } else { - stdout.println("Unknown phone type. Using default."); - } - - person.addPhones(phoneNumber); - } - - return person.build(); - } - - // Main function: Reads the entire address book from a file, - // adds one person based on user input, then writes it back out to the same - // file. - public static void main(String[] args) throws Exception { - if (args.length != 1) { - System.err.println("Usage: AddPerson ADDRESS_BOOK_FILE"); - System.exit(-1); - } - - AddressBook.Builder addressBook = AddressBook.newBuilder(); - - // Read the existing address book. - try { - addressBook.mergeFrom(new FileInputStream(args[0])); - } catch (FileNotFoundException e) { - System.out.println(args[0] + ": File not found. Creating a new file."); - } - - // Add an address. - addressBook.addPerson( - PromptForAddress(new BufferedReader(new InputStreamReader(System.in)), - System.out)); - - // Write the new address book back to disk. - FileOutputStream output = new FileOutputStream(args[0]); - addressBook.build().writeTo(output); - output.close(); - } -} -``` - -## Reading a Message {#reading-a-message} - -Of course, an address book wouldn't be much use if you couldn't get any -information out of it! This example reads the file created by the above example -and prints all the information in it. - -```java -import com.example.tutorial.protos.AddressBook; -import com.example.tutorial.protos.Person; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.PrintStream; - -class ListPeople { - // Iterates though all people in the AddressBook and prints info about them. - static void Print(AddressBook addressBook) { - for (Person person: addressBook.getPeopleList()) { - System.out.println("Person ID: " + person.getId()); - System.out.println(" Name: " + person.getName()); - if (person.hasEmail()) { - System.out.println(" E-mail address: " + person.getEmail()); - } - - for (Person.PhoneNumber phoneNumber : person.getPhonesList()) { - switch (phoneNumber.getType()) { - case PHONE_TYPE_MOBILE: - System.out.print(" Mobile phone #: "); - break; - case PHONE_TYPE_HOME: - System.out.print(" Home phone #: "); - break; - case PHONE_TYPE_WORK: - System.out.print(" Work phone #: "); - break; - } - System.out.println(phoneNumber.getNumber()); - } - } - } - - // Main function: Reads the entire address book from a file and prints all - // the information inside. - public static void main(String[] args) throws Exception { - if (args.length != 1) { - System.err.println("Usage: ListPeople ADDRESS_BOOK_FILE"); - System.exit(-1); - } - - // Read the existing address book. - AddressBook addressBook = - AddressBook.parseFrom(new FileInputStream(args[0])); - - Print(addressBook); - } -} -``` - -## Extending a Protocol Buffer {#extending-a-protobuf} - -Sooner or later after you release the code that uses your protocol buffer, you -will undoubtedly want to "improve" the protocol buffer's definition. If you want -your new buffers to be backwards-compatible, and your old buffers to be -forward-compatible -- and you almost certainly do want this -- then there are -some rules you need to follow. In the new version of the protocol buffer: - -- you *must not* change the tag numbers of any existing fields. -- you *must not* add or delete any required fields. -- you *may* delete optional or repeated fields. -- you *may* add new optional or repeated fields but you must use fresh tag - numbers (that is, tag numbers that were never used in this protocol buffer, - not even by deleted fields). - -(There are -[some exceptions](/programming-guides/proto2#updating) to -these rules, but they are rarely used.) - -If you follow these rules, old code will happily read new messages and simply -ignore any new fields. To the old code, optional fields that were deleted will -simply have their default value, and deleted repeated fields will be empty. New -code will also transparently read old messages. However, keep in mind that new -optional fields will not be present in old messages, so you will need to either -check explicitly whether they're set with `has_`, or provide a reasonable -default value in your `.proto` file with `[default = value]` after the tag -number. If the default value is not specified for an optional element, a -type-specific default value is used instead: for strings, the default value is -the empty string. For booleans, the default value is false. For numeric types, -the default value is zero. Note also that if you added a new repeated field, -your new code will not be able to tell whether it was left empty (by new code) -or never set at all (by old code) since there is no `has_` flag for it. - -## Advanced Usage {#advanced-usage} - -Protocol buffers have uses that go beyond simple accessors and serialization. Be -sure to explore the -[Java API reference](/reference/java/api-docs/index-all.html) -to see what else you can do with them. - -One key feature provided by protocol message classes is *reflection*. You can -iterate over the fields of a message and manipulate their values without writing -your code against any specific message type. One very useful way to use -reflection is for converting protocol messages to and from other encodings, such -as XML or JSON. A more advanced use of reflection might be to find differences -between two messages of the same type, or to develop a sort of "regular -expressions for protocol messages" in which you can write expressions that match -certain message contents. If you use your imagination, it's possible to apply -Protocol Buffers to a much wider range of problems than you might initially -expect! - -Reflection is provided as part of the -[`Message`](/reference/java/api-docs/com/google/protobuf/Message.html) -and -[`Message.Builder`](/reference/java/api-docs/com/google/protobuf/Message.Builder.html) -interfaces. diff --git a/content/getting-started/kotlintutorial.md b/content/getting-started/kotlintutorial.md deleted file mode 100644 index d2b67fcc3..000000000 --- a/content/getting-started/kotlintutorial.md +++ /dev/null @@ -1,370 +0,0 @@ -+++ -title = "Protocol Buffer Basics: Kotlin" -weight = 260 -linkTitle = "Kotlin" -description = "A basic Kotlin programmers introduction to working with protocol buffers." -type = "docs" -+++ - -This tutorial provides a basic Kotlin programmer's introduction to working with -protocol buffers, using the -[proto3](/programming-guides/proto3) version of the -protocol buffers language. By walking through creating a simple example -application, it shows you how to - -- Define message formats in a `.proto` file. -- Use the protocol buffer compiler. -- Use the Kotlin protocol buffer API to write and read messages. - -This isn't a comprehensive guide to using protocol buffers in Kotlin. For more -detailed reference information, see the -[Protocol Buffer Language Guide](/programming-guides/proto3), -the [Kotlin API Reference](/reference/kotlin/api-docs), -the -[Kotlin Generated Code Guide](/reference/kotlin/kotlin-generated), -and the -[Encoding Reference](/programming-guides/encoding). - -## The Problem Domain {#problem-domain} - -The example we're going to use is a very simple "address book" application that -can read and write people's contact details to and from a file. Each person in -the address book has a name, an ID, an email address, and a contact phone -number. - -How do you serialize and retrieve structured data like this? There are a few -ways to solve this problem: - -- Use kotlinx.serialization. This does not work very well if you need to share - data with applications written in C++ or Python. kotlinx.serialization has a - [protobuf mode](https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/formats#protobuf-experimental), - but this does not offer the full features of protocol buffers. -- You can invent an ad-hoc way to encode the data items into a single - string -- such as encoding 4 ints as "12:3:-23:67". This is a simple and - flexible approach, although it does require writing one-off encoding and - parsing code, and the parsing imposes a small run-time cost. This works best - for encoding very simple data. -- Serialize the data to XML. This approach can be very attractive since XML is - (sort of) human readable and there are binding libraries for lots of - languages. This can be a good choice if you want to share data with other - applications/projects. However, XML is notoriously space intensive, and - encoding/decoding it can impose a huge performance penalty on applications. - Also, navigating an XML DOM tree is considerably more complicated than - navigating simple fields in a class normally would be. - -Protocol buffers are the flexible, efficient, automated solution to solve -exactly this problem. With protocol buffers, you write a `.proto` description of -the data structure you wish to store. From that, the protocol buffer compiler -creates a class that implements automatic encoding and parsing of the protocol -buffer data with an efficient binary format. The generated class provides -getters and setters for the fields that make up a protocol buffer and takes care -of the details of reading and writing the protocol buffer as a unit. -Importantly, the protocol buffer format supports the idea of extending the -format over time in such a way that the code can still read data encoded with -the old format. - -## Where to Find the Example Code {#example-code} - -Our example is a set of command-line applications for managing an address book -data file, encoded using protocol buffers. The command `add_person_kotlin` adds -a new entry to the data file. The command `list_people_kotlin` parses the data -file and prints the data to the console. - -You can find the complete example in the -[examples directory](https://github.com/protocolbuffers/protobuf/tree/master/examples) -of the GitHub repository. - -## Defining Your Protocol Format {#protocol-format} - -To create your address book application, you'll need to start with a `.proto` -file. The definitions in a `.proto` file are simple: you add a *message* for -each data structure you want to serialize, then specify a name and a type for -each field in the message. In our example, the `.proto` file that defines the -messages is -[`addressbook.proto`](https://github.com/protocolbuffers/protobuf/blob/master/examples/addressbook.proto). - -The `.proto` file starts with a package declaration, which helps to prevent -naming conflicts between different projects. - -```proto -syntax = "proto3"; -package tutorial; - -import "google/protobuf/timestamp.proto"; -``` - -Next, you have your message definitions. A message is just an aggregate -containing a set of typed fields. Many standard simple data types are available -as field types, including `bool`, `int32`, `float`, `double`, and `string`. You -can also add further structure to your messages by using other message types as -field types. - -```proto -message Person { - string name = 1; - int32 id = 2; // Unique ID number for this person. - string email = 3; - - enum PhoneType { - PHONE_TYPE_UNSPECIFIED = 0; - PHONE_TYPE_MOBILE = 1; - PHONE_TYPE_HOME = 2; - PHONE_TYPE_WORK = 3; - } - - message PhoneNumber { - string number = 1; - PhoneType type = 2; - } - - repeated PhoneNumber phones = 4; - - google.protobuf.Timestamp last_updated = 5; -} - -// Our address book file is just one of these. -message AddressBook { - repeated Person people = 1; -} -``` - -In the above example, the `Person` message contains `PhoneNumber` messages, -while the `AddressBook` message contains `Person` messages. You can even define -message types nested inside other messages -- as you can see, the `PhoneNumber` -type is defined inside `Person`. You can also define `enum` types if you want -one of your fields to have one of a predefined list of values -- here you want -to specify that a phone number can be one of `PHONE_TYPE_MOBILE`, -`PHONE_TYPE_HOME`, or `PHONE_TYPE_WORK`. - -The " = 1", " = 2" markers on each element identify the unique "tag" that field -uses in the binary encoding. Tag numbers 1-15 require one less byte to encode -than higher numbers, so as an optimization you can decide to use those tags for -the commonly used or repeated elements, leaving tags 16 and higher for -less-commonly used optional elements. Each element in a repeated field requires -re-encoding the tag number, so repeated fields are particularly good candidates -for this optimization. - -If a field value isn't set, a -[default value](/programming-guides/proto3#default) is -used: zero for numeric types, the empty string for strings, false for bools. For -embedded messages, the default value is always the "default instance" or -"prototype" of the message, which has none of its fields set. Calling the -accessor to get the value of a field which has not been explicitly set always -returns that field's default value. - -If a field is `repeated`, the field may be repeated any number of times -(including zero). The order of the repeated values will be preserved in the -protocol buffer. Think of repeated fields as dynamically sized arrays. - -You'll find a complete guide to writing `.proto` files -- including all the -possible field types -- in the -[Protocol Buffer Language Guide](/programming-guides/proto3). -Don't go looking for facilities similar to class inheritance, though -- protocol -buffers don't do that. - -## Compiling Your Protocol Buffers {#compiling-protocol-buffers} - -Now that you have a `.proto`, the next thing you need to do is generate the -classes you'll need to read and write `AddressBook` (and hence `Person` and -`PhoneNumber`) messages. To do this, you need to run the protocol buffer -compiler `protoc` on your `.proto`: - -1. If you haven't installed the compiler, - [download the package](/downloads) and follow the - instructions in the README. - -2. Now run the compiler, specifying the source directory (where your - application's source code lives -- the current directory is used if you - don't provide a value), the destination directory (where you want the - generated code to go; often the same as `$SRC_DIR`), and the path to your - `.proto`. In this case, you would invoke: - - ```shell - protoc -I=$SRC_DIR --java_out=$DST_DIR --kotlin_out=$DST_DIR $SRC_DIR/addressbook.proto - ``` - - Because you want Kotlin code, you use the `--kotlin_out` option -- similar - options are provided for other supported languages. - -Note that if you want to generate Kotlin code you must use both `--java_out` and -`--kotlin_out`. This generates a `com/example/tutorial/protos/` subdirectory in -your specified Java destination directory, containing a few generated `.java` -files and a `com/example/tutorial/protos/` subdirectory in your specified Kotlin -destination directory, containing a few generated `.kt` files. - -## The Protocol Buffer API {#protobuf-api} - -The protocol buffer compiler for Kotlin generates Kotlin APIs that add to the -existing APIs generated for protocol buffers for Java. This ensures that -codebases written in a mix of Java and Kotlin can interact with the same -protocol buffer message objects without any special handling or conversion. - -Protocol buffers for other Kotlin compilation targets, such as JavaScript and -native, are not currently supported. - -Compiling `addressbook.proto` gives you the following APIs in Java: - -- The `AddressBook` class - - which, from Kotlin, has the `peopleList : List` property -- The `Person` class - - which, from Kotlin, has `name`, `id`, `email`, and `phonesList` - properties - - the `Person.PhoneNumber` nested class with `number` and `type` - properties - - the `Person.PhoneType` nested enum - -but also generates the following Kotlin APIs: - -- The `addressBook { ... }` and `person { ... }` factory methods -- A `PersonKt` object, with a `phoneNumber { ... }` factory method - -You can read more about the details of exactly what's generated in the -[Kotlin Generated Code guide](/reference/kotlin/kotlin-generated). - -## Writing a Message {#writing-a-message} - -Now let's try using your protocol buffer classes. The first thing you want your -address book application to be able to do is write personal details to your -address book file. To do this, you need to create and populate instances of your -protocol buffer classes and then write them to an output stream. - -Here is a program which reads an `AddressBook` from a file, adds one new -`Person` to it based on user input, and writes the new `AddressBook` back out to -the file again. The parts which directly call or reference code generated by the -protocol compiler are highlighted. - -```kotlin -import com.example.tutorial.Person -import com.example.tutorial.AddressBook -import com.example.tutorial.person -import com.example.tutorial.addressBook -import com.example.tutorial.PersonKt.phoneNumber -import java.util.Scanner - -// This function fills in a Person message based on user input. -fun promptPerson(): Person = person { - print("Enter person ID: ") - id = readLine().toInt() - - print("Enter name: ") - name = readLine() - - print("Enter email address (blank for none): ") - val email = readLine() - if (email.isNotEmpty()) { - this.email = email - } - - while (true) { - print("Enter a phone number (or leave blank to finish): ") - val number = readLine() - if (number.isEmpty()) break - - print("Is this a mobile, home, or work phone? ") - val type = when (readLine()) { - "mobile" -> Person.PhoneType.PHONE_TYPE_MOBILE - "home" -> Person.PhoneType.PHONE_TYPE_HOME - "work" -> Person.PhoneType.PHONE_TYPE_WORK - else -> { - println("Unknown phone type. Using home.") - Person.PhoneType.PHONE_TYPE_HOME - } - } - phones += phoneNumber { - this.number = number - this.type = type - } - } -} - -// Reads the entire address book from a file, adds one person based -// on user input, then writes it back out to the same file. -fun main(args: List) { - if (arguments.size != 1) { - println("Usage: add_person ADDRESS_BOOK_FILE") - exitProcess(-1) - } - val path = Path(arguments.single()) - val initialAddressBook = if (!path.exists()) { - println("File not found. Creating new file.") - addressBook {} - } else { - path.inputStream().use { - AddressBook.newBuilder().mergeFrom(it).build() - } - } - path.outputStream().use { - initialAddressBook.copy { peopleList += promptPerson() }.writeTo(it) - } -} -``` - -## Reading a Message {#reading-a-message} - -Of course, an address book wouldn't be much use if you couldn't get any -information out of it! This example reads the file created by the above example -and prints all the information in it. - -```kotlin -import com.example.tutorial.Person -import com.example.tutorial.AddressBook - -// Iterates though all people in the AddressBook and prints info about them. -fun print(addressBook: AddressBook) { - for (person in addressBook.peopleList) { - println("Person ID: ${person.id}") - println(" Name: ${person.name}") - if (person.hasEmail()) { - println(" Email address: ${person.email}") - } - for (phoneNumber in person.phonesList) { - val modifier = when (phoneNumber.type) { - Person.PhoneType.PHONE_TYPE_MOBILE -> "Mobile" - Person.PhoneType.PHONE_TYPE_HOME -> "Home" - Person.PhoneType.PHONE_TYPE_WORK -> "Work" - else -> "Unknown" - } - println(" $modifier phone #: ${phoneNumber.number}") - } - } -} - -fun main(args: List) { - if (arguments.size != 1) { - println("Usage: list_person ADDRESS_BOOK_FILE") - exitProcess(-1) - } - Path(arguments.single()).inputStream().use { - print(AddressBook.newBuilder().mergeFrom(it).build()) - } -} -``` - -## Extending a Protocol Buffer {#extending-a-protobuf} - -Sooner or later after you release the code that uses your protocol buffer, you -will undoubtedly want to "improve" the protocol buffer's definition. If you want -your new buffers to be backwards-compatible, and your old buffers to be -forward-compatible -- and you almost certainly do want this -- then there are -some rules you need to follow. In the new version of the protocol buffer: - -- you *must not* change the tag numbers of any existing fields. -- you *may* delete fields. -- you *may* add new fields but you must use fresh tag numbers (i.e. tag - numbers that were never used in this protocol buffer, not even by deleted - fields). - -(There are -[some exceptions](/programming-guides/proto3#updating) to -these rules, but they are rarely used.) - -If you follow these rules, old code will happily read new messages and simply -ignore any new fields. To the old code, singular fields that were deleted will -simply have their default value, and deleted repeated fields will be empty. New -code will also transparently read old messages. - -However, keep in mind that new fields will not be present in old messages, so -you will need to do something reasonable with the default value. A type-specific -[default value](/programming-guides/proto3#default) is -used: for strings, the default value is the empty string. For booleans, the -default value is false. For numeric types, the default value is zero. diff --git a/content/getting-started/pythontutorial.md b/content/getting-started/pythontutorial.md deleted file mode 100644 index 9718dda05..000000000 --- a/content/getting-started/pythontutorial.md +++ /dev/null @@ -1,500 +0,0 @@ -+++ -title = "Protocol Buffer Basics: Python" -weight = 270 -linkTitle = "Python" -description = "A basic Python programmers introduction to working with protocol buffers." -type = "docs" -+++ - -This tutorial provides a basic Python programmer's introduction to working with -protocol buffers. By walking through creating a simple example application, it -shows you how to - -- Define message formats in a `.proto` file. -- Use the protocol buffer compiler. -- Use the Python protocol buffer API to write and read messages. - -This isn't a comprehensive guide to using protocol buffers in Python. For more -detailed reference information, see the -[Protocol Buffer Language Guide (proto2)](/programming-guides/proto2), -the -[Protocol Buffer Language Guide (proto3)](/programming-guides/proto3), -the [Python API Reference](https://googleapis.dev/python/protobuf/latest/), the -[Python Generated Code Guide](/reference/python/python-generated), -and the -[Encoding Reference](/programming-guides/encoding). - -## The Problem Domain {#problem-domain} - -The example we're going to use is a very simple "address book" application that -can read and write people's contact details to and from a file. Each person in -the address book has a name, an ID, an email address, and a contact phone -number. - -How do you serialize and retrieve structured data like this? There are a few -ways to solve this problem: - -- Use Python pickling. This is the default approach since it's built into the - language, but it doesn't deal well with schema evolution, and also doesn't - work very well if you need to share data with applications written in C++ or - Java. -- You can invent an ad-hoc way to encode the data items into a single - string -- such as encoding 4 ints as "12:3:-23:67". This is a simple and - flexible approach, although it does require writing one-off encoding and - parsing code, and the parsing imposes a small run-time cost. This works best - for encoding very simple data. -- Serialize the data to XML. This approach can be very attractive since XML is - (sort of) human readable and there are binding libraries for lots of - languages. This can be a good choice if you want to share data with other - applications/projects. However, XML is notoriously space intensive, and - encoding/decoding it can impose a huge performance penalty on applications. - Also, navigating an XML DOM tree is considerably more complicated than - navigating simple fields in a class normally would be. - -Instead of these options, you can use protocol buffers. Protocol buffers are the -flexible, efficient, automated solution to solve exactly this problem. With -protocol buffers, you write a `.proto` description of the data structure you -wish to store. From that, the protocol buffer compiler creates a class that -implements automatic encoding and parsing of the protocol buffer data with an -efficient binary format. The generated class provides getters and setters for -the fields that make up a protocol buffer and takes care of the details of -reading and writing the protocol buffer as a unit. Importantly, the protocol -buffer format supports the idea of extending the format over time in such a way -that the code can still read data encoded with the old format. - -## Where to Find the Example Code {#example-code} - -The example code is included in the source code package, under the "examples" -directory. [Download it here.](/downloads) - -## Defining Your Protocol Format {#protocol-format} - -To create your address book application, you'll need to start with a `.proto` -file. The definitions in a `.proto` file are simple: you add a *message* for -each data structure you want to serialize, then specify a name and a type for -each field in the message. Here is the `.proto` file that defines your messages, -`addressbook.proto`. - -```proto -edition = "2023"; - -package tutorial; - -message Person { - string name = 1; - int32 id = 2; - string email = 3; - - enum PhoneType { - PHONE_TYPE_UNSPECIFIED = 0; - PHONE_TYPE_MOBILE = 1; - PHONE_TYPE_HOME = 2; - PHONE_TYPE_WORK = 3; - } - - message PhoneNumber { - string number = 1; - PhoneType type = 2 [default = PHONE_TYPE_HOME]; - } - - repeated PhoneNumber phones = 4; -} - -message AddressBook { - repeated Person people = 1; -} -``` - -As you can see, the syntax is similar to C++ or Java. Let's go through each part -of the file and see what it does. - -The `.proto` file starts with a package declaration, which helps to prevent -naming conflicts between different projects. In Python, packages are normally -determined by directory structure, so the `package` you define in your `.proto` -file will have no effect on the generated code. However, you should still -declare one to avoid name collisions in the Protocol Buffers name space as well -as in non-Python languages. - -Next, you have your message definitions. A message is just an aggregate -containing a set of typed fields. Many standard simple data types are available -as field types, including `bool`, `int32`, `float`, `double`, and `string`. You -can also add further structure to your messages by using other message types as -field types -- in the above example the `Person` message contains `PhoneNumber` -messages, while the `AddressBook` message contains `Person` messages. You can -even define message types nested inside other messages -- as you can see, the -`PhoneNumber` type is defined inside `Person`. You can also define `enum` types -if you want one of your fields to have one of a predefined list of values -- -here you want to specify that a phone number can be one of the following phone -types: `PHONE_TYPE_MOBILE`, `PHONE_TYPE_HOME`, or `PHONE_TYPE_WORK`. - -The " = 1", " = 2" markers on each element identify the unique "tag" that field -uses in the binary encoding. Tag numbers 1-15 require one less byte to encode -than higher numbers, so as an optimization you can decide to use those tags for -the commonly used or repeated elements, leaving tags 16 and higher for -less-commonly used optional elements. Each element in a repeated field requires -re-encoding the tag number, so repeated fields are particularly good candidates -for this optimization. - -You'll find a complete guide to writing `.proto` files -- including all the -possible field types -- in the -[Protocol Buffer Language Guide](/programming-guides/editions). -Don't go looking for facilities similar to class inheritance, though -- protocol -buffers don't do that. - -## Compiling Your Protocol Buffers {#compiling-protocol-buffers} - -Now that you have a `.proto`, the next thing you need to do is generate the -classes you'll need to read and write `AddressBook` (and hence `Person` and -`PhoneNumber`) messages. To do this, you need to run the protocol buffer -compiler `protoc` on your `.proto`: - -1. If you haven't installed the compiler, - [download the package](/downloads) and follow the - instructions in the README. - -2. Now run the compiler, specifying the source directory (where your - application's source code lives -- the current directory is used if you - don't provide a value), the destination directory (where you want the - generated code to go; often the same as `$SRC_DIR`), and the path to your - `.proto`. In this case, you...: - - ```shell - protoc --proto_path=$SRC_DIR --python_out=$DST_DIR $SRC_DIR/addressbook.proto - ``` - - Because you want Python classes, you use the `--python_out` option -- - similar options are provided for other supported languages. - - Protoc is also able to generate python stubs (`.pyi`) with `--pyi_out`. - -This generates `addressbook_pb2.py` (or `addressbook_pb2.pyi`) in your specified -destination directory. - -## The Protocol Buffer API {#protobuf-api} - -Unlike when you generate Java and C++ protocol buffer code, the Python protocol -buffer compiler doesn't generate your data access code for you directly. Instead -(as you'll see if you look at `addressbook_pb2.py`) it generates special -descriptors for all your messages, enums, and fields, and some mysteriously -empty classes, one for each message type: - -```python -import google3 -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import runtime_version as _runtime_version -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.GOOGLE_INTERNAL, - 0, - 20240502, - 0, - '', - 'main.proto' -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nmain.proto\x12\x08tutorial\"\xa3\x02\n\x06Person\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\x05\x12\r\n\x05\x65mail\x18\x03 \x01(\t\x12,\n\x06phones\x18\x04 \x03(\x0b\x32\x1c.tutorial.Person.PhoneNumber\x1aX\n\x0bPhoneNumber\x12\x0e\n\x06number\x18\x01 \x01(\t\x12\x39\n\x04type\x18\x02 \x01(\x0e\x32\x1a.tutorial.Person.PhoneType:\x0fPHONE_TYPE_HOME\"h\n\tPhoneType\x12\x1a\n\x16PHONE_TYPE_UNSPECIFIED\x10\x00\x12\x15\n\x11PHONE_TYPE_MOBILE\x10\x01\x12\x13\n\x0fPHONE_TYPE_HOME\x10\x02\x12\x13\n\x0fPHONE_TYPE_WORK\x10\x03\"/\n\x0b\x41\x64\x64ressBook\x12 \n\x06people\x18\x01 \x03(\x0b\x32\x10.tutorial.Person') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google3.main_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - DESCRIPTOR._loaded_options = None - _globals['_PERSON']._serialized_start=25 - _globals['_PERSON']._serialized_end=316 - _globals['_PERSON_PHONENUMBER']._serialized_start=122 - _globals['_PERSON_PHONENUMBER']._serialized_end=210 - _globals['_PERSON_PHONETYPE']._serialized_start=212 - _globals['_PERSON_PHONETYPE']._serialized_end=316 - _globals['_ADDRESSBOOK']._serialized_start=318 - _globals['_ADDRESSBOOK']._serialized_end=365 -# @@protoc_insertion_point(module_scope) -``` - -The important line in each class is `__metaclass__ = -reflection.GeneratedProtocolMessageType`. While the details of how Python -metaclasses work is beyond the scope of this tutorial, you can think of them as -like a template for creating classes. At load time, the -`GeneratedProtocolMessageType` metaclass uses the specified descriptors to -create all the Python methods you need to work with each message type and adds -them to the relevant classes. You can then use the fully-populated classes in -your code. - -The end effect of all this is that you can use the `Person` class as if it -defined each field of the `Message` base class as a regular field. For example, -you could write: - -```python -import addressbook_pb2 -person = addressbook_pb2.Person() -person.id = 1234 -person.name = "John Doe" -person.email = "jdoe@example.com" -phone = person.phones.add() -phone.number = "555-4321" -phone.type = addressbook_pb2.Person.PHONE_TYPE_HOME -``` - -Note that these assignments are not just adding arbitrary new fields to a -generic Python object. If you were to try to assign a field that isn't defined -in the `.proto` file, an `AttributeError` would be raised. If you assign a field -to a value of the wrong type, a `TypeError` will be raised. Also, reading the -value of a field before it has been set returns the default value. - -```python -person.no_such_field = 1 # raises AttributeError -person.id = "1234" # raises TypeError -``` - -For more information on exactly what members the protocol compiler generates for -any particular field definition, see the -[Python generated code reference](/reference/python/python-generated). - -### Enums {#enums} - -Enums are expanded by the metaclass into a set of symbolic constants with -integer values. So, for example, the constant -`addressbook_pb2.Person.PhoneType.PHONE_TYPE_WORK` has the value 2. - -### Standard Message Methods {#standard-message-methods} - -Each message class also contains a number of other methods that let you check or -manipulate the entire message, including: - -- `IsInitialized()`: checks if all the required fields have been set. -- `__str__()`: returns a human-readable representation of the message, - particularly useful for debugging. (Usually invoked as `str(message)` or - `print message`.) -- `CopyFrom(other_msg)`: overwrites the message with the given message's - values. -- `Clear()`: clears all the elements back to the empty state. - -These methods implement the `Message` interface. For more information, see the -[complete API documentation for `Message`](https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message). - -### Parsing and Serialization {#parsing-serialization} - -Finally, each protocol buffer class has methods for writing and reading messages -of your chosen type using the protocol buffer -[binary format](/programming-guides/encoding). These -include: - -- `SerializeToString()`: serializes the message and returns it as a string. - Note that the bytes are binary, not text; we only use the `str` type as a - convenient container. -- `ParseFromString(data)`: parses a message from the given string. - -These are just a couple of the options provided for parsing and serialization. -Again, see the -[`Message` API reference](https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message) -for a complete list. - -You can also easily serialize messages to and from JSON. The `json_format` -module provides helpers for this: - -- `MessageToJson(message)`: serializes the message to a JSON string. -- `Parse(json_string, message)`: parses a JSON string into the given message. - -For example: - -```python -from google.protobuf import json_format -import addressbook_pb2 - -person = addressbook_pb2.Person() -person.id = 1234 -person.name = "John Doe" -person.email = "jdoe@example.com" - -# Serialize to JSON -json_string = json_format.MessageToJson(person) - -# Parse from JSON -new_person = addressbook_pb2.Person() -json_format.Parse(json_string, new_person) -``` - -{{% alert title="Important" color="warning" %}} **Protocol Buffers and Object Oriented Design** -Protocol buffer classes are basically data holders (like structs in C) that -don't provide additional functionality; they don't make good first class -citizens in an object model. If you want to add richer behavior to a generated -class, the best way to do this is to wrap the generated protocol buffer class in -an application-specific class. Wrapping protocol buffers is also a good idea if -you don't have control over the design of the `.proto` file (if, say, you're -reusing one from another project). In that case, you can use the wrapper class -to craft an interface better suited to the unique environment of your -application: hiding some data and methods, exposing convenience functions, etc. -**You should never add behavior to the generated classes by inheriting from -them**. This will break internal mechanisms and is not good object-oriented -practice anyway. {{% /alert %}} - -## Writing a Message {#writing-a-message} - -Now let's try using your protocol buffer classes. The first thing you want your -address book application to be able to do is write personal details to your -address book file. To do this, you need to create and populate instances of your -protocol buffer classes and then write them to an output stream. - -Here is a program which reads an `AddressBook` from a file, adds one new -`Person` to it based on user input, and writes the new `AddressBook` back out to -the file again. The parts which directly call or reference code generated by the -protocol compiler are highlighted. - -```python -#!/usr/bin/env python3 - -import addressbook_pb2 -import sys - -# This function fills in a Person message based on user input. -def PromptForAddress(person): - person.id = int(input("Enter person ID number: ")) - person.name = input("Enter name: ") - - email = input("Enter email address (blank for none): ") - if email != "": - person.email = email - - while True: - number = input("Enter a phone number (or leave blank to finish): ") - if number == "": - break - - phone_number = person.phones.add() - phone_number.number = number - - phone_type = input("Is this a mobile, home, or work phone? ") - if phone_type == "mobile": - phone_number.type = addressbook_pb2.Person.PhoneType.PHONE_TYPE_MOBILE - elif phone_type == "home": - phone_number.type = addressbook_pb2.Person.PhoneType.PHONE_TYPE_HOME - elif phone_type == "work": - phone_number.type = addressbook_pb2.Person.PhoneType.PHONE_TYPE_WORK - else: - print("Unknown phone type; leaving as default value.") - -# Main procedure: Reads the entire address book from a file, -# adds one person based on user input, then writes it back out to the same -# file. -if len(sys.argv) != 2: - print("Usage:", sys.argv[0], "ADDRESS_BOOK_FILE") - sys.exit(-1) - -address_book = addressbook_pb2.AddressBook() - -# Read the existing address book. -try: - with open(sys.argv[1], "rb") as f: - address_book.ParseFromString(f.read()) -except IOError: - print(sys.argv[1] + ": Could not open file. Creating a new one.") - -# Add an address. -PromptForAddress(address_book.people.add()) - -# Write the new address book back to disk. -with open(sys.argv[1], "wb") as f: - f.write(address_book.SerializeToString()) -``` - -## Reading a Message {#reading-a-message} - -Of course, an address book wouldn't be much use if you couldn't get any -information out of it! This example reads the file created by the above example -and prints all the information in it. - -```python -#!/usr/bin/env python3 - -import addressbook_pb2 -import sys - -# Iterates though all people in the AddressBook and prints info about them. -def ListPeople(address_book): - for person in address_book.people: - print("Person ID:", person.id) - print(" Name:", person.name) - if person.HasField('email'): - print(" E-mail address:", person.email) - - for phone_number in person.phones: - if phone_number.type == addressbook_pb2.Person.PhoneType.PHONE_TYPE_MOBILE: - print(" Mobile phone #: ", end="") - elif phone_number.type == addressbook_pb2.Person.PhoneType.PHONE_TYPE_HOME: - print(" Home phone #: ", end="") - elif phone_number.type == addressbook_pb2.Person.PhoneType.PHONE_TYPE_WORK: - print(" Work phone #: ", end="") - print(phone_number.number) - -# Main procedure: Reads the entire address book from a file and prints all -# the information inside. -if len(sys.argv) != 2: - print("Usage:", sys.argv[0], "ADDRESS_BOOK_FILE") - sys.exit(-1) - -address_book = addressbook_pb2.AddressBook() - -# Read the existing address book. -with open(sys.argv[1], "rb") as f: - address_book.ParseFromString(f.read()) - -ListPeople(address_book) -``` - -## Extending a Protocol Buffer {#extending-a-protobuf} - -Sooner or later after you release the code that uses your protocol buffer, you -will undoubtedly want to "improve" the protocol buffer's definition. If you want -your new buffers to be backwards-compatible, and your old buffers to be -forward-compatible -- and you almost certainly do want this -- then there are -some rules you need to follow. In the new version of the protocol buffer: - -- you *must not* change the tag numbers of any existing fields. -- you *must not* add or delete any required fields. -- you *may* delete optional or repeated fields. -- you *may* add new optional or repeated fields but you must use fresh tag - numbers (that is, tag numbers that were never used in this protocol buffer, - not even by deleted fields). - -(There are -[some exceptions](/programming-guides/proto2#updating) to -these rules, but they are rarely used.) - -If you follow these rules, old code will happily read new messages and simply -ignore any new fields. To the old code, optional fields that were deleted will -simply have their default value, and deleted repeated fields will be empty. New -code will also transparently read old messages. However, keep in mind that new -optional fields will not be present in old messages, so you will need to either -check explicitly whether they're set with `HasField('field_name')`, or provide a -reasonable default value in your `.proto` file with `[default = value]` after -the tag number. If the default value is not specified for an optional element, a -type-specific default value is used instead: for strings, the default value is -the empty string. For booleans, the default value is false. For numeric types, -the default value is zero. Note also that if you added a new repeated field, -your new code will not be able to tell whether it was left empty (by new code) -or never set at all (by old code) since there is no `HasField` check for it. - -## Advanced Usage {#advanced-usage} - -Protocol buffers have uses that go beyond simple accessors and serialization. Be -sure to explore the -[Python API reference](https://googleapis.dev/python/protobuf/latest/) to see -what else you can do with them. - -One key feature provided by protocol message classes is *reflection*. You can -iterate over the fields of a message and manipulate their values without writing -your code against any specific message type. One very useful way to use -reflection is for converting protocol messages to and from other encodings, such -as XML or JSON (see [Parsing and Serialization](#parsing-serialization) for an -example). A more advanced use of reflection might be to find differences between -two messages of the same type, or to develop a sort of "regular expressions for -protocol messages" in which you can write expressions that match certain message -contents. If you use your imagination, it's possible to apply Protocol Buffers -to a much wider range of problems than you might initially expect! - -Reflection is provided as part of the -[`Message` interface](https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message). diff --git a/content/history.md b/content/history.md deleted file mode 100644 index a45ae45c6..000000000 --- a/content/history.md +++ /dev/null @@ -1,74 +0,0 @@ -+++ -title = "History" -weight = 1020 -description = "A brief history behind the creation of protocol buffers." -type = "docs" -+++ - -Understanding -why protobuf was created and the decisions that changed it over time can help -you to better use the features of the tool. - -## Why Did You Release Protocol Buffers? {#why} - -There are several reasons that we released Protocol Buffers. - -Protocol buffers are used by many projects inside Google. We had other projects -we wanted to release as open source that use protocol buffers, so to do this, we -needed to release protocol buffers first. In fact, bits of the technology had -already found their way into the open; if you dig into the code for Google -AppEngine, you might find some of it. - -We wanted to provide public APIs that accept protocol buffers as well as XML, -both because it is more efficient and because we convert that XML to protocol -buffers on our end, anyway. - -We thought that people outside Google might find protocol buffers useful. -Getting protocol buffers into a form we were happy to release was a fun side -project. - -## Why Is the First Release Version 2? What Happened to Version 1? {#version-1} - -The initial version of protocol buffers ("Proto1") was developed starting in -early 2001 and evolved over the course of many years, sprouting new features -whenever someone needed them and was willing to do the work to create them. Like -anything created in such a way, it was a bit of a mess. We came to the -conclusion that it would not be feasible to release the code as it was. - -Version 2 ("Proto2") was a complete rewrite, though it kept most of the design -and used many of the implementation ideas from Proto1. Some features were added, -some removed. Most importantly, though, the code was cleaned up and did not have -any dependencies on Google libraries that were not yet open-sourced. - -## Why the Name "Protocol Buffers"? {#name} - -The name originates from the early days of the format, before we had the -protocol buffer compiler to generate classes for us. At the time, there was a -class called `ProtocolBuffer` that actually acted as a buffer for an individual -method. Users would add tag/value pairs to this buffer individually by calling -methods like `AddValue(tag, value)`. The raw bytes were stored in a buffer that -could then be written out once the message had been constructed. - -Since that time, the "buffers" part of the name has lost its meaning, but it is -still the name we use. Today, people usually use the term "protocol message" to -refer to a message in an abstract sense, "protocol buffer" to refer to a -serialized copy of a message, and "protocol message object" to refer to an -in-memory object representing the parsed message. - -## Does Google Have Any Patents on Protocol Buffers? {#patents} - -Google currently has no issued patents on protocol buffers, and we are happy to -address any concerns around protocol buffers and patents that people may have. - -## How Do Protocol Buffers Differ from ASN.1, COM, CORBA, and Thrift? {#differ} - -We think all of these systems have strengths and weaknesses. Google relies on -protocol buffers internally and they are a vital component of our success, but -that doesn't mean they are the ideal solution for every problem. You should -evaluate each alternative in the context of your own project. - -It is worth noting, though, that several of these technologies define both an -interchange format and an RPC (remote procedure call) protocol. Protocol buffers -are just an interchange format. They could easily be used for RPC—and, -indeed, they do have limited support for defining RPC services—but they -are not tied to any one RPC implementation or protocol. diff --git a/content/installation.md b/content/installation.md deleted file mode 100644 index 4e1ddc909..000000000 --- a/content/installation.md +++ /dev/null @@ -1,84 +0,0 @@ -+++ -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/v30.2/protoc-30.2-linux-x86_64.zip - - ``` - -2. Unzip the file under `$HOME/.local` or a directory of your choice. For - example: - - ```sh - unzip protoc-30.2-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/navbar.md b/content/navbar.md deleted file mode 100644 index 165d8ce6b..000000000 --- a/content/navbar.md +++ /dev/null @@ -1,4 +0,0 @@ -* [Home](/) -* [Programming Guides](/programming-guides) -* [Codelab](/codelab) -* [Reference](/reference/) diff --git a/content/news/2022-05-06.md b/content/news/2022-05-06.md deleted file mode 100644 index fbf00530b..000000000 --- a/content/news/2022-05-06.md +++ /dev/null @@ -1,61 +0,0 @@ -+++ -title = "Changes announced May 6, 2022" -linkTitle = "May 6, 2022" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on May 6, 2022." -type = "docs" -+++ - -## Versioning {#versioning} - -We changed our versioning scheme to enable more-nimble updates to -language-specific parts of Protocol Buffers. In the new scheme, each language -has its own major version that can be incremented independently of other -languages, as covered later in this topic with the Python release. The minor and -patch versions, however, will remain coupled. This allows us to introduce -breaking changes into some languages without requiring a bump of the major -version in languages that do not experience a breaking change. - -The first instance of this new versioning scheme is the new version of the -Python API, 4.21.0, which follows the preceding version, 3.20.1. Other language -APIs will be released as 3.21.0. - -## Python Updates {#python-updates} - -We made some changes in Python language support in Protocol Buffers. Version -4.21.0 is a new major version, following 3.20.1. The new version is based on the -[upb library](https://github.com/protocolbuffers/upb), and offers -significantly better parsing performance than previous releases, especially for -large payloads. It also includes prebuilt binary modules for Apple silicon for -increased performance without a manual build. - -The new release does contain some breaking changes. Specifically: - -* The - [`UnknownFields()`](https://googleapis.dev/python/protobuf/3.17.0/google/protobuf/message.html#google.protobuf.message.Message.UnknownFields) - method, which relied on an implicitly created class, is replaced with the - explicitly-created `UnknownFieldSet` class. -* Some non-core characteristics may have changed, such as the specific format - of certain strings or error messages. These are not considered breaking - changes, but may still impact your existing code base. -* Applications that rely on sharing messages between Python and C++ break in - the new version. Most developers won't be affected by this, but users of - [Nucleus](https://github.com/google/nucleus) and possibly other - libraries may be. As a workaround, you can - [set an environment variable](/reference/python/python-generated#sharing-messages) - that forces the library to preserve compatibility. -* Python upb requires generated code that has been generated from protoc - 3.19.0 or newer. - -## JavaScript Support {#javascript} - -We moved some things around for Protocol Buffer support of JavaScript to allow -JavaScript to evolve and release independently of the main repo. Specifically, -we decoupled the language support from the -[main project](https://github.com/protocolbuffers/protobuf) and moved -it into its -[own repository](https://github.com/protocolbuffers/protobuf-javascript). - -If you have created any pull requests related to JavaScript support in Protocol -Buffers that you'd still like to merge, feel free to replicate those against the -JavaScript repository. We will transfer GitHub issues automatically. diff --git a/content/news/2022-07-06.md b/content/news/2022-07-06.md deleted file mode 100644 index 870dab7f9..000000000 --- a/content/news/2022-07-06.md +++ /dev/null @@ -1,14 +0,0 @@ -+++ -title = "Changes announced July 6, 2022" -linkTitle = "July 6, 2022" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on July 6, 2022." -type = "docs" -+++ - -## Library Breaking Change Policy - -Google released its -[OSS Library Breaking Change Policy](https://opensource.google/documentation/policies/library-breaking-change), -which some Google-sponsored open source projects have opted into. Protocol -buffers has adopted this policy. diff --git a/content/news/2022-08-03.md b/content/news/2022-08-03.md deleted file mode 100644 index eb1817540..000000000 --- a/content/news/2022-08-03.md +++ /dev/null @@ -1,87 +0,0 @@ -+++ -title = "Changes announced August 3, 2022" -linkTitle = "August 3, 2022" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on August 3, 2022." -type = "docs" -+++ - -This topic covers two areas: general platform support changes, and C++-specific -changes that are being considered for the 22.x release line. - -## Platform Support Changes {#platform-changes} - -We've added guidance about the platforms that we support in -[this section](/programming-guides/proto2#platforms) of -the documentation. The section currently covers C++ and PHP, but may be expanded -with information about other platforms in the future. - -## Official C++ Support Matrix {#cpp-support-matrix} - -With the policy, mentioned earlier in this announcement, of using Google's -official -[foundational C++ support policy](/programming-guides/proto2#platforms), -our -[C++ compiler and toolchain support matrix will change](https://github.com/google/oss-policies-info/blob/8067c719150dfec6a836dd82230c5eb0ba11acd7/foundational-cxx-support-matrix.md). - -## C++ Changes {#cpp-changes} - -Following the announcement of our -[new major version and breaking changes policy](/news/2022-07-06), -we are planning a major version bump for C++. We plan to make some changes to -the assets that we release starting with our 22.x release line. - -The following sections outline the set of breaking changes that we plan to -include in the 22.0 release of protocol buffers. Note that plans can and do -change. These are potential breaking changes to be aware of, but they may not -happen in this particular release, or they may not happen at all. - -### Adding C++20 Support {#c20-support} - -Because of the addition of new keywords to the C++ language, adding support for -C++20 is a breaking change for users even if they do not currently use C++20. - -Mitigations for this to conditionally change names only in certain compiler -modes would break projects that support multiple language standards. - -### Dropping C++11 Support {#c11-support} - -Per our -[C++ support policy](https://opensource.google/documentation/policies/cplusplus-support#4_c_language_standard), -we plan to drop C++11 support. This is a breaking change. - -### Dropping Autotools Support {#autotools} - -Per our -[build systems support policy](https://opensource.google/documentation/policies/cplusplus-support#3_build_systems), -we plan to drop autotools support. This is a breaking change. After autotools -support is dropped, protobuf will support only CMake and Bazel. - -### Dropping Support for PHP <7.4 {#php-74} - -Per our -[PHP support policy](https://cloud.google.com/php/getting-started/supported-php-versions), -we plan to drop support for EOL versions of PHP. This is not considered a -breaking change since these versions are already EOL in the broader ecosystem. - -### Adding an Abseil Dependency {#abseil-dep} - -In order to reduce the Google vs. OSS differences between protobuf and to -simplify our own project, we plan to take a formal dependency on Abseil. In -time, we plan to start using Abseil types in our public APIs, but simply adding -the dependency is a breaking change. - -### Dropping Language-Specific Source Distributions {#lang-specific-distros} - -To reduce dependence on autotools and minimize the number of artifacts we -release, we plan to stop publishing language-specific source distributions on -our -[GitHub release page](https://github.com/protocolbuffers/protobuf/releases). -Instead, we advise users to download the -[source code distribution](https://github.com/protocolbuffers/protobuf/releases) -automatically generated by GitHub on the release page. - -### Changing Maven Release Candidate Artifact Names to Be More Idiomatic {#idiomatic} - -In 22.0 we plan to rename Maven artifacts to use “RC” instead of “rc-” as the -release candidate prefix. diff --git a/content/news/2023-04-11.md b/content/news/2023-04-11.md deleted file mode 100644 index e8d04f25c..000000000 --- a/content/news/2023-04-11.md +++ /dev/null @@ -1,69 +0,0 @@ -+++ -title = "Changes announced April 11, 2023" -linkTitle = "April 11, 2023" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on April 11, 2023." -type = "docs" -+++ - -## Syntax Reflection Deprecation {#deprecation} - -v23 will deprecate the ability to check syntax version using reflection. The -deprecation will be included as warnings at build time. The capability will be -removed in a future release. - -## Adding support for ctype=CORD in C++ {#cord} - -v23 will add `ctype=CORD` support for singular `bytes` -fields, including `oneof` fields, to specify that data should be stored using -[`absl::cord`](https://github.com/abseil/abseil-cpp/blob/master/absl/strings/cord.h) -instead of `string`. Support may be added in future releases for singular -`string` field types and for `repeated` `string` and `byte` fields if there is -enough interest from the open source community. - -`ctype=CORD` will have no effect on extensions. - -You will be able to add the support using field options: - -```proto -optional bytes foo = 25 [ctype=CORD]; -``` - -## Option Retention {#retention} - -Options now have a notion of *retention*, which controls whether an option is -retained in the generated code. Options have always had *runtime retention* by -default, meaning that they are retained in the generated code and are thus -visible at runtime in the generated descriptor pool. However, you can now set -`retention = RETENTION_SOURCE` to specify that an option (or field within an -option) must not be retained at runtime. This is called *source retention*. - -Setting retention looks like this: - -```proto -extend google.protobuf.FileOptions { - optional int32 source_retention_option = 1234 - [retention = RETENTION_SOURCE]; -} -``` - -It can also be set on a plain field, in which case it takes effect only when -that field appears inside an option: - -```proto -message OptionsMessage { - optional int32 source_retention_field = 1 [retention = RETENTION_SOURCE]; -} -``` - -For more information, see -[Option Retention](/programming-guides/proto3#option-retention). - -## Dropping Support for Bazel <5.3 {#bazel} - -v23 will drop support for Bazel 4. Protobuf will continue to support the Bazel 5 -LTS with Bazel 5.3 as the minimum required version. This is per the build -support policy described in -[Foundational C++ Support Policy](https://opensource.google/documentation/policies/cplusplus-support#build_systems) -and as reflected in the versions in -[Foundational C++ Support](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md). diff --git a/content/news/2023-04-20.md b/content/news/2023-04-20.md deleted file mode 100644 index e36edee46..000000000 --- a/content/news/2023-04-20.md +++ /dev/null @@ -1,162 +0,0 @@ -+++ -title = "Changes announced April 20, 2023" -linkTitle = "April 20, 2023" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on April 20, 2023." -type = "docs" -+++ - -## Changes to Ruby Generator {#ruby} - -[This GitHub PR](https://github.com/protocolbuffers/protobuf/pull/12319), which -will appear in the 23.x release, changes the Ruby code generator to emit a -serialized proto instead of the DSL. - -It removes the DSL from the code generator in anticipation of splitting the DSL -out into a separate package. - -Given a .proto file like: - -```proto -syntax = "proto3"; - -package pkg; - -message TestMessage { - optional int32 i32 = 1; - optional TestMessage msg = 2; -} -``` - -Generated code before: - -```ruby -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: protoc_explorer/main.proto - -require 'google/protobuf' - -Google::Protobuf::DescriptorPool.generated_pool.build do - add_file("test.proto", :syntax => :proto3) do - add_message "pkg.TestMessage" do - proto3_optional :i32, :int32, 1 - proto3_optional :msg, :message, 2, "pkg.TestMessage" - end - end -end - -module Pkg - TestMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("pkg.TestMessage").msgclass -end -``` - -Generated code after: - -```ruby -# frozen_string_literal: true -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: test.proto - -require 'google/protobuf' - -descriptor_data = "\n\ntest.proto\x12\x03pkg\"S\n\x0bTestMessage\x12\x10\n\x03i32\x18\x01 \x01(\x05H\x00\x88\x01\x01\x12\"\n\x03msg\x18\x02 \x01(\x0b\x32\x10.pkg.TestMessageH\x01\x88\x01\x01\x42\x06\n\x04_i32B\x06\n\x04_msgb\x06proto3" -begin - Google::Protobuf::DescriptorPool.generated_pool.add_serialized_file(descriptor_data) -rescue TypeError => e - # -end - -module Pkg - TestMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("pkg.TestMessage").msgclass -end -``` - -This change fixes nearly all remaining conformance problems that existed -previously. This is a side effect of moving from the DSL (which is lossy) to a -serialized descriptor (which preserves all information). - -### Backward Compatibility {#backward} - -This change should be 100% compatible with Ruby Protobuf >= 3.18.0, released in -Sept 2021. Additionally, it should be compatible with all existing users and -deployments. - -There **is** some special compatibility code inserted to achieve this level of -backward compatibility that you should be aware of. Without the compatibility -code, there is an edge case that could break backward compatibility. The -previous code is lax in a way that the new code will be more strict. - -When using a full serialized descriptor, it contains a list of all `.proto` -files imported by this file (whereas the DSL never added dependencies properly). -See the code in -[`descriptor.proto`](https://github.com/protocolbuffers/protobuf/blob/dfb71558a2226718dc3bcf5df27cbc11c1f72382/src/google/protobuf/descriptor.proto#L65-L66). - -`add_serialized_file` verifies that all dependencies listed in the descriptor -were previously added with `add_serialized_file`. Generally that should be fine, -because the generated code will contain Ruby `require` statements for all -dependencies, and the descriptor will fail to load anyway if the types depended -on were not previously defined in the `DescriptorPool`. - -But there is a potential for problems if there are ambiguities around file -paths. For example, consider the following scenario: - -```proto -// foo/bar.proto - -syntax = "proto2"; - -message Bar {} -``` - -```proto -// foo/baz.proto - -syntax = "proto2"; - -import "bar.proto"; - -message Baz { - optional Bar bar = 1; -} -``` - -If you invoke `protoc` like so, it will work correctly: - -``` -$ protoc --ruby_out=. -Ifoo foo/bar.proto foo/baz.proto -$ RUBYLIB=. ruby baz_pb.rb -``` - -However if you invoke `protoc` like so, and didn't have any compatibility code, -it would fail to load: - -``` -$ protoc --ruby_out=. -I. -Ifoo foo/baz.proto -$ protoc --ruby_out=. -I. -Ifoo foo/bar.proto -$ RUBYLIB=foo ruby foo/baz_pb.rb -foo/baz_pb.rb:10:in `add_serialized_file': Unable to build file to DescriptorPool: Depends on file 'bar.proto', but it has not been loaded (Google::Protobuf::TypeError) - from foo/baz_pb.rb:10:in `
' -``` - -The problem is that `bar.proto` is being referred to by two different canonical -names: `bar.proto` and `foo/bar.proto`. This is a user error: each import should -always be referred to by a consistent full path. Hopefully user errors of this -sort will be rare, but it is hard to know without trying. - -The code in this change prints a warning using `warn` if we detect that this -edge case has occurred: - -``` -$ RUBYLIB=foo ruby foo/baz_pb.rb -Warning: Protobuf detected an import path issue while loading generated file foo/baz_pb.rb -- foo/baz.proto imports bar.proto, but that import was loaded as foo/bar.proto -Each proto file must use a consistent fully-qualified name. -This will become an error in the next major version. -``` - -There are two possible fixes in this case. One is to consistently use the name -`bar.proto` for the import (removing `-I.`). The other is to consistently use -the name `foo/bar.proto` for the import (changing the import line to `import -"foo/bar.proto"` and removing `-Ifoo`). - -We plan to remove this compatibility code in the next major version. diff --git a/content/news/2023-04-28.md b/content/news/2023-04-28.md deleted file mode 100644 index ef77548cb..000000000 --- a/content/news/2023-04-28.md +++ /dev/null @@ -1,21 +0,0 @@ -+++ -title = "Changes announced April 28, 2023" -linkTitle = "April 28, 2023" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on April 28, 2023." -type = "docs" -+++ - -## Stricter validation for `json_name` {#json-name} - -v24 will forbid zero unicode code points (`\u0000`) in the -[`json_name` field option](/programming-guides/proto3/#json). -Going forward, any valid Unicode characters will be accepted in `json_name`, -**except** `\u0000`. `\0` characters will still be allowed to be used as values. - -Previously, the proto compiler allowed `\0` characters in the `json_name` field -option, but support for this was inconsistent across languages and -implementations. To help prevent interoperability problems relating to -mishandling of keys containing a `\0` character, we are clarifying the spec to -say that `\0` is not allowed in `json_name`, and will be rejected by the -compiler. diff --git a/content/news/2023-06-29.md b/content/news/2023-06-29.md deleted file mode 100644 index 2cfc5b326..000000000 --- a/content/news/2023-06-29.md +++ /dev/null @@ -1,161 +0,0 @@ -+++ -title = "Changes Announced on June 29, 2023" -linkTitle = "June 29, 2023" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on June 29, 2023." -type = "docs" -+++ - -**TL;DR:** We are planning to release Protobuf Editions to the open source project in the second half of 2023. While there is no requirement to move from proto2/proto3 syntax to Editions syntax at initial release, we encourage you to plan a move in your software project's future timeline. - -## Protobuf Editions {#editions} - -Protobuf Editions replace the proto2 and proto3 designations that we have used -for Protocol Buffers. Instead of adding `syntax = "proto2"` or `syntax = -"proto3"` at the top of proto definition files, you use an edition number, such -as `edition = "2024"`, to specify the default behaviors your file will have. -Editions enable the language to evolve incrementally over time. - -Instead of the hardcoded behaviors in older versions, editions will represent a -collection of “features” with a default value (behavior) per feature, which you -can override. Features are options on a file, message, field, enum, and so on -that specify the behavior of protoc, the code generators, and protobuf runtimes. -You can explicitly override the desired behavior at those different levels -(file, message, field, ...) when your needs don't match the default behavior for -the edition you've selected. - -Editions won't break existing binaries, and the first edition will be minimally -disruptive; it will establish the baseline and will combine proto2 and proto3 -definitions into a new single definition format. It won't require any changes to -your code. We will be providing a tool, called Prototiller, to migrate .proto -files. The following examples show a proto2 definition file and a proto3 file, -and what each might look like after using Prototiller to convert them to -Protobuf Editions format: - -
- -#### Proto2 syntax {.new-tab} - -```proto -// proto2 file -syntax = "proto2"; - -message Player { - // in proto2, optional fields have explicit presence - optional string name = 1; - // proto2 still supports the problematic "required" field rule - required int32 id = 2; - // in proto2 this is not packed by default - repeated int32 scores = 3; - - enum Handed { - HANDED_UNSPECIFIED = 0, - HANDED_LEFT = 1, - HANDED_RIGHT = 2, - HANDED_AMBIDEXTROUS = 3, - } - - // in proto2 enums are closed - optional Handed handed = 4; -} -``` - -#### Editions syntax {.new-tab} - -```proto -// Editions version of proto2 file -edition = "2023"; - -message Player { - string name = 1; - int32 id = 2 [features.field_presence = LEGACY_REQUIRED]; - repeated int32 scores = 3 [features.repeated_field_encoding = EXPANDED]; - - enum Handed { - // this overrides the default Edition 2023 behavior, which is OPEN - option features.enum = CLOSED; - HANDED_UNSPECIFIED = 0, - HANDED_LEFT = 1, - HANDED_RIGHT = 2, - HANDED_AMBIDEXTROUS = 3, - } - - Handed handed = 4; -} -``` - -
- -And this is what a similar proto3 definition file might look like: - -
- -#### Proto3 syntax {.new-tab} - -```proto -// proto3 file -syntax = "proto3"; - -message Player { - // in proto3, optional fields have explicit presence - optional string name = 1; - // in proto3 no specified field rule defaults to implicit presence - int32 id = 2; - // in proto3 this is packed by default - repeated int32 scores = 3; - - enum Handed { - HANDED_UNSPECIFIED = 0, - HANDED_LEFT = 1, - HANDED_RIGHT = 2, - HANDED_AMBIDEXTROUS = 3, - } - - // in proto3 enums are open - optional Handed handed = 4; -} -``` - -#### Editions syntax {.new-tab} - -```proto -// Editions version of proto3 file -edition = "2023"; - -message Player { - string name = 1; - int32 id = 2 [features.field_presence = IMPLICIT]; - repeated int32 scores = 3; - - enum Handed { - HANDED_UNSPECIFIED = 0, - HANDED_LEFT = 1, - HANDED_RIGHT = 2, - HANDED_AMBIDEXTROUS = 3, - } - - Handed handed = 4; -} -``` - -
- -While the examples provided in this topic show a direct translation of proto2 -and proto3 to the equivalent representation using Protobuf Editions, you will be -able to mix and match the settings to your project's needs. - -Features have a lifecycle that is governed by the releases of editions. For -example, `features.awesome_new_feature` might be added in Edition 2031, with the -new behavior applying to all definitions that don't explicitly override the new -behavior. In Edition 2033, the new feature is deprecated. Overrides still work, -but developers are alerted to the fact that they need to adapt to the new -behavior soon. In Edition 2036, the feature is removed and the new behavior -applies to all protos; there is no way to override the new behavior at this -point. - -![Editions lifecycle](/images/protobuf-editions-lifecycle-short.png "Editions lifecycle") -\ -**Figure 1: Editions lifecycle flowchart** - -Editions are planned to be released roughly once a year. For more information on -Protobuf Editions, see the overview at https://protobuf.dev/editions/overview. diff --git a/content/news/2023-07-06.md b/content/news/2023-07-06.md deleted file mode 100644 index 08a8698ce..000000000 --- a/content/news/2023-07-06.md +++ /dev/null @@ -1,31 +0,0 @@ -+++ -title = "Changes Announced on July 6, 2023" -linkTitle = "July 6, 2023" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on July 6, 2023." -type = "docs" -+++ - -## Dropping PHP 7.x Support - -As per our official -[PHP support policy](https://cloud.google.com/php/getting-started/supported-php-versions), -we will be dropping support for PHP 7.4 and lower. This means the minimum -supported PHP version is 8.0. - -If you are running an older version of PHP, you can install a previous release -of the protobuf PHP extension by running `pecl install protobuf-3.23.3`. - -## Dropping Ruby 2.6 Support - -As per our official -[Ruby support policy](https://cloud.google.com/ruby/getting-started/supported-ruby-versions), -we will be dropping support for Ruby 2.6 and lower. This means the minimum -supported Ruby version is 2.7. - -## Dropping Python 3.7 Support - -As per our official -[Python support policy](https://cloud.google.com/python/docs/supported-python-versions), -we will be dropping support for Python 3.7 and lower. This means the minimum -supported Python version is 3.8. diff --git a/content/news/2023-07-17.md b/content/news/2023-07-17.md deleted file mode 100644 index 98a66acba..000000000 --- a/content/news/2023-07-17.md +++ /dev/null @@ -1,14 +0,0 @@ -+++ -title = "Changes Announced on July 17, 2023" -linkTitle = "July 17, 2023" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on July 17, 2023." -type = "docs" -+++ - -## Dropping Bazel 5.x Support - -As per our official -[support policy](https://opensource.google/documentation/policies/cplusplus-support), -we will be dropping support for Bazel 5.x and lower. This means the minimum -supported Bazel version is 6.2.x. diff --git a/content/news/2023-08-09.md b/content/news/2023-08-09.md deleted file mode 100644 index 667a87ffc..000000000 --- a/content/news/2023-08-09.md +++ /dev/null @@ -1,37 +0,0 @@ -+++ -title = "Changes Announced on August 9, 2023" -linkTitle = "August 9, 2023" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on August 9, 2023." -type = "docs" -+++ - -## .NET support policy - -The Protobuf team supports .NET in two ways: - -- Generation of C# code by protoc -- The [Google.Protobuf NuGet package](https://www.nuget.org/packages/Google.Protobuf), - which provides runtime support for the generated code, as well as reflection - and other facilities - -The support policy for these has previously been unclear, particularly in terms -of which .NET runtimes are supported. From August 2023 onwards, support will be -provided in accordance with the [Google Open Source support policy for -.NET](https://opensource.google/documentation/policies/dotnet-support). We -expect this to mean that some old versions of .NET will be dropped from the -`Google.Protobuf` package without taking a new major version. - -Protobuf is relatively unusual within Google projects supporting .NET in two -respects: Firstly, as we support generating C# which we expect customers to -compile, we need to consider language versions as well as runtime versions. The -current policy does not cover this aspect of support, so we will publish a -separate policy for this. Secondly, while Unity is not a first-class -supported platform, we understand that Protobuf is commonly used on Unity, and -we will intend to avoid breaking that usage as far as is reasonably possible. - -More details will be published when a new set of target platforms has been -decided for `Google.Protobuf`. This will be at least one month ahead of the -release in which it will take effect, in order to provide time for community -feedback. For now, we recommend that users review the -[support policy](https://opensource.google/documentation/policies/dotnet-support). diff --git a/content/news/2023-08-15.md b/content/news/2023-08-15.md deleted file mode 100644 index 4bd7bae87..000000000 --- a/content/news/2023-08-15.md +++ /dev/null @@ -1,18 +0,0 @@ - - -+++ -title = "Changes Announced on August 15, 2023" -linkTitle = "August 15, 2023" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on August 15, 2023." -type = "docs" -+++ - -## Python Breaking Change - -In v25 -[`message.UnknownFields()`](https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message.UnknownFields) -will be deprecated in pure Python and C++ extensions. It will be removed in v26. -Use the new -[`UnknownFieldSet(message)`](https://googleapis.dev/python/protobuf/latest/google/protobuf/unknown_fields.html) -support in `unknown_fields.py` as a replacement. diff --git a/content/news/2023-09-15.md b/content/news/2023-09-15.md deleted file mode 100644 index 1a1de6f57..000000000 --- a/content/news/2023-09-15.md +++ /dev/null @@ -1,35 +0,0 @@ -+++ -title = "Changes announced on September 15, 2023" -linkTitle = "September 15, 2023" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on September 15, 2023." -type = "docs" -+++ - -## μpb Moving to the Protobuf Git Repository - -Starting with the v25 release, μpb now lives in the -[protobuf repo](https://github.com/protocolbuffers/protobuf) instead -of in its [former location](https://github.com/protocolbuffers/upb) -in a separate repo. All μpb development going forward will take place only in -the new location. - -The merger of the two repos will simplify and speed up our development process -by removing the need to update pinned version dependencies between protobuf and -μpb. Changes to μpb now take effect immediately in protobuf code and vice versa, -without the need for a manual upgrade step. - -We expect that most users will not need to take much, if any, action to -accommodate the change. μpb is the engine behind our Ruby, PHP, and Python -implementations, but you will most likely not notice the change unless you have -code that refers to μpb directly. - -If you refer to μpb from a Bazel project, you will need to update μpb references -to point to protobuf instead (for example, replace `@upb` with -`@com_google_protobuf`). We are keeping μpb file paths and Bazel targets the -same to minimize the need for additional changes, but there are two exceptions: - -- The `upbc` directory has been renamed `upb_generator`. -- The top-level `BUILD` file for μpb has moved into the `upb` directory. So, - for example, references to `@upb//:reflection` should now be written - `@com_google_protobuf//upb:reflection`. diff --git a/content/news/2023-10-10.md b/content/news/2023-10-10.md deleted file mode 100644 index 950fb649d..000000000 --- a/content/news/2023-10-10.md +++ /dev/null @@ -1,13 +0,0 @@ -+++ -title = "Changes announced on October 10, 2023" -linkTitle = "October 10, 2023" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on October 10, 2023." -type = "docs" -+++ - -## Protobuf Editions Features - -Documentation that introduces -[Protobuf Editions features](/editions/features) is now -available. diff --git a/content/news/2023-12-05.md b/content/news/2023-12-05.md deleted file mode 100644 index d8d044d90..000000000 --- a/content/news/2023-12-05.md +++ /dev/null @@ -1,67 +0,0 @@ -+++ -title = "Changes announced on December 5, 2023" -linkTitle = "December 5, 2023" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on December 5, 2023." -type = "docs" -+++ - -## Java Breaking Changes - -In v26, we are planning a major version bump for Java per our -[breaking changes policy](/news/2022-07-06) and -[version support policy](/support/version-support#java). - -The following sections outline the set of breaking changes that we plan to -include in the 26.0 release of protocol buffers. Note that plans can and do -change. These are potential breaking changes to be aware of, but they may not -happen in this particular release, or they may not happen at all. - -### Poison Pilling Gencode / Runtime Mismatches - -Per our -[Cross-Version Runtime Guarantees](/support/cross-version-runtime-guarantee), -Protobuf does not support mixing generated code and runtimes across major -version boundaries, or mixing generated code from a newer version of protoc with -older runtimes within a single major runtime version. We plan to introduce -“poison pills” to detect and enforce these disallowed mismatches. - -This is not considered a breaking change since this simply adds enforcement of -existing policies, but may require users to update their generated code. - -### Breaking Compatibility with Old Generated Code - -v26.x will break compatibility with generated code from older major versions. -Users should regenerate old generated code to be from the same version. - -For example, `GeneratedMessageV3`, which was originally introduced for backwards -compatibility with generated code from v2.x.x against v3.x.x runtime, will be -renamed to `GeneratedMessage`. Runtimes will be updated to support -[Editions](/editions/overview/), which will not be -compatible with old generated code. - -This is in accordance with our existing -[Cross-Version Runtime Guarantees](/support/cross-version-runtime-guarantee) -and is a breaking change. - -### Removing Deprecated Methods/Variables - -v26.x will remove access to deprecated methods and variables. These will -generally have already been marked `@Deprecated` in a previous release. - -This will remove access to the following non-exhaustive list: - -* Descriptor syntax APIs, which should be replaced with corresponding feature - accessors (such as `FieldDescriptor.hasPresence()`, - `EnumDescriptor.isClosed()`) - -* TextFormat print methods, which should be replaced by corresponding - `TextFormat.printer()` methods. - -* PARSER variable, which should be replaced by the `parser()` method. - -* Runtime methods for old v2.x.x gencode compatibility. This is no longer - supported, as per our - [Cross Version Runtime Guarantees](/support/cross-version-runtime-guarantee). - -More details will be available in the corresponding release notes. diff --git a/content/news/2023-12-13.md b/content/news/2023-12-13.md deleted file mode 100644 index 0d4912111..000000000 --- a/content/news/2023-12-13.md +++ /dev/null @@ -1,81 +0,0 @@ -+++ -title = "Changes announced on December 13, 2023" -linkTitle = "December 13, 2023" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on December 13, 2023." -type = "docs" -+++ - -## C++ Breaking Changes - -In v26, we are planning a major version bump for C++ as per our -[breaking changes policy](/news/2022-07-06) and -[version support policy](/support/version-support#cpp-tooling). - -The following sections outline the set of breaking changes that we plan to -include in the 26.0 release of protocol buffers. Note that plans can and do -change. These are potential breaking changes to be aware of, but they may not -happen in this particular release, or they may not happen at all. - -### Remove deprecated clear APIs on repeated fields - -The following deprecated methods are removed: - -* `RepeatedPtrField::ReleaseCleared()` -* `RepeatedPtrField::ClearedCount()` -* `RepeatedPtrField::AddCleared()` - -### Remove C++ legacy syntax descriptor APIs - -With the release of [editions](/editions), syntax is no -longer supported for business logic. Instead, use the various feature helpers -defined in -[`descriptor.h`](/reference/cpp/api-docs/google.protobuf.descriptor) -to query more targeted behaviors, such as -[`has_presence`](/reference/cpp/api-docs/google.protobuf.descriptor#FieldDescriptor.has_presence.details), -to query features in C++. - -### Remove deprecated syntax accessor - -We plan to remove the deprecated syntax accessor, `FileDescriptor::Syntax`, in -v26. We recommend using the getters from `FileDescriptor::edition` instead. - -### Remove deprecated SupportsUnknownEnumValues method - -The `SupportsUnknownEnumValues` method was -[deprecated in March, 2023](https://github.com/protocolbuffers/protobuf/pull/12129). -We plan to remove it in v26. - -### Remove std::string error collector overrides - -We are planning to remove the deprecated `std::string` methods in error -collectors. - -## Python Breaking Changes - -In v26, we are planning a major version bump for Python as per our -[breaking changes policy](/news/2022-07-06) and -[version support policy](/support/version-support#python-support). - -### Timestamps are checked for validity - -In v26, the system will check if `Timestamp` values are valid. Seconds must be -in the range [-62135596800, 253402300799] and nanos must be in range [0, -999999999]. Values outside those ranges will raise an exception. - -### Remove deprecated syntax accessor - -We plan to remove the deprecated syntax accessor, `FileDescriptor.syntax`, in -v26. We plan to add `FileDescriptor.edition` in its place. - -### UnknownFields support removal - -In v25 -[`message.UnknownFields()`](https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message.UnknownFields) -was deprecated in pure Python and C++ extensions. We plan to remove it v26. Use -the new -[`UnknownFieldSet(message)`](https://googleapis.dev/python/protobuf/latest/google/protobuf/unknown_fields.html) -support in `unknown_fields.py` as a replacement. - -More details about all of these changes will be available in the corresponding -release notes. diff --git a/content/news/2023-12-27.md b/content/news/2023-12-27.md deleted file mode 100644 index 46a9c12ef..000000000 --- a/content/news/2023-12-27.md +++ /dev/null @@ -1,54 +0,0 @@ -+++ -title = "Changes announced on December 27, 2023" -linkTitle = "December 27, 2023" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on December 27, 2023." -type = "docs" -+++ - -## Ruby Breaking Changes - -The following changes are planned for the 26.x line: - -* Fix `RepeatedField#each_index` to have the correct semantics. - ([#11767](https://github.com/protocolbuffers/protobuf/pull/11767)) -* Remove Ruby DSL and associated compatibility code, which will complete the - [migration announced in April](/news/2023-04-20). -* `Message#to_h` fixes: - * Remove unset oneof fields. - ([#6167](https://github.com/protocolbuffers/protobuf/issues/6167)) - * Remove unset sub-message fields -* Use message's pool for - [`encode_json`](https://github.com/protocolbuffers/protobuf/blob/2fb0b93d9de226ea96f2dc2b4779eb4712d01d5c/ruby/ext/google/protobuf_c/message.c#L1118)/[`decode_json`](https://github.com/protocolbuffers/protobuf/blob/2fb0b93d9de226ea96f2dc2b4779eb4712d01d5c/ruby/ext/google/protobuf_c/message.c#L1004). -* Remove the deprecated syntax accessor, `FileDescriptor.syntax` and add - semantic checks in its place: - * `FieldDescriptor.has_presence` to test if a field has presence. - * `FieldDescriptor.is_packed` to test if a repeated field is packed. - * `FieldDescriptor.requires_utf8_validation` to test if a string field - requires UTF-8 validation. - * `EnumDescriptor.is_closed` to test if an enum is closed. - -## PHP Breaking Changes - -The following changes are planned for the 26.x line: - -* Validate UTF-8 for string fields in setters. -* Remove generic services. - ([commit 40ad3fa](https://github.com/protocolbuffers/protobuf/commit/40ad3fac603ba3c96e52a1266cd785a7adb8e3e4)) - -## Python Breaking Changes - -The following changes are planned for the 26.x line: - -* Make `str(msg)` escape any invalid UTF-8 in string fields. -* Make `text_format.MessageToString()` default to outputting raw UTF-8, while - escaping any invalid UTF-8 sequences. -* Fix timestamp bounds ([commit 1250d5f](https://github.com/protocolbuffers/protobuf/commit/1250d5f6cccb0a45f959c7219980a0aad5060ee5)) - -## upb Breaking Changes - -The following changes are planned for the 26.x line: - -* Fix - [nonconformance in JSON parsing](https://github.com/protocolbuffers/protobuf/blob/2f7b2832b6a62fec88efacbb97bf0a91b6a3670e/upb/conformance/conformance_upb_failures.txt) - when `IgnoreUnknownEnumString` is enabled. diff --git a/content/news/2024-01-05.md b/content/news/2024-01-05.md deleted file mode 100644 index dfe63c207..000000000 --- a/content/news/2024-01-05.md +++ /dev/null @@ -1,44 +0,0 @@ -+++ -title = "Changes announced January 5, 2024" -linkTitle = "January 5, 2024" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on January 5, 2024." -type = "docs" -+++ - -This topic covers breaking changes in Ruby and Python in the 26.x line. - -## Ruby Breaking Changes - -### Freeze Is Now Recursive in Ruby - -Starting in the 26.x line, when freeze is applied it will be applied -recursively, affecting all sub-messages, maps, and repeated fields. - -## Python Breaking Changes - -### Removing Deprecated APIs - -In the 26.x release, the following deprecated APIs will be removed: - -* [`AddFileDescriptor`](https://googleapis.dev/python/protobuf/latest/google/protobuf/descriptor_pool.html#google.protobuf.descriptor_pool.DescriptorPool.AddFileDescriptor) -* [`AddDescriptor`](https://googleapis.dev/python/protobuf/latest/google/protobuf/descriptor_pool.html#google.protobuf.descriptor_pool.DescriptorPool.AddDescriptor) -* [`AddEnumDescriptor`](https://googleapis.dev/python/protobuf/latest/google/protobuf/descriptor_pool.html#google.protobuf.descriptor_pool.DescriptorPool.AddEnumDescriptor) -* [`AddExtensionDescriptor`](https://googleapis.dev/python/protobuf/latest/google/protobuf/descriptor_pool.html#google.protobuf.descriptor_pool.DescriptorPool.AddExtensionDescriptor) -* [`AddServiceDescriptor`](https://googleapis.dev/python/protobuf/latest/google/protobuf/descriptor_pool.html#google.protobuf.descriptor_pool.DescriptorPool.AddServiceDescriptor) - -### Rejecting Extend Repeated Field with None Iterable - -Starting in the 26.x release, extending repeated fields with a `None` iterable -will be rejected (it will raise a `TypeError`). For example, -`m.repeated_int32.extend(None)` will be rejected. - -### Removing RegisterExtension in message class - -Starting in the 26.x release, -[`RegisterExtension`](https://googleapis.dev/python/protobuf/latest/google/protobuf/descriptor_pb2.html#google.protobuf.descriptor_pb2.DescriptorProto.ExtensionRange.RegisterExtension) -will be removed. You can access extensions in Python using the `Extensions` -property on message objects. - -This affects both pure Python and the C++ implementation of Python, but not upb -Python. diff --git a/content/news/2024-01-31.md b/content/news/2024-01-31.md deleted file mode 100644 index ea8bffff2..000000000 --- a/content/news/2024-01-31.md +++ /dev/null @@ -1,30 +0,0 @@ -+++ -title = "Changes announced January 31, 2024" -linkTitle = "January 31, 2024" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on January 31, 2024." -type = "docs" -+++ - -This topic covers breaking changes in Python in the 26.x line. - -## Python Breaking Changes - -### Removing `setup.py` and `setup.cfg` support from GitHub - -In the 26.x release, `setup.py` and `setup.cfg` will no longer be present in the -`python/` directory of -[the GitHub repository](https://github.com/protocolbuffers/protobuf/tree/main/python) -or GitHub -[release tarballs](https://github.com/protocolbuffers/protobuf/releases). This -means it will no longer be possible to build a Python package directly from the -GitHub repo or release tarball. - -The Python source packages published -[on PyPI](https://pypi.org/project/protobuf/#files) *will* continue to have a -`setup.py` in the top-level directory. This is the supported and recommended way -of building Python binary packages, for users who do not want to use the binary -packages that we distribute on PyPI. - -For more information, see -[#15671](https://github.com/protocolbuffers/protobuf/pull/15671). diff --git a/content/news/2024-02-05.md b/content/news/2024-02-05.md deleted file mode 100644 index 0e5316234..000000000 --- a/content/news/2024-02-05.md +++ /dev/null @@ -1,26 +0,0 @@ -+++ -title = "Changes announced February 5, 2024" -linkTitle = "February 5, 2024" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on February 5, 2024." -type = "docs" -+++ - -This topic covers breaking changes in Java, C++, and Python in the 26.x line. - -## JSON Formatter Option Changes {#JSON} - -Starting in the 26.x line, the JSON formatter option to print default-valued -fields is replaced with a fixed way to handle proto2 and proto3 `optional` -fields consistently. - -* Java: `includingDefaultValueFields()` is replaced with - `alwaysPrintFieldsWithNoPresence()`. -* C++: `always_print_default_values` is replaced with - `always_print_fields_with_no_presence=True`. -* Py: `including_default_value_fields=True` is replaced with - `always_print_fields_with_no_presence=True`. - -The new flag behaves identically to the old flag on proto3 messages, but no -longer applies to proto2 `optional` fields. The old flags applied to proto2 -`optional` fields but not proto3 `optional` fields. diff --git a/content/news/2024-02-27.md b/content/news/2024-02-27.md deleted file mode 100644 index b80268a90..000000000 --- a/content/news/2024-02-27.md +++ /dev/null @@ -1,14 +0,0 @@ -+++ -title = "Changes Announced on February 27, 2024" -linkTitle = "February 27, 2024" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on February 27, 2024." -type = "docs" -+++ - -## Dropping Ruby 2.7 Support - -As per our official -[Ruby support policy](https://cloud.google.com/ruby/getting-started/supported-ruby-versions), -we will be dropping support for Ruby 2.7 and lower on March 31, 2024. The -minimum supported Ruby version will be 3.0. diff --git a/content/news/2024-06-26.md b/content/news/2024-06-26.md deleted file mode 100644 index 95a1606d6..000000000 --- a/content/news/2024-06-26.md +++ /dev/null @@ -1,24 +0,0 @@ -+++ -title = "Changes Announced on June 26, 2024" -linkTitle = "June 26, 2024" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on June 26, 2024." -type = "docs" -+++ - -## Dropping Support for Building Protobuf Java from Source with Maven - -We are planning to drop support for building Protobuf Java OSS from source with -the Maven build system in the Protobuf Java 4.28 release. This has been marked -deprecated in the 4.27 release. - -After this point, you can continue to use Bazel, or another build system, to -build Protobuf. You can read more about building from source in -[the Protobuf Java README](https://github.com/protocolbuffers/protobuf/tree/main/java). - -This change may impact Protobuf Java contributors that build protobuf from -source. It does not impact the majority of users that uses the precompiled -protobuf-java or protobuf-javalite artifacts from a repository. Note -specifically that we do not plan to stop supporting the ability to compile -gencode with Maven, and we plan to continue to make prebuilt artifacts available -in the Maven Central repository. diff --git a/content/news/2024-10-01.md b/content/news/2024-10-01.md deleted file mode 100644 index 9a2ad57d9..000000000 --- a/content/news/2024-10-01.md +++ /dev/null @@ -1,49 +0,0 @@ -+++ -title = "Changes Announced on October 1, 2024" -linkTitle = "October 1, 2024" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on October 1, 2024." -type = "docs" -+++ - -## Bazel and Proto Rules - -There are upcoming changes to the way that Bazel will work for protobuf builds. -These changes require awareness in the first stage, and action by project owners -before the second stage. - -### Stage 1 - -With the release of Bazel 8, proto rules (`proto_library`, `cc_proto_library`, -`java_proto_library`, `java_lite_proto_library`, and `py_proto_library`) will be -removed from the Bazel project. The will be added to the Protocol Buffers -project in v29. Bazel will be updated to automatically use the rules from the -protobuf project, so the change is initially a no-op for project owners. - -After the release of Bazel 8 and before the release of Bazel 9, users will need -to explicitly `load` the rules from the Protocol Buffers project repository. The -automatic use of the rules is only temporary to support the migration. - -Users should add the following `load()` statements to any `BUILD` or `.bzl` -files that use these proto rules. Note that these require Protobuf v29.0 or -higher. - -```bazel -load("@protobuf//bazel:proto_library.bzl", "proto_library") - -load("@protobuf//bazel:cc_proto_library.bzl", "cc_proto_library") -load("@protobuf//bazel:java_proto_library.bzl", "java_proto_library") -load("@protobuf//bazel:java_lite_proto_library.bzl", "java_lite_proto_library") -load("@protobuf//bazel:py_proto_library.bzl", "py_proto_library") -``` - -### Stage 2 - -When Bazel 9 is released, the automatic loading of the protobuf library’s rules -will be removed. At that point, you will need to have `load` statements in your -Bazel build files. - -### End Goal - -Once the rules are in the protobuf repo, we intend to address common user -requests, such as using prebuilts for the proto compiler where possible. diff --git a/content/news/2024-10-02.md b/content/news/2024-10-02.md deleted file mode 100644 index 45ddbe68e..000000000 --- a/content/news/2024-10-02.md +++ /dev/null @@ -1,323 +0,0 @@ -+++ -title = "Changes Announced on October 2, 2024" -linkTitle = "October 2, 2024" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on October 2, 2024." -type = "docs" -+++ - -The following sections cover planned breaking changes in the v30 release, -expected in 2025 Q1. These describe changes as we anticipate them being -implemented, but due to the flexible nature of software some of these changes -may not land or may vary from how they are described in this topic. - -## Changes in C++ {#cpp} - -C++ will bump its major version from 5.29.x to 6.30.x. - -### Descriptor APIs {#descriptor-apis} - -v30 will update return types in descriptor (such as `full_name`) to be -`absl::string_view`. This opens up memory savings in descriptors. - -v28 introduced the `PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE` macro, which you -can use in the meantime to enable the updated return type ahead of the breaking -release. The v30 release will flip the default and remove the macro. - -### ctype Removed from FieldDescriptor Options {#ctype-removed} - -v30 will stop exposing the `ctype` from `FieldDescriptor` options. You can use -the `FieldDescriptor::cpp_string_type()` API, added in the -[v28 release](https://github.com/protocolbuffers/protobuf/releases/tag/v28.0), -in its place. - -### Replace CMake Submodules with Fetched Deps {#replace-cmake-submods} - -v30 will remove submodules and switches to upb's old CMake pattern of fetching -dependencies. - -If you use installed packages, you won't be affected. It could break some CMake -workflows. - -### Remove Deprecated APIs {#remove-deprecated} - -v30 will remove the following public runtime APIs, which have been marked -deprecated (such as `ABSL_DEPRECATED`) for at least one minor or major release -and that are obsolete or replaced. - -#### Arena::CreateMessage - -**API:** -[`Arena::CreateMessage`](https://github.com/protocolbuffers/protobuf/blob/f4b57b98b08aec8bc52e6a7b762edb7a1b9e8883/src/google/protobuf/arena.h#L179) - -**Replacement:** -[`Arena::Create`](https://github.com/protocolbuffers/protobuf/blob/f4b57b98b08aec8bc52e6a7b762edb7a1b9e8883/src/google/protobuf/arena.h#L191) - -#### Arena::GetArena - -**API:** -[`Arena::GetArena`](https://github.com/protocolbuffers/protobuf/blob/237332ef92daf83a53e76decd6ac43c3fcee782b/src/google/protobuf/arena.h#L346) - -**Replacement:** `value->GetArena()` - -#### RepeatedPtrField::ClearedCount - -**API:** -[`RepeatedPtrField::ClearedCount`](https://github.com/protocolbuffers/protobuf/blame/f4b57b98b08aec8bc52e6a7b762edb7a1b9e8883/src/google/protobuf/repeated_ptr_field.h#L1157) - -**Replacement:** Migrate to Arenas -([migration guide](https://protobuf.dev/support/migration/#cleared-elements)). - -#### JsonOptions - -**API:** -[`JsonOptions`](https://github.com/protocolbuffers/protobuf/blob/f4b57b98b08aec8bc52e6a7b762edb7a1b9e8883/src/google/protobuf/util/json_util.h#L22) - -**Replacement:** `JsonPrintOptions` - -### Dropping C++14 Support {#drop-cpp-14} - -This release will drop C++ 14 as the minimum supported version and raise it to -17, as per the -[Foundational C++ Support matrix](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md). - -Per [our policies](https://protobuf.dev/support/version-support/), we do not -consider this to be a breaking change. - -## Changes in JRuby {#jruby} - -v30 will flip the default implementation for JRuby to FFI, which may be breaking -for some JRuby users. - -Note that this change doesn't create a Ruby major version bump because JRuby is -[not officially supported](/support/version-support/#ruby). - -## Changes in Python {#python} - -Python will bump its major version from 5.29.x to 6.30.x. - -### Dropping Python 3.8 Support - -As per our official Python support policy, we will be dropping support for -Python 3.8 and lower. This means the minimum supported Python version is 3.9. - -### Remove bazel/system_python.bzl Alias {#python-remove-alias} - -v30 will remove the legacy `bazel/system_python.bzl` alias. - -Remove direct references to `system_python.bzl` in favor of using -`protobuf_deps.bzl` instead. Use `python/dist/system_python.bzl` where it was -moved -[in v5.27.0](https://github.com/protocolbuffers/protobuf/commit/d7f032ad1596ceeabd45ca1354516c39b97b2551) -if you need a direct reference. - -### Field Setter Validation Changes {#python-setter-validation} - -Python's and upb's field setters will be fixed in v30 to validate closed enums -under edition 2023. Closed enum fields updated with invalid values will generate -errors. - -### Remove Deprecated APIs {#python-remove-apis} - -v30 will remove the following public runtime APIs, which have been marked -deprecated for at least one minor or major release and are obsolete or replaced. - -#### Reflection Methods - -**APIs:** -[`reflection.ParseMessage`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/reflection.py#L40), -[`reflection.MakeClass`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/reflection.py#L66) - -**Replacement:** `message_factory.GetMessageClass()` - -#### RPC Service Interfaces - -**APIs:** -[`service.RpcException`](https://github.com/protocolbuffers/protobuf/blob/21c545c8c5cec0b052dc7715b778f0353d37d02c/python/google/protobuf/service.py#L23), -[`service.Service`](https://github.com/protocolbuffers/protobuf/blob/21c545c8c5cec0b052dc7715b778f0353d37d02c/python/google/protobuf/service.py#L28), -[`service.RpcController`](https://github.com/protocolbuffers/protobuf/blob/21c545c8c5cec0b052dc7715b778f0353d37d02c/python/google/protobuf/service.py#L97), -and -[`service.RpcChannel`](https://github.com/protocolbuffers/protobuf/blob/21c545c8c5cec0b052dc7715b778f0353d37d02c/python/google/protobuf/service.py#L180) - -**Replacement:** Starting with version 2.3.0, RPC implementations should not try -to build on these, but should instead provide code generator plugins which -generate code specific to the particular RPC implementation. - -#### MessageFactory and SymbolDatabase Methods - -**APIs:** -[`MessageFactory.GetPrototype`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/message_factory.py#L145), -[`MessageFactory.CreatePrototype`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/message_factory.py#L165), -[`MessageFactory.GetMessages`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/message_factory.py#L185), -[`SymbolDatabase.GetPrototype`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/symbol_database.py#L54), -[`SymbolDatabase.CreatePrototype`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/symbol_database.py#L60), -and -[`SymbolDatabase.GetMessages`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/symbol_database.py#L66) - -**Replacement:** `message_factory.GetMessageClass()` and -`message_factory.GetMessageClassesForFiles()`. - -#### GetDebugString - -**APIs:** -[`GetDebugString`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/pyext/descriptor.cc#L1510) - -**Replacement:** - -No replacement. It's only in Python C++ which is no longer released. It is not -supported in pure Python or UPB. - -## Changes in Objective-C {#objc} - -**This will be the first breaking release for Objective-C**. - -Objective-C will bump its major version from 3.x.x to 4.30.x. - -### Overhaul Unknown Field Handling APIs Deprecating Most of the Existing APIs {#objc-field-handling} - -v30 will deprecate `GPBUnknownFieldSet` and replace it with `GPBUnknownFields`. -The new type will preserve the ordering of unknown fields from the original -input or API calls, to ensure any semantic meaning to the ordering is maintained -when a message is written back out. - -As part of this, the `GPBUnknownField` type also has its APIs changed, with -almost all of the existing APIs becoming deprecated and new ones added. - -Deprecated property APIs: - -* `varintList` -* `fixed32List` -* `fixed64List` -* `lengthDelimitedList` -* `groupList` - -Deprecated modification APIs: - -* `addVarint:` -* `addFixed32:` -* `addFixed64:` -* `addLengthDelimited:` -* `addGroup:` - -Deprecated initializer `initWithNumber:`. - -New property APIs: - -* `type` -* `varint` -* `fixed32` -* `fixed64` -* `lengthDelimited` -* `group` - -This type will model a single field number in its value, rather than *grouping* -all the values for a given field number. The APIs for creating new fields are -the `add*` APIs on the `GPBUnknownFields` class. - -v30 will also deprecate `-[GPBMessage unknownFields]`. In its place, there will -be new APIs to extract and update the unknown fields of the message. - -### Remove Deprecated APIs {#objc-remove-apis} - -v30 will remove the following public runtime APIs, which have been marked -deprecated for at least one minor or major release and are obsolete or replaced. - -#### GPBFileDescriptor - -**API:** -[-[`GPBFileDescriptor` syntax]](https://github.com/protocolbuffers/protobuf/blob/44bd65b2d3c0470d91a23cc14df5ffb1ab0af7cd/objectivec/GPBDescriptor.h#L118-L119) - -**Replacement:** Obsolete. - -#### GPBMessage mergeFrom:extensionRegistry - -**API:** -[-[`GPBMessage mergeFrom:extensionRegistry:`]](https://github.com/protocolbuffers/protobuf/blob/44bd65b2d3c0470d91a23cc14df5ffb1ab0af7cd/objectivec/GPBMessage.h#L258-L261) - -**Replacement:** -[-[`GPBMessage mergeFrom:extensionRegistry:error:`]](https://github.com/protocolbuffers/protobuf/blob/44bd65b2d3c0470d91a23cc14df5ffb1ab0af7cd/objectivec/GPBMessage.h#L275-L277) - -#### GPBDuration timeIntervalSince1970 - -**API:** -[-[`GPBDuration timeIntervalSince1970`]](https://github.com/protocolbuffers/protobuf/blob/29fca8a64b62491fb0a2ce61878e70eda88dde98/objectivec/GPBWellKnownTypes.h#L95-L100) - -**Replacement:** -[-[`GPBDuration timeInterval`]](https://github.com/protocolbuffers/protobuf/blob/29fca8a64b62491fb0a2ce61878e70eda88dde98/objectivec/GPBWellKnownTypes.h#L74-L89) - -#### GPBTextFormatForUnknownFieldSet - -**API:** -[`GPBTextFormatForUnknownFieldSet()`](https://github.com/protocolbuffers/protobuf/blob/29fca8a64b62491fb0a2ce61878e70eda88dde98/objectivec/GPBUtilities.h#L32-L43) - -**Replacement:** Obsolete - Use -[`GPBTextFormatForMessage()`](https://github.com/protocolbuffers/protobuf/blob/29fca8a64b62491fb0a2ce61878e70eda88dde98/objectivec/GPBUtilities.h#L20-L30), -which includes any unknown fields. - -#### GPBUnknownFieldSet - -**API:** -[`GPBUnknownFieldSet`](https://github.com/protocolbuffers/protobuf/blob/224573d66a0cc958c76cb43d8b2eb3aa7cdb89f2/objectivec/GPBUnknownFieldSet.h) - -**Replacement:** -[`GPBUnknownFields`](https://github.com/protocolbuffers/protobuf/blob/224573d66a0cc958c76cb43d8b2eb3aa7cdb89f2/objectivec/GPBUnknownFields.h) - -#### GPBMessage unknownFields - -**API:** -[`GPBMessage unknownFields` property](https://github.com/protocolbuffers/protobuf/blob/224573d66a0cc958c76cb43d8b2eb3aa7cdb89f2/objectivec/GPBMessage.h#L73-L76) - -**Replacement:** -[-[`GPBUnknownFields initFromMessage:`]](https://github.com/protocolbuffers/protobuf/blob/224573d66a0cc958c76cb43d8b2eb3aa7cdb89f2/objectivec/GPBUnknownFields.h#L30-L38), -[-[`GPBMessage mergeUnknownFields:extensionRegistry:error:`]](https://github.com/protocolbuffers/protobuf/blob/f26bdff7cc0bb7e8ed88253ba16f81614a26cf16/objectivec/GPBMessage.h#L506-L528), -and -[-[`GPBMessage clearUnknownFields`]](https://github.com/protocolbuffers/protobuf/blob/224573d66a0cc958c76cb43d8b2eb3aa7cdb89f2/objectivec/GPBMessage.h#L497-L504C9) - -### Remove Deprecated Runtime APIs for Old Gencode {#objc-remove-apis-gencode} - -This release will remove deprecated runtime methods that support the Objective-C -gencode from before the 3.22.x release. The library will also issue a log -message at runtime when old generated code is starting up. - -**API:** [`+[GPBFileDescriptor -allocDescriptorForClass:file:fields:fieldCount:storageSize:flags:]`](https://github.com/protocolbuffers/protobuf/blob/1b44ce0feef45a78ba99d09bd2e5ff5052a6541b/objectivec/GPBDescriptor_PackagePrivate.h#L213-L220) - -**Replacement:** Regenerate with a current version of the library. - -**API:** [`+[GPBFileDescriptor -allocDescriptorForClass:rootClass:file:fields:fieldCount:storageSize:flags:]`](https://github.com/protocolbuffers/protobuf/blob/1b44ce0feef45a78ba99d09bd2e5ff5052a6541b/objectivec/GPBDescriptor_PackagePrivate.h#L221-L229) - -**Replacement:** Regenerate with a current version of the library. - -**API:** [`+[GPBEnumDescriptor -allocDescriptorForName:valueNames:values:count:enumVerifier:]`](https://github.com/protocolbuffers/protobuf/blob/1b44ce0feef45a78ba99d09bd2e5ff5052a6541b/objectivec/GPBDescriptor_PackagePrivate.h#L285-L291) - -**Replacement:** Regenerate with a current version of the library. - -**API:** [`+[GPBEnumDescriptor -allocDescriptorForName:valueNames:values:count:enumVerifier:extraTextFormatInfo:]`](https://github.com/protocolbuffers/protobuf/blob/1b44ce0feef45a78ba99d09bd2e5ff5052a6541b/objectivec/GPBDescriptor_PackagePrivate.h#L292-L299) - -**Replacement:** Regenerate with a current version of the library. - -**API:** -[`-[GPBExtensionDescriptor initWithExtensionDescription:]`](https://github.com/protocolbuffers/protobuf/blob/1b44ce0feef45a78ba99d09bd2e5ff5052a6541b/objectivec/GPBDescriptor_PackagePrivate.h#L317-L320) - -**Replacement:** Regenerate with a current version of the library. - -## Other Changes {#non-breaking} - -In addition to those breaking changes are some other changes worth noting. While -the following are not considered breaking changes, they may still impact users. - -### Poison Pill Warnings {#poison} - -v30 will update poison pills to emit warnings for old gencode + new runtime -combinations that work under the new rolling upgrade policy, but will break in -the *next* major bump. For example, Java 4.x.x gencode should work against 5.x.x -runtime but warn of upcoming breakage against 6.x.x runtime. - -### Changes to UTF-8 Enforcement in C# and Ruby {#utf-8-enforcement} - -v30 will includes a fix to make UTF-8 enforcement consistent across languages. -Users with bad non-UTF8 data in string fields may see surfaced UTF-8 enforcement -errors earlier. diff --git a/content/news/2024-11-07.md b/content/news/2024-11-07.md deleted file mode 100644 index a41587005..000000000 --- a/content/news/2024-11-07.md +++ /dev/null @@ -1,76 +0,0 @@ -+++ -title = "Changes Announced on November 7, 2024" -linkTitle = "November 7, 2024" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on November 7, 2024." -type = "docs" -+++ - -The following sections cover planned breaking changes in the v30 release, -expected in 2025 Q1. Also included are some changes that aren't breaking but may -require action on your part. These are in addition to those mentioned in the -[News article from October 2](/news/2024-10-02). - -These describe changes as we anticipate them being implemented, but due to the -flexible nature of software some of these changes may not land or may vary from -how they are described in this topic. - -## Introduce ASAN Poisoning After Clearing Oneof Messages on Arena - -This change adds a hardening check that affects C++ protobufs using Arenas. -Oneof messages allocated on the protobuf arena will now be cleared in debug and -poisoned in ASAN mode. After calling clear, future attempts to use the memory -region will cause a crash in ASAN as a use-after-free error. - -This implementation -[requires C++17](/news/2024-10-02#drop-cpp-14). - -## Python setdefault Behavior Change for Map Fields - -Starting in v30, `setdefault` will be similar to `dict` for `ScalarMap`, except -that both key and value must be set. `setdefault` will be rejected for -`MessageMaps`. - -## Remove Deprecated py_proto_library Macro - -The deprecated internal `py_proto_library` Bazel macro in `protobuf.bzl` will be -removed in v30.x. - -This should be replaced by the official `py_proto_library` which will be moved -to protobuf in `bazel/py_proto_library` as of v29.x. This implementation was -previously available in `rules_python` prior to v29.x. - -## Python Nested Message Class \_\_qualname\_\_ Contains the Outer Message Name - -Python nested message class `__qualname__` now contains the outer message name. -Prior to v30, `__qualname__` has the same result with `__name__` for nested -message, in that the outer message name was not included. - -For example: - -```python -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 -``` - -## Dropping our C++ CocoaPods release - -In v30, we will be dropping our C++ CocoaPods release, which has been broken -since v4.x.x. C++ users should use our -[GitHub release](https://github.com/protocolbuffers/protobuf/releases) directly -instead. - -## Ruby and PHP Errors in JSON Parsing - -v30 fixes non-conformance in JSON parsing of strings in numeric fields per the -[JSON spec](https://protobuf.dev/programming-guides/json/). - -This fix will not be accompanied by a major version bump, but Ruby and PHP will -now raise errors for non-numeric strings (e.g. "", "12abc", "abc") in numeric -fields. v29.x will include a warning for these error cases. diff --git a/content/news/2024-12-04.md b/content/news/2024-12-04.md deleted file mode 100644 index 927799b9e..000000000 --- a/content/news/2024-12-04.md +++ /dev/null @@ -1,77 +0,0 @@ -+++ -title = "Changes announced December 4, 2024" -linkTitle = "December 4, 2024" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on December 4, 2024." -type = "docs" -+++ - -We are planning to modify the Protobuf debug APIs for C++ (including Protobuf -AbslStringify, `proto2::ShortFormat`, `proto2::Utf8Format`, -`Message::DebugString`, `Message::ShortDebugString`, `Message::Utf8DebugString`) -in v30 to redact sensitive fields annotated by `debug_redact`; the outputs of -these APIs will contain a per-process randomized prefix, and so will no longer -be parseable by Protobuf TextFormat Parsers. - -## Motivation - -Currently Protobuf debug APIs print every field in a proto into human-readable -formats. This may lead to privacy incidents where developers accidentally log -Protobuf debug outputs containing sensitive fields. - -## How to Annotate Sensitive Fields - -There are two ways to mark fields sensitive: - -* Mark a field with the field option `debug_redact = true`, directly. - - ```proto - message Foo { - optional string secret = 1 [debug_redact = true]; - } - ``` - -* If you have already defined a field annotation of type Enum by extending - `proto2.FieldOptions`, and certain values of this annotation are used to - annotate fields you would like to redact, then you can annotate these values - with `debug_redact = true`. All the fields that have been annotated with - such values will be redacted. - - ```proto - package my.package; - - extend proto2.FieldOptions { - # The existing field annotation - optional ContentType content_type = 1234567; - }; - - enum ContentType { - PUBLIC = 0; - SECRET = 1 [debug_redact = true]; - }; - - message Foo { - # will not be redacted - optional string public_info = 1 [ - (my.package.content_type) = PUBLIC - ]; - # will be redacted - optional string secret = 1 [ - (my.package.content_type) = SECRET - ]; - } - ``` - -## New Debug Format - -Compared to the existing debug format, the new debug format has two major -differences: - -* The sensitive fields annotated with `debug_redact` are redacted - automatically in the output formats -* The output formats will contain a per-process randomized prefix, which will - make them no longer be parsable by TextFormat parsers. - -Note that the second change is true regardless of whether the proto contains -sensitive fields or not, which ensures that any debug output always cannot be -deserialized regardless of the proto content. diff --git a/content/news/2024-12-13.md b/content/news/2024-12-13.md deleted file mode 100644 index d54dd2837..000000000 --- a/content/news/2024-12-13.md +++ /dev/null @@ -1,18 +0,0 @@ -+++ -title = "Changes announced December 13, 2024" -linkTitle = "December 13, 2024" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on December 13, 2024." -type = "docs" -+++ - -## Removing a Reflection-related Function - -In v30.x, we are removing the following reflection-related function: -`MutableRepeatedFieldRef::Reserve()`. - -An upcoming performance improvement in -[`RepeatedPtrField`](/reference/cpp/api-docs/google.protobuf.repeated_field#RepeatedPtrField) -is incompatible with this API. The improvement is projected to accelerate -repeated access to the elements of `RepeatedPtrField`, in particular and -especially sequential access. diff --git a/content/news/2024-12-18.md b/content/news/2024-12-18.md deleted file mode 100644 index 3cb8db458..000000000 --- a/content/news/2024-12-18.md +++ /dev/null @@ -1,30 +0,0 @@ -+++ -title = "Changes announced December 18, 2024" -linkTitle = "December 18, 2024" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on December 18, 2024." -type = "docs" -+++ - -## Go Protobuf: The new Opaque API - -Back in March 2020, we released the `google.golang.org/protobuf` module, -[a major overhaul of the Go Protobuf API](https://go.dev/blog/protobuf-apiv2). -This package introduced first-class -[support for reflection](https://pkg.go.dev/google.golang.org/protobuf/reflect/protoreflect), -a [`dynamicpb`](https://pkg.go.dev/google.golang.org/protobuf/types/dynamicpb) -implementation and the -[`protocmp`](https://pkg.go.dev/google.golang.org/protobuf/testing/protocmp) -package for easier testing. - -That release introduced a new protobuf module with a new API. Today, we are -releasing an additional API for generated code, meaning the Go code in the -`.pb.go` files created by the protocol compiler (`protoc`). The blog post at -https://go.dev/blog/protobuf-opaque explains our motivation for creating a new -API and shows you how to use it in your projects. - -To be clear: We are not removing anything. We will continue to support the -existing API for generated code, just like we still support the older protobuf -module (by wrapping the `google.golang.org/protobuf` implementation). Go is -[committed to backwards compatibility](https://go.dev/blog/compat) and this -applies to Go Protobuf, too! diff --git a/content/news/2025-01-23.md b/content/news/2025-01-23.md deleted file mode 100644 index fe42e3f63..000000000 --- a/content/news/2025-01-23.md +++ /dev/null @@ -1,41 +0,0 @@ -+++ -title = "Changes announced January 23, 2025" -linkTitle = "January 23, 2025" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on January 23, 2025." -type = "docs" -+++ - -## Poison Java gencode - -We are patching a change into the 25.x branch that will poison Java gencode that -was created prior to the -[3.21.7 release](https://github.com/protocolbuffers/protobuf/releases/tag/v21.7). -We will then mark all versions of Java protobuf from 3.21.7 through 3.25.5 as -vulnerable to the -[footmitten CVE](https://github.com/protocolbuffers/protobuf/security/advisories/GHSA-h4h5-3hr4-j3g2). - -After this change is patched in, protobuf will throw an -`UnsupportedOperationException` from the -[`makeExtensionsImmutable`](https://protobuf.dev/reference/java/api-docs/com/google/protobuf/GeneratedMessage.html#makeExtensionsImmutable\(\)) -method unless you set the system property -"`-Dcom.google.protobuf.use_unsafe_pre22_gencode`". Using this system property -can buy you some time if you can't update your code immediately, but should be -considered a short-term workaround. - -## Poison MSVC + Bazel - -**Update:** This plan has been canceled. You can learn more about this in the -announcement on [July 16, 2025](/news/2025-07-16). - -~~We will be dropping support for using Bazel and MSVC together in v34. As of -v30, we will poison this combination with an error unless you specify the -opt-out flag `--define=protobuf_allow_msvc=true` to silence it.~~ - -~~MSVC's path length limits combined with Bazel's sandboxing have become -increasingly difficult to support in combination. Rather than randomly break -users who install protobuf into a long path, we will prohibit the use of MSVC -from Bazel altogether. We will continue to support MSVC with CMake, and begin -supporting [clang-cl](https://clang.llvm.org/docs/UsersManual.html#clang-cl) -with Bazel. For any feedback or discussion, see -https://github.com/protocolbuffers/protobuf/issues/20085.~~ diff --git a/content/news/2025-03-18.md b/content/news/2025-03-18.md deleted file mode 100644 index fe810aa2b..000000000 --- a/content/news/2025-03-18.md +++ /dev/null @@ -1,14 +0,0 @@ -+++ -title = "Changes Announced on March 18, 2025" -linkTitle = "March 18, 2025" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on March 18, 2025." -type = "docs" -+++ - -## Dropping Ruby 3.0 Support - -As per our official -[Ruby support policy](https://cloud.google.com/ruby/getting-started/supported-ruby-versions), -we will be dropping support for Ruby 3.0 and lower in Protobuf version 31, due -to release in April, 2025. The minimum supported Ruby version will be 3.1. diff --git a/content/news/2025-06-27.md b/content/news/2025-06-27.md deleted file mode 100644 index 333f0cb13..000000000 --- a/content/news/2025-06-27.md +++ /dev/null @@ -1,227 +0,0 @@ -+++ -title = "Changes Announced on June 27, 2025" -linkTitle = "June 27, 2025" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on June 27, 2025." -type = "docs" -+++ - -## Edition 2024 - -We are planning to release Protobuf Edition 2024 in 32.x in Q3 2025. - -These describe changes as we anticipate them being implemented, but due to the -flexible nature of software some of these changes may not land or may vary from -how they are described in this topic. - -More documentation on Edition 2024 will be published in -[Feature Settings for Editions](/editions/features), -including information on migrating from Edition 2023. - -## Changes to Existing Features {#changes} - -This section details any existing features whose default settings will change in -Edition 2024. - -### C++ string_type {#string_type} - -The default for `string_type` feature, originally released in Edition 2023, will -change from `STRING` to `VIEW` in Edition 2024. - -See -[`features.(pb.cpp).string_type`](/editions/features#string_type) -and [String View APIs](/reference/cpp/string-view) for -more information on this feature and its feature values. - -## New Features {#new-features} - -This section details any new features that will be introduced in Edition 2024. - -### `enforce_naming_style` {#enforce_naming} - -[`feature.enforce_naming_style`](/editions/features#enforce_naming) -enables strict naming style enforcement to ensure protos are round-trippable by -default with a feature value to opt-out to use legacy naming style. - -### `default_symbol_visibility` {#default_symbol} - -This feature controls whether the default symbol visibility of importable -symbols (such as messages and enums) is either: - -* `export`: referenceable from other protos via import statements -* `local`: un-referenceable outside of current file - -The default feature value `EXPORT_TOP_LEVEL` in Edition 2024 ensures top-level -symbols are export by default, whereas nested symbols are local by default. - -This can be used along with the [`export` and `local` keywords](#export-local) -to explicitly annotate symbol visibility, also added in Edition 2024. - -Symbol visibility only controls which symbols can be imported from other proto -files, but does not affect code-generation. - -### C++: `enum_name_uses_string_view` {#enum_name} - -Previously, all generated enum types provide the following function to obtain -the label out of an enum value, which has significant overhead to construct the -`std::string` instances at runtime: - -```cpp -const std::string& Foo_Name(int); -``` - -The default feature value in Edition 2024 instead migrates this signature to -return `absl::string_view` to allow for better storage decoupling and potential -memory/CPU savings. - -```cpp -absl::string_view Foo_Name(int); -``` - -Users should migrate their code to handle the new return-type following -[the migration guide](/support/migration#string_view-return-type). - -See [String View APIs](/reference/cpp/string-view) for -more information. - -### Java: `nest_in_file_class` {#nest_in} - -This feature controls whether the Java generator will nest the generated class -in the Java generated file class. - -The default value in Edition 2024 generates classes in their own files by -default, which is also the default behavior of the previous -`java_multiple_files = true` file option. This replaces `java_multiple_files` -which is removed in Edition 2024. - -The default outer classname is also updated to always be the camel-cased -`.proto` filename suffixed with Proto by default (for example, -`foo/bar_baz.proto -> BarBazProto`). You can override this using the -`java_outer_classname` file option and replace the pre-Edition 2024 default of -`BarBaz` or `BarBazOuterClass` depending on the presence of conflicts. - -### Java: `large_enum` {#large_enum} - -This feature allows creation of large Java enums, extending beyond the enum -limit due to standard constant limits imposed by the Java language. - -Creation of large enums is not enabled by default, but you can explicitly enable -it using this feature. Note that this feature replicates enum-like behavior but -has some notable differences (for example, switch statements are not supported). - -## Grammar Changes {#grammar-changes} - -### `import option` {#import-option} - -Edition 2024 adds support for option imports using the syntax `import option`. - -Unlike normal `import` statements, `import option` only imports custom options -defined in a `.proto` file, without importing other symbols. - -This means that messages and enums are excluded from the option import. In the -following example, the `Bar` message cannot be used as a field type in -`foo.proto`, but options with type `Bar` can still be set. - -Option imports must also come after any other import statements. - -Example: - -```proto -// bar.proto -edition = "2024"; - -import "google/protobuf/descriptor.proto"; - -message Bar { - bool bar = 1; -} - -extend proto2.FileOptions { - bool file_opt1 = 5000; - Bar file_opt2 = 5001; -} -``` - -```proto -// foo.proto: -edition = "2024"; - -import option "bar.proto"; - -option (file_opt1) = true; -option (file_opt2) = {bar: true}; - -message Foo { - // Bar bar = 1; // This is not allowed -} -``` - -Option imports do not require generated code for its symbols and thus must be -provided as `option_deps` in `proto_library` instead of `deps`. This avoids -generating unreachable code. - -```build -proto_library( - name = "foo", - srcs = ["foo.proto"], - option_deps = [":custom_option"] -) -``` - -Option imports and `option_deps` are strongly recommended when importing -protobuf language features and other custom options to avoid generating -unnecessary code. - -`option_deps` requires Bazel 8 or later since the `native.proto_library` in -Bazel 7 does not support this. - -This also replaces `import weak`, which is removed in Edition 2024. - -### `export` / `local` Keywords {#export-local} - -`export` and `local` keywords are added in Edition 2024 as modifiers for the -symbol visibility of importable symbols, from the default behavior specified by -the -[`default_symbol_visibility` feature](/editions/features#symbol-vis). - -This controls which symbols can be imported from other proto files, but does not -affect code-generation. - -In Edition 2024, these can be set on all message and enum symbols by default. -However, some values of the `default_symbol_visibility` feature further restrict -which symbols are exportable. - -Example: - -```proto -// Top-level symbols are exported by default in Edition 2024 -local message LocalMessage { - // Nested symbols are local by default in Edition 2024 - export enum ExportedNestedEnum { - UNKNOWN_EXPORTED_NESTED_ENUM_VALUE = 0; - } -} -``` - -### "import weak" and `weak` Field Option {#import-weak} - -Weak imports are no longer allowed as of Edition 2024. - -Most users previously relying on `import weak` to declare a “weak dependency” to -import custom options without generated code for C++ and Go should instead -migrate to use -[`import option`](/editions/overview#import-option) -instead. - -### `ctype` Field Option {#ctype} - -`ctype` field option is no longer allowed as of Edition 2024. Use the -[`features.(pb.cpp).string_type`](/editions/features#string_type) -feature, instead. - -### `java_multiple_files` File Option {#java_multiple} - -The `java_multiple_files` file option is removed in Edition 2024 in favor of the -new -[`features.nest_in_file_class`](/editions/features#java-nest_in_file) -Java feature. diff --git a/content/news/2025-07-14.md b/content/news/2025-07-14.md deleted file mode 100644 index 95baca143..000000000 --- a/content/news/2025-07-14.md +++ /dev/null @@ -1,69 +0,0 @@ -+++ -title = "Changes Announced on July 14, 2025" -linkTitle = "July 14, 2025" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on July 14, 2025." -type = "docs" -+++ - -## Deprecating FieldDescriptor Enums - -We are announcing an upcoming change regarding the `FieldDescriptor` enum and -its associated values representing optional, required, and repeated. These are -being deprecated as we encourage the use of more precise accessor methods. - -### Background - -While at one time the `FieldDescriptor.label` enum served a purpose, the -evolution of Protocol Buffers has introduced more idiomatic ways to determine a -field's cardinality (singular/repeated) and presence semantics. - -* In proto2, `optional`, `required`, and `repeated` are explicit keywords. -* In proto3, `required` is no longer supported. All scalar fields are - implicitly "`optional`" in the sense that they have default values if not - set. The `optional` keyword was later reintroduced in proto3 to explicitly - track presence for scalar fields (distinguishing between an unset field and - a field set to its default value). -* In edition 2023 we removed the `optional` and `required` keywords and use - features to control those behaviors. - -The `label` enum conflates these distinct concepts (cardinality, requiredness, -and explicit presence tracking), leading to potential confusion, especially with -proto3's field presence model. - -### Impact and Migration - -The `FieldDescriptor.label` field will eventually be removed from the API. - -Note that the method names in this topic may be spelled slightly differently in -some languages. - -* **For Protocol Buffer Editions fields:** - * **Key Methods for Editions:** - * `hasPresence` becomes the primary method to determine if a singular - field tracks presence, reflecting the - [`features.field_presence`](/editions/features#field_presence) - setting for that field. - * **Migration:** Rely on `isRepeated` and `isRequired` for cardinality and - `hasPresence` to check for explicit presence tracking in singular - fields. -* **For proto2/proto3 fields:** `getLabel` will eventually be removed, and is - not recommended in the meantime. - -All users of Protocol Buffers who interact with `FieldDescriptor` objects in -their code (for example for code generation, reflection, and dynamic message -handling) should migrate away from using `FieldDescriptor.label` directly. - -Instead, update your code to use the following methods: - -* To check if a field is repeated: `field.isRepeated` -* To check if a field is required (proto2 and editions only): - `field.isRequired` -* To check if a singular field has explicit presence, use `hasPresence` - -### Timeline - -This deprecation is effective immediately. While `getLabel` will continue to -function, we recommend migrating your code proactively to ensure future -compatibility and clarity. This change will lead to a more robust and -understandable experience for developers using Protocol Buffers. diff --git a/content/news/2025-07-16.md b/content/news/2025-07-16.md deleted file mode 100644 index 9222ebeff..000000000 --- a/content/news/2025-07-16.md +++ /dev/null @@ -1,16 +0,0 @@ -+++ -title = "Changes Announced on July 16, 2025" -linkTitle = "July 16, 2025" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on July 16, 2025." -type = "docs" -+++ - -## Retaining support for Bazel with MSVC - -We announced on January 23, 2025 that we were planning to drop support for using -Bazel and MSVC together starting in v34. This plan is canceled due to Bazel's -[upcoming changes](https://github.com/bazelbuild/bazel/pull/26532) to virtual -includes on Windows. Clang-cl support will be kept in place as an alternative on -Windows. The opt-out flag `--define=protobuf_allow_msvc=true` will no longer be -required as of the 32.0 release. diff --git a/content/news/2025-09-19.md b/content/news/2025-09-19.md deleted file mode 100644 index 777505afb..000000000 --- a/content/news/2025-09-19.md +++ /dev/null @@ -1,279 +0,0 @@ -+++ -title = "Changes Announced on September 19, 2025" -linkTitle = "September 19, 2025" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on September 19, 2025." -type = "docs" -+++ - -The following sections cover planned breaking changes in the v34 release, -expected in 2026 Q1. These describe changes as we anticipate them being -implemented, but due to the flexible nature of software some of these changes -may not land or may vary from how they are described in this topic. - -## Changes in C++ {#cpp} - -C++ will bump its major version to 7 with the 7.34.0 release. 6.33 will be the -final minor version release on 6.x - -### Removal of Future Macros {#cpp-remove-macros} - -The following macros, introduced for staged roll-out of breaking changes, will -be removed and their behavior will become the default: - -* `PROTOBUF_FUTURE_RENAME_ADD_UNUSED_IMPORT` -* `PROTOBUF_FUTURE_REMOVE_ADD_IGNORE_CRITERIA` -* `PROTOBUF_FUTURE_STRING_VIEW_DESCRIPTOR_DATABASE` -* `PROTOBUF_FUTURE_NO_RECURSIVE_MESSAGE_COPY` -* `PROTOBUF_FUTURE_REMOVE_REPEATED_PTR_FIELD_ARENA_CONSTRUCTOR` -* `PROTOBUF_FUTURE_REMOVE_MAP_FIELD_ARENA_CONSTRUCTOR` -* `PROTOBUF_FUTURE_REMOVE_REPEATED_FIELD_ARENA_CONSTRUCTOR` - -### New RepeatedPtrField Layout {#cpp-repeatedptrfield-layout} - -`RepeatedPtrField` will transition to a new internal element layout where -elements are stored in contiguous chunks of preallocated memory, similar to -`std::deque`. This results in some changes to copy/move semantics of some APIs, -and some `UnsafeArena` APIs may become functional equivalents of their -arena-safe counterparts and be deprecated. - -### MSB Hardening Check on RepeatedField::Get and RepeatedPtrField::Get {#cpp-repeatedfield-get-hardening} - -Protobufs will be hardened against OOB errors by adding comprehensive bounds -checking to repeated field accesses. - - - -### Remove Arena-enabled constructors from Repeated/Map Fields {#cpp-remove-arena-ctors} - -The `RepeatedField(Arena*)`, `RepeatedPtrField(Arena*)`, and `Map(Arena*)` -constructors will be deleted. - -### Remove Deprecated APIs {#cpp-remove-apis} - -This release will remove the following public runtime APIs, which have been -marked deprecated for at least one minor or major release and that are obsolete -or replaced. - -#### AddUnusedImportTrackFile() and ClearUnusedImportTrackFiles() - -**API:** `AddUnusedImportTrackFile()`, `ClearUnusedImportTrackFiles()` - -**Replacement:** `AddDirectInputFile()` and `ClearDirectInputFiles()` - -#### AddIgnoreCriteria from message differencer - -`PROTOBUF_FUTURE_REMOVE_ADD_IGNORE_CRITERIA` was added for the breaking change. -This release will remove the macro. - -**API:** `AddIgnoreCriteria()` - -**Replacement:** Wrap the raw pointer in a `unique_ptr`. - -#### FieldDescriptor::has_optional_keyword() - -**API:** `FieldDescriptor::has_optional_keyword()` - -**Replacement:** `has_presence()` - -#### FieldDescriptor::label() - -**API:** `FieldDescriptor::label()` - -**Replacement:** `is_repeated()` or `is_required()` - -#### FieldDescriptor::is_optional() - -**API:** `FieldDescriptor::is_optional()` - -**Replacement:** `!is_required() && !is_repeated()` - -#### UseDeprecatedLegacyJsonFieldConflicts() - -**API:** `UseDeprecatedLegacyJsonFieldConflicts()` - -**Replacement:** No replacement. - -### Stricter Name Length Limits {#cpp-name-limits} - -The protobuf compiler will enforce stricter limits on the length of symbol -names, such as field names, to prevent potential issues. If the length of any -field name is > 2^16, it will generate an error. - -### Hide Private Generator Headers in CMake {#cpp-cmake-headers} - -The protoc generator headers will no longer be installed by CMake. This should -not affect most users. - -### [[nodiscard]] on Logically Constant Operations {#cpp-nodiscard} - -`[[nodiscard]]` will be added to several logically constant protobuf APIs where -failure to consume the returned value indicates a probable bug. This follows -patterns used commonly in the C++ standard library. - -## Changes in Python {#python} - -Python will bump its major version to 7 with the 7.34.0 release. 6.33 will be -the final minor version release on 6.x - -There is no change in the gencode and we will relax the poison pills. No -warnings or errors will be raised for old generated files for 7.34.x. - -### Raise TypeError on Incorrect Type Conversion to Timestamp/Duration {#python-type-error-timestamp-duration} - -This release will raise a `TypeError` instead of an `AttributeError` when -converting an incorrect type to a `Timestamp` or `Duration`. - -### Reject bool to enum and int field {#python-reject-bool-enum-int} - -This release will reject setting enum or int fields with boolean values. The API -will raise an error instead of implicitly converting them. - -### Remove float_precision from json_format {#python-remove-float-precision} - -This release will remove the deprecated `float_precision` option from the -`json_format` serializer. This option does not exist in other ProtoJSON -serializers and has confusing semantics. - -### Remove float_format/double_format from text_format {#python-remove-text-format-options} - -This release will remove the deprecated `float_format` and `double_format` -options from `text_format`. These options are not available in other proto text -format serializers. - -### Remove Deprecated APIs {#python-remove-apis} - -This release will remove the following public runtime APIs. - -#### FieldDescriptor.label - -**API:** `FieldDescriptor.label` - -**Replacement:** Use `is_repeated()` or `is_required()`. - -## Changes in PHP {#php} - -PHP will bump its major version to 5 with the 5.34.0 release. 4.33 will be the -final minor version release on 4.x - -### Remove Deprecated APIs {#php-remove-apis} - -This release will remove the following public runtime APIs. - -#### FieldDescriptor getLabel - -**API:** `FieldDescriptor getLabel` - -**Replacement:** `isRepeated()` or `isRequired()` - -#### Google\Protobuf\Field_Kind - -**API:** `Google\Protobuf\Field_Kind` - -**Replacement:** `Google\Protobuf\Field\Kind` - -#### Google\Protobuf\Field_Cardinality - -**API:** `Google\Protobuf\Field_Cardinality` - -**Replacement:** `Google\Protobuf\Field\Cardinality` - -#### Google\Protobuf\Internal\RepeatedField - -**API:** `Google\Protobuf\Internal\RepeatedField` - -**Replacement:** `Google\Protobuf\RepeatedField` - -### JSON Parsing Strictness {#php-json-parsing} - -The JSON parser will become stricter and reject several cases that were -previously accepted. This includes out-of-bound values, non-integer numeric -values for integer fields, duplicate oneof fields, and non-string values for -string fields. The JSON serializer will also reject `Infinity` and `NaN` for -number values. - -### Fix Silent Ignoring of Default Values {#php-fix-default-values} - -The PHP runtime will be fixed to honor default values on scalar fields in proto2 -and editions, instead of silently ignoring them. - -### Type Checking Alignment {#php-type-checking} - -Type checking for pure-PHP and upb-PHP implementations will be aligned. Notably, -pure-PHP will reject `null` for string fields, matching the behavior of upb-PHP. - -## Changes in Objective-C {#objc} - -Objective-C will bump its major version to 5 with the 5.34.0 release. 4.33 will -be the final minor version release on 4.x - -The nullability annotations for some `GPB*Dictionary` APIs will be corrected to -mark when APIs could return `nil`. This will result in Swift code getting a -Swift `Optional` and thus becoming a breaking API change. For Objective-C -callers, the annotation correction is less likely to have any impact on the -source code. - -### Remove Deprecated APIs {#objc-remove-apis} - -This release will remove the following public runtime APIs. - -#### -[GPBFieldDescriptor optional] - -**API:** `-[GPBFieldDescriptor optional]` - -**Replacement:** Use `!required && fieldType == GPBFieldTypeSingle` instead. - -## Changes in Bazel {#bazel} - -### Migration of Proto Flags to Starlark {#bazel-starlark-flags} - -`--proto_toolchain_for*` and `--proto_compiler` are no longer read by Proto -rules. These toolchain-related flags are deprecated and will be removed in the -future. Switching to the equivalent Starlark flags is a short-term fix: - -* `--@protobuf//bazel/flags/cc:proto_toolchain_for_cc` -* `--@protobuf//bazel/flags/java:proto_toolchain_for_java` -* `--@protobuf//bazel/flags/java:proto_toolchain_for_javalite` -* `--@protobuf//bazel/flags:proto_compiler` - -The longer-term fix is to enable -`--incompatible_enable_proto_toolchain_resolution` (which is the default in -Bazel 9 anyway) and to register toolchains using the normal platforms-related -mechanisms (`register_toolchain()` in `MODULE.bazel` or `WORKSPACE`, or -`--extra_toolchains`). - -All other Bazel Proto flags have also been migrated to Starlark, and the native -flags will be deprecated with the next Bazel release. Use the following Starlark -flags to avoid future breakages: - -* `--@protobuf//bazel/flags:strict_proto_deps` -* `--@protobuf//bazel/flags:strict_public_imports` -* `--@protobuf//bazel/flags:experimental_proto_descriptor_sets_include_source_info` -* `--@protobuf//bazel/flags/cc:cc_proto_library_header_suffixes` -* `--@protobuf//bazel/flags/cc:cc_proto_library_source_suffixes` -* `--@protobuf//bazel/flags:protocopt` - -**NOTE:** In v34.0, `--@protobuf//bazel/flags:protocopt` was incorrectly located -at `--@protobuf//bazel/flags/cc:protocopt`. The flag will be moved to its -correct location, and the `cc` location will remain as a deprecated alias -starting in v34.1. This alias should not be used and will be removed in the next -breaking change. - -### Remove deprecated ProtoInfo.transitive_imports {#bazel-transitive-imports} - -The deprecated `transitive_imports` field in `ProtoInfo` will be removed. Users -should migrate to `transitive_sources`. - -### Remove protobuf_allow_msvc flag and continue support Bazel+MSVC {#remove-protobuf_allow_msvc} - -Due to Bazel's recent improvements on Windows, we now plan to continue to -support Bazel+MSVC. The `--define=protobuf_allow_msvc` flag will be removed. - -## Other Changes {#other-changes} - -The following are additional breaking changes. - -### Languages Without a Major Version Bump - -Java, Ruby, C#, Rust, and JRuby will not have a major version bump in this -release. diff --git a/content/news/2026-01-16.md b/content/news/2026-01-16.md deleted file mode 100644 index 4e70d2fa8..000000000 --- a/content/news/2026-01-16.md +++ /dev/null @@ -1,43 +0,0 @@ -+++ -title = "Changes Announced on January 16, 2026" -linkTitle = "January 16, 2026" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on January 16, 2026." -type = "docs" -+++ - -## Prebuilt proto compiler (protoc) for Bazel - -In an effort to speed up builds, protobuf 33.4 offers an option to skip -re-compiling Protobuf tools and runtimes and use a pre-built protoc binary, -available to Bazel 7 and later. Using a pre-built protoc also avoids build -failures from incompatible or non-hermetic C++ compilation toolchain installed -on your machine. - -To use the prebuilt protoc, upgrade to protobuf version 33.4 or later, and set -the `--incompatible_enable_proto_toolchain_resolution` and -`--@protobuf//bazel/flags:prefer_prebuilt_protoc` flags. The first flag is set -by default in Bazel 9 onwards. - -In the breaking v34 release, protobuf will change the default of -`--@protobuf//bazel/flags:prefer_prebuilt_protoc` to true. - -### Reasons not to use the prebuilt compiler - -There are some use cases in which using the prebuilt protoc is not recommended: - -* Your corporate security policy requires all dependencies be built from - source. -* You need to build for the exec platform with a specific compiler or specific - compiler flags. -* You are making changes to protoc, itself, and want to ensure that those - changes are tested. - -### Troubleshooting - -For information on troubleshooting the prebuilt protoc compiler configuration, -see -[Bazel: Resolving Issues with Prebuilt Protoc](/support/debugging-playbook#prebuilt-protoc) - -For more information on other changes in Bazel 9 that affect Protocol Buffers, -see https://bazel.build/about/roadmap. diff --git a/content/news/2026-03-13.md b/content/news/2026-03-13.md deleted file mode 100644 index 47cd10571..000000000 --- a/content/news/2026-03-13.md +++ /dev/null @@ -1,44 +0,0 @@ -+++ -title = "Changes Announced on March 13, 2026" -linkTitle = "March 13, 2026" -toc_hide = "true" -description = "Changes announced for Protocol Buffers on March 13, 2026." -type = "docs" -+++ - -## Changes in Bazel {#bazel} - -### Migration of Proto Flags to Starlark {#bazel-starlark-flags} - -`--proto_toolchain_for*` and `--proto_compiler` are no longer read by Proto -rules. These toolchain-related flags are deprecated and will be removed in the -future. Switching to the equivalent Starlark versions of the flags is a -short-term fix: - -* `--@protobuf//bazel/flags/cc:proto_toolchain_for_cc` -* `--@protobuf//bazel/flags/java:proto_toolchain_for_java` -* `--@protobuf//bazel/flags/java:proto_toolchain_for_javalite` -* `--@protobuf//bazel/flags:proto_compiler` - -The longer-term fix is to enable -`--incompatible_enable_proto_toolchain_resolution` (which is the default in -Bazel 9 anyway) and to register toolchains using the normal platforms-related -mechanisms (`register_toolchain()` in `MODULE.bazel` or `WORKSPACE`, or -`--extra_toolchains`). - -All other Bazel Proto flags have also been migrated to Starlark, and the native -flags will be deprecated with the next Bazel release. Use the following Starlark -flags to avoid future breakages: - -* `--@protobuf//bazel/flags:strict_proto_deps` -* `--@protobuf//bazel/flags:strict_public_imports` -* `--@protobuf//bazel/flags:experimental_proto_descriptor_sets_include_source_info` -* `--@protobuf//bazel/flags/cc:cc_proto_library_header_suffixes` -* `--@protobuf//bazel/flags/cc:cc_proto_library_source_suffixes` -* `--@protobuf//bazel/flags:protocopt` - -**NOTE:** In v34.0, `--@protobuf//bazel/flags:protocopt` was incorrectly located -at `--@protobuf//bazel/flags/cc:protocopt`. The flag will be moved to its -correct location, and the `cc` location will remain as a deprecated alias -starting in v34.1. This alias should not be used and will be removed in the next -breaking change. diff --git a/content/news/_index.md b/content/news/_index.md deleted file mode 100644 index c84cd87d6..000000000 --- a/content/news/_index.md +++ /dev/null @@ -1,120 +0,0 @@ -+++ -title = "News" -weight = 20 -description = "Get the latest news about Protocol Buffers." -type = "docs" -no_list = "true" -+++ - -News topics provide information about past events and changes with Protocol -Buffers, and plans for upcoming changes. The information is available both -chronologically and per-release. Note that not everything is included in the -per-release topics, as some content is not tied to a version. - -New news topics will also be published to the -[protobuf@](https://groups.google.com/g/protobuf) mailing list under the subject -\[Announcement\]. - -## Chronological {#chronological} - -The following news topics provide information in the reverse order in which it -was released. - -* [March 13, 2026](/news/2026-03-13) - Breaking changes - in Bazel for the upcoming 34.x release -* [January 16, 2026](/news/2026-01-16) - Prebuilt proto - compiler (protoc) for Bazel -* [September 19, 2025](/news/2025-09-19) - Breaking - changes in the upcoming 34.x release -* [July 16, 2025](/news/2025-07-16) - Resuming support - for Bazel with MSVC -* [July 14, 2025](/news/2025-07-14) - Deprecating - FieldDescriptor labels -* [June 27, 2025](/news/2025-06-27) - Edition 2024 -* [March 18, 2025](/news/2025-03-18) - Dropping support - for Ruby 3.0 -* [January 23, 2025](/news/2025-01-23) - Poison Java - gencode -* [December 18, 2024](/news/2024-12-18) - Go Protobuf: - The new Opaque API -* [December 13, 2024](/news/2024-12-13) - Removing - `MutableRepeatedFieldRef::Reserve()` in v30 -* [December 4, 2024](/news/2024-12-04) - `DebugString` - replaced -* [November 7, 2024](/news/2024-11-07) - More breaking - changes in the upcoming 30.x release -* [October 2, 2024](/news/2024-10-02) - Breaking - changes in the upcoming 30.x release -* [October 1, 2024](/news/2024-10-01) - Changes to - Bazel builds -* [June 26, 2024](/news/2024-06-26) - Dropping support - for building Protobuf Java from source with Maven -* [February 27, 2024](/news/2024-02-27) - Dropping - support for older versions of Ruby -* [February 5, 2024](/news/2024-02-05) - Breaking - changes in Java, C++, and Python in the 26.x line. -* [January 31, 2024](/news/2024-01-31) - Breaking - changes in the 26.x line for Python -* [January 5, 2024](/news/2024-01-05) - Breaking - changes in the 26.x line for Ruby and Python -* [December 27, 2023](/news/2023-12-27) - Breaking - changes in the 26.x line for Ruby, PHP, Python, and upb -* [December 13, 2023](/news/2023-12-13) - Breaking - Python and C++ changes in the 26.x line -* [December 5, 2023](/news/2023-12-05) - Breaking Java - changes in the 26.x line -* [October 10, 2023](/news/2023-10-10) - Documentation - for Protobuf Editions features is published -* [September 15, 2023](/news/2023-09-15) - μpb Moving - to the Protobuf GitHub repository -* [August 15, 2023](/news/2023-08-15) - Breaking Python - change with the replacement of `message.UnknownFields()` -* [August 9, 2023](/news/2023-08-09) - Support policy - for .NET -* [July 17, 2023](/news/2023-07-17) - Dropping support - for older versions of Bazel -* [July 6, 2023](/news/2023-07-06) - Dropping support - for older versions of PHP, Ruby, and Python -* [June 29, 2023](/news/2023-06-29) - Protobuf Editions - announcement -* [April 28, 2023](/news/2023-04-28) - Null no longer - allowed in `json_name` field options -* [April 20, 2023](/news/2023-04-20) - Update to Ruby - code generator -* [April 11, 2023](/news/2023-04-11) - Removing syntax - reflection, releasing C++ CORD support for singular `bytes` fields to OSS, - option retention, and dropping support for Bazel <5.3 -* [August 3, 2022](/news/2022-08-03) - Platform Support - Changes and Upcoming Changes in the C++ 22.x Line -* [July 6, 2022](/news/2022-07-06) - Library Breaking - Change Policy -* [May 6, 2022](/news/2022-05-06) - Versioning, Python - Updates, and JavaScript Support - -## Per Release {#per-release} - - - -The following new topics provide per-release information. All News entries -appear in the chronological listing in the previous section, but only entries -that are specific to a particular version appear in the pages listed in this -section. - -These pages do not replace the -[release notes](https://github.com/protocolbuffers/protobuf/releases), as the -release notes will be more complete. Also, not everything from the chronological -listing will be in these topics, as some content is not specific to a particular -release. - -* [Version 34.x](/news/v34) -* [Version 32.x](/news/v32) -* [Version 31.x](/news/v31) -* [Version 30.x](/news/v30) -* [Version 29.x](/news/v29) -* [Version 26.x](/news/v26) -* [Version 25.x](/news/v25) -* [Version 24.x](/news/v24) -* [Version 23.x](/news/v23) -* [Version 22.x](/news/v22) -* [Version 21.x](/news/v21) diff --git a/content/news/v21.md b/content/news/v21.md deleted file mode 100644 index 4634ec40f..000000000 --- a/content/news/v21.md +++ /dev/null @@ -1,38 +0,0 @@ -+++ -title = "News Announcements for Version 21.x" -linkTitle = "Version 21.x" -toc_hide = "true" -description = "Changes announced for Protocol Buffers version 21.x." -type = "docs" -+++ - -The following announcements are specific to Version 21.x, which was released May -25, 2022. For information presented chronologically, see -[News](/news). - -## Python Updates {#python-updates} - -We made some changes in Python language support in Protocol Buffers. Version -4.21.0 is a new major version, following 3.20.1. The new version is based on the -[upb library](https://github.com/protocolbuffers/upb), and offers -significantly better parsing performance than previous releases, especially for -large payloads. It also includes prebuilt binary modules for Apple silicon for -increased performance without a manual build. - -The new release does contain some breaking changes. Specifically: - -* The - [`UnknownFields()`](https://googleapis.dev/python/protobuf/3.17.0/google/protobuf/message.html#google.protobuf.message.Message.UnknownFields) - method, which relied on an implicitly created class, is replaced with the - explicitly-created `UnknownFieldSet` class. -* Some non-core characteristics may have changed, such as the specific format - of certain strings or error messages. These are not considered breaking - changes, but may still impact your existing code base. -* Applications that rely on sharing messages between Python and C++ break in - the new version. Most developers won't be affected by this, but users of - [Nucleus](https://github.com/google/nucleus) and possibly other - libraries may be. As a workaround, you can - [set an environment variable](/reference/python/python-generated#sharing-messages) - that forces the library to preserve compatibility. -* Python upb requires generated code that has been generated from protoc - 3.19.0 or newer. diff --git a/content/news/v22.md b/content/news/v22.md deleted file mode 100644 index 23b1fdca4..000000000 --- a/content/news/v22.md +++ /dev/null @@ -1,63 +0,0 @@ -+++ -title = "News Announcements for Version 22.x" -linkTitle = "Version 22.x" -toc_hide = "true" -description = "Changes announced for Protocol Buffers version 22.x." -type = "docs" -+++ - -The following announcements are specific to Version 22.x, which was released -February 16, 2023. For information presented chronologically, see -[News](/news). - -### Changing Maven Release Candidate Artifact Names to Be More Idiomatic {#idiomatic} - -In 22.0 we plan to rename Maven artifacts to use “RC” instead of “rc-” as the -release candidate prefix. - -### Adding an Abseil Dependency {#abseil-dep} - -In order to reduce the Google vs. OSS differences between protobuf and to -simplify our own project, we plan to take a formal dependency on Abseil. In -time, we plan to start using Abseil types in our public APIs, but simply adding -the dependency is a breaking change. - -### Dropping Support for PHP <7.4 {#php-74} - -Per our -[PHP support policy](https://cloud.google.com/php/getting-started/supported-php-versions), -we plan to drop support for EOL versions of PHP. This is not considered a -breaking change since these versions are already EOL in the broader ecosystem. - -### Dropping Autotools Support {#autotools} - -Per our -[build systems support policy](https://opensource.google/documentation/policies/cplusplus-support#3_build_systems), -we plan to drop autotools support. This is a breaking change. After autotools -support is dropped, protobuf will support only CMake and Bazel. - -### Dropping C++11 Support {#c11-support} - -Per our -[C++ support policy](https://opensource.google/documentation/policies/cplusplus-support#4_c_language_standard), -we plan to drop C++11 support. This is a breaking change. - -### Adding C++20 Support {#c20-support} - -Because of the addition of new keywords to the C++ language, adding support for -C++20 is a breaking change for users even if they do not currently use C++20. - -Mitigations for this to conditionally change names only in certain compiler -modes would break projects that support multiple language standards. - -## C++ Changes {#cpp-changes} - -Following the announcement of our -[new major version and breaking changes policy](/news/2022-07-06), -we are planning a major version bump for C++. We plan to make some changes to -the assets that we release starting with our 22.x release line. - -The following sections outline the set of breaking changes that we plan to -include in the 22.0 release of protocol buffers. Note that plans can and do -change. These are potential breaking changes to be aware of, but they may not -happen in this particular release, or they may not happen at all. diff --git a/content/news/v23.md b/content/news/v23.md deleted file mode 100644 index c33eb9026..000000000 --- a/content/news/v23.md +++ /dev/null @@ -1,181 +0,0 @@ -+++ -title = "News Announcements for Version 23.x" -linkTitle = "Version 23.x" -toc_hide = "true" -description = "Changes announced for Protocol Buffers version 23.x." -type = "docs" -+++ - -The following announcements are specific to Version 23.x, which was released May -8, 2023. For information presented chronologically, see -[News](/news). - -## Changes to Ruby Generator {#ruby} - -[This GitHub PR](https://github.com/protocolbuffers/protobuf/pull/12319), which -will appear in the 23.x release, changes the Ruby code generator to emit a -serialized proto instead of the DSL. - -It removes the DSL from the code generator in anticipation of splitting the DSL -out into a separate package. - -Given a .proto file like: - -```proto -syntax = "proto3"; - -package pkg; - -message TestMessage { - optional int32 i32 = 1; - optional TestMessage msg = 2; -} -``` - -Generated code before: - -```ruby -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: protoc_explorer/main.proto - -require 'google/protobuf' - -Google::Protobuf::DescriptorPool.generated_pool.build do - add_file("test.proto", :syntax => :proto3) do - add_message "pkg.TestMessage" do - proto3_optional :i32, :int32, 1 - proto3_optional :msg, :message, 2, "pkg.TestMessage" - end - end -end - -module Pkg - TestMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("pkg.TestMessage").msgclass -end -``` - -Generated code after: - -```ruby -# frozen_string_literal: true -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: test.proto - -require 'google/protobuf' - -descriptor_data = "\n\ntest.proto\x12\x03pkg\"S\n\x0bTestMessage\x12\x10\n\x03i32\x18\x01 \x01(\x05H\x00\x88\x01\x01\x12\"\n\x03msg\x18\x02 \x01(\x0b\x32\x10.pkg.TestMessageH\x01\x88\x01\x01\x42\x06\n\x04_i32B\x06\n\x04_msgb\x06proto3" -begin - Google::Protobuf::DescriptorPool.generated_pool.add_serialized_file(descriptor_data) -rescue TypeError => e - # -end - -module Pkg - TestMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("pkg.TestMessage").msgclass -end -``` - -This change fixes nearly all remaining conformance problems that existed -previously. This is a side effect of moving from the DSL (which is lossy) to a -serialized descriptor (which preserves all information). - -### Backward Compatibility {#backward} - -This change should be 100% compatible with Ruby Protobuf >= 3.18.0, released in -Sept 2021. Additionally, it should be compatible with all existing users and -deployments. - -There **is** some special compatibility code inserted to achieve this level of -backward compatibility that you should be aware of. Without the compatibility -code, there is an edge case that could break backward compatibility. The -previous code is lax in a way that the new code will be more strict. - -When using a full serialized descriptor, it contains a list of all `.proto` -files imported by this file (whereas the DSL never added dependencies properly). -See the code in -[`descriptor.proto`](https://github.com/protocolbuffers/protobuf/blob/dfb71558a2226718dc3bcf5df27cbc11c1f72382/src/google/protobuf/descriptor.proto#L65-L66). - -`add_serialized_file` verifies that all dependencies listed in the descriptor -were previously added with `add_serialized_file`. Generally that should be fine, -because the generated code will contain Ruby `require` statements for all -dependencies, and the descriptor will fail to load anyway if the types depended -on were not previously defined in the `DescriptorPool`. - -But there is a potential for problems if there are ambiguities around file -paths. For example, consider the following scenario: - -```proto -// foo/bar.proto - -syntax = "proto2"; - -message Bar {} -``` - -```proto -// foo/baz.proto - -syntax = "proto2"; - -import "bar.proto"; - -message Baz { - optional Bar bar = 1; -} -``` - -If you invoke `protoc` like so, it will work correctly: - -``` -$ protoc --ruby_out=. -Ifoo foo/bar.proto foo/baz.proto -$ RUBYLIB=. ruby baz_pb.rb -``` - -However if you invoke `protoc` like so, and didn't have any compatibility code, -it would fail to load: - -``` -$ protoc --ruby_out=. -I. -Ifoo foo/baz.proto -$ protoc --ruby_out=. -I. -Ifoo foo/bar.proto -$ RUBYLIB=foo ruby foo/baz_pb.rb -foo/baz_pb.rb:10:in `add_serialized_file': Unable to build file to DescriptorPool: Depends on file 'bar.proto', but it has not been loaded (Google::Protobuf::TypeError) - from foo/baz_pb.rb:10:in `
' -``` - -The problem is that `bar.proto` is being referred to by two different canonical -names: `bar.proto` and `foo/bar.proto`. This is a user error: each import should -always be referred to by a consistent full path. Hopefully user errors of this -sort will be rare, but it is hard to know without trying. - -The code in this change prints a warning using `warn` if we detect that this -edge case has occurred: - -``` -$ RUBYLIB=foo ruby foo/baz_pb.rb -Warning: Protobuf detected an import path issue while loading generated file foo/baz_pb.rb -- foo/baz.proto imports bar.proto, but that import was loaded as foo/bar.proto -Each proto file must use a consistent fully-qualified name. -This will become an error in the next major version. -``` - -There are two possible fixes in this case. One is to consistently use the name -`bar.proto` for the import (removing `-I.`). The other is to consistently use -the name `foo/bar.proto` for the import (changing the import line to `import -"foo/bar.proto"` and removing `-Ifoo`). - -We plan to remove this compatibility code in the next major version. - -## Dropping Support for Bazel <5.3 {#bazel} - -v23 will drop support for Bazel 4. Protobuf will continue to support the Bazel 5 -LTS with Bazel 5.3 as the minimum required version. This is per the build -support policy described in -[Foundational C++ Support Policy](https://opensource.google/documentation/policies/cplusplus-support#build_systems) -and as reflected in the versions in -[Foundational C++ Support](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md). - -## Syntax Reflection Deprecation {#deprecation} - -v23 will deprecate the ability to check syntax version using reflection. The -deprecation will be included as warnings at build time. The capability will be -removed in a future release. diff --git a/content/news/v24.md b/content/news/v24.md deleted file mode 100644 index 4fd1b15fb..000000000 --- a/content/news/v24.md +++ /dev/null @@ -1,23 +0,0 @@ -+++ -title = "News Announcements for Version 24.x" -linkTitle = "Version 24.x" -toc_hide = "true" -description = "Changes announced for Protocol Buffers version 24.x." -type = "docs" -+++ - -The following announcements are specific to Version 24.x, which was released -August 8, 2023. For information presented chronologically, see -[News](/news). - -## Stricter validation for `json_name` {#json-name} - -v24 will forbid embedded null characters in the -[`json_name` field option](/programming-guides/proto3/#json). -Going forward, any valid Unicode characters will be accepted, **except** -`\u0000`. Null will still be allowed in field values. - -Previously, the proto compiler allowed null characters, but support for this was -inconsistent across languages and implementations. To fix this, we are -clarifying the spec to say that null is not allowed in `json_name`, and will be -rejected by the compiler. diff --git a/content/news/v25.md b/content/news/v25.md deleted file mode 100644 index 30d57201a..000000000 --- a/content/news/v25.md +++ /dev/null @@ -1,65 +0,0 @@ -+++ -title = "News Announcements for Version 25.x" -linkTitle = "Version 25.x" -toc_hide = "true" -description = "Changes announced for Protocol Buffers version 25.x." -type = "docs" -+++ - -The following announcements are specific to Version 25.x, which was released -November 1, 2023. For information presented chronologically, see -[News](/news). - -## Python Breaking Change - -In v25 -[`message.UnknownFields()`](https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message.UnknownFields) -will be deprecated in pure Python and C++ extensions. It will be removed in v26. -Use the new -[`UnknownFieldSet(message)`](https://googleapis.dev/python/protobuf/latest/google/protobuf/unknown_fields.html) -support in `unknown_fields.py` as a replacement. - -## μpb Moving to the Protobuf Git Repository - -Starting with the v25 release, μpb now lives in the -[protobuf repo](https://github.com/protocolbuffers/protobuf) instead -of in its [former location](https://github.com/protocolbuffers/upb) -in a separate repo. All μpb development going forward will take place only in -the new location. - -The merger of the two repos will simplify and speed up our development process -by removing the need to update pinned version dependencies between protobuf and -μpb. Changes to μpb now take effect immediately in protobuf code and vice versa, -without the need for a manual upgrade step. - -We expect that most users will not need to take much, if any, action to -accommodate the change. μpb is the engine behind our Ruby, PHP, and Python -implementations, but you will most likely not notice the change unless you have -code that refers to μpb directly. - -If you refer to μpb from a Bazel project, you will need to update μpb references -to point to protobuf instead (for example, replace `@upb` with -`@com_google_protobuf`). We are keeping μpb file paths and Bazel targets the -same to minimize the need for additional changes, but there are two exceptions: - -- The `upbc` directory has been renamed `upb_generator`. -- The top-level `BUILD` file for μpb has moved into the `upb` directory. So, - for example, references to `@upb//:reflection` should now be written - `@com_google_protobuf//upb:reflection`. - -## Poison Java gencode - -We are patching a change into the 25.x branch that will poison Java gencode that -was created prior to the -[3.21.7 release](https://github.com/protocolbuffers/protobuf/releases/tag/v21.7). -We will then mark all versions of Java protobuf from 3.21.7 through 3.25.5 as -vulnerable to the -[footmitten CVE](https://github.com/protocolbuffers/protobuf/security/advisories/GHSA-h4h5-3hr4-j3g2). - -After this change is patched in, protobuf will throw an -`UnsupportedOperationException` from the -[`makeExtensionsImmutable`](https://protobuf.dev/reference/java/api-docs/com/google/protobuf/GeneratedMessage.html#makeExtensionsImmutable\(\)) -method unless you set the system property -"`-Dcom.google.protobuf.use_unsafe_pre22_gencode`". Using this system property -can buy you some time if you can't update your code immediately, but should be -considered a short-term workaround. diff --git a/content/news/v26.md b/content/news/v26.md deleted file mode 100644 index 8c5697218..000000000 --- a/content/news/v26.md +++ /dev/null @@ -1,257 +0,0 @@ -+++ -title = "News Announcements for Version 26.x" -linkTitle = "Version 26.x" -toc_hide = "true" -description = "Changes announced for Protocol Buffers version 26.x." -type = "docs" -+++ - -The following announcements are specific to Version 26.x, which was released -March 13, 2024. For information presented chronologically, see -[News](/news). - -## General Changes - -### JSON Formatter Option Changes {#JSON} - -Starting in the 26.x line, the JSON formatter option to print default-valued -fields is replaced with a fixed way to handle proto2 and proto3 `optional` -fields consistently. - -* Java: `includingDefaultValueFields()` is replaced with - `alwaysPrintFieldsWithNoPresence()`. -* C++: `always_print_default_values` is replaced with - `always_print_fields_with_no_presence=True`. -* Py: `including_default_value_fields=True` is replaced with - `always_print_fields_with_no_presence=True`. - -The new flag behaves identically to the old flag on proto3 messages, but no -longer applies to proto2 `optional` fields. The old flags applied to proto2 -`optional` fields but not proto3 `optional` fields. - -### Poison Pilling Gencode / Runtime Mismatches - -Per our -[Cross-Version Runtime Guarantees](/support/cross-version-runtime-guarantee), -Protobuf does not support mixing generated code and runtimes across major -version boundaries, or mixing generated code from a newer version of protoc with -older runtimes within a single major runtime version. We plan to introduce -“poison pills” to detect and enforce these disallowed mismatches. - -This is not considered a breaking change since this simply adds enforcement of -existing policies, but may require users to update their generated code. - -## C++ Breaking Changes - -In v26, we are planning a major version bump for C++ as per our -[breaking changes policy](/news/2022-07-06) and -[version support policy](/support/version-support#cpp-tooling). - -The following sections outline the set of breaking changes that we plan to -include in the 26.0 release of protocol buffers. Note that plans can and do -change. These are potential breaking changes to be aware of, but they may not -happen in this particular release, or they may not happen at all. - -### Remove deprecated clear APIs on repeated fields - -The following deprecated methods are removed: - -* `RepeatedPtrField::ReleaseCleared()` -* `RepeatedPtrField::ClearedCount()` -* `RepeatedPtrField::AddCleared()` - -### Remove C++ legacy syntax descriptor APIs - -With the release of [editions](/editions), syntax is no -longer supported for business logic. Instead, use the various feature helpers -defined in -[`descriptor.h`](/reference/cpp/api-docs/google.protobuf.descriptor) -to query more targeted behaviors, such as -[`has_presence`](/reference/cpp/api-docs/google.protobuf.descriptor#FieldDescriptor.has_presence.details), -to query features in C++. - -### Remove deprecated syntax accessor - -We plan to remove the deprecated syntax accessor, `FileDescriptor::Syntax`, in -v26. We recommend using the getters from `FileDescriptor::edition` instead. - -### Remove deprecated SupportsUnknownEnumValues method - -The `SupportsUnknownEnumValues` method was -[deprecated in March, 2023](https://github.com/protocolbuffers/protobuf/pull/12129). -We plan to remove it in v26. - -### Remove std::string error collector overrides - -We are planning to remove the deprecated `std::string` methods in error -collectors. - -## Java Breaking Changes - -In v26, we are planning a major version bump for Java per our -[breaking changes policy](/news/2022-07-06) and -[version support policy](/support/version-support#java). - -The following sections outline the set of breaking changes that we plan to -include in the 26.0 release of protocol buffers. Note that plans can and do -change. These are potential breaking changes to be aware of, but they may not -happen in this particular release, or they may not happen at all. - -### Breaking Compatibility with Old Generated Code - -v26.x will break compatibility with generated code from older major versions. -Users should regenerate old generated code to be from the same version. - -For example, `GeneratedMessageV3`, which was originally introduced for backwards -compatibility with generated code from v2.x.x against v3.x.x runtime, will be -renamed to `GeneratedMessage`. Runtimes will be updated to support -[Editions](/editions/overview/), which will not be -compatible with old generated code. - -This is in accordance with our existing -[Cross-Version Runtime Guarantees](/support/cross-version-runtime-guarantee) -and is a breaking change. - -### Removing Deprecated Methods/Variables - -v26.x will remove access to deprecated methods and variables. These will -generally have already been marked `@Deprecated` in a previous release. - -This will remove access to the following non-exhaustive list: - -* Descriptor syntax APIs, which should be replaced with corresponding feature - accessors (such as `FieldDescriptor.hasPresence()`, - `EnumDescriptor.isClosed()`) - -* TextFormat print methods, which should be replaced by corresponding - `TextFormat.printer()` methods. - -* PARSER variable, which should be replaced by the `parser()` method. - -* Runtime methods for old v2.x.x gencode compatibility. This is no longer - supported, as per our - [Cross Version Runtime Guarantees](/support/cross-version-runtime-guarantee). - -More details will be available in the corresponding release notes. - -## PHP Breaking Changes - -The following changes are planned for the 26.x line: - -* Validate UTF-8 for string fields in setters. -* Remove generic services. - ([commit 40ad3fa](https://github.com/protocolbuffers/protobuf/commit/40ad3fac603ba3c96e52a1266cd785a7adb8e3e4)) - -## Python Breaking Changes - -In v26, we are planning a major version bump for Python as per our -[breaking changes policy](/news/2022-07-06) and -[version support policy](/support/version-support#python-support). - -The following changes are planned for the 26.x line: - -* Make `str(msg)` escape any invalid UTF-8 in string fields. -* Make `text_format.MessageToString()` default to outputting raw UTF-8, while - escaping any invalid UTF-8 sequences. -* Fix timestamp bounds ([commit 1250d5f](https://github.com/protocolbuffers/protobuf/commit/1250d5f6cccb0a45f959c7219980a0aad5060ee5)) - -### Removing Deprecated APIs - -In the 26.x release, the following deprecated APIs will be removed: - -* [`AddFileDescriptor`](https://googleapis.dev/python/protobuf/latest/google/protobuf/descriptor_pool.html#google.protobuf.descriptor_pool.DescriptorPool.AddFileDescriptor) -* [`AddDescriptor`](https://googleapis.dev/python/protobuf/latest/google/protobuf/descriptor_pool.html#google.protobuf.descriptor_pool.DescriptorPool.AddDescriptor) -* [`AddEnumDescriptor`](https://googleapis.dev/python/protobuf/latest/google/protobuf/descriptor_pool.html#google.protobuf.descriptor_pool.DescriptorPool.AddEnumDescriptor) -* [`AddExtensionDescriptor`](https://googleapis.dev/python/protobuf/latest/google/protobuf/descriptor_pool.html#google.protobuf.descriptor_pool.DescriptorPool.AddExtensionDescriptor) -* [`AddServiceDescriptor`](https://googleapis.dev/python/protobuf/latest/google/protobuf/descriptor_pool.html#google.protobuf.descriptor_pool.DescriptorPool.AddServiceDescriptor) - -### Rejecting Extend Repeated Field with None Iterable - -Starting in the 26.x release, extending repeated fields with a `None` iterable -will be rejected (it will raise a `TypeError`). For example, -`m.repeated_int32.extend(None)` will be rejected. - -### Removing RegisterExtension in message class - -Starting in the 26.x release, -[`RegisterExtension`](https://googleapis.dev/python/protobuf/latest/google/protobuf/descriptor_pb2.html#google.protobuf.descriptor_pb2.DescriptorProto.ExtensionRange.RegisterExtension) -will be removed. You can access extensions in Python using the `Extensions` -property on message objects. - -This affects both pure Python and the C++ implementation of Python, but not upb -Python. - -### Removing `setup.py` and `setup.cfg` support from GitHub - -In the 26.x release, `setup.py` and `setup.cfg` will no longer be present in the -`python/` directory of -[the GitHub repository](https://github.com/protocolbuffers/protobuf/tree/main/python) -or GitHub -[release tarballs](https://github.com/protocolbuffers/protobuf/releases). This -means it will no longer be possible to build a Python package directly from the -GitHub repo or release tarball. - -The Python source packages published -[on PyPI](https://pypi.org/project/protobuf/#files) *will* continue to have a -`setup.py` in the top-level directory. This is the supported and recommended way -of building Python binary packages, for users who do not want to use the binary -packages that we distribute on PyPI. - -For more information, see -[#15671](https://github.com/protocolbuffers/protobuf/pull/15671). - -### Timestamps are checked for validity - -In v26, the system will check if `Timestamp` values are valid. Seconds must be -in the range [-62135596800, 253402300799] and nanos must be in range [0, -999999999]. Values outside those ranges will raise an exception. - -### Remove deprecated syntax accessor - -We plan to remove the deprecated syntax accessor, `FileDescriptor.syntax`, in -v26. We plan to add `FileDescriptor.edition` in its place. - -### UnknownFields support removal - -In v25 -[`message.UnknownFields()`](https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message.UnknownFields) -was deprecated in pure Python and C++ extensions. We plan to remove it v26. Use -the new -[`UnknownFieldSet(message)`](https://googleapis.dev/python/protobuf/latest/google/protobuf/unknown_fields.html) -support in `unknown_fields.py` as a replacement. - -More details about all of these changes will be available in the corresponding -release notes. - -## Ruby Breaking Changes - -* Fix `RepeatedField#each_index` to have the correct semantics. - ([#11767](https://github.com/protocolbuffers/protobuf/pull/11767)) -* Remove Ruby DSL and associated compatibility code, which will complete the - [migration announced in April](/news/2023-04-20). -* `Message#to_h` fixes: - * Remove unset oneof fields. - ([#6167](https://github.com/protocolbuffers/protobuf/issues/6167)) - * Remove unset sub-message fields -* Use message's pool for - [`encode_json`](https://github.com/protocolbuffers/protobuf/blob/2fb0b93d9de226ea96f2dc2b4779eb4712d01d5c/ruby/ext/google/protobuf_c/message.c#L1118)/[`decode_json`](https://github.com/protocolbuffers/protobuf/blob/2fb0b93d9de226ea96f2dc2b4779eb4712d01d5c/ruby/ext/google/protobuf_c/message.c#L1004). -* Remove the deprecated syntax accessor, `FileDescriptor.syntax` and add - semantic checks in its place: - * `FieldDescriptor.has_presence` to test if a field has presence. - * `FieldDescriptor.is_packed` to test if a repeated field is packed. - * `FieldDescriptor.requires_utf8_validation` to test if a string field - requires UTF-8 validation. - * `EnumDescriptor.is_closed` to test if an enum is closed. - -### Freeze Is Now Recursive in Ruby - -Starting in the 26.x line, when freeze is applied it will be applied -recursively, affecting all sub-messages, maps, and repeated fields. - -## upb Breaking Changes - -The following changes are planned for the 26.x line: - -* Fix - [nonconformance in JSON parsing](https://github.com/protocolbuffers/protobuf/blob/2f7b2832b6a62fec88efacbb97bf0a91b6a3670e/upb/conformance/conformance_upb_failures.txt) - when `IgnoreUnknownEnumString` is enabled. diff --git a/content/news/v29.md b/content/news/v29.md deleted file mode 100644 index a4bfe9bec..000000000 --- a/content/news/v29.md +++ /dev/null @@ -1,53 +0,0 @@ -+++ -title = "News Announcements for Version 29.x" -linkTitle = "Version 29.x" -toc_hide = "true" -description = "Changes announced for Protocol Buffers version 29.x." -type = "docs" -+++ - -The following announcements are specific to Version 29.x, which was released -November 27, 2024. For information presented chronologically, see -[News](/news). - -## Bazel and Proto Rules - -There are upcoming changes to the way that Bazel will work for protobuf builds. -These changes require awareness in the first stage, and action by project owners -before the second stage. - -### Stage 1 - -With the release of Bazel 8, proto rules (`proto_library`, `cc_proto_library`, -`java_proto_library`, `java_lite_proto_library`, and `py_proto_library`) will be -removed from the Bazel project. The will be added to the Protocol Buffers -project in v29. Bazel will be updated to automatically use the rules from the -protobuf project, so the change is initially a no-op for project owners. - -After the release of Bazel 8 and before the release of Bazel 9, users will need -to explicitly `load` the rules from the Protocol Buffers project repository. The -automatic use of the rules is only temporary to support the migration. - -Users should add the following `load()` statements to any `BUILD` or `.bzl` -files that use these proto rules. Note that these require Protobuf v29.0 or -higher. - -```bazel -load("@protobuf//bazel:proto_library.bzl", "proto_library") - -load("@protobuf//bazel:cc_proto_library.bzl", "cc_proto_library") -load("@protobuf//bazel:java_proto_library.bzl", "java_proto_library") -load("@protobuf//bazel:java_lite_proto_library.bzl", "java_lite_proto_library") -load("@protobuf//bazel:py_proto_library.bzl", "py_proto_library") -``` - -### Stage 2 - -When Bazel 9 is released, the automatic loading of the protobuf library’s rules -will be removed. At that point, you will need to have `load` statements in your -Bazel build files. - -### End Goal - -Once the rules are in the protobuf repo, we intend to address common user -requests, such as using prebuilts for the proto compiler where possible. diff --git a/content/news/v30.md b/content/news/v30.md deleted file mode 100644 index b3b0871f3..000000000 --- a/content/news/v30.md +++ /dev/null @@ -1,426 +0,0 @@ -+++ -title = "News Announcements for Version 30.x" -linkTitle = "Version 30.x" -toc_hide = "true" -description = "Changes announced for Protocol Buffers version 30.x." -type = "docs" -+++ - -The following announcements are specific to Version 30.x, which was released -March 4, 2025. For information presented chronologically, see -[News](/news). - -The following sections cover planned breaking changes in the v30 release, -expected in 2025 Q1. Also included are some changes that aren't breaking but may -require action on your part. These describe changes as we anticipate them being -implemented, but due to the flexible nature of software some of these changes -may not land or may vary from how they are described in this topic. - -## Changes in C++ {#cpp} - -C++ will bump its major version from 5.29.x to 6.30.x. - -### Descriptor APIs {#descriptor-apis} - -v30 will update return types in descriptor (such as `full_name`) to be -`absl::string_view`. This opens up memory savings in descriptors. - -v28 introduced the `PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE` macro, which you -can use in the meantime to enable the updated return type ahead of the breaking -release. The v30 release will flip the default and remove the macro. - -### ctype Removed from FieldDescriptor Options {#ctype-removed} - -v30 will stop exposing the `ctype` from `FieldDescriptor` options. You can use -the `FieldDescriptor::cpp_string_type()` API, added in the -[v28 release](https://github.com/protocolbuffers/protobuf/releases/tag/v28.0), -in its place. - -### Replace CMake Submodules with Fetched Deps {#replace-cmake-submods} - -v30 will remove submodules and switches to upb's old CMake pattern of fetching -dependencies. - -If you use installed packages, you won't be affected. It could break some CMake -workflows. - -### Modify Debug APIs to Redact Sensitive Fields {#debug-redaction} - -We are planning to modify the Protobuf debug APIs (including Protobuf -AbslStringify, `proto2::ShortFormat`, `proto2::Utf8Format`, -`Message::DebugString`, `Message::ShortDebugString`, `Message::Utf8DebugString`) -in v30 to redact sensitive fields annotated by `debug_redact`; the outputs of -these APIs will contain a per-process randomized prefix, and so will no longer -be parseable by Protobuf TextFormat Parsers. - -Read more about this in the -[news article released November 21, 2024](/news/2024-11-21). - -### Removing a Reflection-related Function {#removing-mutable-repeated} - -We are removing the following reflection-related function: -`MutableRepeatedFieldRef::Reserve()`. - -An upcoming performance improvement in -[`RepeatedPtrField`](/reference/cpp/api-docs/google.protobuf.repeated_field#RepeatedPtrField) -is incompatible with this API. The improvement is projected to accelerate -repeated access to the elements of `RepeatedPtrField`, in particular and -especially sequential access. - -### Remove Deprecated APIs {#remove-deprecated} - -v30 will remove the following public runtime APIs, which have been marked -deprecated (such as `ABSL_DEPRECATED`) for at least one minor or major release -and that are obsolete or replaced. - -#### Arena::CreateMessage - -**API:** -[`Arena::CreateMessage`](https://github.com/protocolbuffers/protobuf/blob/f4b57b98b08aec8bc52e6a7b762edb7a1b9e8883/src/google/protobuf/arena.h#L179) - -**Replacement:** -[`Arena::Create`](https://github.com/protocolbuffers/protobuf/blob/f4b57b98b08aec8bc52e6a7b762edb7a1b9e8883/src/google/protobuf/arena.h#L191) - -#### Arena::GetArena - -**API:** -[`Arena::GetArena`](https://github.com/protocolbuffers/protobuf/blob/237332ef92daf83a53e76decd6ac43c3fcee782b/src/google/protobuf/arena.h#L346) - -**Replacement:** `value->GetArena()` - -#### RepeatedPtrField::ClearedCount - -**API:** -[`RepeatedPtrField::ClearedCount`](https://github.com/protocolbuffers/protobuf/blame/f4b57b98b08aec8bc52e6a7b762edb7a1b9e8883/src/google/protobuf/repeated_ptr_field.h#L1157) - -**Replacement:** Migrate to Arenas -([migration guide](https://protobuf.dev/support/migration/#cleared-elements)). - -#### JsonOptions - -**API:** -[`JsonOptions`](https://github.com/protocolbuffers/protobuf/blob/f4b57b98b08aec8bc52e6a7b762edb7a1b9e8883/src/google/protobuf/util/json_util.h#L22) - -**Replacement:** `JsonPrintOptions` - -### Dropping C++14 Support {#drop-cpp-14} - -This release will drop C++ 14 as the minimum supported version and raise it to -17, as per the -[Foundational C++ Support matrix](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md). - -Per [our policies](https://protobuf.dev/support/version-support), we do not -consider this to be a breaking change. - -### Introduce ASAN Poisoning After Clearing Oneof Messages on Arena - -This change adds a hardening check that affects C++ protobufs using Arenas. -Oneof messages allocated on the protobuf arena will now be cleared in debug and -poisoned in ASAN mode. After calling clear, future attempts to use the memory -region will cause a crash in ASAN as a use-after-free error. - -This implementation requires C++17. - -### Dropping our C++ CocoaPods release - -In v30, we will be dropping our C++ CocoaPods release, which has been broken -since v4.x.x. C++ users should use our -[GitHub release](https://github.com/protocolbuffers/protobuf/releases) directly -instead. - -## Changes in JRuby {#jruby} - -v30 will flip the default implementation for JRuby to FFI, which may be breaking -for some JRuby users. - -Note that this change doesn't create a Ruby major version bump because JRuby is -[not officially supported](/support/version-support/#ruby). - -## Changes in Python {#python} - -Python will bump its major version from 5.29.x to 6.30.x. - -### Dropping Python 3.8 Support - -As per our official Python support policy, we will be dropping support for -Python 3.8 and lower. This means the minimum supported Python version is 3.9. - -### Remove bazel/system_python.bzl Alias {#python-remove-alias} - -v30 will remove the legacy `bazel/system_python.bzl` alias. - -Remove direct references to `system_python.bzl` in favor of using -`protobuf_deps.bzl` instead. Use `python/dist/system_python.bzl` where it was -moved -[in v5.27.0](https://github.com/protocolbuffers/protobuf/commit/d7f032ad1596ceeabd45ca1354516c39b97b2551) -if you need a direct reference. - -### Field Setter Validation Changes {#python-setter-validation} - -Python's and upb's field setters will be fixed in v30 to validate closed enums -under edition 2023. Closed enum fields updated with invalid values will generate -errors. - -### Remove Deprecated py_proto_library Macro - -The deprecated internal `py_proto_library` Bazel macro in `protobuf.bzl` will be -removed in v30.x. - -This should be replaced by the official `py_proto_library` which will be moved -to protobuf in `bazel/py_proto_library` as of v29.x. This implementation was -previously available in `rules_python` prior to v29.x. - -### Remove Deprecated APIs {#python-remove-apis} - -v30 will remove the following public runtime APIs, which have been marked -deprecated for at least one minor or major release and are obsolete or replaced. - -#### Reflection Methods - -**APIs:** -[`reflection.ParseMessage`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/reflection.py#L40), -[`reflection.MakeClass`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/reflection.py#L66) - -**Replacement:** `message_factory.GetMessageClass()` - -#### RPC Service Interfaces - -**APIs:** -[`service.RpcException`](https://github.com/protocolbuffers/protobuf/blob/21c545c8c5cec0b052dc7715b778f0353d37d02c/python/google/protobuf/service.py#L23), -[`service.Service`](https://github.com/protocolbuffers/protobuf/blob/21c545c8c5cec0b052dc7715b778f0353d37d02c/python/google/protobuf/service.py#L28), -[`service.RpcController`](https://github.com/protocolbuffers/protobuf/blob/21c545c8c5cec0b052dc7715b778f0353d37d02c/python/google/protobuf/service.py#L97), -and -[`service.RpcChannel`](https://github.com/protocolbuffers/protobuf/blob/21c545c8c5cec0b052dc7715b778f0353d37d02c/python/google/protobuf/service.py#L180) - -**Replacement:** Starting with version 2.3.0, RPC implementations should not try -to build on these, but should instead provide code generator plugins which -generate code specific to the particular RPC implementation. - -#### MessageFactory and SymbolDatabase Methods - -**APIs:** -[`MessageFactory.GetPrototype`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/message_factory.py#L145), -[`MessageFactory.CreatePrototype`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/message_factory.py#L165), -[`MessageFactory.GetMessages`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/message_factory.py#L185), -[`SymbolDatabase.GetPrototype`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/symbol_database.py#L54), -[`SymbolDatabase.CreatePrototype`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/symbol_database.py#L60), -and -[`SymbolDatabase.GetMessages`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/symbol_database.py#L66) - -**Replacement:** `message_factory.GetMessageClass()` and -`message_factory.GetMessageClassesForFiles()`. - -#### GetDebugString - -**APIs:** -[`GetDebugString`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/pyext/descriptor.cc#L1510) - -**Replacement:** - -No replacement. It's only in Python C++ which is no longer released. It is not -supported in pure Python or UPB. - -### Python setdefault Behavior Change for Map Fields - -Starting in v30, `setdefault` will be similar to `dict` for `ScalarMap`, except -that both key and value must be set. `setdefault` will be rejected for -`MessageMaps`. - -## Python Nested Message Class \_\_qualname\_\_ Contains the Outer Message Name - -Python nested message class `__qualname__` now contains the outer message name. -Prior to v30, `__qualname__` has the same result with `__name__` for nested -message, in that the outer message name was not included. - -For example: - -```python -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 -``` - -## Changes in Objective-C {#objc} - -**This will be the first breaking release for Objective-C**. - -Objective-C will bump its major version from 3.x.x to 4.30.x. - -### Overhaul Unknown Field Handling APIs Deprecating Most of the Existing APIs {#objc-field-handling} - -v30 will deprecate `GPBUnknownFieldSet` and replace it with `GPBUnknownFields`. -The new type will preserve the ordering of unknown fields from the original -input or API calls, to ensure any semantic meaning to the ordering is maintained -when a message is written back out. - -As part of this, the `GPBUnknownField` type also has its APIs changed, with -almost all of the existing APIs becoming deprecated and new ones added. - -Deprecated property APIs: - -* `varintList` -* `fixed32List` -* `fixed64List` -* `lengthDelimitedList` -* `groupList` - -Deprecated modification APIs: - -* `addVarint:` -* `addFixed32:` -* `addFixed64:` -* `addLengthDelimited:` -* `addGroup:` - -Deprecated initializer `initWithNumber:`. - -New property APIs: - -* `type` -* `varint` -* `fixed32` -* `fixed64` -* `lengthDelimited` -* `group` - -This type will model a single field number in its value, rather than *grouping* -all the values for a given field number. The APIs for creating new fields are -the `add*` APIs on the `GPBUnknownFields` class. - -v30 will also deprecate `-[GPBMessage unknownFields]`. In its place, there will -be new APIs to extract and update the unknown fields of the message. - -### Remove Deprecated APIs {#objc-remove-apis} - -v30 will remove the following public runtime APIs, which have been marked -deprecated for at least one minor or major release and are obsolete or replaced. - -#### GPBFileDescriptor - -**API:** -[-[`GPBFileDescriptor` syntax]](https://github.com/protocolbuffers/protobuf/blob/44bd65b2d3c0470d91a23cc14df5ffb1ab0af7cd/objectivec/GPBDescriptor.h#L118-L119) - -**Replacement:** Obsolete. - -#### GPBMessage mergeFrom:extensionRegistry - -**API:** -[-[`GPBMessage mergeFrom:extensionRegistry:`]](https://github.com/protocolbuffers/protobuf/blob/44bd65b2d3c0470d91a23cc14df5ffb1ab0af7cd/objectivec/GPBMessage.h#L258-L261) - -**Replacement:** -[-[`GPBMessage mergeFrom:extensionRegistry:error:`]](https://github.com/protocolbuffers/protobuf/blob/44bd65b2d3c0470d91a23cc14df5ffb1ab0af7cd/objectivec/GPBMessage.h#L275-L277) - -#### GPBDuration timeIntervalSince1970 - -**API:** -[-[`GPBDuration timeIntervalSince1970`]](https://github.com/protocolbuffers/protobuf/blob/29fca8a64b62491fb0a2ce61878e70eda88dde98/objectivec/GPBWellKnownTypes.h#L95-L100) - -**Replacement:** -[-[`GPBDuration timeInterval`]](https://github.com/protocolbuffers/protobuf/blob/29fca8a64b62491fb0a2ce61878e70eda88dde98/objectivec/GPBWellKnownTypes.h#L74-L89) - -#### GPBTextFormatForUnknownFieldSet - -**API:** -[`GPBTextFormatForUnknownFieldSet()`](https://github.com/protocolbuffers/protobuf/blob/29fca8a64b62491fb0a2ce61878e70eda88dde98/objectivec/GPBUtilities.h#L32-L43) - -**Replacement:** Obsolete - Use -[`GPBTextFormatForMessage()`](https://github.com/protocolbuffers/protobuf/blob/29fca8a64b62491fb0a2ce61878e70eda88dde98/objectivec/GPBUtilities.h#L20-L30), -which includes any unknown fields. - -#### GPBUnknownFieldSet - -**API:** -[`GPBUnknownFieldSet`](https://github.com/protocolbuffers/protobuf/blob/224573d66a0cc958c76cb43d8b2eb3aa7cdb89f2/objectivec/GPBUnknownFieldSet.h) - -**Replacement:** -[`GPBUnknownFields`](https://github.com/protocolbuffers/protobuf/blob/224573d66a0cc958c76cb43d8b2eb3aa7cdb89f2/objectivec/GPBUnknownFields.h) - -#### GPBMessage unknownFields - -**API:** -[`GPBMessage unknownFields` property](https://github.com/protocolbuffers/protobuf/blob/224573d66a0cc958c76cb43d8b2eb3aa7cdb89f2/objectivec/GPBMessage.h#L73-L76) - -**Replacement:** -[-[`GPBUnknownFields initFromMessage:`]](https://github.com/protocolbuffers/protobuf/blob/224573d66a0cc958c76cb43d8b2eb3aa7cdb89f2/objectivec/GPBUnknownFields.h#L30-L38), -[-[`GPBMessage mergeUnknownFields:extensionRegistry:error:`]](https://github.com/protocolbuffers/protobuf/blob/f26bdff7cc0bb7e8ed88253ba16f81614a26cf16/objectivec/GPBMessage.h#L506-L528), -and -[-[`GPBMessage clearUnknownFields`]](https://github.com/protocolbuffers/protobuf/blob/224573d66a0cc958c76cb43d8b2eb3aa7cdb89f2/objectivec/GPBMessage.h#L497-L504C9) - -### Remove Deprecated Runtime APIs for Old Gencode {#objc-remove-apis-gencode} - -This release will remove deprecated runtime methods that support the Objective-C -gencode from before the 3.22.x release. The library will also issue a log -message at runtime when old generated code is starting up. - -**API:** [`+[GPBFileDescriptor -allocDescriptorForClass:file:fields:fieldCount:storageSize:flags:]`](https://github.com/protocolbuffers/protobuf/blob/1b44ce0feef45a78ba99d09bd2e5ff5052a6541b/objectivec/GPBDescriptor_PackagePrivate.h#L213-L220) - -**Replacement:** Regenerate with a current version of the library. - -**API:** [`+[GPBFileDescriptor -allocDescriptorForClass:rootClass:file:fields:fieldCount:storageSize:flags:]`](https://github.com/protocolbuffers/protobuf/blob/1b44ce0feef45a78ba99d09bd2e5ff5052a6541b/objectivec/GPBDescriptor_PackagePrivate.h#L221-L229) - -**Replacement:** Regenerate with a current version of the library. - -**API:** [`+[GPBEnumDescriptor -allocDescriptorForName:valueNames:values:count:enumVerifier:]`](https://github.com/protocolbuffers/protobuf/blob/1b44ce0feef45a78ba99d09bd2e5ff5052a6541b/objectivec/GPBDescriptor_PackagePrivate.h#L285-L291) - -**Replacement:** Regenerate with a current version of the library. - -**API:** [`+[GPBEnumDescriptor -allocDescriptorForName:valueNames:values:count:enumVerifier:extraTextFormatInfo:]`](https://github.com/protocolbuffers/protobuf/blob/1b44ce0feef45a78ba99d09bd2e5ff5052a6541b/objectivec/GPBDescriptor_PackagePrivate.h#L292-L299) - -**Replacement:** Regenerate with a current version of the library. - -**API:** -[`-[GPBExtensionDescriptor initWithExtensionDescription:]`](https://github.com/protocolbuffers/protobuf/blob/1b44ce0feef45a78ba99d09bd2e5ff5052a6541b/objectivec/GPBDescriptor_PackagePrivate.h#L317-L320) - -**Replacement:** Regenerate with a current version of the library. - -## Other Changes {#other} - -### Poison MSVC + Bazel - -We will be dropping support for using Bazel and MSVC together in v34. As of v30, -we will poison this combination with an error unless you specify the opt-out -flag `--define=protobuf_allow_msvc=true` to silence it. - -MSVC's path length limits combined with Bazel's sandboxing have become -increasingly difficult to support in combination. Rather than randomly break -users who install protobuf into a long path, we will prohibit the use of MSVC -from Bazel altogether. We will continue to support MSVC with CMake, and begin -supporting [clang-cl](https://clang.llvm.org/docs/UsersManual.html#clang-cl) -with Bazel. For any feedback or discussion, see -https://github.com/protocolbuffers/protobuf/issues/20085. - -## Other Changes (Non-Breaking) {#non-breaking} - -In addition to those breaking changes are some other changes worth noting. While -the following are not considered breaking changes, they may still impact users. - -### Poison Pill Warnings {#poison} - -v30 will update poison pills to emit warnings for old gencode + new runtime -combinations that work under the new rolling upgrade policy, but will break in -the *next* major bump. For example, Java 4.x.x gencode should work against 5.x.x -runtime but warn of upcoming breakage against 6.x.x runtime. - -### Changes to UTF-8 Enforcement in C# and Ruby {#utf-8-enforcement} - -v30 will includes a fix to make UTF-8 enforcement consistent across languages. -Users with bad non-UTF8 data in string fields may see surfaced UTF-8 enforcement -errors earlier. - -### Ruby and PHP Errors in JSON Parsing - -v30 fixes non-conformance in JSON parsing of strings in numeric fields per the -[JSON spec](https://protobuf.dev/programming-guides/json/). - -This fix will not be accompanied by a major version bump, but Ruby and PHP will -now raise errors for non-numeric strings (e.g. "", "12abc", "abc") in numeric -fields. v29.x will include a warning for these error cases. diff --git a/content/news/v31.md b/content/news/v31.md deleted file mode 100644 index 781ffbb88..000000000 --- a/content/news/v31.md +++ /dev/null @@ -1,99 +0,0 @@ -+++ -title = "News Announcements for Version 31.x" -linkTitle = "Version 31.x" -toc_hide = "true" -description = "Changes announced for Protocol Buffers version 31.x." -type = "docs" -+++ - -The following announcements are specific to Version 31.x, which was released May -14, 2025. For information presented chronologically, see -[News](/news). - -The following sections cover planned breaking changes in the v31 release, -expected in 2025 Q2. Also included are some changes that aren't breaking but may -require action on your part. These describe changes as we anticipate them being -implemented, but due to the flexible nature of software some of these changes -may not land or may vary from how they are described in this topic. - -## Dropping Ruby 3.0 Support - -As per our official -[Ruby support policy](https://cloud.google.com/ruby/getting-started/supported-ruby-versions), -we will be dropping support for Ruby 3.0. The minimum supported Ruby version -will be 3.1. - -## Deprecating Label Enums - -We are announcing an upcoming change regarding the `FieldDescriptor.label` enum -and its associated values: `FieldDescriptor.LABEL_OPTIONAL`, -`FieldDescriptor.LABEL_REQUIRED`, and `FieldDescriptor.LABEL_REPEATED`. These -are being deprecated as we encourage the use of more precise accessor methods. - -### Background - -While at one time the `FieldDescriptor.label` enum served a purpose, the -evolution of Protocol Buffers has introduced more explicit ways to determine a -field's cardinality (singular/repeated) and presence semantics. - -* In proto2, `optional`, `required`, and `repeated` are explicit keywords. -* In proto3, `required` is no longer supported. All scalar fields are - implicitly "`optional`" in the sense that they have default values if not - set. The `optional` keyword was later reintroduced in proto3 to explicitly - track presence for scalar fields (distinguishing between an unset field and - a field set to its default value). -* In edition 2023 we removed the `optional` and `required` keywords and use - features to control those behaviors. - -The `label` enum conflates these distinct concepts (cardinality, requiredness, -and explicit presence tracking), leading to potential confusion, especially with -proto3's field presence model. - -### Impact and Migration - -The `FieldDescriptor.label` field will eventually be removed from the API to -maintain backward compatibility. Note that the method names in this topic may be -spelled slightly differently in some languages. - -* **For Protocol Buffer Editions fields:** - * **Behavior:** The `getLabel` method will be simplified: - * It will return `FieldDescriptor.LABEL_OPTIONAL` for all singular - fields. - * It will return `FieldDescriptor.LABEL_REPEATED` for all repeated - fields. - * **Key Methods for Editions:** - * `hasOptionalKeyword` will always return `false` (as the optional - keyword's role in presence is superseded by feature-based presence - in Editions). - * `hasPresence` becomes the primary method to determine if a singular - field tracks presence, reflecting the - [`features.field_presence`](/editions/features#field_presence) - setting for that field. - * **Migration:** Rely on `isRepeated` for cardinality and `hasPresence` to - check for explicit presence tracking in singular fields. -* **For proto3 fields:** `getLabel` will eventually be removed, and is not - recommended in the meantime. Update your code to use `hasOptionalKeyword` - and `getRealContainingOneof` instead. -* **For proto2 fields:** `getLabel` will continue to reflect `LABEL_OPTIONAL`, - `LABEL_REQUIRED`, or `LABEL_REPEATED` as defined in the .proto file for the - time being. - -All users of Protocol Buffers who interact with `FieldDescriptor` objects in -their code (for example for code generation, reflection, and dynamic message -handling) should migrate away from using `FieldDescriptor.label` directly. - -Instead, update your code to use the following methods: - -* To check if a field is repeated: `field.isRepeated` -* To check if a field is required (proto2 and editions only): - `field.isRequired` -* To check if a singular proto3 field has explicit presence, use `hasPresence` -* To check if a singular field has explicit presence via a oneof, use - `hasPresence` - -### Timeline - -This deprecation is effective immediately. While `getLabel` will continue to -function, we recommend migrating your code proactively to ensure future -compatibility and clarity. This change will lead to a more robust and -understandable experience for developers using Protocol Buffers. diff --git a/content/news/v32.md b/content/news/v32.md deleted file mode 100644 index d78dbe2a6..000000000 --- a/content/news/v32.md +++ /dev/null @@ -1,215 +0,0 @@ -+++ -title = "News Announcements for Version 32.x" -linkTitle = "Version 32.x" -toc_hide = "true" -description = "Changes announced for Protocol Buffers version 32.x." -type = "docs" -+++ - -## Changes to Existing Features - -This section details any existing features whose default settings will change in -Edition 2024. - -### C++ string_type {#string_type} - -The default for `string_type` feature, originally released in Edition 2023, will -change from `STRING` to `VIEW` in Edition 2024. - -See -[`features.(pb.cpp).string_type`](/editions/features#string_type) -and [String View APIs](/reference/cpp/string-view) for -more information on this feature and its feature values. - -## New Features {#new-features} - -This section details any new features that will be introduced in Edition 2024. - -### `enforce_naming_style` {#enforce_naming} - -[`feature.enforce_naming_style`](/editions/features#enforce_naming) -enables strict naming style enforcement to ensure protos are round-trippable by -default with a feature value to opt-out to use legacy naming style. - -### `default_symbol_visibility` {#default_symbol} - -This feature controls whether the default symbol visibility of importable -symbols (such as messages and enums) is either: - -* `export`: referenceable from other protos via import statements -* `local`: un-referenceable outside of current file - -The default feature value `EXPORT_TOP_LEVEL` in Edition 2024 ensures top-level -symbols are export by default, whereas nested symbols are local by default. - -This can be used along with the [`export` and `local` keywords](#export-local) -to explicitly annotate symbol visibility, also added in Edition 2024. - -Symbol visibility only controls which symbols can be imported from other proto -files, but does not affect code-generation. - -### C++: `enum_name_uses_string_view` {#enum_name} - -Previously, all generated enum types provide the following function to obtain -the label out of an enum value, which has significant overhead to construct the -`std::string` instances at runtime: - -```cpp -const std::string& Foo_Name(int); -``` - -The default feature value in Edition 2024 instead migrates this signature to -return `absl::string_view` to allow for better storage decoupling and potential -memory/CPU savings. - -```cpp -absl::string_view Foo_Name(int); -``` - -Users should migrate their code to handle the new return-type following -[the migration guide](/support/migration#string_view-return-type). - -See [String View APIs](/reference/cpp/string-view) for -more information. - -### Java: `nest_in_file_class` {#nest_in} - -This feature controls whether the Java generator will nest the generated class -in the Java generated file class. - -The default value in Edition 2024 generates classes in their own files by -default, which is also the default behavior of the previous -`java_multiple_files = true` file option. This replaces `java_multiple_files` -which is removed in Edition 2024. - -The default outer classname is also updated to always be the camel-cased -`.proto` filename suffixed with Proto by default (for example, -`foo/bar_baz.proto -> BarBazProto`). You can override this using the -`java_outer_classname` file option and replace the pre-Edition 2024 default of -`BarBaz` or `BarBazOuterClass` depending on the presence of conflicts. - -### Java: `large_enum` {#large_enum} - -This feature allows creation of large Java enums, extending beyond the enum -limit due to standard constant limits imposed by the Java language. - -Creation of large enums is not enabled by default, but you can explicitly enable -it using this feature. Note that this feature replicates enum-like behavior but -has some notable differences (for example, switch statements are not supported). - -## Grammar Changes {#grammar-changes} - -### `import option` {#import-option} - -Edition 2024 adds support for option imports using the syntax `import option`. - -Unlike normal `import` statements, `import option` only imports custom options -defined in a `.proto` file, without importing other symbols. - -This means that messages and enums are excluded from the option import. In the -following example, the `Bar` message cannot be used as a field type in -`foo.proto`, but options with type `Bar` can still be set. - -Option imports must also come after any other import statements. - -Example: - -```proto -// bar.proto -edition = "2024"; - -import "google/protobuf/descriptor.proto"; - -message Bar { - bool bar = 1; -} - -extend proto2.FileOptions { - bool file_opt1 = 5000; - Bar file_opt2 = 5001; -} -``` - -```proto -// foo.proto: -edition = "2024"; - -import option "bar.proto"; - -option (file_opt1) = true; -option (file_opt2) = {bar: true}; - -message Foo { - // Bar bar = 1; // This is not allowed -} -``` - -Option imports do not require generated code for its symbols and thus must be -provided as `option_deps` in `proto_library` instead of `deps`. This avoids -generating unreachable code. - -```build -proto_library( - name = "foo", - srcs = ["foo.proto"], - option_deps = [":custom_option"] -) -``` - -Option imports and `option_deps` are strongly recommended when importing -protobuf language features and other custom options to avoid generating -unnecessary code. - -`option_deps` requires Bazel 8 or later since the `native.proto_library` in -Bazel 7 does not support this. - -This also replaces `import weak`, which is removed in Edition 2024. - -### `export` / `local` Keywords {#export-local} - -`export` and `local` keywords are added in Edition 2024 as modifiers for the -symbol visibility of importable symbols, from the default behavior specified by -the -[`default_symbol_visibility` feature](/editions/features#symbol-vis). - -This controls which symbols can be imported from other proto files, but does not -affect code-generation. - -In Edition 2024, these can be set on all message and enum symbols by default. -However, some values of the `default_symbol_visibility` feature further restrict -which symbols are exportable. - -Example: - -```proto -// Top-level symbols are exported by default in Edition 2024 -local message LocalMessage { - // Nested symbols are local by default in Edition 2024 - export enum ExportedNestedEnum { - UNKNOWN_EXPORTED_NESTED_ENUM_VALUE = 0; - } -} -``` - -### "import weak" and `weak` Field Option {#import-weak} - -Weak imports are no longer allowed as of Edition 2024. - -Most users previously relying on `import weak` to declare a “weak dependency” to -import custom options without generated code for C++ and Go should instead -migrate to use -[`import option`](/editions/overview#import-option) -instead. - -### `ctype` Field Option {#ctype} - -`ctype` field option is no longer allowed as of Edition 2024. Use the -[`features.(pb.cpp).string_type`](/editions/features#string_type) -feature, instead. - -### `java_multiple_files` File Option {#java_multiple} - -The `java_multiple_files` file option is removed in Edition 2024 in favor of the -new -[`features.nest_in_file_class`](/editions/features#java-nest_in_file) -Java feature. diff --git a/content/news/v34.md b/content/news/v34.md deleted file mode 100644 index 1d9d4d05f..000000000 --- a/content/news/v34.md +++ /dev/null @@ -1,18 +0,0 @@ -+++ -title = "News Announcements for Version 34.x" -linkTitle = "Version 34.x" -toc_hide = "true" -description = "Changes announced for Protocol Buffers version 34.x." -type = "docs" -+++ - -The following news topics provide information about changes in the 34.x release. - -* [March 13, 2026](/news/2026-03-13) - Breaking changes - in Bazel for the upcoming 34.x release -* [January 16, 2026](/news/2026-01-16) - Prebuilt proto - compiler (protoc) for Bazel -* [September 19, 2025](/news/2025-09-19) - Breaking - changes in the upcoming 34.x release -* [July 16, 2025](/news/2025-07-16) - Resuming support - for Bazel with MSVC diff --git a/content/overview.md b/content/overview.md deleted file mode 100644 index 32db7c42c..000000000 --- a/content/overview.md +++ /dev/null @@ -1,305 +0,0 @@ -+++ -title = "Overview" -weight = 10 -description = "Protocol Buffers are a language-neutral, platform-neutral extensible mechanism for serializing structured data." -type = "docs" -+++ - -It’s like JSON, except it's -smaller and faster, and it generates native language bindings. You define how -you want your data to be structured once, then you can use special generated -source code to easily write and read your structured data to and from a variety -of data streams and using a variety of languages. - -Protocol buffers are a combination of the definition language (created in -`.proto` files), the code that the proto compiler generates to interface with -data, language-specific runtime libraries, the serialization format for data -that is written to a file (or sent across a network connection), and the -serialized data. - -## What Problems do Protocol Buffers Solve? {#solve} - -Protocol buffers provide a serialization format for packets of typed, structured -data that are up to a few megabytes in size. The format is suitable for both -ephemeral network traffic and long-term data storage. Protocol buffers can be -extended with new information without invalidating existing data or requiring -code to be updated. - -Protocol buffers are the most commonly-used data format at Google. They are used -extensively in inter-server communications as well as for archival storage of -data on disk. Protocol buffer *messages* and *services* are described by -engineer-authored `.proto` files. The following shows an example `message`: - -```proto -edition = "2023"; - -message Person { - string name = 1; - int32 id = 2; - string email = 3; -} -``` - -The proto compiler is invoked at build time on `.proto` files to generate code -in various programming languages (covered in -[Cross-language Compatibility](#cross-lang) later in this topic) to manipulate -the corresponding protocol buffer. Each generated class contains simple -accessors for each field and methods to serialize and parse the whole structure -to and from raw bytes. The following shows you an example that uses those -generated methods: - -```java -Person john = Person.newBuilder() - .setId(1234) - .setName("John Doe") - .setEmail("jdoe@example.com") - .build(); -output = new FileOutputStream(args[0]); -john.writeTo(output); -``` - -Because protocol buffers are used extensively across all manner of services at -Google and data within them may persist for some time, maintaining backwards -compatibility is crucial. Protocol buffers allow for the seamless support of -changes, including the addition of new fields and the deletion of existing -fields, to any protocol buffer without breaking existing services. For more on -this topic, see -[Updating Proto Definitions Without Updating Code](#updating-defs), later in -this topic. - -## What are the Benefits of Using Protocol Buffers? {#benefits} - -Protocol buffers are ideal for any situation in which you need to serialize -structured, record-like, typed data in a language-neutral, platform-neutral, -extensible manner. They are most often used for defining communications -protocols (together with gRPC) and for data storage. - -Some of the advantages of using protocol buffers include: - -* Compact data storage -* Fast parsing -* Availability in many programming languages -* Optimized functionality through automatically-generated classes - -### Cross-language Compatibility {#cross-lang} - -The same messages can be read by code written in any supported programming -language. You can have a Java program on one platform capture data from one -software system, serialize it based on a `.proto` definition, and then extract -specific values from that serialized data in a separate Python application -running on another platform. - -The following languages are supported directly in the protocol buffers compiler, -protoc: - -* [C++](/reference/cpp/cpp-generated#invocation) -* [C#](/reference/csharp/csharp-generated#invocation) -* [Java](/reference/java/java-generated#invocation) -* [Kotlin](/reference/kotlin/kotlin-generated#invocation) -* [Objective-C](/reference/objective-c/objective-c-generated#invocation) -* [PHP](/reference/php/php-generated#invocation) -* [Python](/reference/python/python-generated#invocation) -* [Ruby](/reference/ruby/ruby-generated#invocation) - -The following languages are supported by Google, but the projects' source code -resides in GitHub repositories. The protoc compiler uses plugins for these -languages: - -* [Dart](https://github.com/google/protobuf.dart) -* [Go](https://github.com/protocolbuffers/protobuf-go) - -Additional languages are not directly supported by Google, but rather by other -GitHub projects. These languages are covered in -[Third-Party Add-ons for Protocol Buffers](https://github.com/protocolbuffers/protobuf/blob/master/docs/third_party.md). - -### Cross-project Support {#cross-proj} - -You can use protocol buffers across projects by defining `message` types in -`.proto` files that reside outside of a specific project’s code base. If you're -defining `message` types or enums that you anticipate will be widely used -outside of your immediate team, you can put them in their own file with no -dependencies. - -A couple of examples of proto definitions widely-used within Google are -[`timestamp.proto`](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/timestamp.proto) -and -[`status.proto`](https://github.com/googleapis/googleapis/blob/master/google/rpc/status.proto). - -### Updating Proto Definitions Without Updating Code {#updating-defs} - -It's standard for software products to be backward compatible, but it is less -common for them to be forward compatible. As long as you follow some -[simple practices](/programming-guides/proto3#updating) -when updating `.proto` definitions, old code will read new messages without -issues, ignoring any newly added fields. To the old code, fields that were -deleted will have their default value, and deleted repeated fields will be -empty. For information on what “repeated” fields are, see -[Protocol Buffers Definition Syntax](#syntax) later in this topic. - -New code will also transparently read old messages. New fields will not be -present in old messages; in these cases protocol buffers provide a reasonable -default value. - -### When are Protocol Buffers not a Good Fit? {#not-good-fit} - -Protocol buffers do not fit all data. In particular: - -* Protocol buffers tend to assume that entire messages can be loaded into - memory at once and are not larger than an object graph. For data that - exceeds a few megabytes, consider a different solution; when working with - larger data, you may effectively end up with several copies of the data due - to serialized copies, which can cause surprising spikes in memory usage. -* When protocol buffers are serialized, the same data can have many different - binary serializations. You cannot compare two messages for equality without - fully parsing them. -* Messages are not compressed. While messages can be zipped or gzipped like - any other file, special-purpose compression algorithms like the ones used by - JPEG and PNG will produce much smaller files for data of the appropriate - type. -* Protocol buffer messages are less than maximally efficient in both size and - speed for many scientific and engineering uses that involve large, - multi-dimensional arrays of floating point numbers. For these applications, - [FITS](https://en.wikipedia.org/wiki/FITS) and similar formats have less - overhead. -* Protocol buffers are not well supported in non-object-oriented languages - popular in scientific computing, such as Fortran and IDL. -* Protocol buffer messages don't inherently self-describe their data, but they - have a fully reflective schema that you can use to implement - self-description. That is, you cannot fully interpret one without access to - its corresponding `.proto` file. -* Protocol buffers are not a formal standard of any organization. This makes - them unsuitable for use in environments with legal or other requirements to - build on top of standards. - -## Who Uses Protocol Buffers? {#who-uses} - -Many projects use protocol buffers, including the following: - -+ [gRPC](https://grpc.io) -+ [Google Cloud](https://cloud.google.com) -+ [Envoy Proxy](https://www.envoyproxy.io) - -## How do Protocol Buffers Work? {#work} - -The following diagram shows how you use protocol buffers to work with your data. - -![Compilation workflow showing the creation of a proto file, generated code, and compiled classes](/images/protocol-buffers-concepts.png) \ -**Figure 1. Protocol buffers workflow** - -The code generated by protocol buffers provides utility methods to retrieve data -from files and streams, extract individual values from the data, check if data -exists, serialize data back to a file or stream, and other useful functions. - -The following code samples show you an example of this flow in Java. As shown -earlier, this is a `.proto` definition: - -```proto -message Person { - string name = 1; - int32 id = 2; - string email = 3; -} -``` - -Compiling this `.proto` file creates a `Builder` class that you can use to -create new instances, as in the following Java code: - -```java -Person john = Person.newBuilder() - .setId(1234) - .setName("John Doe") - .setEmail("jdoe@example.com") - .build(); -output = new FileOutputStream(args[0]); -john.writeTo(output); -``` - -You can then deserialize data using the methods protocol buffers creates in -other languages, like C++: - -```cpp -Person john; -fstream input(argv[1], ios::in | ios::binary); -john.ParseFromIstream(&input); -int id = john.id(); -std::string name = john.name(); -std::string email = john.email(); -``` - -## Protocol Buffers Definition Syntax {#syntax} - -When defining `.proto` files, you can specify cardinality (singular or -repeated). In proto2 and proto3, you can also specify if the field is optional. -In proto3, setting a field to optional -[changes it from implicit presence to explicit presence](/programming-guides/field_presence). - -After setting the cardinality of a field, you specify the data type. Protocol -buffers support the usual primitive data types, such as integers, booleans, and -floats. For the full list, see -[Scalar Value Types](/programming-guides/proto3#scalar). - -A field can also be of: - -* A `message` type, so that you can nest parts of the definition, such as for - repeating sets of data. -* An `enum` type, so you can specify a set of values to choose from. -* A `oneof` type, which you can use when a message has many optional fields - and at most one field will be set at the same time. -* A `map` type, to add key-value pairs to your definition. - -Messages can allow **extensions** to define fields outside of the message, -itself. For example, the protobuf library's internal message schema allows -extensions for custom, usage-specific options. - -For more information about the options available, see the language guide for -[proto2](/programming-guides/proto2), -[proto3](/programming-guides/proto3), or -[edition 2023](/programming-guides/editions). - -After setting cardinality and data type, you choose a name for the field. There -are some things to keep in mind when setting field names: - -* It can sometimes be difficult, or even impossible, to change field names - after they've been used in production. -* Field names cannot contain dashes. For more on field name syntax, see - [Message and Field Names](/programming-guides/style#message-field-names). -* Use pluralized names for repeated fields. - -After assigning a name to the field, you assign a field number. Field -numbers cannot be repurposed or reused. If you delete a field, you should -reserve its field number to prevent someone from accidentally reusing the -number. - -## Additional Data Type Support {#data-types} - -Protocol buffers support many scalar value types, including integers that use -both variable-length encoding and fixed sizes. You can also create your own -composite data types by defining messages that are, themselves, data types that -you can assign to a field. In addition to the simple and composite value types, -several [common types](/best-practices/dos-donts#common) -are published. - -## History {#history} - -To read about the history of the protocol buffers project, see -[History of Protocol Buffers](/history). - -## Protocol Buffers Open Source Philosophy {#philosophy} - -Protocol buffers were open sourced in 2008 as a way to provide developers -outside of Google with the same benefits that we derive from them internally. We -support the open source community through regular updates to the language as we -make those changes to support our internal requirements. While we accept select -pull requests from external developers, we cannot always prioritize feature -requests and bug fixes that don’t conform to Google’s specific needs. - -## Developer Community {#community} - -To be alerted to upcoming changes in Protocol Buffers and to connect with -protobuf developers and users, -[join the Google Group](https://groups.google.com/g/protobuf). - -## Additional Resources {#additional-resources} - -* [Protocol Buffers GitHub](https://github.com/protocolbuffers/protobuf/) - * [Tutorials](https://protobuf.dev/getting-started/) diff --git a/content/programming-guides/_index.md b/content/programming-guides/_index.md deleted file mode 100644 index 38f09fd4e..000000000 --- a/content/programming-guides/_index.md +++ /dev/null @@ -1,6 +0,0 @@ -+++ -title = "Programming Guides" -weight = 27 -description = "Learn how to use Protocol Buffers in your projects." -type = "docs" -+++ diff --git a/content/programming-guides/addons.md b/content/programming-guides/addons.md deleted file mode 100644 index 6213e5454..000000000 --- a/content/programming-guides/addons.md +++ /dev/null @@ -1,11 +0,0 @@ -+++ -title = "Third-Party Add-ons" -weight = 80 -linkTitle = "Add-ons" -description = "Links out to many open source projects that seek to add useful functionality on top of Protocol Buffers." -type = "docs" -+++ - -Many open source projects seek to add useful functionality on top of Protocol -Buffers. For a list of links to projects we know about, see the -[third-party add-ons wiki page](https://github.com/protocolbuffers/protobuf/blob/master/docs/third_party.md). diff --git a/content/programming-guides/deserialize-debug.md b/content/programming-guides/deserialize-debug.md deleted file mode 100644 index 6e4a75949..000000000 --- a/content/programming-guides/deserialize-debug.md +++ /dev/null @@ -1,120 +0,0 @@ -+++ -title = "Deserializing Debug Proto Representations" -weight = 89 -description = "How to log debugging information in Protocol Buffers." -type = "docs" -+++ - -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 -"[REDACTED]" (without the quotation marks). In -addition, to ensure that this new output format cannot be deserialized by -Protobuf TextFormat parsers, regardless of whether the underlying proto contains -SPII fields, we add a set of randomized links pointing to this article -and a randomized-length whitespace sequence. The new debugging format looks as -follows: - -```none -goo.gle/debugstr -spii_field: [REDACTED] -normal_field: "value" -``` - -Note that the new debugging format is only different from the output format of -DebugString format in two ways: - -* The URL prefix -* The values of SPII fields are replaced by - "[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. -**If you don't see certain fields in the output, it is because those fields are -not set in the proto.** - -**Tip:** If you see only the URL and nothing else, your proto is empty! - -## Why is this URL here? - -We want to make sure nobody deserializes human-readable representations of a -protobuf message intended for humans debugging a system. Historically, -`.DebugString()` and `TextFormat` were interchangeable, and existing systems use -DebugString to transport and store data. - -We want to make sure sensitive data does not accidentally end up in logs. -Therefore, we are transparently redacting some field values from protobuf -messages before turning them into a string -("[REDACTED]"). This reduces the security & privacy -risk of accidental logging, but risks data loss if other systems deserialize -your message. To address this risk, we are intentionally splitting the -machine-readable TextFormat from the human-readable debug format to be used in -log messages. - -### Why are there links in my web page? Why is my code producing this new "debug representation"? - -This is intentional, to make the "debug representation" of your protos -(produced, for example, by logging) incompatible with TextFormat. We want to -prevent anyone from depending on debugging mechanisms to transport data between -programs. Historically, the debug format (generated by the DebugString APIs) and -TextFormat have been incorrectly used in a interchangeable fashion. We hope this -intentional effort will prevent that going forward. - -We intentionally picked a link over less visible format changes to get an -opportunity to provide context. This might stand out in UIs, such as if you -display status information on a table in a webpage. You may use -`TextFormat::PrintToString` instead, which will not redact any information and -preserves formatting. However, use this API cautiously -- there are no built in -protections. As a rule of thumb, if you are writing data to debug logs, or -producing status messages, you should continue to use the Debug Format with the -link. Even if you are currently not handling sensitive data, keep in mind that -systems can change and code gets re-used. - -### I tried converting this message into TextFormat, but I noticed the format changes every time my process restarts. - -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 should be -using a TextFormat API rather than using the debug representation of a proto. - -## FAQ - -### Can I Just Use TextFormat Everywhere? - -Don't use TextFormat for producing log messages. This will bypass all built-in -protections, and you risk accidentally logging sensitive information. Even if -your systems are currently not handling any sensitive data, this can change in -the future. - -Distinguish logs from information that's meant for further processing by other -systems by using either the debug representation or TextFormat as appropriate. - -### I Want to Write Configuration Files That Need to Be Both Human-Readable And Machine-Readable - -For this use case, you can use TextFormat explicitly. You are responsible for -making sure your configuration files don't contain any PII. - -### I Am Writing a Unit Test, and Want to Compare Debugstring in a Test Assertion - -If you want to compare protobuf values, use `MessageDifferencer` like in the -following: - -```cpp -using google::protobuf::util::MessageDifferencer; -... -MessageDifferencer diff; -... -diff.Compare(foo, bar); -``` - -Besides ignoring formatting and field order differences, you will also get -better error messages. diff --git a/content/programming-guides/editions.md b/content/programming-guides/editions.md deleted file mode 100644 index d2b0436a3..000000000 --- a/content/programming-guides/editions.md +++ /dev/null @@ -1,2165 +0,0 @@ -+++ -title = "Language Guide (editions)" -weight = 40 -description = "Covers how to use the editions revisions of the Protocol Buffers language in your project." -type = "docs" -+++ - -This guide describes how to use the protocol buffer language to structure your -protocol buffer data, including `.proto` file syntax and how to generate data -access classes from your `.proto` files. It covers **edition 2023** to **edition -2024** of the protocol buffers language. For information about how editions -differ from proto2 and proto3 conceptually, see -[Protobuf Editions Overview](/editions/overview). - -For information on the **proto2** syntax, see the -[Proto2 Language Guide](/programming-guides/proto2). - -For information on **proto3** syntax, see the -[Proto3 Language Guide](/programming-guides/proto3). - -This is a reference guide – for a step by step example that uses many of the -features described in this document, see the -[tutorial](/getting-started) -for your chosen language. - -## Defining A Message Type {#simple} - -First let's look at a very simple example. Let's say you want to define a search -request message format, where each search request has a query string, the -particular page of results you are interested in, and a number of results per -page. Here's the `.proto` file you use to define the message type. - -```proto -edition = "2023"; - -message SearchRequest { - string query = 1; - int32 page_number = 2; - int32 results_per_page = 3; -} -``` - -* The first line of the file specifies that you're using edition 2023 of the - protobuf language spec. - - * The `edition` (or `syntax` for proto2/proto3) must be the first - non-empty, non-comment line of the file. - * If no `edition` or `syntax` is specified, the protocol buffer compiler - will assume you are using - [proto2](/programming-guides/proto2). - -* The `SearchRequest` message definition specifies three fields (name/value - pairs), one for each piece of data that you want to include in this type of - message. Each field has a name and a type. - -### Specifying Field Types {#specifying-types} - -In the earlier example, all the fields are [scalar types](#scalar): two integers -(`page_number` and `results_per_page`) and a string (`query`). You can also -specify [enumerations](#enum) and composite types like other message types for -your field. - -### Assigning Field Numbers {#assigning} - -You must give each field in your message definition a number between `1` and -`536,870,911` with the following restrictions: - -- The given number **must be unique** among all fields for that message. -- Field numbers `19,000` to `19,999` are reserved for the Protocol Buffers - implementation. The protocol buffer compiler will complain if you use one of - these reserved field numbers in your message. -- You cannot use any previously [reserved](#fieldreserved) field numbers or - any field numbers that have been allocated to [extensions](#extensions). - -This number **cannot be changed once your message type is in use** because it -identifies the field in the -[message wire format](/programming-guides/encoding). -"Changing" a field number is equivalent to deleting that field and creating a -new field with the same type but a new number. See [Deleting Fields](#deleting) -for how to do this properly. - -Field numbers **should never be reused**. Never take a field number out of the -[reserved](#fieldreserved) list for reuse with a new field definition. See -[Consequences of Reusing Field Numbers](#consequences). - -You should use the field numbers 1 through 15 for the most-frequently-set -fields. Lower field number values take less space in the wire format. For -example, field numbers in the range 1 through 15 take one byte to encode. Field -numbers in the range 16 through 2047 take two bytes. You can find out more about -this in -[Protocol Buffer Encoding](/programming-guides/encoding#structure). - -#### Consequences of Reusing Field Numbers {#consequences} - -Reusing a field number makes decoding wire-format messages ambiguous. - -The protobuf wire format is lean and doesn't provide a way to detect fields -encoded using one definition and decoded using another. - -Encoding a field using one definition and then decoding that same field with a -different definition can lead to: - -- Developer time lost to debugging -- A parse/merge error (best case scenario) -- Leaked PII/SPII -- Data corruption - -Common causes of field number reuse: - -- renumbering fields (sometimes done to achieve a more aesthetically pleasing - number order for fields). Renumbering effectively deletes and re-adds all - the fields involved in the renumbering, resulting in incompatible - wire-format changes. -- deleting a field and not [reserving](#fieldreserved) the number to prevent - future reuse. - - - This has been a very easy mistake to make with - [extension fields](#extensions) for several reasons. - [Extension Declarations](/programming-guides/extension_declarations) - provide a mechanism for reserving extension fields. - -The field number is limited to 29 bits rather than 32 bits because three bits -are used to specify the field's wire format. For more on this, see the -[Encoding topic](/programming-guides/encoding#structure). - - - -### Specifying Field Cardinality {#field-labels} - -Message fields can be one of the following: - -* *Singular*: - - A singular field has no explicit cardinality label. It has two possible - states: - - * the field is set, and contains a value that was explicitly set or parsed - from the wire. It will be serialized to the wire. - * the field is unset, and will return the default value. It will not be - serialized to the wire. - - You can check to see if the value was explicitly set. - - Proto3 *implicit* fields that have been migrated to editions will use the - `field_presence` feature set to the `IMPLICIT` value. - - Proto2 `required` fields that have been migrated to editions will also use - the `field_presence` feature, but set to `LEGACY_REQUIRED`. - -* `repeated`: this field type can be repeated zero or more times in a - well-formed message. The order of the repeated values will be preserved. - -* `map`: this is a paired key/value field type. See - [Maps](/programming-guides/encoding#maps) for more on - this field type. - -#### Repeated Fields are Packed by Default {#use-packed} - -In proto editions, `repeated` fields of scalar numeric types use `packed` -encoding by default. - -You can find out more about `packed` encoding in -[Protocol Buffer Encoding](/programming-guides/encoding#packed). - -#### Well-formed Messages {#well-formed} - -The term "well-formed," when applied to protobuf messages, refers to the bytes -serialized/deserialized. The protoc parser validates that a given proto -definition file is parseable. - -Singular fields can appear more than once in wire-format bytes. The parser will -accept the input, but only the last instance of that field will be accessible -through the generated bindings. See -[Last One Wins](/programming-guides/encoding#last-one-wins) -for more on this topic. - -### Adding More Message Types {#adding-types} - -Multiple message types can be defined in a single `.proto` file. This is useful -if you are defining multiple related messages – so, for example, if you wanted -to define the reply message format that corresponds to your `SearchResponse` -message type, you could add it to the same `.proto`: - -```proto -message SearchRequest { - string query = 1; - int32 page_number = 2; - int32 results_per_page = 3; -} - -message SearchResponse { - ... -} -``` - -**Combining Messages leads to bloat** While multiple message types (such as -message, enum, and service) can be defined in a single `.proto` file, it can -also lead to dependency bloat when large numbers of messages with varying -dependencies are defined in a single file. It's recommended to include as few -message types per `.proto` file as possible. - -### Adding Comments {#adding-comments} - -To add comments to your `.proto` files: - -* Prefer C/C++/Java line-end-style comments '//' on the line before the .proto - code element -* C-style inline/multi-line comments `/* ... */` are also accepted. - - * When using multi-line comments, a margin line of '*' is preferred. - -```proto -/** - * SearchRequest represents a search query, with pagination options to - * indicate which results to include in the response. - */ -message SearchRequest { - string query = 1; - - // Which page number do we want? - int32 page_number = 2; - - // Number of results to return per page. - int32 results_per_page = 3; -} -``` - -### Deleting Fields {#deleting} - -Deleting fields can cause serious problems if not done properly. - -When you no longer need a field and all references have been deleted from client -code, you may delete the field definition from the message. However, you -**must** [reserve the deleted field number](#fieldreserved). If you do not -reserve the field number, it is possible for a developer to reuse that number in -the future. - -You should also reserve the field name to allow JSON and TextFormat encodings of -your message to continue to parse. - - - -#### Reserved Field Numbers {#reserved-field-numbers} - -If you [update](#updating) a message type by entirely deleting a field, or -commenting it out, future developers can reuse the field number when making -their own updates to the type. This can cause severe issues, as described in -[Consequences of Reusing Field Numbers](#consequences). To make sure this -doesn't happen, add your deleted field number to the `reserved` list. - -The protoc compiler will generate error messages if any future developers try to -use these reserved field numbers. - -```proto -message Foo { - reserved 2, 15, 9 to 11; -} -``` - -Reserved field number ranges are inclusive (`9 to 11` is the same as `9, 10, -11`). - -#### Reserved Field Names {#reserved-field-names} - -Reusing an old field name later is generally safe, except when using TextProto -or JSON encodings where the field name is serialized. To avoid this risk, you -can add the deleted field name to the `reserved` list. - -Reserved names affect only the protoc compiler behavior and not runtime -behavior, with one exception: TextProto implementations may discard unknown -fields (without raising an error like with other unknown fields) with reserved -names at parse time (only the C++ and Go implementations do so today). Runtime -JSON parsing is not affected by reserved names. - -```proto -message Foo { - reserved 2, 15, 9 to 11; - reserved foo, bar; -} -``` - -Note that you can't mix field names and field numbers in the same `reserved` -statement. - -### What's Generated from Your `.proto`? {#generated} - -When you run the [protocol buffer compiler](#generating) on a `.proto`, the -compiler generates the code in your chosen language you'll need to work with the -message types you've described in the file, including getting and setting field -values, serializing your messages to an output stream, and parsing your messages -from an input stream. - -* For **C++**, the compiler generates a `.h` and `.cc` file from each - `.proto`, with a class for each message type described in your file. -* For **Java**, the compiler generates a `.java` file with a class for each - message type, as well as a special `Builder` class for creating message - class instances. -* For **Kotlin**, in addition to the Java generated code, the compiler - generates a `.kt` file for each message type with an improved Kotlin API. - This includes a DSL that simplifies creating message instances, a nullable - field accessor, and a copy function. -* **Python** is a little different — the Python compiler generates a module - with a static descriptor of each message type in your `.proto`, which is - then used with a *metaclass* to create the necessary Python data access - class at runtime. -* For **Go**, the compiler generates a `.pb.go` file with a type for each - message type in your file. -* For **Ruby**, the compiler generates a `.rb` file with a Ruby module - containing your message types. -* For **Objective-C**, the compiler generates a `pbobjc.h` and `pbobjc.m` file - from each `.proto`, with a class for each message type described in your - file. -* For **C#**, the compiler generates a `.cs` file from each `.proto`, with a - class for each message type described in your file. -* For **PHP**, the compiler generates a `.php` message file for each message - type described in your file, and a `.php` metadata file for each `.proto` - file you compile. The metadata file is used to load the valid message types - into the descriptor pool. -* For **Dart**, the compiler generates a `.pb.dart` file with a class for each - message type in your file. - -You can find out more about using the APIs for each language by following the -tutorial for your chosen language. For even more API -details, see the relevant [API reference](/reference/). - -## Scalar Value Types {#scalar} - -A scalar message field can have one of the following types – the table shows the -type specified in the `.proto` file, and the corresponding type in the -automatically generated class: - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Proto TypeNotes
double
float
int32Uses variable-length encoding. Inefficient for encoding negative - numbers – if your field is likely to have negative values, use sint32 - instead.
int64Uses variable-length encoding. Inefficient for encoding negative - numbers – if your field is likely to have negative values, use sint64 - instead.
uint32Uses variable-length encoding.
uint64Uses variable-length encoding.
sint32Uses variable-length encoding. Signed int value. These more - efficiently encode negative numbers than regular int32s.
sint64Uses variable-length encoding. Signed int value. These more - efficiently encode negative numbers than regular int64s.
fixed32Always four bytes. More efficient than uint32 if values are often - greater than 228.
fixed64Always eight bytes. More efficient than uint64 if values are often - greater than 256.
sfixed32Always four bytes.
sfixed64Always eight bytes.
bool
stringA string must always contain UTF-8 encoded or 7-bit ASCII text, and cannot - be longer than 232.
bytesMay contain any arbitrary sequence of bytes no longer than 232.
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Proto TypeC++ TypeJava/Kotlin Type[1]Python Type[3]Go TypeRuby TypeC# TypePHP TypeDart TypeRust Type
doubledoubledoublefloatfloat64Floatdoublefloatdoublef64
floatfloatfloatfloatfloat32Floatfloatfloatdoublef32
int32int32_tintintint32Fixnum or Bignum (as required)intintegerinti32
int64int64_tlongint/long[4]int64Bignumlonginteger/string[6]Int64i64
uint32uint32_tint[2]int/long[4]uint32Fixnum or Bignum (as required)uintintegerintu32
uint64uint64_tlong[2]int/long[4]uint64Bignumulonginteger/string[6]Int64u64
sint32int32_tintintint32Fixnum or Bignum (as required)intintegerinti32
sint64int64_tlongint/long[4]int64Bignumlonginteger/string[6]Int64i64
fixed32uint32_tint[2]int/long[4]uint32Fixnum or Bignum (as required)uintintegerintu32
fixed64uint64_tlong[2]int/long[4]uint64Bignumulonginteger/string[6]Int64u64
sfixed32int32_tintintint32Fixnum or Bignum (as required)intintegerinti32
sfixed64int64_tlongint/long[4]int64Bignumlonginteger/string[6]Int64i64
boolboolbooleanboolboolTrueClass/FalseClassboolbooleanboolbool
stringstringStringstr/unicode[5]stringString (UTF-8)stringstringStringProtoString
bytesstringByteStringstr (Python 2), bytes (Python 3)[]byteString (ASCII-8BIT)ByteStringstringListProtoBytes
-
- -[1] Kotlin uses the corresponding types from Java, even for unsigned -types, to ensure compatibility in mixed Java/Kotlin codebases. - -[2] In Java, unsigned 32-bit and 64-bit integers are represented -using their signed counterparts, with the top bit simply being stored in the -sign bit. - -[3] In all cases, setting values to a field will perform type -checking to make sure it is valid. - -[4] 64-bit or unsigned 32-bit integers are always represented as long -when decoded, but can be an int if an int is given when setting the field. In -all cases, the value must fit in the type represented when set. See [2]. - -[5] Python strings are represented as unicode on decode but can be -str if an ASCII string is given (this is subject to change). - -[6] Integer is used on 64-bit machines and string is used on 32-bit -machines. - -You can find out more about how these types are encoded when you serialize your -message in -[Protocol Buffer Encoding](/programming-guides/encoding). - -## Default Field Values {#default} - -When a message is parsed, if the encoded message bytes do not contain a -particular field, accessing that field in the parsed object returns the default -value for that field. The default values are type-specific: - -* For strings, the default value is the empty string. -* For bytes, the default value is empty bytes. -* For bools, the default value is false. -* For numeric types, the default value is zero. -* For message fields, the field is not set. Its exact value is - language-dependent. See the - [generated code guide](/reference/) for details. -* For enums, the default value is the **first defined enum value**, which must - be 0. See [Enum Default Value](#enum-default). - -The default value for repeated fields is empty (generally an empty list in the -appropriate language). - -The default value for map fields is empty (generally an empty map in the -appropriate language). - -### Overriding Default Scalar Values {#explicit-default} - -In protobuf editions, you can specify explicit default values for singular -non-message fields. For example, let's say you want to provide a default value -of 10 for the `SearchRequest.result_per_page` field: - -```proto -int32 result_per_page = 3 [default = 10]; -``` - -If the sender does not specify `result_per_page`, the receiver will observe the -following state: - -* The result_per_page field is not present. That is, the - `has_result_per_page()` (hazzer method) method would return `false`. -* The value of `result_per_page` (returned from the "getter") is `10`. - -If the sender does send a value for `result_per_page` the default value of 10 is -ignored and the sender's value is returned from the "getter". - -See the [generated code guide](/reference/) for your -chosen language for more details about how defaults work in generated code. - -Explicit default values cannot be specified for fields that have the -`field_presence` feature set to `IMPLICIT`. - -## Enumerations {#enum} - -When you're defining a message type, you might want one of its fields to only -have one of a predefined list of values. For example, let's say you want to add -a `corpus` field for each `SearchRequest`, where the corpus can be `UNIVERSAL`, -`WEB`, `IMAGES`, `LOCAL`, `NEWS`, `PRODUCTS` or `VIDEO`. You can do this very -simply by adding an `enum` to your message definition with a constant for each -possible value. - -In the following example we've added an `enum` called `Corpus` with all the -possible values, and a field of type `Corpus`: - -```proto -enum Corpus { - CORPUS_UNSPECIFIED = 0; - CORPUS_UNIVERSAL = 1; - CORPUS_WEB = 2; - CORPUS_IMAGES = 3; - CORPUS_LOCAL = 4; - CORPUS_NEWS = 5; - CORPUS_PRODUCTS = 6; - CORPUS_VIDEO = 7; -} - -message SearchRequest { - string query = 1; - int32 page_number = 2; - int32 results_per_page = 3; - Corpus corpus = 4; -} -``` - -### Enum Default Value {#enum-default} - -The default value for the `SearchRequest.corpus` field is `CORPUS_UNSPECIFIED` -because that is the first value defined in the enum. - -In edition 2023, the first value defined in an enum definition **must** have the -value zero and should have the name `ENUM_TYPE_NAME_UNSPECIFIED` or -`ENUM_TYPE_NAME_UNKNOWN`. This is because: - -* The zero value needs to be the first element for compatibility with - [proto2](/programming-guides/proto2#enum-default) - semantics, where the first enum value is the default unless a different - value is explicitly specified. -* There must be a zero value for compatibility with - [proto3](/programming-guides/proto3#enum-default) - semantics, where the zero value is used as the default value for all - implicit-presence fields using this enum type. - -It is also recommended that this first, default value have no semantic meaning -other than "this value was unspecified". - -The default value for an enum field like `SearchRequest.corpus` field can be -explicitly overridden like this: - -``` - Corpus corpus = 4 [default = CORPUS_UNIVERSAL]; -``` - -If an enum type has been migrated from proto2 using `option features.enum_type = -CLOSED;` there is no restriction on the first value in the enum. It is not -recommended to change the first value of these types of enums because it will -change the default value for any fields using that enum type without an explicit -field default. - -### Enum Value Aliases {#enum-aliases} - -You can define aliases by assigning the same value to different enum constants. -To do this you need to set the `allow_alias` option to `true`. Otherwise, the -protocol buffer compiler generates a warning message when aliases are -found. Though all alias values are valid for serialization, only the first value -is used when deserializing. - -```proto -enum EnumAllowingAlias { - option allow_alias = true; - EAA_UNSPECIFIED = 0; - EAA_STARTED = 1; - EAA_RUNNING = 1; - EAA_FINISHED = 2; -} - -enum EnumNotAllowingAlias { - ENAA_UNSPECIFIED = 0; - ENAA_STARTED = 1; - // ENAA_RUNNING = 1; // Uncommenting this line will cause a warning message. - ENAA_FINISHED = 2; -} -``` - -### Enum Constants {#enum-constants} - -Enumerator constants must be in the range of a 32-bit integer. Since `enum` -values use -[varint encoding](/programming-guides/encoding) on the -wire, negative values are inefficient and thus not recommended. You can define -`enum`s within a message definition, as in the earlier example, or outside – -these `enum`s can be reused in any message definition in your `.proto` file. You -can also use an `enum` type declared in one message as the type of a field in a -different message, using the syntax `_MessageType_._EnumType_`. - -### Language-specific Enum Implementations {#enum-language} - -When you run the protocol buffer compiler on a `.proto` that uses an `enum`, the -generated code will have a corresponding `enum` for Java, Kotlin, or C++, or a -special `EnumDescriptor` class for Python that's used to create a set of -symbolic constants with integer values in the runtime-generated class. - -{{% alert title="Important" color="warning" %}} The -generated code may be subject to language-specific limitations on the number of -enumerators (low thousands for one language). Review the -limitations for the languages you plan to use. -{{% /alert %}} - -During deserialization, unrecognized enum values will be preserved in the -message, though how this is represented when the message is deserialized is -language-dependent. In languages that support open enum types with values -outside the range of specified symbols, such as C++ and Go, the unknown enum -value is simply stored as its underlying integer representation. In languages -with closed enum types such as Java, a case in the enum is used to represent an -unrecognized value, and the underlying integer can be accessed with special -accessors. In either case, if the message is serialized the unrecognized value -will still be serialized with the message. - -{{% alert title="Important" color="warning" %}} For -information on how enums should work contrasted with how they currently work in -different languages, see -[Enum Behavior](/programming-guides/enum). -{{% /alert %}} - -For more information about how to work with message `enum`s in your -applications, see the [generated code guide](/reference/) -for your chosen language. - -### Reserved Values {#reserved} - -If you [update](#updating) an enum type by entirely removing an enum entry, or -commenting it out, future users can reuse the numeric value when making their -own updates to the type. This can cause severe issues if they later load old -instances of the same `.proto`, including data corruption, privacy bugs, and so -on. One way to make sure this doesn't happen is to specify that the numeric -values (and/or names, which can also cause issues for JSON serialization) of -your deleted entries are `reserved`. The protocol buffer compiler will complain -if any future users try to use these identifiers. You can specify that your -reserved numeric value range goes up to the maximum possible value using the -`max` keyword. - -```proto -enum Foo { - reserved 2, 15, 9 to 11, 40 to max; - reserved FOO, BAR; -} -``` - -Note that you can't mix field names and numeric values in the same `reserved` -statement. - -## Using Other Message Types {#other} - -You can use other message types as field types. For example, let's say you -wanted to include `Result` messages in each `SearchResponse` message – to do -this, you can define a `Result` message type in the same `.proto` and then -specify a field of type `Result` in `SearchResponse`: - -```proto -message SearchResponse { - repeated Result results = 1; -} - -message Result { - string url = 1; - string title = 2; - repeated string snippets = 3; -} -``` - -### Importing Definitions {#importing} - -In the earlier example, the `Result` message type is defined in the same file as -`SearchResponse` – what if the message type you want to use as a field type is -already defined in another `.proto` file? - -You can use definitions from other `.proto` files by *importing* them. To import -another `.proto`'s definitions, you add an import statement to the top of your -file: - -```proto -import "myproject/other_protos.proto"; -``` - -As of Edition 2024, you can also use `import option` to use -[custom option definitions](#customoptions) from other `.proto` files. Unlike -regular imports, this only allows use of custom options definitions but not -other message or enum definitions to avoid dependencies in the generated code. - -```proto -import option "myproject/other_protos.proto"; -``` - -By default, you can use definitions only from directly imported `.proto` files. -However, sometimes you may need to move a `.proto` file to a new location. -Instead of moving the `.proto` file directly and updating all the call sites in -a single change, you can put a placeholder `.proto` file in the old location to -forward all the imports to the new location using the `import public` notion. - -**Note that the public import functionality is not available in Java, Kotlin, -TypeScript, JavaScript, or GCL.** - -`import public` dependencies can be transitively relied upon by any code -importing the proto containing the `import public` statement. For example: - -```proto -// new.proto -// All definitions are moved here -``` - -```proto -// old.proto -// This is the proto that all clients are importing. -import public "new.proto"; -import "other.proto"; -``` - -```proto -// client.proto -import "old.proto"; -// You use definitions from old.proto and new.proto, but not other.proto -``` - -The protocol compiler searches for imported files in a set of directories -specified on the protocol compiler command line using the `-I`/`--proto_path` -flag. If no flag was given, it looks in the directory in which the compiler was -invoked. In general you should set the `--proto_path` flag to the root of your -project and use fully qualified names for all imports. - -### Symbol Visibility {#proto2} - -Visibility of what symbols are available or unavailable when imported by other -protos is controlled by the -[`features.default_symbol_visibility`](/editions/features#symbol-vis) -feature and the -[`export` and `local` keywords](/editions/overview#export-local) -which were added in Edition 2024. - -Only symbols that are exported, either via the default symbol visibility or with -an `export` keyword, can be referenced by the importing file. - -### Using proto2 and proto3 Message Types {#proto2} - -It's possible to import -[proto2](/programming-guides/proto2) and -[proto3](/programming-guides/proto3) message types and -use them in your editions messages, and vice versa. - -## Nested Types {#nested} - -You can define and use message types inside other message types, as in the -following example – here the `Result` message is defined inside the -`SearchResponse` message: - -```proto -message SearchResponse { - message Result { - string url = 1; - string title = 2; - repeated string snippets = 3; - } - repeated Result results = 1; -} -``` - -If you want to reuse this message type outside its parent message type, you -refer to it as `_Parent_._Type_`: - -```proto -message SomeOtherMessage { - SearchResponse.Result result = 1; -} -``` - -You can nest messages as deeply as you like. In the example below, note that the -two nested types named `Inner` are entirely independent, since they are defined -within different messages: - -```proto -message Outer { // Level 0 - message MiddleAA { // Level 1 - message Inner { // Level 2 - int64 ival = 1; - bool booly = 2; - } - } - message MiddleBB { // Level 1 - message Inner { // Level 2 - int32 ival = 1; - bool booly = 2; - } - } -} -``` - -## Updating A Message Type {#updating} - -If an existing message type no longer meets all your needs – for example, you'd -like the message format to have an extra field – but you'd still like to use -code created with the old format, don't worry! It's very simple to update -message types without breaking any of your existing code when you use the binary -wire format. - -{{% alert title="Note" color="note" %}} If -you use ProtoJSON or -[proto text format](/reference/protobuf/textformat-spec) -to store your protocol buffer messages, the changes that you can make in your -proto definition are different. The ProtoJSON wire format safe changes are -described -[here](/programming-guides/json#json-wire-safety). -{{% /alert %}} - -Check -[Proto Best Practices](/best-practices/dos-donts) and the -following rules: - -### Binary Wire-unsafe Changes {#wire-unsafe-changes} - -Wire-unsafe changes are schema changes that will break if you use parse data -that was serialized using the old schema with a parser that is using the new -schema (or vice versa). Only make wire-unsafe changes if you know that all -serializers and deserializers of the data are using the new schema. - -* Changing field numbers for any existing field is not safe. - * Changing the field number is equivalent to deleting the field and adding - a new field with the same type. If you want to renumber a field, see the - instructions for [deleting a field](#deleting). -* Moving fields into an existing `oneof` is not safe. - -### Binary Wire-safe Changes {#wire-safe-changes} - -Wire-safe changes are ones where it is fully safe to evolve the schema in this -way without risk of data loss or new parse failures. - -Note that any wire-safe changes may be a breaking change to application code in -a given language. For example, adding a value to a preexisting enum would be a -compilation break for any code with an exhaustive switch on that enum. For that -reason, Google may avoid making some of these types of changes on public -messages: the AIPs contain guidance for which of these changes are safe to make -there. - -* Adding new fields is safe. - * If you add new fields, any messages serialized by code using your "old" - message format can still be parsed by your new generated code. You - should keep in mind the [default values](#default) for these elements so - that new code can properly interact with messages generated by old code. - Similarly, messages created by your new code can be parsed by your old - code: old binaries simply ignore the new field when parsing. See the - [Unknown Fields](#unknowns) section for details. -* Removing fields is safe. - * The same field number must not used again in your updated message type. - You may want to rename the field instead, perhaps adding the prefix - "OBSOLETE_", or make the field number [reserved](#fieldreserved), so - that future users of your `.proto` can't accidentally reuse the number. -* Adding additional values to an enum is safe. -* Changing a single explicit presence field or extension into a member of a - **new** `oneof` is safe. -* Changing a `oneof` which contains only one field to an explicit presence - field is safe. -* Changing a field into an extension of same number and type is safe. - -### Binary Wire-compatible Changes (Conditionally Safe) {#conditionally-safe-changes} - -Unlike Wire-safe changes, wire-compatible means that the same data can be parsed -both before and after a given change. However, a parse of the data may be lossy -under this shape of change. For example, changing an int32 to an int64 is a -compatible change, but if a value larger than INT32_MAX is written, a client -that reads it as an int32 will discard the high order bits of the number. - -You can make compatible changes to your schema only if you manage the roll out -to your system carefully. For example, you may change an int32 to an int64 but -ensure you continue to only write legal int32 values until the new schema is -deployed to all endpoints, and then subsequently start writing larger values -after that. - -If your schema is published outside of your organization, you should generally -not make wire-compatible changes, as you cannot manage the deployment of the new -schema to know when the different range of values may be safe to use. - -* `int32`, `uint32`, `int64`, `uint64`, and `bool` are all compatible. - * If a number is parsed from the wire which doesn't fit in the - corresponding type, you will get the same effect as if you had cast the - number to that type in C++ (for example, if a 64-bit number is read as - an int32, it will be truncated to 32 bits). -* `sint32` and `sint64` are compatible with each other but are *not* - compatible with the other integer types. - * If the value written was between INT_MIN and INT_MAX inclusive it will - parse as the same value with either type. If an sint64 value was written - outside of that range and parsed as an sint32, the varint is truncated - to 32 bits and then zigzag decoding occurs (which will cause a different - value to be observed). -* `string` and `bytes` are compatible as long as the bytes are valid UTF-8. -* Embedded messages are compatible with `bytes` if the bytes contain an - encoded instance of the message. -* `fixed32` is compatible with `sfixed32`, and `fixed64` with `sfixed64`. -* For `string`, `bytes`, and message fields, singular is compatible with - `repeated`. - * Given serialized data of a repeated field as input, clients that expect - this field to be singular will take the last input value if it's a - primitive type field or merge all input elements if it's a message type - field. Note that this is **not** generally safe for numeric types, - including bools and enums. Repeated fields of numeric types are - serialized in the - [packed](/programming-guides/encoding#packed) - format by default, which will not be parsed correctly when a singular - field is expected. -* `enum` is compatible with `int32`, `uint32`, `int64`, and `uint64` - * Be aware that client code may treat them differently when the message is - deserialized: for example, unrecognized proto3 `enum` values will be - preserved in the message, but how this is represented when the message - is deserialized is language-dependent. -* Changing a field between a `map` and the corresponding `repeated` - message field is binary compatible (see [Maps](#maps), below, for the - message layout and other restrictions). - * However, the safety of the change is application-dependent: when - deserializing and reserializing a message, clients using the `repeated` - field definition will produce a semantically identical result; however, - clients using the `map` field definition may reorder entries and drop - entries with duplicate keys. - -## Unknown Fields {#unknowns} - -Unknown fields are well-formed protocol buffer serialized data representing -fields that the parser does not recognize. For example, when an old binary -parses data sent by a new binary with new fields, those new fields become -unknown fields in the old binary. - -Editions messages preserve unknown fields and include them during parsing and in -the serialized output, which matches proto2 and proto3 behavior. - -### Retaining Unknown Fields {#retaining} - -Some actions can cause unknown fields to be lost. For example, if you do one of -the following, unknown fields are lost: - -* Serialize a proto to JSON. -* Iterate over all of the fields in a message to populate a new message. - -To avoid losing unknown fields, do the following: - -* Use binary; avoid using text formats for data exchange. -* Use message-oriented APIs, such as `CopyFrom()` and `MergeFrom()`, to copy data - rather than copying field-by-field - -TextFormat is a bit of a special case. Serializing to TextFormat prints unknown -fields using their field numbers. But parsing TextFormat data back into a binary -proto fails if there are entries that use field numbers. - -## Extensions {#extensions} - -An extension is a field defined outside of its container message; usually in a -`.proto` file separate from the container message's `.proto` file. - -### Why Use Extensions? {#why-ext} - -There are two main reasons to use extensions: - -* The container message's `.proto` file will have fewer imports/dependencies. - This can improve build times, break circular dependencies, and otherwise - promote loose coupling. Extensions are very good for this. -* Allow systems to attach data to a container message with minimal dependency - and coordination. Extensions are not a great solution for this because of - the limited field number space and the - [Consequences of Reusing Field Numbers](#consequences). If your use case - requires very low coordination for a large number of extensions, consider - using the - [`Any` message type](/reference/protobuf/google.protobuf#any) - instead. - -### Example Extension {#ext-example} - -Using an extension is a two-step process. First, in the message you want to -extend (the "container"), you must reserve a range of field numbers for -extensions. Then, in a separate file, you define the extension field itself. - -Here is an example that shows how to add an extension for kitten videos to a -generic `UserContent` message. - -**Step 1: Reserve an extension range in the container message.** - -The container message must use the `extensions` keyword to reserve a range of -field numbers for others to use. It is a best practice to also add a -`declaration` for the specific extension you plan to add. This declaration acts -as a forward-declaration, making it easier for developers to discover extensions -and avoid reusing field numbers. - -```proto -// media/user_content.proto -edition = "2023"; - -package media; - -// A container for user-created content. -message UserContent { - extensions 100 to 199 [ - declaration = { - number: 126, - full_name: ".kittens.kitten_videos", - type: ".kittens.Video", - repeated: true - } - ]; -} -``` - -This declaration specifies the field number, full name, type, and cardinality of -the extension that will be defined elsewhere. - -**Step 2: Define the extension in a separate file.** - -The extension itself is defined in a different `.proto` file, which typically -focuses on a specific feature (like kitten videos). This avoids adding a -dependency from the generic container to the specific feature. - -```proto -// kittens/video_ext.proto -edition = "2023"; - -import "media/user_content.proto"; // Imports the container message -import "kittens/video.proto"; // Imports the extension's message type - -package kittens; - -// This defines the extension field. -extend media.UserContent { - repeated Video kitten_videos = 126; -} -``` - -The `extend` block ties the new `kitten_videos` field back to the -`media.UserContent` message, using the field number `126` that was reserved in -the container. - -There is no difference in the wire-format encoding of extension fields as -compared to a standard field with the same field number, type, and cardinality. -Therefore, it is safe to move a standard field out of its container to be an -extension or to move an extension field into its container message as a standard -field so long as the field number, type, and cardinality remain constant. - -However, because extensions are defined outside of the container message, no -specialized accessors are generated to get and set specific extension fields. -For our example, the protobuf compiler **will not generate** `AddKittenVideos()` -or `GetKittenVideos()` accessors. Instead, extensions are accessed through -parameterized functions like: `HasExtension()`, `ClearExtension()`, -`GetExtension()`, `MutableExtension()`, and `AddExtension()`. - -In C++, it would look something like: - -```cpp -UserContent user_content; -user_content.AddExtension(kittens::kitten_videos, new kittens::Video()); -assert(1 == user_content.GetRepeatedExtension(kittens::kitten_videos).size()); -user_content.GetRepeatedExtension(kittens::kitten_videos)[0]; -``` - -### Defining Extension Ranges {#defining-ranges} - -If you are the owner of a container message, you will need to define an -extension range for the extensions to your message. - -Field numbers allocated to extension fields cannot be reused for standard -fields. - -It is safe to expand an extension range after it is defined. A good default is -to allocate 1000 relatively small numbers, and densely populate that space using -extension declarations: - -```proto -message ModernExtendableMessage { - // All extensions in this range should use extension declarations. - extensions 1000 to 2000 [verification = DECLARATION]; -} -``` - -When adding a range for extension declarations before the actual extensions, you -should add `verification = DECLARATION` to enforce that declarations are used -for this new range. This placeholder can be removed once an actual declaration -is added. - -It is safe to split an existing extension range into separate ranges that cover -the same total range. This might be necessary for migrating a legacy message -type to -[Extension Declarations](/programming-guides/extension_declarations). -For example, before migration, the range might be defined as: - -```proto -message LegacyMessage { - extensions 1000 to max; -} -``` - -And after migration (splitting the range) it can be: - -```proto -message LegacyMessage { - // Legacy range that was using an unverified allocation scheme. - extensions 1000 to 524999999 [verification = UNVERIFIED]; - // Current range that uses extension declarations. - extensions 525000000 to max [verification = DECLARATION]; -} -``` - -It is not safe to increase the start field number nor decrease the end field -number to move or shrink an extension range. These changes can invalidate an -existing extension. - -Prefer using field numbers 1 to 15 for standard fields that are populated in -most instances of your proto. It is not recommended to use these numbers for -extensions. - -If your numbering convention might involve extensions having very large field -numbers, you can specify that your extension range goes up to the maximum -possible field number using the `max` keyword: - -```proto -message Foo { - extensions 1000 to max; -} -``` - -`max` is 229 - 1, or 536,870,911. - -### Choosing Extension Numbers {#choosing} - -Extensions are just fields that can be specified outside of their container -messages. All the same rules for [Assigning Field Numbers](#assigning) apply to -extension field numbers. The same -[Consequences of Reusing Field Numbers](#consequences) also apply to reusing -extension field numbers. - -Choosing unique extension field numbers is simple if the container message uses -[extension declarations](/programming-guides/extension_declarations). -When defining a new extension, choose the lowest field number above all other -declarations from the highest extension range defined in the container message. -For example, if a container message is defined like this: - -```proto -message Container { - // Legacy range that was using an unverified allocation scheme - extensions 1000 to 524999999; - // Current range that uses extension declarations. (highest extension range) - extensions 525000000 to max [ - declaration = { - number: 525000001, - full_name: ".bar.baz_ext", - type: ".bar.Baz" - } - // 525,000,002 is the lowest field number above all other declarations - ]; -} -``` - -The next extension of `Container` should add a new declaration with the number -`525000002`. - -#### Unverified Extension Number Allocation (not recommended) {#unverified} - -The owner of a container message may choose to forgo extension declarations in -favor of their own unverified extension number allocation strategy. - -An unverified allocation scheme uses a mechanism external to the protobuf -ecosystem to allocate extension field numbers within the selected extension -range. One example could be using a monorepo's commit number. This system is -"unverified" from the protobuf compiler's point of view since there is no way to -check that an extension is using a properly acquired extension field number. - -The benefit of an unverified system over a verified system like extension -declarations is the ability to define an extension without coordinating with the -container message owner. - -The downside of an unverified system is that the protobuf compiler cannot -protect participants from reusing extension field numbers. - -**Unverified extension field number allocation strategies are not recommended** -because the [Consequences of Reusing Field Numbers](#consequences) fall on all -extenders of a message (not just the developer that didn't follow the -recommendations). If your use case requires very low coordination, consider -using the -[`Any` message](/reference/protobuf/google.protobuf#any) -instead. - -Unverified extension field number allocation strategies are limited to the range -1 to 524,999,999. Field numbers 525,000,000 and above can only be used with -extension declarations. - -### Specifying Extension Types {#specifying-extension-types} - -Extensions can be of any field type except `oneof`s and `map`s. - -### Nested Extensions (not recommended) {#nested-exts} - -You can declare extensions in the scope of another message: - -```proto -import "common/user_profile.proto"; - -package puppies; - -message Photo { - extend common.UserProfile { - int32 likes_count = 111; - } - ... -} -``` - -In this case, the C++ code to access this extension is: - -```cpp -UserProfile user_profile; -user_profile.SetExtension(puppies::Photo::likes_count, 42); -``` - -In other words, the only effect is that `likes_count` is defined within the -scope of `puppies.Photo`. - -This is a common source of confusion: Declaring an `extend` block nested inside -a message type *does not* imply any relationship between the outer type and the -extended type. In particular, the earlier example *does not* mean that `Photo` -is any sort of subclass of `UserProfile`. All it means is that the symbol -`likes_count` is declared inside the scope of `Photo`; it's simply a static -member. - -A common pattern is to define extensions inside the scope of the extension's -field type - for example, here's an extension to `media.UserContent` of type -`puppies.Photo`, where the extension is defined as part of `Photo`: - -```proto -import "media/user_content.proto"; - -package puppies; - -message Photo { - extend media.UserContent { - Photo puppy_photo = 127; - } - ... -} -``` - -However, there is no requirement that an extension with a message type be -defined inside that type. You can also use the standard definition pattern: - -```proto -import "media/user_content.proto"; - -package puppies; - -message Photo { - ... -} - -// This can even be in a different file. -extend media.UserContent { - Photo puppy_photo = 127; -} -``` - -This **standard (file-level) syntax is preferred** to avoid confusion. The -nested syntax is often mistaken for subclassing by users who are not already -familiar with extensions. - -## Any {#any} - -The `Any` message type lets you use messages as embedded types without having -their .proto definition. An `Any` contains an arbitrary serialized message as -`bytes`, along with a URL that acts as a globally unique identifier for and -resolves to that message's type. To use the `Any` type, you need to -[import](#other) `google/protobuf/any.proto`. - -```proto -import "google/protobuf/any.proto"; - -message ErrorStatus { - string message = 1; - repeated google.protobuf.Any details = 2; -} -``` - -The default type URL for a given message type is -`type.googleapis.com/_packagename_._messagename_`. - -Different language implementations will support runtime library helpers to pack -and unpack `Any` values in a typesafe manner – for example, in Java, the `Any` -type will have special `pack()` and `unpack()` accessors, while in C++ there are -`PackFrom()` and `UnpackTo()` methods: - -```cpp -// Storing an arbitrary message type in Any. -NetworkErrorDetails details = ...; -ErrorStatus status; -status.add_details()->PackFrom(details); - -// Reading an arbitrary message from Any. -ErrorStatus status = ...; -for (const google::protobuf::Any& detail : status.details()) { - if (detail.Is()) { - NetworkErrorDetails network_error; - detail.UnpackTo(&network_error); - ... processing network_error ... - } -} -``` - -If you want to limit contained messages to a small number of types and to -require permission before adding new types to the list, consider using -[extensions](#extensions) with -[extension declarations](/programming-guides/extension_declarations) -instead of `Any` message types. - -## Oneof {#oneof} - -If you have a message with many singular fields and where at most one field will -be set at the same time, you can enforce this behavior and save memory by using -the oneof feature. - -Oneof fields are like singular fields except all the fields in a oneof share -memory, and at most one field can be set at the same time. Setting any member of -the oneof automatically clears all the other members. You can check which value -in a oneof is set (if any) using a special `case()` or `WhichOneof()` method, -depending on your chosen language. - -Note that if *multiple values are set, the last set value as determined by the -order in the proto will overwrite all previous ones*. - -Field numbers for oneof fields must be unique within the enclosing message. - -### Using Oneof {#using-oneof} - -To define a oneof in your `.proto` you use the `oneof` keyword followed by your -oneof name, in this case `test_oneof`: - -```proto -message SampleMessage { - oneof test_oneof { - string name = 4; - SubMessage sub_message = 9; - } -} -``` - -You then add your oneof fields to the oneof definition. You can add fields of -any type, except `map` fields and `repeated` fields. If you need to add a -repeated field to a oneof, you can use a message containing the repeated field. - -In your generated code, oneof fields have the same getters and setters as -regular fields. You also get a special method for checking which value (if any) -in the oneof is set. You can find out more about the oneof API for your chosen -language in the relevant [API reference](/reference/). - -### Oneof Features {#oneof-features} - -* Setting a oneof field will automatically clear all other members of the - oneof. So if you set several oneof fields, only the *last* field you set - will still have a value. - - ```cpp - SampleMessage message; - message.set_name("name"); - CHECK(message.has_name()); - // Calling mutable_sub_message() will clear the name field and will set - // sub_message to a new instance of SubMessage with none of its fields set. - message.mutable_sub_message(); - CHECK(!message.has_name()); - ``` - -* If the parser encounters multiple members of the same oneof on the wire, - only the last member seen is used in the parsed message. When parsing data - on the wire, starting at the beginning of the bytes, evaluate the next - value, and apply the following parsing rules: - - * First, check if a *different* field in the same oneof is currently set, - and if so clear it. - - * Then apply the contents as though the field was not in a oneof: - - * A primitive will overwrite any value already set - * A message will merge into any value already set - -* Extensions are not supported for oneof. - -* A oneof cannot be `repeated`. - -* Reflection APIs work for oneof fields. - -* If you set a oneof field to the default value (such as setting an int32 - oneof field to 0), the "case" of that oneof field will be set, and the value - will be serialized on the wire. - -* If you're using C++, make sure your code doesn't cause memory crashes. The - following sample code will crash because `sub_message` was already deleted - by calling the `set_name()` method. - - ```cpp - SampleMessage message; - SubMessage* sub_message = message.mutable_sub_message(); - message.set_name("name"); // Will delete sub_message - sub_message->set_... // Crashes here - ``` - -* Again in C++, if you `Swap()` two messages with oneofs, each message will - end up with the other's oneof case: in the example below, `msg1` will have a - `sub_message` and `msg2` will have a `name`. - - ```cpp - SampleMessage msg1; - msg1.set_name("name"); - SampleMessage msg2; - msg2.mutable_sub_message(); - msg1.swap(&msg2); - CHECK(msg1.has_sub_message()); - CHECK(msg2.has_name()); - ``` - -### Backwards-compatibility issues {#backward} - -Be careful when adding or removing oneof fields. If checking the value of a -oneof returns `None`/`NOT_SET`, it could mean that the oneof has not been set or -it has been set to a field in a different version of the oneof. There is no way -to tell the difference, since there's no way to know if an unknown field on the -wire is a member of the oneof. - -#### Tag Reuse Issues {#reuse} - -* **Move singular fields into or out of a oneof**: You may lose some of your - information (some fields will be cleared) after the message is serialized - and parsed. However, you can safely move a single field into a **new** oneof - and may be able to move multiple fields if it is known that only one is ever - set. See [Updating A Message Type](#updating) for further details. -* **Delete a oneof field and add it back**: This may clear your currently set - oneof field after the message is serialized and parsed. -* **Split or merge oneof**: This has similar issues to moving singular fields. - -## Maps {#maps} - -If you want to create an associative map as part of your data definition, -protocol buffers provides a handy shortcut syntax: - -```proto -map map_field = N; -``` - -...where the `key_type` can be any integral or string type (so, any -[scalar](#scalar) type except for floating point types and `bytes`). Note that -neither enum nor proto messages are valid for `key_type`. -The `value_type` can be any type except another map. - -So, for example, if you wanted to create a map of projects where each `Project` -message is associated with a string key, you could define it like this: - -```proto -map projects = 3; -``` - -### Maps Features {#maps-features} - -* Extensions are not supported for maps. -* Map fields cannot be `repeated`. -* Wire format ordering and map iteration ordering of map values is undefined, - so you cannot rely on your map items being in a particular order. -* When generating text format for a `.proto`, maps are sorted by key. Numeric - keys are sorted numerically. -* When parsing from the wire or when merging, if there are duplicate map keys - the last key seen is used. When parsing a map from text format, parsing may - fail if there are duplicate keys. -* If you provide a key but no value for a map field, the behavior when the - field is serialized is language-dependent. In C++, Java, Kotlin, and Python - the default value for the type is serialized, while in other languages - nothing is serialized. -* No symbol `FooEntry` can exist in the same scope as a map `foo`, because - `FooEntry` is already used by the implementation of the map. - -The generated map API is currently available for all supported languages. You -can find out more about the map API for your chosen language in the relevant -[API reference](/reference/). - -### Backwards Compatibility {#backwards} - -The map syntax is equivalent to the following on the wire, so protocol buffers -implementations that do not support maps can still handle your data: - -```proto -message MapFieldEntry { - key_type key = 1; - value_type value = 2; -} - -repeated MapFieldEntry map_field = N; -``` - -Any protocol buffers implementation that supports maps must both produce and -accept data that can be accepted by the earlier definition. - -## Packages {#packages} - -You can add an optional `package` specifier to a `.proto` file to prevent name -clashes between protocol message types. - -```proto -package foo.bar; -message Open { ... } -``` - -You can then use the package specifier when defining fields of your message -type: - -```proto -message Foo { - ... - foo.bar.Open open = 1; - ... -} -``` - -The way a package specifier affects the generated code depends on your chosen -language: - -* In **C++** the generated classes are wrapped inside a C++ namespace. For - example, `Open` would be in the namespace `foo::bar`. -* In **Java** and **Kotlin**, the package is used as the Java package, unless - you explicitly provide an `option java_package` in your `.proto` file. -* In **Python**, the `package` directive is ignored, since Python modules are - organized according to their location in the file system. -* In **Go**, the `package` directive is ignored, and the generated `.pb.go` - file is in the package named after the corresponding `go_proto_library` - Bazel rule. For open source projects, you **must** provide either a `go_package` option or set the Bazel `-M` flag. -* In **Ruby**, the generated classes are wrapped inside nested Ruby - namespaces, converted to the required Ruby capitalization style (first - letter capitalized; if the first character is not a letter, `PB_` is - prepended). For example, `Open` would be in the namespace `Foo::Bar`. -* In **PHP** the package is used as the namespace after converting to - PascalCase, unless you explicitly provide an `option php_namespace` in your - `.proto` file. For example, `Open` would be in the namespace `Foo\Bar`. -* In **C#** the package is used as the namespace after converting to - PascalCase, unless you explicitly provide an `option csharp_namespace` in - your `.proto` file. For example, `Open` would be in the namespace `Foo.Bar`. - -Note that even when the `package` directive does not directly affect the -generated code, for example in Python, it is still strongly recommended to -specify the package for the `.proto` file, as otherwise it may lead to naming -conflicts in descriptors and make the proto not portable for other languages. - -### Packages and Name Resolution {#name-resolution} - -Type name resolution in the protocol buffer language works like C++: first the -innermost scope is searched, then the next-innermost, and so on, with each -package considered to be "inner" to its parent package. A leading '.' (for -example, `.foo.bar.Baz`) means to start from the outermost scope instead. - -The protocol buffer compiler resolves all type names by parsing the imported -`.proto` files. The code generator for each language knows how to refer to each -type in that language, even if it has different scoping rules. - -## Defining Services {#services} - -If you want to use your message types with an RPC (Remote Procedure Call) -system, you can define an RPC service interface in a `.proto` file and the -protocol buffer compiler will generate service interface code and stubs in your -chosen language. So, for example, if you want to define an RPC service with a -method that takes your `SearchRequest` and returns a `SearchResponse`, you can -define it in your `.proto` file as follows: - -```proto -service SearchService { - rpc Search(SearchRequest) returns (SearchResponse); -} -``` - -The most straightforward RPC system to use with protocol buffers is -[gRPC](https://grpc.io): a language- and platform-neutral open source RPC system -developed at Google. gRPC works particularly well with protocol buffers and lets -you generate the relevant RPC code directly from your `.proto` files using a -special protocol buffer compiler plugin. - -If you don't want to use gRPC, it's also possible to use protocol buffers with -your own RPC implementation. You can find out more about this in the -[Proto2 Language Guide](/programming-guides/proto2#services). - -There are also a number of ongoing third-party projects to develop RPC -implementations for Protocol Buffers. For a list of links to projects we know -about, see the -[third-party add-ons wiki page](https://github.com/protocolbuffers/protobuf/blob/master/docs/third_party.md). - -## JSON Mapping {#json} - -The standard protobuf binary wire format is the preferred serialization format -for communication between two systems that use protobufs. For communicating with -systems that use JSON rather than protobuf wire format, Protobuf supports a -canonical encoding in -[ProtoJSON](/programming-guides/json). - -## Options {#options} - -Individual declarations in a `.proto` file can be annotated with a number of -*options*. Options do not change the overall meaning of a declaration, but may -affect the way it is handled in a particular context. The complete list of -available options is defined in [`/google/protobuf/descriptor.proto`](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto). - -Some options are file-level options, meaning they should be written at the -top-level scope, not inside any message, enum, or service definition. Some -options are message-level options, meaning they should be written inside message -definitions. Some options are field-level options, meaning they should be -written inside field definitions. Options can also be written on enum types, -enum values, oneof fields, service types, and service methods; however, no -useful options currently exist for any of these. - -Here are a few of the most commonly used options: - -* `java_package` (file option): The package you want to use for your generated - Java/Kotlin classes. If no explicit `java_package` option is given in the - `.proto` file, then by default the proto package (specified using the - "package" keyword in the `.proto` file) will be used. However, proto - packages generally do not make good Java packages since proto packages are - not expected to start with reverse domain names. If not generating Java or - Kotlin code, this option has no effect. - - ```proto - option java_package = "com.example.foo"; - ``` - -* `java_outer_classname` (file option): The class name (and hence the file - name) for the wrapper Java class you want to generate. If no explicit - `java_outer_classname` is specified in the `.proto` file, the class name - will be constructed by converting the `.proto` file name to camel-case (so - `foo_bar.proto` becomes `FooBar.java`). If the `java_multiple_files` option - is disabled, then all other classes/enums/etc. generated for the `.proto` - file will be generated *within* this outer wrapper Java class as nested - classes/enums/etc. If not generating Java code, this option has no effect. - - ```proto - option java_outer_classname = "Ponycopter"; - ``` - -* `java_multiple_files` (file option): If false, only a single `.java` file - will be generated for this `.proto` file, and all the Java - classes/enums/etc. generated for the top-level messages, services, and - enumerations will be nested inside of an outer class (see - `java_outer_classname`). If true, separate `.java` files will be generated - for each of the Java classes/enums/etc. generated for the top-level - messages, services, and enumerations, and the wrapper Java class generated - for this `.proto` file won't contain any nested classes/enums/etc. This is a - Boolean option which defaults to `false`. If not generating Java code, this - option has no effect. This was removed in edition 2024 and replaced with - [`features.(pb.java).nest_in_file_class`](/editions/features/#java-nest_in_file) - - ```proto - option java_multiple_files = true; - ``` - -* `optimize_for` (file option): Can be set to `SPEED`, `CODE_SIZE`, or - `LITE_RUNTIME`. This affects the C++ and Java code generators (and possibly - third-party generators) in the following ways: - - * `SPEED` (default): The protocol buffer compiler will generate code for - serializing, parsing, and performing other common operations on your - message types. This code is highly optimized. - * `CODE_SIZE`: The protocol buffer compiler will generate minimal classes - and will rely on shared, reflection-based code to implement - serialization, parsing, and various other operations. The generated code - will thus be much smaller than with `SPEED`, but operations will be - slower. Classes will still implement exactly the same public API as they - do in `SPEED` mode. This mode is most useful in apps that contain a very - large number of `.proto` files and do not need all of them to be - blindingly fast. - * `LITE_RUNTIME`: The protocol buffer compiler will generate classes that - depend only on the "lite" runtime library (`libprotobuf-lite` instead of - `libprotobuf`). The lite runtime is much smaller than the full library - (around an order of magnitude smaller) but omits certain features like - descriptors and reflection. This is particularly useful for apps running - on constrained platforms like mobile phones. The compiler will still - generate fast implementations of all methods as it does in `SPEED` mode. - Generated classes will only implement the `MessageLite` interface in - each language, which provides only a subset of the methods of the full - `Message` interface. - - ```proto - option optimize_for = CODE_SIZE; - ``` - -* `cc_generic_services`, `java_generic_services`, `py_generic_services` (file - options): **Generic services are deprecated.** Whether or not the protocol - buffer compiler should generate abstract service code based on - [services definitions](#services) in C++, Java, and Python, respectively. - For legacy reasons, these default to `true`. However, as of version 2.3.0 - (January 2010), it is considered preferable for RPC implementations to - provide - [code generator plugins](/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb) - to generate code more specific to each system, rather than rely on the - "abstract" services. - - ```proto - // This file relies on plugins to generate service code. - option cc_generic_services = false; - option java_generic_services = false; - option py_generic_services = false; - ``` - -* `cc_enable_arenas` (file option): Enables - [arena allocation](/reference/cpp/arenas) for C++ - generated code. - -* `objc_class_prefix` (file option): Sets the Objective-C class prefix which - is prepended to all Objective-C generated classes and enums from this - .proto. There is no default. You should use prefixes that are between 3-5 - uppercase characters as - [recommended by Apple](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Conventions/Conventions.html#//apple_ref/doc/uid/TP40011210-CH10-SW4). - Note that all 2 letter prefixes are reserved by Apple. - -* `packed` (field option): In protobuf editions, this option is locked to - `true`. To use unpacked wireformat, you can override this option using an - editions feature. This provides compatibility with parsers prior to version - 2.3.0 (rarely needed) as shown in the following example: - - ```proto - repeated int32 samples = 4 [features.repeated_field_encoding = EXPANDED]; - ``` - -* `deprecated` (field option): If set to `true`, indicates that the field is - deprecated and should not be used by new code. In most languages this has no - actual effect. In Java, this becomes a `@Deprecated` annotation. For C++, - clang-tidy will generate warnings whenever deprecated fields are used. In - the future, other language-specific code generators may generate deprecation - annotations on the field's accessors, which will in turn cause a warning to - be emitted when compiling code which attempts to use the field. If the field - is not used by anyone and you want to prevent new users from using it, - consider replacing the field declaration with a [reserved](#fieldreserved) - statement. - - ```proto - int32 old_field = 6 [deprecated = true]; - ``` - -### Enum Value Options {#enum-value-options} - -Enum value options are supported. You can use the `deprecated` option to -indicate that a value shouldn't be used anymore. You can also create custom -options using extensions. - -The following example shows the syntax for adding these options: - -```proto -import "google/protobuf/descriptor.proto"; - -extend google.protobuf.EnumValueOptions { - string string_name = 123456789; -} - -enum Data { - DATA_UNSPECIFIED = 0; - DATA_SEARCH = 1 [deprecated = true]; - DATA_DISPLAY = 2 [ - (string_name) = "display_value" - ]; -} -``` - -The C++ code to read the `string_name` option might look something like this: - -```cpp -const absl::string_view foo = proto2::GetEnumDescriptor() - ->FindValueByName("DATA_DISPLAY")->options().GetExtension(string_name); -``` - -See [Custom Options](#customoptions) to see how to apply custom options to enum -values and to fields. - -### Custom Options {#customoptions} - -Protocol Buffers also allows you to define and use your own options. Note that -this is an **advanced feature** which most people don't need. If you do think -you need to create your own options, see the -[Proto2 Language Guide](/programming-guides/proto2#customoptions) -for details. Note that creating custom options uses -[extensions](/programming-guides/proto2#extensions). - -Starting in edition 2024, import custom option definitions using `import -option`. See [Importing](#importing). - -### Option Retention {#option-retention} - -Options have a notion of *retention*, which controls whether an option is -retained in the generated code. Options have *runtime retention* by default, -meaning that they are retained in the generated code and are thus visible at -runtime in the generated descriptor pool. However, you can set `retention = -RETENTION_SOURCE` to specify that an option (or field within an option) must not -be retained at runtime. This is called *source retention*. - -Option retention is an advanced feature that most users should not need to worry -about, but it can be useful if you would like to use certain options without -paying the code size cost of retaining them in your binaries. Options with -source retention are still visible to `protoc` and `protoc` plugins, so code -generators can use them to customize their behavior. - -Retention can be set directly on an option, like this: - -```proto -extend google.protobuf.FileOptions { - int32 source_retention_option = 1234 - [retention = RETENTION_SOURCE]; -} -``` - -It can also be set on a plain field, in which case it takes effect only when -that field appears inside an option: - -```proto -message OptionsMessage { - int32 source_retention_field = 1 [retention = RETENTION_SOURCE]; -} -``` - -You can set `retention = RETENTION_RUNTIME` if you like, but this has no effect -since it is the default behavior. When a message field is marked -`RETENTION_SOURCE`, its entire contents are dropped; fields inside it cannot -override that by trying to set `RETENTION_RUNTIME`. - -{{% alert title="Note" color="note" %}} As -of Protocol Buffers 22.0, support for option retention is still in progress and -only C++ and Java are supported. Go has support starting from 1.29.0. Python -support is complete but has not made it into a release yet. -{{% /alert %}} - -### Option Targets {#option-targets} - -Fields have a `targets` option which controls the types of entities that the -field may apply to when used as an option. For example, if a field has -`targets = TARGET_TYPE_MESSAGE` then that field cannot be set in a custom option -on an enum (or any other non-message entity). Protoc enforces this and will -raise an error if there is a violation of the target constraints. - -At first glance, this feature may seem unnecessary given that every custom -option is an extension of the options message for a specific entity, which -already constrains the option to that one entity. However, option targets are -useful in the case where you have a shared options message applied to multiple -entity types and you want to control the usage of individual fields in that -message. For example: - -```proto -message MyOptions { - string file_only_option = 1 [targets = TARGET_TYPE_FILE]; - int32 message_and_enum_option = 2 [targets = TARGET_TYPE_MESSAGE, - targets = TARGET_TYPE_ENUM]; -} - -extend google.protobuf.FileOptions { - MyOptions file_options = 50000; -} - -extend google.protobuf.MessageOptions { - MyOptions message_options = 50000; -} - -extend google.protobuf.EnumOptions { - MyOptions enum_options = 50000; -} - -// OK: this field is allowed on file options -option (file_options).file_only_option = "abc"; - -message MyMessage { - // OK: this field is allowed on both message and enum options - option (message_options).message_and_enum_option = 42; -} - -enum MyEnum { - MY_ENUM_UNSPECIFIED = 0; - // Error: file_only_option cannot be set on an enum. - option (enum_options).file_only_option = "xyz"; -} -``` - -## Generating Your Classes {#generating} - -To generate the Java, Kotlin, Python, C++, Go, Ruby, Objective-C, or C# code -that you need to work with the message types defined in a `.proto` file, you -need to run the protocol buffer compiler `protoc` on the `.proto` file. If you -haven't installed the compiler, -[download the package](/downloads) and follow the -instructions in the README. For Go, you also need to install a special code -generator plugin for the compiler; you can find this and installation -instructions in the [golang/protobuf](https://github.com/golang/protobuf/) -repository on GitHub. - -The Protocol Compiler is invoked as follows: - -```sh -protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR --go_out=DST_DIR --ruby_out=DST_DIR --objc_out=DST_DIR --csharp_out=DST_DIR path/to/file.proto -``` - -* `IMPORT_PATH` specifies a directory in which to look for `.proto` files when - resolving `import` directives. If omitted, the current directory is used. - Multiple import directories can be specified by passing the `--proto_path` - option multiple times; they will be searched in order. `-I=_IMPORT_PATH_` - can be used as a short form of `--proto_path`. - -**Note:** File paths relative to their `proto_path` must be globally unique in a -given binary. For example, if you have `proto/lib1/data.proto` and -`proto/lib2/data.proto`, those two files cannot be used together with -`-I=proto/lib1 -I=proto/lib2` because it would be ambiguous which file `import -"data.proto"` will mean. Instead `-Iproto/` should be used and the global names -will be `lib1/data.proto` and `lib2/data.proto`. - -If you are publishing a library and other users may use your messages directly, -you should include a unique library name in the path that they are expected to -be used under to avoid file name collisions. If you have multiple directories in -one project, it is best practice to prefer setting one `-I` to a top level -directory of the project. - -* You can provide one or more *output directives*: - - * `--cpp_out` generates C++ code in `DST_DIR`. See the - [C++ generated code reference](/reference/cpp/cpp-generated) - for more. - * `--java_out` generates Java code in `DST_DIR`. See the - [Java generated code reference](/reference/java/java-generated) - for more. - * `--kotlin_out` generates additional Kotlin code in `DST_DIR`. See the - [Kotlin generated code reference](/reference/kotlin/kotlin-generated) - for more. - * `--python_out` generates Python code in `DST_DIR`. See the - [Python generated code reference](/reference/python/python-generated) - for more. - * `--go_out` generates Go code in `DST_DIR`. See the - [Go generated code reference](/reference/go/go-generated-opaque) - for more. - * `--ruby_out` generates Ruby code in `DST_DIR`. See the - [Ruby generated code reference](/reference/ruby/ruby-generated) - for more. - * `--objc_out` generates Objective-C code in `DST_DIR`. See the - [Objective-C generated code reference](/reference/objective-c/objective-c-generated) - for more. - * `--csharp_out` generates C# code in `DST_DIR`. See the - [C# generated code reference](/reference/csharp/csharp-generated) - for more. - * `--php_out` generates PHP code in `DST_DIR`. See the - [PHP generated code reference](/reference/php/php-generated) - for more. - - As an extra convenience, if the `DST_DIR` ends in `.zip` or `.jar`, the - compiler will write the output to a single ZIP-format archive file with the - given name. `.jar` outputs will also be given a manifest file as required by - the Java JAR specification. Note that if the output archive already exists, - it will be overwritten. - -* You must provide one or more `.proto` files as input. Multiple `.proto` - files can be specified at once. Although the files are named relative to the - current directory, each file must reside in one of the `IMPORT_PATH`s so - that the compiler can determine its canonical name. - -## File location {#location} - -Prefer not to put `.proto` files in the same -directory as other language sources. Consider -creating a subpackage `proto` for `.proto` files, under the root package for -your project. - -### Location Should be Language-agnostic {#location-language-agnostic} - -When working with Java code, it's handy to put related `.proto` files in the -same directory as the Java source. However, if any non-Java code ever uses the -same protos, the path prefix will no longer make sense. So in -general, put the protos in a related language-agnostic directory such as -`//myteam/mypackage`. - -The exception to this rule is when it's clear that the protos will be used only -in a Java context, such as for testing. - -## Supported Platforms {#platforms} - -For information about: - -* the operating systems, compilers, build systems, and C++ versions that are - supported, see - [Foundational C++ Support Policy](https://opensource.google/documentation/policies/cplusplus-support). -* the PHP versions that are supported, see - [Supported PHP versions](https://cloud.google.com/php/getting-started/supported-php-versions). diff --git a/content/programming-guides/encoding.md b/content/programming-guides/encoding.md deleted file mode 100644 index bcd4db815..000000000 --- a/content/programming-guides/encoding.md +++ /dev/null @@ -1,589 +0,0 @@ -+++ -title = "Encoding" -weight = 60 -description = "Explains how Protocol Buffers encodes data to files or to the wire." -type = "docs" -+++ - -This document describes the protocol buffer *wire format*, which defines the -details of how your message is sent on the wire and how much space it consumes -on disk. You probably don't need to understand this to use protocol buffers in -your application, but it's useful information for doing optimizations. - -If you already know the concepts but want a reference, skip to the -[Condensed reference card](#cheat-sheet) section. - -[Protoscope](https://github.com/protocolbuffers/protoscope) is a very simple -language for describing snippets of the low-level wire format, which we'll use -to provide a visual reference for the encoding of various messages. Protoscope's -syntax consists of a sequence of *tokens* that each encode down to a specific -byte sequence. - -For example, backticks denote a raw hex literal, like `` `70726f746f6275660a` -``. This encodes into the exact bytes denoted as hex in the literal. Quotes -denote UTF-8 strings, like `"Hello, Protobuf!"`. This literal is synonymous with -`` `48656c6c6f2c2050726f746f62756621` `` (which, if you observe closely, is -composed of ASCII bytes). We'll introduce more of the Protoscope language as we -discuss aspects of the wire format. - -The Protoscope tool can also dump encoded protocol buffers as text. See -https://github.com/protocolbuffers/protoscope/tree/main/testdata for examples. - -All examples in this topic assume that you are using Edition 2023 or later. - -## A Simple Message {#simple} - -Let's say you have the following very simple message definition: - -```proto -message Test1 { - int32 a = 1; -} -``` - -In an application, you create a `Test1` message and set `a` to 150. You then -serialize the message to an output stream. If you were able to examine the -encoded message, you'd see three bytes: - -```proto -08 96 01 -``` - -So far, so small and numeric -- but what does it mean? If you use the Protoscope -tool to dump those bytes, you'd get something like `1: 150`. How does it know -this is the contents of the message? - -## Base 128 Varints {#varints} - -Variable-width integers, or *varints*, are at the core of the wire format. They -allow encoding unsigned 64-bit integers using anywhere between one and ten -bytes, with small values using fewer bytes. - -Each byte in the varint has a *continuation bit* that indicates if the byte that -follows it is part of the varint. This is the *most significant bit* (MSB) of -the byte (sometimes also called the *sign bit*). The lower 7 bits are a payload; -the resulting integer is built by appending together the 7-bit payloads of its -constituent bytes. - -So, for example, here is the number 1, encoded as `` `01` `` -- it's a single -byte, so the MSB is not set: - -```proto -0000 0001 -^ msb -``` - -And here is 150, encoded as `` `9601` `` -- this is a bit more complicated: - -```proto -10010110 00000001 -^ msb ^ msb -``` - -How do you figure out that this is 150? First you drop the MSB from each byte, -as this is just there to tell us whether we've reached the end of the number (as -you can see, it's set in the first byte as there is more than one byte in the -varint). These 7-bit payloads are in little-endian order. Convert to big-endian -order, concatenate, and interpret as an unsigned 64-bit integer: - -```proto -10010110 00000001 // Original inputs. - 0010110 0000001 // Drop continuation bits. - 0000001 0010110 // Convert to big-endian. - 00000010010110 // Concatenate. - 128 + 16 + 4 + 2 = 150 // Interpret as an unsigned 64-bit integer. -``` - -Because varints are so crucial to protocol buffers, in protoscope syntax, we -refer to them as plain integers. `150` is the same as `` `9601` ``. - -## Message Structure {#structure} - -A protocol buffer message is a series of key-value pairs. The binary version of -a message just uses the field's number as the key -- the name and declared type -for each field can only be determined on the decoding end by referencing the -message type's definition (i.e. the `.proto` file). Protoscope does not have -access to this information, so it can only provide the field numbers. - -When a message is encoded, each key-value pair is turned into a *record* -consisting of the field number, a wire type and a payload. The wire type tells -the parser how big the payload after it is. This allows old parsers to skip over -new fields they don't understand. This type of scheme is sometimes called -[Tag-Length-Value](https://en.wikipedia.org/wiki/Type%E2%80%93length%E2%80%93value), -or TLV. - -There are six wire types: `VARINT`, `I64`, `LEN`, `SGROUP`, `EGROUP`, and `I32` - -ID | Name | Used For ---- | ------ | -------------------------------------------------------- -0 | VARINT | int32, int64, uint32, uint64, sint32, sint64, bool, enum -1 | I64 | fixed64, sfixed64, double -2 | LEN | string, bytes, embedded messages, packed repeated fields -3 | SGROUP | group start (deprecated) -4 | EGROUP | group end (deprecated) -5 | I32 | fixed32, sfixed32, float - -The "tag" of a record is encoded as a varint formed from the field number and -the wire type via the formula `(field_number << 3) | wire_type`. In other words, -after decoding the varint representing a field, the low 3 bits tell us the wire -type, and the rest of the integer tells us the field number. - -Now let's look at our simple example again. You now know that the first number -in the stream is always a varint key, and here it's `` `08` ``, or (dropping the -MSB): - -```proto -000 1000 -``` - -You take the last three bits to get the wire type (0) and then right-shift by -three to get the field number (1). Protoscope represents a tag as an integer -followed by a colon and the wire type, so we can write the above bytes as -`1:VARINT`. - -Because the wire type is 0, or `VARINT`, we know that we need to decode a varint -to get the payload. As we saw above, the bytes `` `9601` `` varint-decode to -150, giving us our record. We can write it in Protoscope as `1:VARINT 150`. - -Protoscope can infer the type for a tag if there is whitespace after the `:`. It -does so by looking ahead at the next token and guessing what you meant (the -rules are documented in detail in -[Protoscope's language.txt](https://github.com/protocolbuffers/protoscope/blob/main/language.txt)). -For example, in `1: 150`, there is a varint immediately after the untyped tag, -so Protoscope infers its type to be `VARINT`. If you wrote `2: {}`, it would see -the `{` and guess `LEN`; if you wrote `3: 5i32` it would guess `I32`, and so on. - -## More Integer Types {#int-types} - -### Bools and Enums {#bools-and-enums} - -Bools and enums are both encoded as if they were `int32`s. Bools, in particular, -always encode as either `` `00` `` or `` `01` ``. In Protoscope, `false` and -`true` are aliases for these byte strings. - -### Signed Integers {#signed-ints} - -As you saw in the previous section, all the protocol buffer types associated -with wire type 0 are encoded as varints. However, varints are unsigned, so the -different signed types, `sint32` and `sint64` vs `int32` or `int64`, encode -negative integers differently. - -The `intN` types encode negative numbers as two's complement, which means that, -as unsigned, 64-bit integers, they have their highest bit set. As a result, this -means that *all ten bytes* must be used. For example, `-2` is converted by -protoscope into - -```proto -11111110 11111111 11111111 11111111 11111111 -11111111 11111111 11111111 11111111 00000001 -``` - -This is the *two's complement* of 2, defined in unsigned arithmetic as `~0 - 2 + -1`, where `~0` is the all-ones 64-bit integer. It is a useful exercise to -understand why this produces so many ones. - - -`sintN` uses the "ZigZag" encoding instead of two's complement to encode -negative integers. Positive integers `p` are encoded as `2 * p` (the even -numbers), while negative integers `n` are encoded as `2 * |n| - 1` (the odd -numbers). The encoding thus "zig-zags" between positive and negative numbers. -For example: - - -Signed Original | Encoded As ---------------- | ---------- -0 | 0 --1 | 1 -1 | 2 --2 | 3 -... | ... -0x7fffffff | 0xfffffffe --0x80000000 | 0xffffffff - -In other words, each value `n` is encoded using - -``` -(n << 1) ^ (n >> 31) -``` - -for `sint32`s, or - -``` -(n << 1) ^ (n >> 63) -``` - -for the 64-bit version. - -When the `sint32` or `sint64` is parsed, its value is decoded back to the -original, signed version. - -In protoscope, suffixing an integer with a `z` will make it encode as ZigZag. -For example, `-500z` is the same as the varint `999`. - -### Non-varint Numbers {#non-varints} - -Non-varint numeric types are simple. `double` and `fixed64` have wire type -`I64`, which tells the parser to expect a fixed eight-byte lump of data. -`double` values are encoded in IEEE 754 double-precision format. We can specify -a `double` record by writing `5: 25.4`, or a `fixed64` record with `6: 200i64`. - -Similarly `float` and `fixed32` have wire type `I32`, which tells it to expect -four bytes instead. `float` values are encoded in IEEE 754 single-precision -format. The syntax for these consists of adding an `i32` suffix. `25.4i32` will -emit four bytes, as will `200i32`. Tag types are inferred as `I32`. - -## Length-Delimited Records {#length-types} - -*Length prefixes* are another major concept in the wire format. The `LEN` wire -type has a dynamic length, specified by a varint immediately after the tag, -which is followed by the payload as usual. - -Consider this message schema: - -```proto -message Test2 { - string b = 2; -} -``` - -A record for the field `b` is a string, and strings are `LEN`-encoded. If we set -`b` to `"testing"`, we encoded as a `LEN` record with field number 2 containing -the ASCII string `"testing"`. The result is `` `120774657374696e67` ``. Breaking -up the bytes, - -```proto -12 07 [74 65 73 74 69 6e 67] -``` - -we see that the tag, `` `12` ``, is `00010 010`, or `2:LEN`. The byte that -follows is the int32 varint `7`, and the next seven bytes are the UTF-8 -encoding of `"testing"`. The int32 varint means that the max length of a string -is 2GB. - -In Protoscope, this is written as `2:LEN 7 "testing"`. However, it can be -inconvenient to repeat the length of the string (which, in Protoscope text, is -already quote-delimited). Wrapping Protoscope content in braces will generate a -length prefix for it: `{"testing"}` is a shorthand for `7 "testing"`. `{}` is -always inferred by fields to be a `LEN` record, so we can write this record -simply as `2: {"testing"}`. - -`bytes` fields are encoded in the same way. - -### Submessages {#embedded} - -Submessage fields also use the `LEN` wire type. Here's a message definition with -an embedded message of our original example message, `Test1`: - -```proto -message Test3 { - Test1 c = 3; -} -``` - -If `Test1`'s `a` field (i.e., `Test3`'s `c.a` field) is set to 150, we get ` -``1a03089601`` `. Breaking it up: - -```proto - 1a 03 [08 96 01] -``` - -The last three bytes (in `[]`) are exactly the same ones from our -[very first example](#simple). These bytes are preceded by a `LEN`-typed tag, -and a length of 3, exactly the same way as strings are encoded. - -In Protoscope, submessages are quite succinct. ` ``1a03089601`` ` can be written -as `3: {1: 150}`. - -## Missing Elements {#optional} - -Missing fields are easy to encode: we just leave out the record if -it's not present. This means that "huge" protos with only a few fields set are -quite sparse. - - - -## Repeated Elements {#repeated} - -Starting in Edition 2023, `repeated` fields of a primitive type -(any [scalar type](/programming-guides/proto2#scalar) -that is not `string` or `bytes`) are ["packed"](/editions/features#repeated_field_encoding) by default. - -Packed `repeated` fields, instead of being encoded as one -record per entry, are encoded as a single `LEN` record that contains each -element concatenated. To decode, elements are decoded from the `LEN` record one -by one until the payload is exhausted. The start of the next element is -determined by the length of the previous, which itself depends on the type of -the field. Thus, if we have: - -```proto -message Test4 { - string d = 4; - repeated int32 e = 6; -} -``` - -and we construct a `Test4` message with `d` set to `"hello"`, and `e` set to -`1`, `2`, and `3`, this *could* be encoded as `` `3206038e029ea705` ``, or -written out as Protoscope, - -```proto -4: {"hello"} -6: {3 270 86942} -``` - -However, if the repeated field is set to expanded (overriding the default packed -state) or is not packable (strings and messages) then an entry for each -individual value is encoded. Also, records for `e` do not need to appear -consecutively, and can be interleaved with other fields; only the order of -records for the same field with respect to each other is preserved. Thus, this -could look like the following: - -```proto -6: 1 -6: 2 -4: {"hello"} -6: 3 -``` - -Only repeated fields of primitive numeric types can be declared "packed". These -are types that would normally use the `VARINT`, `I32`, or `I64` wire types. - -Note that although there's usually no reason to encode more than one key-value -pair for a packed repeated field, parsers must be prepared to accept multiple -key-value pairs. In this case, the payloads should be concatenated. Each pair -must contain a whole number of elements. The following is a valid encoding of -the same message above that parsers must accept: - -```proto -6: {3 270} -6: {86942} -``` - -Protocol buffer parsers must be able to parse repeated fields that were compiled -as `packed` as if they were not packed, and vice versa. This permits adding -`[packed=true]` to existing fields in a forward- and backward-compatible way. - -### Oneofs {#oneofs} - -[`Oneof` fields](/programming-guides/proto2#oneof) are -encoded the same as if the fields were not in a `oneof`. The rules that apply to -`oneofs` are independent of how they are represented on the wire. - -### Last One Wins {#last-one-wins} - -Normally, an encoded message would never have more than one instance of a -non-`repeated` field. However, parsers are expected to handle the case in which -they do. For numeric types and strings, if the same field appears multiple -times, the parser accepts the *last* value it sees. For embedded message fields, -the parser merges multiple instances of the same field, as if with the -`Message::MergeFrom` method -- that is, all singular scalar fields in the latter -instance replace those in the former, singular embedded messages are merged, and -`repeated` fields are concatenated. The effect of these rules is that parsing -the concatenation of two encoded messages produces exactly the same result as if -you had parsed the two messages separately and merged the resulting objects. -That is, this: - -```cpp -MyMessage message; -message.ParseFromString(str1 + str2); -``` - -is equivalent to this: - -```cpp -MyMessage message, message2; -message.ParseFromString(str1); -message2.ParseFromString(str2); -message.MergeFrom(message2); -``` - -This property is occasionally useful, as it allows you to merge two messages (by -concatenation) even if you do not know their types. - -### Maps {#maps} - -Map fields are just a shorthand for a special kind of repeated field. If we have - -```proto -message Test6 { - map g = 7; -} -``` - -this is actually the same as - -```proto -message Test6 { - message g_Entry { - string key = 1; - int32 value = 2; - } - repeated g_Entry g = 7; -} -``` - -Thus, maps are encoded almost exactly like a `repeated` message field: as a -sequence of `LEN`-typed records, with two fields each. The exception is that -order is not guaranteed to be preserved with maps during serialization. - -## Groups {#groups} - -Groups are a deprecated feature that should not be used, but they remain in the -wire format, and deserve a passing mention. - -A group is a bit like a submessage, but it is delimited by special tags rather -than by a `LEN` prefix. Each group in a message has a field number, which is -used on these special tags. - -A group with field number `8` begins with an `8:SGROUP` tag. `SGROUP` records -have empty payloads, so all this does is denote the start of the group. Once all -the fields in the group are listed, a corresponding `8:EGROUP` tag denotes its -end. `EGROUP` records also have no payload, so `8:EGROUP` is the entire record. -Group field numbers need to match up. If we encounter `7:EGROUP` where we expect -`8:EGROUP`, the message is mal-formed. - -Protoscope provides a convenient syntax for writing groups. Instead of writing - -```proto -8:SGROUP - 1: 2 - 3: {"foo"} -8:EGROUP -``` - -Protoscope allows - -```proto -8: !{ - 1: 2 - 3: {"foo"} -} -``` - -This will generate the appropriate start and end group markers. The `!{}` syntax -can only occur immediately after an un-typed tag expression, like `8:`. - -## Field Order {#order} - -Field numbers may be declared in any order in a `.proto` file. The order chosen -has no effect on how the messages are serialized. - -When a message is serialized, there is no guaranteed order for how its known or -[unknown fields](/programming-guides/proto2#updating) -will be written. Serialization order is an implementation detail, and the -details of any particular implementation may change in the future. Therefore, -protocol buffer parsers must be able to parse fields in any order. - -### Implications {#implications} - -* Do not assume the byte output of a serialized message is stable. This is - especially true for messages with transitive bytes fields representing other - serialized protocol buffer messages. -* By default, repeated invocations of serialization methods on the same - protocol buffer message instance may not produce the same byte output. That - is, the default serialization is not deterministic. - * Deterministic serialization only guarantees the same byte output for a - particular binary. The byte output may change across different versions - of the binary. -* The following checks may fail for a protocol buffer message instance `foo`: - * `foo.SerializeAsString() == foo.SerializeAsString()` - * `Hash(foo.SerializeAsString()) == Hash(foo.SerializeAsString())` - * `CRC(foo.SerializeAsString()) == CRC(foo.SerializeAsString())` - * `FingerPrint(foo.SerializeAsString()) == - FingerPrint(foo.SerializeAsString())` -* Here are a few example scenarios where logically equivalent protocol buffer - messages `foo` and `bar` may serialize to different byte outputs: - * `bar` is serialized by an old server that treats some fields as unknown. - * `bar` is serialized by a server that is implemented in a different - programming language and serializes fields in different order. - * `bar` has a field that serializes in a non-deterministic manner. - * `bar` has a field that stores a serialized byte output of a protocol - buffer message which is serialized differently. - * `bar` is serialized by a new server that serializes fields in a - different order due to an implementation change. - * `foo` and `bar` are concatenations of the same individual messages in a - different order. - -## Encoded Proto Size Limitations {#size-limit} - -Protos must be smaller than 2 GiB when serialized. Many proto implementations -will refuse to serialize or parse messages that exceed this limit. - -## Condensed Reference Card {#cheat-sheet} - -The following provides the most prominent parts of the wire format in an -easy-to-reference format. - -```none -message := (tag value)* - -tag := (field << 3) bit-or wire_type; - encoded as uint32 varint -value := varint for wire_type == VARINT, - i32 for wire_type == I32, - i64 for wire_type == I64, - len-prefix for wire_type == LEN, - for wire_type == SGROUP or EGROUP - -varint := int32 | int64 | uint32 | uint64 | bool | enum | sint32 | sint64; - encoded as varints (sintN are ZigZag-encoded first) -i32 := sfixed32 | fixed32 | float; - encoded as 4-byte little-endian (float is IEEE 754 - single-precision); memcpy of the equivalent C types (u?int32_t, - float) -i64 := sfixed64 | fixed64 | double; - encoded as 8-byte little-endian (double is IEEE 754 - double-precision); memcpy of the equivalent C types (u?int64_t, - double) - -len-prefix := size (message | string | bytes | packed); - size encoded as int32 varint -string := valid UTF-8 string (e.g. ASCII); - max 2GB of bytes -bytes := any sequence of 8-bit bytes; - max 2GB of bytes -packed := varint* | i32* | i64*, - consecutive values of the type specified in `.proto` -``` - -See also the -[Protoscope Language Reference](https://github.com/protocolbuffers/protoscope/blob/main/language.txt). - -### Key {#cheat-sheet-key} - -`message := (tag value)*` -: A message is encoded as a sequence of zero or more pairs of tags and values. - -`tag := (field << 3) bit-or wire_type` -: A tag is a combination of a `wire_type`, stored in the least significant - three bits, and the field number that is defined in the `.proto` file. - -`value := varint for wire_type == VARINT, ...` -: A value is stored differently depending on the `wire_type` specified in the - tag. - -`varint := int32 | int64 | uint32 | uint64 | bool | enum | sint32 | sint64` -: You can use varint to store any of the listed data types. - -`i32 := sfixed32 | fixed32 | float` -: You can use fixed32 to store any of the listed data types. - -`i64 := sfixed64 | fixed64 | double` -: You can use fixed64 to store any of the listed data types. - -`len-prefix := size (message | string | bytes | packed)` -: A length-prefixed value is stored as a length (encoded as a varint), and - then one of the listed data types. - -`string := valid UTF-8 string (e.g. ASCII)` -: As described, a string must use UTF-8 character encoding. A string cannot - exceed 2GB. - -`bytes := any sequence of 8-bit bytes` -: As described, bytes can store custom data types, up to 2GB in size. - -`packed := varint* | i32* | i64*` -: Use the `packed` data type when you are storing consecutive values of the - type described in the protocol definition. The tag is dropped for values - after the first, which amortizes the costs of tags to one per field, rather - than per element. diff --git a/content/programming-guides/enum.md b/content/programming-guides/enum.md deleted file mode 100644 index 64b6fe170..000000000 --- a/content/programming-guides/enum.md +++ /dev/null @@ -1,219 +0,0 @@ -+++ -title = "Enum Behavior" -weight = 55 -description = "Explains how enums currently work in Protocol Buffers vs. how they should work." -type = "docs" -+++ - -Enums behave differently in different language libraries. This topic covers the -different behaviors as well as the plans to move protobufs to a state where they -are consistent across all languages. If you're looking for information on how to -use enums in general, see the corresponding sections in the -[proto2](/programming-guides/proto2#enum), -[proto3](/programming-guides/proto3#enum), and -[editions 2023](/programming-guides/editions#enum) -language guide topics. - -## Definitions {#definitions} - -Enums have two distinct flavors (*open* and *closed*). They behave identically -except in their handling of unknown values. Practically, this means that simple -cases work the same, but some corner cases have interesting implications. - -For the purpose of explanation, let us assume we have the following `.proto` -file (we are deliberately not specifying if this is a `syntax = "proto2"`, -`syntax = "proto3"`, or `edition = "2023"` file right now): - -``` -enum Enum { - A = 0; - B = 1; -} - -message Msg { - optional Enum enum = 1; -} -``` - -The distinction between *open* and *closed* can be encapsulated in a single -question: - -> What happens when a program parses binary data that contains field 1 with the -> value `2`? - -* **Open** enums will parse the value `2` and store it directly in the field. - Accessor will report the field as being *set* and will return something that - represents `2`. -* **Closed** enums will parse the value `2` and store it in the message's - unknown field set. Accessors will report the field as being *unset* and will - return the enum's default value. - -## Implications of *Closed* Enums - -The behavior of *closed* enums has unexpected consequences when parsing a -repeated field. When a `repeated Enum` field is parsed, all unknown values will -be placed in the -[unknown field](/programming-guides/proto3/#unknowns) -set. When it is serialized those unknown values will be written again, *but not -in their original place in the list*. For example, given the `.proto` file: - -``` -enum Enum { - A = 0; - B = 1; -} - -message Msg { - repeated Enum r = 1; -} -``` - -A wire format containing the values `[0, 2, 1, 2]` for field 1 will parse so -that the repeated field contains `[0, 1]` and the value `[2, 2]` will end up -stored as an unknown field. After reserializing the message, the wire format -will correspond to `[0, 1, 2, 2]`. - -Similarly, maps with *closed* enums for their value will place entire entries -(key and value) in the unknown fields whenever the value is unknown. - -## History {#history} - -Prior to the introduction of `syntax = "proto3"` all enums were *closed*. Proto3 -and editions use *open* enums specifically because of the unexpected behavior -that *closed* enums cause. You can use -[`features.enum_type`](/editions/features#enum_type) to -explicitly set editions enums to closed, if needed. - -## Specification {#spec} - -The following specifies the behavior of conformant implementations for protobuf. -Because this is subtle, many implementations are out of conformance. See -[Known Issues](#known-issues) for details on how different implementations -behave. - -* When a `proto2` file imports an enum defined in a `proto2` file, that enum - should be treated as **closed**. -* When a `proto3` file imports an enum defined in a `proto3` file, that enum - should be treated as **open**. -* When a `proto3` file imports an enum defined in a `proto2` file, the - `protoc` compiler will produce an error. -* When a `proto2` file imports an enum defined in a `proto3` file, that enum - should be treated as **open**. - -Editions honor whatever behavior the enum had in the file being imported from. -Proto2 enums are always treated as closed, proto3 enums are always treated as -open, and when importing from another editions file it uses the feature setting. - -## Known Issues {#known-issues} - -### C++ {#cpp} - -All known C++ releases are out of conformance. When a `proto2` file imports an -enum defined in a `proto3` file, C++ treats that field as a **closed** enum. -Under editions, this behavior is represented by the deprecated field feature -[`features.(pb.cpp).legacy_closed_enum`](/editions/features#legacy_closed_enum). -There are two options for moving to conformant behavior: - -* Remove the field feature. This is the recommended approach, but may cause - runtime behavior changes. Without the feature, unrecognized integers will - end up stored in the field cast to the enum type instead of being put into - the unknown field set. -* Change the enum to closed. This is discouraged, and can cause runtime - behavior changes if *anybody else* is using the enum. Unrecognized integers - will end up in the unknown field set instead of those fields. - -### C# {#csharp} - -All known C# releases are out of conformance. C# treats all enums as **open**. - -### Java {#java} - -All known Java releases are out of conformance. When a `proto2` file imports an -enum defined in a `proto3` file, Java treats that field as a **closed** enum. - -Under editions, this behavior is represented by the deprecated field feature -[`features.(pb.java).legacy_closed_enum`](/editions/features#legacy_closed_enum)). -There are two options for moving to conformant behavior: - -* Remove the field feature. This may cause runtime behavior changes. Without - the feature, unrecognized integers will end up stored in the field and the - `UNRECOGNIZED` value will be returned by the enum getter. Before, these - values would be put into the unknown field set. -* Change the enum to closed. If *anybody else* is using it they may see - runtime behavior changes. Unrecognized integers will end up in the unknown - field set instead of those fields. - -> **NOTE:** Java's handling of **open** enums has surprising edge cases. Given -> the following definitions: -> -> ``` -> syntax = "proto3"; -> -> enum Enum { -> A = 0; -> B = 1; -> } -> -> message Msg { -> repeated Enum name = 1; -> } -> ``` -> -> Java will generate the methods `Enum getName()` and `int getNameValue()`. The -> method `getName` will return `Enum.UNRECOGNIZED` for values outside the known -> set (such as `2`), whereas `getNameValue` will return `2`. -> -> Similarly, Java will generate methods `Builder setName(Enum value)` and -> `Builder setNameValue(int value)`. The method `setName` will throw an -> exception when passed `Enum.UNRECOGNIZED`, whereas `setNameValue` will accept -> `2`. - -### Kotlin {#kotlin} - -All known Kotlin releases are out of conformance. When a `proto2` file imports -an enum defined in a `proto3` file, Kotlin treats that field as a **closed** -enum. - -Kotlin is built on Java and shares all of its oddities. - -### Go {#go} - -All known Go releases are out of conformance. Go treats all enums as **open**. - -### JSPB {#jspb} - -All known JSPB releases are out of conformance. JSPB treats all enums as -**open**. - -### PHP {#php} - -PHP is conformant. - -### Python {#python} - -Python is conformant in versions above 4.22.0 (released 2023 Q1). - -Older versions which are no longer supported are out of conformance. When a -`proto2` file imports an enum defined in a `proto3` file, non-conformant Python -versions treat that field as a **closed** enum. - -### Ruby {#ruby} - -All known Ruby releases are out of conformance. Ruby treats all enums as -**open**. - -### Objective-C {#obj-c} - -Objective-C is conformant in versions above 3.22.0 (released 2023 Q1). - -Older versions which are no longer supported and are out of conformance. When a -`proto2` file imports an enum defined in a `proto3` file, non-conformant ObjC -versions treat that field as a **closed** enum. - -### Swift {#swift} - -Swift is conformant. - -### Dart {#dart} - -Dart treats all enums as **closed**. diff --git a/content/programming-guides/extension_declarations.md b/content/programming-guides/extension_declarations.md deleted file mode 100644 index cca3d71e6..000000000 --- a/content/programming-guides/extension_declarations.md +++ /dev/null @@ -1,256 +0,0 @@ -+++ -title = "Extension Declarations" -weight = 83 -description = "Describes in detail what extension declarations are, why we need them, and how we use them." -type = "docs" -+++ - - - -## Introduction {#intro} - -This page describes in detail what extension declarations are, why we need them, -and how we use them. - -{{% alert title="Note" color="note" %}} -Proto3 does not support extensions (except for -[declaring custom options](/programming-guides/proto3/#customoptions)). -Extensions are fully supported in proto2 and editions -though.{{% /alert %}} - -If you need an introduction to extensions, read this -[extensions guide](https://protobuf.dev/programming-guides/proto2/#extensions) - -## Motivation {#motivation} - -Extension declarations aim to strike a happy medium between regular fields and -extensions. Like extensions, they avoid creating a dependency on the message -type of the field, which therefore results in a leaner build graph and smaller -binaries in environments where unused messages are difficult or impossible to -strip. Like regular fields, the field name/number appear in the enclosing -message, which makes it easier to avoid conflicts and see a convenient listing -of what fields are declared. - -Listing the occupied extension numbers with extension declarations makes it -easier for users to pick an available extension number and to avoid conflicts. - -## Usage {#usage} - -Extension declarations are an option of extension ranges. Like forward -declarations in C++, you can declare the field type, field name, and cardinality -(singular or repeated) of an extension field without importing the `.proto` file -containing the full extension definition: - -```proto -edition = "2023"; - -message Foo { - extensions 4 to 1000 [ - declaration = { - number: 4, - full_name: ".my.package.event_annotations", - type: ".logs.proto.ValidationAnnotations", - repeated: true }, - declaration = { - number: 999, - full_name: ".foo.package.bar", - type: "int32"}]; -} -``` - -This syntax has the following semantics: - -* Multiple `declaration`s with distinct extension numbers can be defined in a - single extension range if the size of the range allows. -* If there is any declaration for the extension range, *all* extensions of the - range must also be declared. This prevents non-declared extensions from - being added, and enforces that any new extensions use declarations for the - range. -* The given message type (`.logs.proto.ValidationAnnotations`) does not need - to have been previously defined or imported. We check only that it is a - valid name that could potentially be defined in another `.proto` file. -* When this or another `.proto` file defines an extension of this message - (`Foo`) with this name or number, we enforce that the number, type, and full - name of the extension match what is forward-declared here. - -{{% alert title="Warning" color="warning" %}} -Avoid using declarations for extension range groups such as `extensions 4, 999`. -It is unclear which extension range the declarations apply to, and it is -currently -unsupported.{{% /alert %}} - -The extension declarations expect two extension fields with different packages: - -```proto -package my.package; -extend Foo { - repeated logs.proto.ValidationAnnotations event_annotations = 4; -} -``` - -```proto -package foo.package; -extend Foo { - optional int32 bar = 999; -} -``` - -### Reserved Declarations {#reserved} - -An extension declaration can be marked `reserved: true` to indicate that it is -no longer actively used and the extension definition has been deleted. **Do not -delete the extension declaration or edit its `type` or `full_name` value**. - -This `reserved` tag is separate from the reserved keyword for regular fields and -**does not require breaking up the extension range**. - -```proto {highlight="context:reserved"} -edition = "2023"; - -message Foo { - extensions 4 to 1000 [ - declaration = { - number: 500, - full_name: ".my.package.event_annotations", - type: ".logs.proto.ValidationAnnotations", - reserved: true }]; -} -``` - -An extension field definition using a number that is `reserved` in the -declaration will fail to compile. - -## Representation in descriptor.proto {#representation} - -Extension declaration is represented in descriptor.proto as fields in -`proto2.ExtensionRangeOptions`: - -```proto -message ExtensionRangeOptions { - message Declaration { - optional int32 number = 1; - optional string full_name = 2; - optional string type = 3; - optional bool reserved = 5; - optional bool repeated = 6; - } - repeated Declaration declaration = 2; -} -``` - -## Reflection Field Lookup {#reflection} - -Extension declarations are *not* returned from the normal field lookup functions -like `Descriptor::FindFieldByName()` or `Descriptor::FindFieldByNumber()`. Like -extensions, they are discoverable by extension lookup routines like -`DescriptorPool::FindExtensionByName()`. This is an explicit choice that -reflects the fact that declarations are not definitions and do not have enough -information to return a full `FieldDescriptor`. - -Declared extensions still behave like regular extensions from the perspective of -TextFormat and JSON. It also means that migrating an existing field to a -declared extension will require first migrating any reflective use of that -field. - -## Use Extension Declarations to Allocate Numbers {#recommendation} - -Extensions use field numbers just like ordinary fields do, so it is important -for each extension to be assigned a number that is unique within the parent -message. We recommend using extension -declarations to declare the field -number and type for each extension in the parent message. The extension -declarations serve as a registry of all the parent message's extensions, and -protoc will enforce that there are no field number conflicts. When you add a new -extension, choose the next available number usually by just incrementing by one -the previously added extension number. - -**TIP:** There is a [special guidance](#message-set) for -`MessageSet` which provides a script to help pick -the next available number. - -Whenever you delete an extension, make sure to mark the field number `reserved` -to eliminate the risk of accidentally reusing -it. - -This convention is only a recommendation--the protobuf team does not have the -ability or desire to force anyone to adhere to it for every extendable message. -If you as the owner of an extendable proto do not want to coordinate extension -numbers through extension declarations, you can choose to provide coordination -through other means. Be very careful, though, -because accidental reuse of an extension number can cause serious problems. - -One way to sidestep the issue would be to avoid extensions entirely and use -[`google.protobuf.Any`](/programming-guides/proto3/#any) -instead. This could be a good choice for APIs that front storage or for -pass-through systems where the client cares about the contents of the proto but -the system receiving it does not. - -### Consequences of Reusing an Extension Number {#reusing} - -An extension is a field defined outside the container message; usually in a -separate .proto file. This distribution of definitions makes it easy for two -developers to accidentally create different definitions for the same extension -field number. - -The consequences of changing an extension definition are the same for extensions -and standard fields. Reusing a field number introduces an ambiguity in how a -proto should be decoded from the wire format. The protobuf wire format is lean -and doesn’t provide a good way to detect fields encoded using one definition and -decoded using another. - -This ambiguity can manifest in a short time frame, such as a client using one -extension definition and a server using another communicating -. - -This ambiguity can also manifest over a longer time frame, such as storing data -encoded using one extension definition and later retrieving and decoding using -the second extension definition. This long-term case can be difficult to -diagnose if the first extension definition was deleted after the data was -encoded and stored. - -The outcome of this can be: - -1. A parse error (best case scenario). -2. Leaked PII / SPII – if PII or SPII is written using one extension definition - and read using another extension definition. -3. Data Corruption – if data is read using the “wrong” definition, modified and - rewritten. - -Data definition ambiguity is almost certainly going to cost someone time for -debugging at a minimum. It could also cause data leaks or corruption that takes -months to clean up. - -## Usage Tips - -### Never Delete an Extension Declaration {#never-delete} - -Deleting an extension declaration opens the door to accidental reuse in the -future. If the extension is no longer processed and the definition is deleted, -the extension declaration can be [marked reserved](#reserved). - -### Never Use a Field Name or Number from the `reserved` List for a New Extension Declaration {#never-reuse-reserved} - -Reserved numbers may have been used for fields or other extensions in the past. - -Using the `full_name` of a reserved field -is not recommended -due -to the possibility of ambiguity when using textproto. - -### Never change the type of an existing extension declaration {#never-change-type} - -Changing the extension field's type can result in data corruption. - -If the extension field is of an enum or message type, and that enum or message -type is being renamed, updating the declaration name is required and safe. To -avoid breakages, the update of the type, the extension field definition, and -extension declaration should all happen in a single -commit. - -### Use Caution When Renaming an Extension Field {#caution-renaming} - -While renaming an extension field is fine for the wire format, it can break JSON -and TextFormat parsing. diff --git a/content/programming-guides/field_presence.md b/content/programming-guides/field_presence.md deleted file mode 100644 index 22d998915..000000000 --- a/content/programming-guides/field_presence.md +++ /dev/null @@ -1,660 +0,0 @@ -+++ -title = "Application Note: Field Presence" -weight = 85 -linkTitle = "Field Presence" -description = "Explains the various presence-tracking disciplines for protobuf fields. It also explains the behavior of explicit presence-tracking for singular proto3 fields with basic types." -type = "docs" -+++ - -## Background {#background} - -*Field presence* is the notion of whether a protobuf field has a value. There -are two different manifestations of presence for protobufs: *implicit presence*, -where the generated message API stores field values (only), and *explicit -presence*, where the API also stores whether or not a field has been set. - -{{% alert title="Note" color="note" %}} We -recommend always adding the `optional` label for proto3 basic types. This -provides a smoother path to editions, which uses explicit presence by -default.{{% /alert %}} - -### Presence Disciplines {#disciplines} - -*Presence disciplines* define the semantics for translating between the *API -representation* and the *serialized representation*. The *implicit presence* -discipline relies upon the field value itself to make decisions at -(de)serialization time, while the *explicit presence* discipline relies upon the -explicit tracking state instead. - -### Presence in *Tag-value stream* (Wire Format) Serialization {#presence-tag-value} - -The wire format is a stream of tagged, *self-delimiting* values. By definition, -the wire format represents a sequence of *present* values. In other words, every -value found within a serialization represents a *present* field; furthermore, -the serialization contains no information about not-present values. - -The generated API for a proto message includes (de)serialization definitions -which translate between API types and a stream of definitionally *present* (tag, -value) pairs. This translation is designed to be forward- and -backward-compatible across changes to the message definition; however, this -compatibility introduces some (perhaps surprising) considerations when -deserializing wire-formatted messages: - -- When serializing, fields with *implicit presence* are not serialized if they - contain their default value. - - For numeric types, the default is 0. - - For enums, the default is the zero-valued enumerator. - - For strings, bytes, and repeated fields, the default is the zero-length - 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 - presence, then these values may not be re-serialized; i.e., the empty field - may be "not present" after a serialization round-trip. -- When deserializing, duplicate field values may be handled in different ways - depending on the field definition. - - Duplicate `repeated` fields are typically appended to the field's API - representation. (Note that serializing a *packed* repeated field - produces only one, length-delimited value in the tag stream.) - - Duplicate `optional` field values follow the rule that "the last one - wins." -- `oneof` fields expose the API-level invariant that only one field is set at - a time. However, the wire format may include multiple (tag, value) pairs - which notionally belong to the `oneof`. Similar to `optional` fields, the - generated API follows the "last one wins" rule. -- Out-of-range values are not returned for enum fields in generated proto2 - APIs. However, out-of-range values may be stored as *unknown fields* in the - API, even though the wire-format tag was recognized. - -### Presence in *Named-field Mapping* Formats {#presence-named-field} - -Protobufs can be represented in human-readable, textual forms. Two notable -formats are TextFormat (the output format produced by generated message -`DebugString` methods) and JSON. - -These formats have correctness requirements of their own, and are generally -stricter than *tagged-value stream* formats. However, TextFormat more closely -mimics the semantics of the wire format, and does, in certain cases, provide -similar semantics (for example, appending repeated name-value mappings to a -repeated field). In particular, similar to the wire format, TextFormat only -includes fields which are present. - -JSON is a much stricter format, however, and cannot validly represent some -semantics of the wire format or TextFormat. - -- Notably, JSON *elements* are semantically unordered, and each member must - have a unique name. This is different from TextFormat rules for repeated - fields. -- JSON may include fields that are "not present," unlike the *implicit - presence* discipline for other formats: - - JSON defines a `null` value, which may be used to represent a *defined - but not-present field*. - - Repeated field values may be included in the formatted output, even if - they are equal to the default (an empty list). -- Because JSON elements are unordered, there is no way to unambiguously - interpret the "last one wins" rule. - - In most cases, this is fine: JSON elements must have unique names: - repeated field values are not valid JSON, so they do not need to be - resolved as they are for TextFormat. - - However, this means that it may not be possible to interpret `oneof` - fields unambiguously: if multiple cases are present, they are unordered. - -In theory, JSON *can* represent presence in a semantic-preserving fashion. In -practice, however, presence correctness can vary depending upon implementation -choices, especially if JSON was chosen as a means to interoperate with clients -not using protobufs. - -### Presence in Proto2 APIs {#presence-proto2} - -This table outlines whether presence is tracked for fields in proto2 APIs (both -for generated APIs and using dynamic reflection): - -Field type | Explicit Presence --------------------------------------------- | ----------------- -Singular numeric (integer or floating point) | ✔️ -Singular enum | ✔️ -Singular string or bytes | ✔️ -Singular message | ✔️ -Repeated | -Oneofs | ✔️ -Maps | - -Singular fields (of all types) track presence explicitly in the generated API. -The generated message interface includes methods to query presence of fields. -For example, the field `foo` has a corresponding `has_foo` method. (The specific -name follows the same language-specific naming convention as the field -accessors.) These methods are sometimes referred to as "hazzers" within the -protobuf implementation. - -Similar to singular fields, `oneof` fields explicitly track which one of the -members, if any, contains a value. For example, consider this example `oneof`: - -```protobuf -oneof foo { - int32 a = 1; - float b = 2; -} -``` - -Depending on the target language, the generated API would generally include -several methods: - -- A hazzer for the oneof: `has_foo` -- A *oneof case* method: `foo` -- Hazzers for the members: `has_a`, `has_b` -- Getters for the members: `a`, `b` - -Repeated fields and maps do not track presence: there is no distinction between -an *empty* and a *not-present* repeated field. - -### Presence in Proto3 APIs {#presence-proto3} - -This table outlines whether presence is tracked for fields in proto3 APIs (both -for generated APIs and using dynamic reflection): - -Field type | `optional` | Explicit Presence --------------------------------------------- | ---------- | ----------------- -Singular numeric (integer or floating point) | No | -Singular numeric (integer or floating point) | Yes | ✔️ -Singular enum | No | -Singular enum | Yes | ✔️ -Singular string or bytes | No | -Singular string or bytes | Yes | ✔️ -Singular message | No | ✔️ -Singular message | Yes | ✔️ -Repeated | N/A | -Oneofs | N/A | ✔️ -Maps | N/A | - -Similar to proto2 APIs, proto3 does not track presence explicitly for repeated -fields. Without the `optional` label, proto3 APIs do not track presence for -basic types (numeric, string, bytes, and enums), either. Oneof fields -affirmatively expose presence, although the same set of hazzer methods may not -generated as in proto2 APIs. - -This default behavior of not tracking presence without the `optional` label is -different from the proto2 behavior. We recommend using the `optional` label with -proto3 unless you have a specific reason not to. - -Under the *implicit presence* discipline, the default value is synonymous with -"not present" for purposes of serialization. To notionally "clear" a field (so -it won't be serialized), an API user would set it to the default value. - -The default value for enum-typed fields under *implicit presence* is the -corresponding 0-valued enumerator. Under proto3 syntax rules, all enum types are -required to have an enumerator value which maps to 0. By convention, this is an -`UNKNOWN` or similarly-named enumerator. If the zero value is notionally outside -the domain of valid values for the application, this behavior can be thought of -as tantamount to *explicit presence*. - -### Presence in Editions APIs {#presence-editions} - -This table outlines whether presence is tracked for fields in editions APIs -(both for generated APIs and using dynamic reflection): - -Field type | Explicit Presence --------------------------------------------- | ----------------- -Singular numeric (integer or floating point) | ✔️ -Singular enum | ✔️ -Singular string or bytes | ✔️ -Singular message† | ✔️ -Repeated | -Oneofs† | ✔️ -Maps | - -† Messages and oneofs have never had implicit presence, and editions -doesn't allow you to set `field_presence = IMPLICIT`. - -Editions-based APIs track field presence explicitly, similarly to proto2, unless -`features.field_presence` is set to `IMPLICIT`. Similar to proto2 APIs, -editions-based APIs do not track presence explicitly for repeated fields. - -## Semantic Differences {#semantic-differences} - -The *implicit presence* serialization discipline results in visible differences -from the *explicit presence* tracking discipline, when the default value is set. -For a singular field with numeric, enum, or string type: - -- *Implicit presence* discipline: - - Default values are not serialized. - - Default values are *not* merged-from. - - To "clear" a field, it is set to its default value. - - The default value may mean: - - the field was explicitly set to its default value, which is valid in - the application-specific domain of values; - - the field was notionally "cleared" by setting its default; or - - the field was never set. - - `has_` methods are not generated (but see note after this list) -- *Explicit presence* discipline: - - Explicitly set values are always serialized, including default values. - - Un-set fields are never merged-from. - - Explicitly set fields -- including default values -- *are* merged-from. - - A generated `has_foo` method indicates whether or not the field `foo` - has been set (and not cleared). - - A generated `clear_foo` method must be used to clear (i.e., un-set) the - value. - -{{% alert title="Note" color="note" %}} -`Has_` methods are not generated for implicit members in most cases. The -exception to this behavior is Dart, which generates `has_` methods with proto3 -proto schema files.{{% /alert %}} - -### Considerations for Merging {#merging} - -Under the *implicit presence* rules, it is effectively impossible for a target -field to merge-from its default value (using the protobuf's API merging -functions). This is because default values are skipped, similar to the *implicit -presence* serialization discipline. Merging only updates the target (merged-to) -message using the non-skipped values from the update (merged-from) message. - -The difference in merging behavior has further implications for protocols which -rely on partial "patch" updates. If field presence is not tracked, then an -update patch alone cannot represent an update to the default value, because only -non-default values are merged-from. - -Updating to set a default value in this case requires some external mechanism, -such as `FieldMask`. However, if presence *is* tracked, then all explicitly-set -values -- even default values -- will be merged into the target. - -### Considerations for change-compatibility {#change-compatibility} - -Changing a field between *explicit presence* and *implicit presence* is a -binary-compatible change for serialized values in wire format. However, the -serialized representation of the message may differ, depending on which version -of the message definition was used for serialization. Specifically, when a -"sender" explicitly sets a field to its default value: - -- The serialized value following *implicit presence* discipline does not - contain the default value, even though it was explicitly set. -- The serialized value following *explicit presence* discipline contains every - "present" field, even if it contains the default value. - -This change may or may not be safe, depending on the application's semantics. -For example, consider two clients with different versions of a message -definition. - -Client A uses this definition of the message, which follows the *explicit -presence* serialization discipline for field `foo`: - -```protobuf -syntax = "proto3"; -message Msg { - optional int32 foo = 1; -} -``` - -Client B uses a definition of the same message, except that it follows the *no -presence* discipline: - -```protobuf -syntax = "proto3"; -message Msg { - int32 foo = 1; -} -``` - -Now, consider a scenario where client A observes `foo`'s presence as the clients -repeatedly exchange the "same" message by deserializing and reserializing: - -```protobuf -// Client A: -Msg m_a; -m_a.set_foo(1); // non-default value -assert(m_a.has_foo()); // OK -Send(m_a.SerializeAsString()); // to client B - -// Client B: -Msg m_b; -m_b.ParseFromString(Receive()); // from client A -assert(m_b.foo() == 1); // OK -Send(m_b.SerializeAsString()); // to client A - -// Client A: -m_a.ParseFromString(Receive()); // from client B -assert(m_a.foo() == 1); // OK -assert(m_a.has_foo()); // OK -m_a.set_foo(0); // default value -Send(m_a.SerializeAsString()); // to client B - -// Client B: -Msg m_b; -m_b.ParseFromString(Receive()); // from client A -assert(m_b.foo() == 0); // OK -Send(m_b.SerializeAsString()); // to client A - -// Client A: -m_a.ParseFromString(Receive()); // from client B -assert(m_a.foo() == 0); // OK -assert(m_a.has_foo()); // FAIL -``` - -If client A depends on *explicit presence* for `foo`, then a "round trip" -through client B will be lossy from the perspective of client A. In the example, -this is not a safe change: client A requires (by `assert`) that the field is -present; even without any modifications through the API, that requirement fails -in a value- and peer-dependent case. - -## How to Enable *Explicit Presence* in Proto3 {#enable-explicit-proto3} - -These are the general steps to use field tracking support for proto3: - -1. Add an `optional` field to a `.proto` file. -1. Run `protoc` (at least v3.15, or v3.12 using - `--experimental_allow_proto3_optional` flag). -1. Use the generated "hazzer" methods and "clear" methods in application code, - instead of comparing or setting default values. - -### `.proto` File Changes {#proto-file-changes} - -This is an example of a proto3 message with fields which follow both *no -presence* and *explicit presence* semantics: - -```protobuf -syntax = "proto3"; -package example; - -message MyMessage { - // implicit presence: - int32 not_tracked = 1; - - // Explicit presence: - optional int32 tracked = 2; -} -``` - -### `protoc` Invocation {#protoc-invocation} - -Presence tracking for proto3 messages is enabled by default -[since v3.15.0](https://github.com/protocolbuffers/protobuf/releases/tag/v3.15.0) -release, formerly up until -[v3.12.0](https://github.com/protocolbuffers/protobuf/releases/tag/v3.12.0) the -`--experimental_allow_proto3_optional` flag was required when using presence -tracking with protoc. - -### Using the Generated Code - -The generated code for proto3 fields with *explicit presence* (the `optional` -label) will be the same as it would be in a proto2 file. - -This is the definition used in the "implicit presence" examples below: - -```protobuf -syntax = "proto3"; -package example; -message Msg { - int32 foo = 1; -} -``` - -This is the definition used in the "explicit presence" examples below: - -```protobuf -syntax = "proto3"; -package example; -message Msg { - optional int32 foo = 1; -} -``` - -In the examples, a function `GetProto` constructs and returns a message of type -`Msg` with unspecified contents. - -#### C++ Example {#cpp-example} - -Implicit presence: - -```cpp -Msg m = GetProto(); -if (m.foo() != 0) { - // "Clear" the field: - m.set_foo(0); -} else { - // Default value: field may not have been present. - m.set_foo(1); -} -``` - -Explicit presence: - -```c++ -Msg m = GetProto(); -if (m.has_foo()) { - // Clear the field: - m.clear_foo(); -} else { - // Field is not present, so set it. - m.set_foo(1); -} -``` - -#### C# Example {#csharp-example} - -Implicit presence: - -```c# -var m = GetProto(); -if (m.Foo != 0) { - // "Clear" the field: - m.Foo = 0; -} else { - // Default value: field may not have been present. - m.Foo = 1; -} -``` - -Explicit presence: - -```c# -var m = GetProto(); -if (m.HasFoo) { - // Clear the field: - m.ClearFoo(); -} else { - // Field is not present, so set it. - m.Foo = 1; -} -``` - -#### Go Example {#go-example} - -Implicit presence: - -```go -m := GetProto() -if m.Foo != 0 { - // "Clear" the field: - m.Foo = 0 -} else { - // Default value: field may not have been present. - m.Foo = 1 -} -``` - -Explicit presence: - -```go -m := GetProto() -if m.Foo != nil { - // Clear the field: - m.Foo = nil -} else { - // Field is not present, so set it. - m.Foo = proto.Int32(1) -} -``` - -#### Java Example {#java-example} - -These examples use a `Builder` to demonstrate clearing. Simply checking presence -and getting values from a `Builder` follows the same API as the message type. - -Implicit presence: - -```java -Msg.Builder m = GetProto().toBuilder(); -if (m.getFoo() != 0) { - // "Clear" the field: - m.setFoo(0); -} else { - // Default value: field may not have been present. - m.setFoo(1); -} -``` - -Explicit presence: - -```java -Msg.Builder m = GetProto().toBuilder(); -if (m.hasFoo()) { - // Clear the field: - m.clearFoo() -} else { - // Field is not present, so set it. - m.setFoo(1); -} -``` - -#### Python Example {#python-example} - -Implicit presence: - -```python -m = example.Msg() -if m.foo != 0: - # "Clear" the field: - m.foo = 0 -else: - # Default value: field may not have been present. - m.foo = 1 -``` - -Explicit presence: - -```python -m = example.Msg() -if m.HasField('foo'): - # Clear the field: - m.ClearField('foo') -else: - # Field is not present, so set it. - m.foo = 1 -``` - -#### Ruby Example {#ruby-example} - -Implicit presence: - -```ruby -m = Msg.new -if m.foo != 0 - # "Clear" the field: - m.foo = 0 -else - # Default value: field may not have been present. - m.foo = 1 -end -``` - -Explicit presence: - -```ruby -m = Msg.new -if m.has_foo? - # Clear the field: - m.clear_foo -else - # Field is not present, so set it. - m.foo = 1 -end -``` - -#### Javascript Example {#js-example} - -Implicit presence: - -```js -var m = new Msg(); -if (m.getFoo() != 0) { - // "Clear" the field: - m.setFoo(0); -} else { - // Default value: field may not have been present. - m.setFoo(1); -} -``` - -Explicit presence: - -```js -var m = new Msg(); -if (m.hasFoo()) { - // Clear the field: - m.clearFoo() -} else { - // Field is not present, so set it. - m.setFoo(1); -} -``` - -#### Objective-C Example {#objc-example} - -Implicit presence: - -```objective-c -Msg *m = [Msg message]; -if (m.foo != 0) { - // "Clear" the field: - m.foo = 0; -} else { - // Default value: field may not have been present. - m.foo = 1; -} -``` - -Explicit presence: - -```objective-c -Msg *m = [Msg message]; -if ([m hasFoo]) { - // Clear the field: - [m clearFoo]; -} else { - // Field is not present, so set it. - m.foo = 1; -} -``` - -## Cheat sheet {#cheat} - -**Proto2:** - -Is field presence tracked? - -Field type | Tracked? ----------------------- | -------- -Singular field | yes -Singular message field | yes -Field in a oneof | yes -Repeated field & map | no - -**Proto3:** - -Is field presence tracked? - -Field type | Tracked? ----------------------- | ------------------------ -*Other* singular field | if defined as `optional` -Singular message field | yes -Field in a oneof | yes -Repeated field & map | no - -**Edition 2023:** - -Is field presence tracked? - -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/json.md b/content/programming-guides/json.md deleted file mode 100644 index 9f9eab470..000000000 --- a/content/programming-guides/json.md +++ /dev/null @@ -1,604 +0,0 @@ -+++ -title = "ProtoJSON Format" -weight = 62 -description = "Describes the spec details of the canonical JSON representation for Protobuf messages." -type = "docs" -+++ - -Protobuf supports a canonical encoding in JSON, making it easier to share data -with systems that do not support the standard protobuf binary wire format. - -This page specifies the format, but a number of additional edge cases which -define a conformant ProtoJSON parser are covered in the Protobuf Conformance -Test Suite and are not exhaustively detailed here. - -## Non-goals of the Format {#non-goals} - -### Cannot Represent Some JSON schemas {#non-goals-arbitrary-json-schema} - -The ProtoJSON format is designed to be a JSON representation of schemas which -are expressible in the Protobuf schema language. - -It may be possible to represent many pre-existing JSON schemas as a Protobuf -schema and parse it using ProtoJSON, but it is not designed to be able to -represent arbitrary JSON schemas. - -For example, there is no way to express in Protobuf schema to write types that -may be common in JSON schemas like `number[][]` or `number|string`. - -It is possible to use `google.protobuf.Struct` and `google.protobuf.Value` types -to allow arbitrary JSON to be parsed into a Protobuf schema, but these only -allow you to capture the values as schemaless unordered key-value maps. - -### Not as efficient as the binary wire format {#non-goals-highly-efficient} - -ProtoJSON Format is not as efficient as binary wire format and never will be. - -The converter uses more CPU to encode and decode messages and (except in rare -cases) encoded messages consume more space. - -### Does not have as good schema-evolution guarantees as binary wire format {#non-goals-optimal-schema-evolution} - -ProtoJSON format does not support unknown fields, and it puts field and enum -value names into encoded messages which makes it much harder to change those -names later. Removing fields is a breaking change that will trigger a parsing -error. - -See [JSON Wire Safety](#json-wire-safety) below for more details. - -## Format Description {#format} - -### Representation of each type {#field-representation} - -The following table shows how data is represented in JSON files. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Protobuf typeJSONJSON exampleNotes
messageobject{"fooBar": v, "g": null, ...}Generates JSON objects. -

- Keys are serialized as lowerCamelCase of field name. See - Field Names for more special cases regarding mapping of field names - to object keys. -

- Well-known types have special representations, as described in the Well-known types table. -

- null is valid for any field and leaves the field unset. See Null Values for clarification about the semantic behavior of null values. -

enumstring"FOO_BAR"The name of the enum value as specified in proto is used. Parsers - accept both enum names and integer values. -
map<K,V>object{"k": v, ...}All keys are converted to strings (object keys in JSON can only be strings).
repeated Varray[v, ...]
booltrue, falsetrue, false
stringstring"Hello World!"
bytesbase64 string"YWJjMTIzIT8kKiYoKSctPUB+"JSON value will be the data encoded as a string using standard base64 - encoding with paddings. Either standard or URL-safe base64 encoding - with/without paddings are accepted. -
int32, fixed32, uint32number1, -10, 0JSON value will be a number. Either numbers or strings are - accepted. Empty strings are invalid. Exponent notation (such as 1e2) is - accepted in both quoted and unquoted forms. -
int64, fixed64, uint64string"1", "-10"JSON value will be a decimal string. Either numbers or strings are - accepted. Empty strings are invalid. Exponent notation (such as 1e2) is - accepted in both quoted and unquoted forms. See Strings for int64s - for the explanation why strings are used for int64s. -
float, doublenumber1.1, -10.0, 0, "NaN", "Infinity"JSON value will be a number or one of the special string values "NaN", - "Infinity", and "-Infinity". Either numbers or strings are accepted. - Empty strings are invalid. Exponent notation is also accepted. -
- - -

Well-Known Types

- -

Some messages in the google.protobuf package have a special representation -when represented in JSON. - -

No message type outside of the google.protobuf package has a special ProtoJSON -handling; for example, types in google.types package are represented with the -neutral representation. - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Message typeJSONJSON exampleNotes
Anyobject{"@type": "url", "f": v, ... }See Any
Timestampstring"1972-01-01T10:00:20.021Z"Uses RFC 3339 (see clarification). Generated output will always be Z-normalized - with 0, 3, 6 or 9 fractional digits. Offsets other than "Z" are - also accepted. -
Durationstring"1.000340012s", "1s"Generated output always contains 0, 3, 6, or 9 fractional digits, - depending on required precision, followed by the suffix "s". Accepted - are any fractional digits (also none) as long as they fit into - nanoseconds precision and the suffix "s" is required. This is not RFC 3339 - 'duration' format (see Durations for clarification). -
Structobject{ ... }Any JSON object. See struct.proto.
Wrapper typesvarious types2, "2", "foo", true, "true", null, 0, ...Wrappers use the same representation in JSON as the wrapped primitive - type, except that null is allowed and preserved during data - conversion and transfer. -
FieldMaskstring"f.fooBar,h"See field_mask.proto.
ListValuearray[foo, bar, ...]
ValuevalueAny JSON value. Check - google.protobuf.Value - for details. -
NullValuenullJSON null. Special case of the null parsing behavior.
Emptyobject{} (not special cased)An empty JSON object
- -### Field names as JSON keys {#field-names} - -Message field names are mapped to lowerCamelCase to be used as JSON object keys. -If the `json_name` field option is specified, the specified value will be used -as the key instead. - -Parsers accept both the lowerCamelCase name (or the one specified by the -`json_name` option) and the original proto field name. This allows for a -serializer option to choose to print using the original field name (see -[JSON Options](#json-options)) and have the resulting output still be parsed -back by all spec parsers. - -`\0 (nul)` is not allowed within a `json_name` value. For more on why, see -Stricter validation -for json_name. Note that `\0` is still considered a legal character within -the value of a `string` field. - -### Presence and default-values {#presence} - -When generating JSON-encoded output from a protocol buffer, if a field supports -presence, serializers must emit the field value if and only if the corresponding -hazzer would return true. - -If the field doesn't support field presence and has the default value (for -example any empty repeated field) serializers should omit it from the output. An -implementation may provide options to include fields with default values in the -output. - -### Null values {#null-values} - -Serializers should not emit `null` values. - -Parsers accept `null` as a legal value for any field, with the following -behavior: - -* Any key validity checking should still occur (disallowing unknown fields). -* The field should remain unset, as though it was not present in the input at - all (hazzers should still return false where applicable). - -The implication of this is that a `null` value for an implicit presence field -will behave the identically to the behavior to the default value of that field, -since there are no hazzers for those fields. For example, a value of `null` or -`[]` for a repeated field will cause key-validation checks, but both will -otherwise behave the same as if the field was not present in the JSON at all. - -`null` values are not allowed within repeated fields. - -`google.protobuf.NullValue` is a special exception to this behavior: `null` is -handled as a sentinel-present value for this type, and so a field of this type -must be handled by serializers and parsers under the standard presence behavior. -This behavior correspondingly allows `google.protobuf.Struct` and -`google.protobuf.Value` to losslessly round trip arbitrary JSON. - -### Duplicate values {#duplicate-values} - -Serializers must never serialize the same field multiple times, nor multiple -different cases in the same oneof in the same JSON object. - -Parsers should accept the same field being duplicated, and the last value -provided should be retained. This also applies to "alternate spellings" of the -same field name. - -If implementations cannot maintain the necessary information about field order -it is preferred to reject inputs with duplicate keys rather than have an -arbitrary value win. In some implementations maintaining field order of objects -may be impractical or infeasible, so it is strongly recommended that systems -avoid relying on specific behavior for duplicate fields in ProtoJSON where -possible. - -### Out of range numeric values {#out-of-range-values} - -When parsing a numeric value, if the number that is is parsed from the wire -doesn't fit in the corresponding type, the parser should fail to parse. - -This includes any negative number for `uint32`, and numbers less than `INT_MIN` -or larger than `INT_MAX` for `int32`. - -Values with nonzero fractional portions are not allowed for integer-typed -fields. Zero fractional portions are accepted. For example `1.0` is valid for an -int32 field, but `1.5` is not. - -### Strings for int64 {#int64-strings} - -Unfortunately, the [json.org](https://json.org) spec does not speak to the -intended precision limits of numbers. Many implementations follow the original -JS behavior that JSON was derived from and interpret all numbers as binary64 -(double precision) and are silently lossy if a number is an integer larger than -2**53. Other implementations may support unlimited precision bigints, int64s, or -even bigfloats with unlimited fractional precision. - -This creates a situation where if the JSON contains a number that is not exactly -representable by double precision, different parsers will behave differently, -including silent precision loss in many languages. - -To avoid these problems, ProtoJSON serializers emit int64s as strings to ensure -no precision loss will occur on large int64s by any implementation. - -When parsing a bare number when expecting an int64, the implementation should -coerce that value to double-precision even if the corresponding language's -built-in JSON parser supports parsing of JSON numbers as bigints. This ensures a -consistent interpretation of the same data, regardless of language used. - -This design follows established best practices in how to handle large numbers in -JSON when prioritizing interoperability, including: - -* [RFC8259](https://datatracker.ietf.org/doc/html/rfc8259#section-6) includes - a note that software that intends good interoperability should only presume - double precision on all numbers. - -* [OpenAPI int64](https://spec.openapis.org/registry/format/int64) - documentation recommends using a JSON string instead of a number when - precision beyond 2**53 is desired. - -## Any {#any} - -### Normal messages {#any-normal-messages} - -For any message that is not a well-known type with a special JSON -representation, the message contained inside the `Any` is turned into a JSON -object with an additional `"@type"` field inserted that contains the `type_url` -that was set on the `Any`. - -For example, if you have this message definition: - -```proto -package x; -message Child { int32 x = 1; string y = 2; } -``` - -When an instance of Child is packed into an `Any`, the JSON representation is: - -```json -{ - "@type": "type.googleapis.com/x.Child", - "x": 1, - "y": "hello world" -} -``` - -### Special-cased well-known types {#any-special-cases} - -If the `Any` contains a well-known type that has a special JSON mapping, the -message is converted into the special representation and set as a field with key -"value". - -For example, a `google.protobuf.Duration` that represents 3.1 seconds will be -represented by the string `"3.1s"` in the special case handling. When that -`Duration` is packed into an `Any` it will be serialized as: - -```json -{ - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "3.1s" -} -``` - -Message types with special JSON encodings include: - -- `google.protobuf.Any` -- `google.protobuf.BoolValue` -- `google.protobuf.BytesValue` -- `google.protobuf.DoubleValue` -- `google.protobuf.Duration` -- `google.protobuf.FieldMask` -- `google.protobuf.FloatValue` -- `google.protobuf.Int32Value` -- `google.protobuf.Int64Value` -- `google.protobuf.ListValue` -- `google.protobuf.StringValue` -- `google.protobuf.Struct` -- `google.protobuf.Timestamp` -- `google.protobuf.UInt32Value` -- `google.protobuf.UInt64Value` -- `google.protobuf.Value` - -Note that `google.protobuf.Empty` is not considered to have any special JSON -mapping; it is simply a normal message that has zero fields. This means the -expected representation of an `Empty` packed into an `Any` is `{"@type": -"type.googleapis.com/google.protobuf.Empty"}` and not `{"@type": -"type.googleapis.com/google.protobuf.Empty", "value": {}}`. - -## ProtoJSON Wire Safety {#json-wire-safety} - -When using ProtoJSON, only some schema changes are safe to make in a distributed -system. This contrasts with the same concepts applied to the -[the binary wire format](/programming-guides/editions#updating). - -### JSON Wire-unsafe Changes {#wire-unsafe} - -Wire-unsafe changes are schema changes that will break if you parse data that -was serialized using the old schema with a parser that is using the new schema -(or vice versa). You should almost never do this shape of schema change. - -* Changing a field to or from an extension of same number and type is not - safe. -* Changing a field between `string` and `bytes` is not safe. -* Changing a field between a message type and `bytes` is not safe. -* Changing any field from `optional` to `repeated` is not safe. -* Changing a field between a `map` and the corresponding `repeated` - message field is not safe. -* Moving fields into an existing `oneof` is not safe. - -### JSON Wire-safe Changes {#wire-safe} - -Wire-safe changes are ones where it is fully safe to evolve the schema in this -way without risk of data loss or new parse failures. - -Note that nearly all wire-safe changes may be a breaking change to application -code. For example, adding a value to a preexisting enum would be a compilation -break for any code with an exhaustive switch on that enum. For that reason, -Google may avoid making some of these types of changes on public messages. The -AIPs contain guidance for which of these changes are safe to make there. - -* Changing a single `optional` field into a member of a **new** `oneof` is - safe. -* Changing a `oneof` which contains only one field to an `optional` field is - safe. -* Changing a field between any of `int32`, `sint32`, `sfixed32`, `fixed32` is - safe. -* Changing a field between any of `int64`, `sint64`, `sfixed64`, `fixed64` is - safe. -* Changing a field number is safe (as the field numbers are not used in the - ProtoJSON format), but still strongly discouraged since it is very unsafe in - the binary wire format. -* Adding values to an enum is safe if the "Emit enum values as integers" is - set on all relevant clients (see [options](#json-options)) - -### JSON Wire-compatible Changes (Conditionally safe) {#conditionally-safe} - -Unlike wire-safe changes, wire-compatible means that the same data can be parsed -both before and after a given change. However, a client that reads it will get -lossy data under this shape of change. For example, changing an int32 to an -int64 is a compatible change, but if a value larger than INT32_MAX is written, a -client that reads it as an int32 will discard the high order bits. - -You can make compatible changes to your schema only if you manage the roll out -to your system carefully. For example, you may change an int32 to an int64 but -ensure you continue to only write legal int32 values until the new schema is -deployed to all endpoints, and then start writing larger values after that. - -#### Compatible But With Unknown Field Handling Problems {#compatible-ish} - -Unlike the binary wire format, ProtoJSON implementations generally do not -propagate unknown fields. This means that adding to schemas is generally -compatible but will result in parse failures if a client using the old schema -observes the new content. - -This means you can add to your schema, but you cannot safely start writing them -until you know the schema has been deployed to the relevant client or server (or -that the relevant clients set an Ignore Unknown Fields flag, discussed -[below](#json-options)). - -* Adding and removing fields is considered compatible with this caveat. -* Removing enum values is considered compatible with this caveat. - -#### Compatible But Potentially Lossy {#compatible-lossy} - -* Changing between any of the 32-bit integers (`int32`, `uint32`, `sint32`, - `sfixed32`, `fixed32`) and any of the 64-bit integers ( `int64`, `uint64`, - `sint64`, `sfixed32`) is a compatible change. - * If a number is parsed from the wire that doesn't fit in the - corresponding type, a parse failure will occur. - * Unlike binary wire format, `bool` is not compatible with integers. - * Note that the int64 and uint64 types are quoted by default to avoid - precision loss when handled as a double or JavaScript number, and the 32 - bit types are unquoted by default. Conformant parsers will accept either - quoted or unquoted for all integer types, but nonconformant - implementations may mishandle this case and not handle quoted-int32s or - unquoted-int64s, so caution should be taken. -* `enum` may be conditionally compatible with `string` - * If "enums-as-ints" flag is used by any client, then enums will instead - be compatible with the integer types instead. - -## RFC 3339 Clarifications {#rfc3339} - -### Timestamps {#rfc3339-timestamp} - -ProtoJSON timestamps use the RFC 3339 timestamp format. Unfortunately, some -ambiguity in the RFC 3339 spec has created a few edge cases where various other -RFC 3339 implementations do not agree on whether or not the format is legal. - -[RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) intends to declare a strict -subset of ISO-8601 format, and some additional ambiguity was created since RFC -3339 was published in 2002 and then ISO-8601 was subsequently revised without -any corresponding revisions of RFC 3339. - -Most notably, ISO-8601-1988 contains this note: - -> In date and time representations lower case characters may be used when upper -> case characters are not available. - -It is ambiguous whether this note is suggesting that parsers should accept -lowercase letters in general, or if it is only suggesting that lowercase letters -may be used as a substitute in environments where uppercase cannot be -technically used. RFC 3339 contains a note that intends to clarify the -interpretation to be that lowercase letters should be accepted in general. - -ISO-8601-2019 does not contain the corresponding note and is unambiguous that -lowercase letters are not allowed. - -This created some confusion for all libraries that declare they support RFC -3339: today RFC 3339 declares it is a profile of ISO-8601 but contains a -clarifying note referencing text that is not present in the latest ISO-8601 -spec. - -ProtoJSON spec takes the decision that the timestamp format is the stricter -definition of "RFC 3339 as a profile of ISO-8601-2019". Some Protobuf -implementations may be non-conformant by using a timestamp parsing -implementation that is implemented as "RFC 3339 as a profile of ISO-8601-1988," -which will accept a few additional edge cases. - -For consistent interoperability, parsers should only accept the stricter subset -format where possible. When using a non-conformant implementation that accepts -the laxer definition, strongly avoid relying on the additional edge cases being -accepted. - -### Durations {#rfc3339-duration} - -RFC 3339 also defines a duration format, but unfortunately the RFC 3339 duration -format does not have any way to express sub-second resolution. - -The ProtoJSON duration encoding is directly inspired by RFC 3339 `dur-seconds` -representation, but it is able to encode nanosecond precision. For integer -number of seconds the two representations may match (like `10s`), but the -ProtoJSON durations accept fractional values and conformant implementations must -precisely represent nanosecond precision (like `10.500000001s`). - -## JSON Options {#json-options} - -A conformant protobuf JSON implementation may provide the following options: - -* **Always emit fields without presence**: Fields that don't support presence - and that have their default value are omitted by default in JSON output (for - example, an implicit presence integer with a 0 value, implicit presence - string fields that are empty strings, and empty repeated and map fields). An - implementation may provide an option to override this behavior and output - fields with their default values. - - As of v25.x, the C++, Java, and Python implementations are nonconformant, as - this flag affects proto2 `optional` fields but not proto3 `optional` fields. - A fix is planned for a future release. - -* **Ignore unknown fields**: The protobuf JSON parser should reject unknown - fields by default but may provide an option to ignore unknown fields in - parsing. - -* **Use proto field name instead of lowerCamelCase name**: By default the - protobuf JSON printer should convert the field name to lowerCamelCase and - use that as the JSON name. An implementation may provide an option to use - proto field name as the JSON name instead. Protobuf JSON parsers are - required to accept both the converted lowerCamelCase name and the proto - field name. - -* **Emit enum values as integers instead of strings**: The name of an enum - value is used by default in JSON output. An option may be provided to use - the numeric value of the enum value instead. diff --git a/content/programming-guides/proto-limits.md b/content/programming-guides/proto-limits.md deleted file mode 100644 index 98708a4a9..000000000 --- a/content/programming-guides/proto-limits.md +++ /dev/null @@ -1,58 +0,0 @@ -+++ -title = "Proto Limits" -weight = 45 -description = "Covers the limits to number of supported elements in proto schemas." -type = "docs" -+++ - -This topic documents the limits to the number of supported elements (fields, -enum values, and so on) in proto schemas. - -This information is a collection of discovered limitations by many engineers, -but is not exhaustive and may be incorrect/outdated in some areas. As you -discover limitations in your work, contribute those to this document to help -others. - -## Number of Fields {#fields} - -All messages are limited to 65,535 fields. - -Message with only singular proto fields (such as Boolean): - -* ~2100 fields (proto2) -* ~3100 (proto3 without using optional fields) - -Empty message extended by singular fields (such as Boolean): - -* ~4100 fields (proto2) - -Extensions are not supported in proto3. - -To test this limitation, create a proto message with more than the upper bound -number of fields and compile using a Java proto rule. The limit comes from JVM -specs. - -## Number of Values in an Enum {#enum} - -The lowest limit is ~1700 values, in Java -. Other languages have different -limits. - -## Total Size of the Message {#total} - -Any proto in serialized form must be <2GiB, as that is the maximum size -supported by all implementations. It's recommended to bound request and response -sizes. - -## Depth Limit for Proto Unmarshaling {#depth} - -* Java: - 100 -* C++: - 100 -* Go: - 10000 - (there is a plan to reduce this to 100) - -If you try to unmarshal a message that is nested deeper than the depth limit, -the unmarshaling will fail. diff --git a/content/programming-guides/proto2.md b/content/programming-guides/proto2.md deleted file mode 100644 index d9b3a5161..000000000 --- a/content/programming-guides/proto2.md +++ /dev/null @@ -1,2481 +0,0 @@ -+++ -title = "Language Guide (proto 2)" -weight = 40 -description = "Covers how to use the proto2 revision of Protocol Buffers language in your project." -aliases = "/programming-guides/proto/" -type = "docs" -+++ - -This guide describes how to use the protocol buffer language to structure your -protocol buffer data, including `.proto` file syntax and how to generate data -access classes from your `.proto` files. It covers the **proto2** revision of -the protocol buffers language. - -For information on **editions** syntax, see the -[Protobuf Editions Language Guide](/programming-guides/editions). - -For information on **proto3** syntax, see the -[Proto3 Language Guide](/programming-guides/proto3). - -This is a reference guide – for a step by step example that uses many of the -features described in this document, see the -[tutorial](/getting-started) -for your chosen language. - -## Defining A Message Type {#simple} - -First let's look at a very simple example. Let's say you want to define a search -request message format, where each search request has a query string, the -particular page of results you are interested in, and a number of results per -page. Here's the `.proto` file you use to define the message type. - -```proto -syntax = "proto2"; - -message SearchRequest { - optional string query = 1; - optional int32 page_number = 2; - optional int32 results_per_page = 3; -} -``` - -* The first line of the file specifies that you're using the proto2 revision - of the protobuf language spec. - - * The `syntax` must be the first non-empty, non-comment line of the file. - * If no `syntax` is specified, the protocol buffer compiler will assume - you are using proto2. - -* The `SearchRequest` message definition specifies three fields (name/value - pairs), one for each piece of data that you want to include in this type of - message. Each field has a name and a type. - -### Specifying Field Types {#specifying-types} - -In the earlier example, all the fields are [scalar types](#scalar): two integers -(`page_number` and `results_per_page`) and a string (`query`). You can also -specify [enumerations](#enum) and composite types like other message types for -your field. - -### Assigning Field Numbers {#assigning} - -You must give each field in your message definition a number between `1` and -`536,870,911` with the following restrictions: - -- The given number **must be unique** among all fields for that message. -- Field numbers `19,000` to `19,999` are reserved for the Protocol Buffers - implementation. The protocol buffer compiler will complain if you use one of - these reserved field numbers in your message. -- You cannot use any previously [reserved](#fieldreserved) field numbers or - any field numbers that have been allocated to [extensions](#extensions). - -This number **cannot be changed once your message type is in use** because it -identifies the field in the -[message wire format](/programming-guides/encoding). -"Changing" a field number is equivalent to deleting that field and creating a -new field with the same type but a new number. See [Deleting Fields](#deleting) -for how to do this properly. - -Field numbers **should never be reused**. Never take a field number out of the -[reserved](#fieldreserved) list for reuse with a new field definition. See -[Consequences of Reusing Field Numbers](#consequences). - -You should use the field numbers 1 through 15 for the most-frequently-set -fields. Lower field number values take less space in the wire format. For -example, field numbers in the range 1 through 15 take one byte to encode. Field -numbers in the range 16 through 2047 take two bytes. You can find out more about -this in -[Protocol Buffer Encoding](/programming-guides/encoding#structure). - -#### Consequences of Reusing Field Numbers {#consequences} - -Reusing a field number makes decoding wire-format messages ambiguous. - -The protobuf wire format is lean and doesn't provide a way to detect fields -encoded using one definition and decoded using another. - -Encoding a field using one definition and then decoding that same field with a -different definition can lead to: - -- Developer time lost to debugging -- A parse/merge error (best case scenario) -- Leaked PII/SPII -- Data corruption - -Common causes of field number reuse: - -- renumbering fields (sometimes done to achieve a more aesthetically pleasing - number order for fields). Renumbering effectively deletes and re-adds all - the fields involved in the renumbering, resulting in incompatible - wire-format changes. -- deleting a field and not [reserving](#fieldreserved) the number to prevent - future reuse. - - - This has been a very easy mistake to make with - [extension fields](#extensions) for several reasons. - [Extension Declarations](/programming-guides/extension_declarations) - provide a mechanism for reserving extension fields. - -The field number is limited to 29 bits rather than 32 bits because three bits -are used to specify the field's wire format. For more on this, see the -[Encoding topic](/programming-guides/encoding#structure). - - - -### Specifying Field Cardinality {#field-labels} - -Message fields can be one of the following: - -* *Singular*: - - In proto2, there are two types of singular fields: - - * `optional`: (recommended) An `optional` field is in one of two possible - states: - - * the field is set, and contains a value that was explicitly set or - parsed from the wire. It will be serialized to the wire. - * the field is unset, and will return the default value. It will not - be serialized to the wire. - - You can check to see if the value was explicitly set. - - * `required`: **Do not use.** Required fields are so problematic they were - removed from proto3 and editions. Semantics for required field should be - implemented at the application layer. - When it *is* used, a - well-formed message must have exactly one of this field. - -* `repeated`: this field type can be repeated zero or more times in a - well-formed message. The order of the repeated values will be preserved. - -* `map`: this is a paired key/value field type. See - [Maps](/programming-guides/encoding#maps) for more on - this field type. - -#### Use Packed Encoding for New Repeated Fields {#use-packed} - -For historical reasons, `repeated` fields of scalar numeric types (for example, -`int32`, `int64`, `enum`) aren't encoded as efficiently as they could be. New -code should use the special option `[packed = true]` to get a more efficient -encoding. For example: - -```proto -repeated int32 samples = 4 [packed = true]; -repeated ProtoEnum results = 5 [packed = true]; -``` - -You can find out more about `packed` encoding in -[Protocol Buffer Encoding](/programming-guides/encoding#packed). - -#### Required is Strongly Deprecated {#required-deprecated} - -{{% alert title="Important" color="warning" %}} **Required Is Forever** -As mentioned earlier **`required` must not be used for new fields**. Semantics -for required fields should be implemented at the application layer instead. -Existing `required` fields should be treated as permanent, immutable elements of -the message definition. It is nearly impossible to safely change a field from -`required` to `optional`. If there is any chance that a stale reader exists, it -will consider messages without this field to be incomplete and may reject or -drop them. {{% /alert %}} - -A second issue with required fields appears when someone adds a value to an -enum. In this case, the unrecognized enum value is treated as if it were -missing, which also causes the required value check to fail. - -#### Well-formed Messages {#well-formed} - -The term "well-formed," when applied to protobuf messages, refers to the bytes -serialized/deserialized. The protoc parser validates that a given proto -definition file is parseable. - -Singular fields can appear more than once in wire-format bytes. The parser will -accept the input, but only the last instance of that field will be accessible -through the generated bindings. See -[Last One Wins](/programming-guides/encoding#last-one-wins) -for more on this topic. - -### Adding More Message Types {#adding-types} - -Multiple message types can be defined in a single `.proto` file. This is useful -if you are defining multiple related messages – so, for example, if you wanted -to define the reply message format that corresponds to your `SearchResponse` -message type, you could add it to the same `.proto`: - -```proto -message SearchRequest { - optional string query = 1; - optional int32 page_number = 2; - optional int32 results_per_page = 3; -} - -message SearchResponse { - ... -} -``` - -**Combining Messages leads to bloat** While multiple message types (such as -message, enum, and service) can be defined in a single `.proto` file, it can -also lead to dependency bloat when large numbers of messages with varying -dependencies are defined in a single file. It's recommended to include as few -message types per `.proto` file as possible. - -### Adding Comments {#adding-comments} - -To add comments to your `.proto` files: - -* Prefer C/C++/Java line-end-style comments '//' on the line before the .proto - code element -* C-style inline/multi-line comments `/* ... */` are also accepted. - - * When using multi-line comments, a margin line of '*' is preferred. - -```proto -/** - * SearchRequest represents a search query, with pagination options to - * indicate which results to include in the response. - */ -message SearchRequest { - optional string query = 1; - - // Which page number do we want? - optional int32 page_number = 2; - - // Number of results to return per page. - optional int32 results_per_page = 3; -} -``` - -### Deleting Fields {#deleting} - -Deleting fields can cause serious problems if not done properly. - -**Do not delete** `required` fields. This is almost impossible to do safely. If -you must delete a `required` field, you should first mark the field `optional` -and `deprecated` and ensure that all systems which in any way observe the -message have been deployed with the new schema. Then you can consider removing -the field (but note that this is still an error-prone process). - -When you no longer need a field that is not `required`, first delete all -references to the field from client code, and then delete the field definition -from the message. However, you **must** -[reserve the deleted field number](#fieldreserved). If you do not reserve the -field number, it is possible for a developer to reuse that number in the future -and cause a breakage. - -You should also reserve the field name to allow JSON and TextFormat encodings of -your message to continue to parse. - - - -#### Reserved Field Numbers {#reserved-field-numbers} - -If you [update](#updating) a message type by entirely deleting a field, or -commenting it out, future developers can reuse the field number when making -their own updates to the type. This can cause severe issues, as described in -[Consequences of Reusing Field Numbers](#consequences). To make sure this -doesn't happen, add your deleted field number to the `reserved` list. - -The protoc compiler will generate error messages if any future developers try to -use these reserved field numbers. - -```proto -message Foo { - reserved 2, 15, 9 to 11; -} -``` - -Reserved field number ranges are inclusive (`9 to 11` is the same as `9, 10, -11`). - -#### Reserved Field Names {#reserved-field-names} - -Reusing an old field name later is generally safe, except when using TextProto -or JSON encodings where the field name is serialized. To avoid this risk, you -can add the deleted field name to the `reserved` list. - -Reserved names affect only the protoc compiler behavior and not runtime -behavior, with one exception: TextProto implementations may discard unknown -fields (without raising an error like with other unknown fields) with reserved -names at parse time (only the C++ and Go implementations do so today). Runtime -JSON parsing is not affected by reserved names. - -```proto -message Foo { - reserved 2, 15, 9 to 11; - reserved "foo", "bar"; -} -``` - -Note that you can't mix field names and field numbers in the same `reserved` -statement. - -### What's Generated from Your `.proto`? {#generated} - -When you run the [protocol buffer compiler](#generating) on a `.proto`, the -compiler generates the code in your chosen language you'll need to work with the -message types you've described in the file, including getting and setting field -values, serializing your messages to an output stream, and parsing your messages -from an input stream. - -* For **C++**, the compiler generates a `.h` and `.cc` file from each - `.proto`, with a class for each message type described in your file. -* For **Java**, the compiler generates a `.java` file with a class for each - message type, as well as a special `Builder` class for creating message - class instances. -* For **Kotlin**, in addition to the Java generated code, the compiler - generates a `.kt` file for each message type with an improved Kotlin API. - This includes a DSL that simplifies creating message instances, a nullable - field accessor, and a copy function. -* **Python** is a little different — the Python compiler generates a module - with a static descriptor of each message type in your `.proto`, which is - then used with a *metaclass* to create the necessary Python data access - class at runtime. -* For **Go**, the compiler generates a `.pb.go` file with a type for each - message type in your file. -* For **Ruby**, the compiler generates a `.rb` file with a Ruby module - containing your message types. -* For **Objective-C**, the compiler generates a `pbobjc.h` and `pbobjc.m` file - from each `.proto`, with a class for each message type described in your - file. -* For **C#**, the compiler generates a `.cs` file from each `.proto`, with a - class for each message type described in your file. -* For **PHP**, the compiler generates a `.php` message file for each message - type described in your file, and a `.php` metadata file for each `.proto` - file you compile. The metadata file is used to load the valid message types - into the descriptor pool. -* For **Dart**, the compiler generates a `.pb.dart` file with a class for each - message type in your file. - -You can find out more about using the APIs for each language by following the -tutorial for your chosen language. For even more API -details, see the relevant [API reference](/reference/). - -## Scalar Value Types {#scalar} - -A scalar message field can have one of the following types – the table shows the -type specified in the `.proto` file, and the corresponding type in the -automatically generated class: - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Proto TypeNotes
double
float
int32Uses variable-length encoding. Inefficient for encoding negative - numbers – if your field is likely to have negative values, use sint32 - instead.
int64Uses variable-length encoding. Inefficient for encoding negative - numbers – if your field is likely to have negative values, use sint64 - instead.
uint32Uses variable-length encoding.
uint64Uses variable-length encoding.
sint32Uses variable-length encoding. Signed int value. These more - efficiently encode negative numbers than regular int32s.
sint64Uses variable-length encoding. Signed int value. These more - efficiently encode negative numbers than regular int64s.
fixed32Always four bytes. More efficient than uint32 if values are often - greater than 228.
fixed64Always eight bytes. More efficient than uint64 if values are often - greater than 256.
sfixed32Always four bytes.
sfixed64Always eight bytes.
bool
stringA string must always contain UTF-8 encoded or 7-bit ASCII text, and cannot - be longer than 232.
bytesMay contain any arbitrary sequence of bytes no longer than 232.
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Proto TypeC++ TypeJava/Kotlin Type[1]Python Type[3]Go TypeRuby TypeC# TypePHP TypeDart TypeRust Type
doubledoubledoublefloat*float64Floatdoublefloatdoublef64
floatfloatfloatfloat*float32Floatfloatfloatdoublef32
int32int32_tintintint32Fixnum or Bignum (as required)intinteger*int32i32
int64int64_tlongint/long[4]*int64Bignumlonginteger/string[6]Int64i64
uint32uint32_tint[2]int/long[4]*uint32Fixnum or Bignum (as required)uintintegerintu32
uint64uint64_tlong[2]int/long[4]*uint64Bignumulonginteger/string[6]Int64u64
sint32int32_tintintint32Fixnum or Bignum (as required)intinteger*int32i32
sint64int64_tlongint/long[4]*int64Bignumlonginteger/string[6]Int64i64
fixed32uint32_tint[2]int/long[4]*uint32Fixnum or Bignum (as required)uintintegerintu32
fixed64uint64_tlong[2]int/long[4]*uint64Bignumulonginteger/string[6]Int64u64
sfixed32int32_tintint*int32Fixnum or Bignum (as required)intintegerinti32
sfixed64int64_tlongint/long[4]*int64Bignumlonginteger/string[6]Int64i64
boolboolbooleanbool*boolTrueClass/FalseClassboolbooleanboolbool
stringstringStringunicode (Python 2), str (Python 3)*stringString (UTF-8)stringstringStringProtoString
bytesstringByteStringbytes[]byteString (ASCII-8BIT)ByteStringstringListProtoBytes
-
- -[1] Kotlin uses the corresponding types from Java, even for unsigned -types, to ensure compatibility in mixed Java/Kotlin codebases. - -[2] In Java, unsigned 32-bit and 64-bit integers are represented -using their signed counterparts, with the top bit simply being stored in the -sign bit. - -[3] In all cases, setting values to a field will perform type -checking to make sure it is valid. - -[4] 64-bit or unsigned 32-bit integers are always represented as long -when decoded, but can be an int if an int is given when setting the field. In -all cases, the value must fit in the type represented when set. See [2]. - -[5] Proto2 typically doesn't ever check the UTF-8 validity of string -fields. Behavior varies between languages though, and invalid UTF-8 data should -not be stored in string fields. - -[6] Integer is used on 64-bit machines and string is used on 32-bit -machines. - -You can find out more about how these types are encoded when you serialize your -message in -[Protocol Buffer Encoding](/programming-guides/encoding). - -## Default Field Values {#default} - -When a message is parsed, if the encoded message bytes do not contain a -particular field, accessing that field in the parsed object returns the default -value for that field. The default values are type-specific: - -* For strings, the default value is the empty string. -* For bytes, the default value is empty bytes. -* For bools, the default value is false. -* For numeric types, the default value is zero. -* For message fields, the field is not set. Its exact value is - language-dependent. See the - [generated code guide](/reference/) for your language - for details. -* For enums, the default value is the **first defined enum value**, which - should be 0 (recommended for compatibility with open enums). See - [Enum Default Value](#enum-default). - -The default value for repeated fields is empty (generally an empty list in the -appropriate language). - -The default value for map fields is empty (generally an empty map in the -appropriate language). - -### Overriding Default Scalar Values {#explicit-default} - -In proto2, you can specify explicit default values for singular non-message -fields. For example, let's say you want to provide a default value of 10 for the -`SearchRequest.results_per_page` field: - -```proto -optional int32 results_per_page = 3 [default = 10]; -``` - -If the sender does not specify `results_per_page`, the receiver will observe the -following state: - -* The `results_per_page` field is not present. That is, the - `has_results_per_page()` (hazzer method) method would return `false`. -* The value of `results_per_page` (returned from the "getter") is `10`. - -If the sender does send a value for `results_per_page` the default value of 10 -is ignored and the sender's value is returned from the "getter". - -See the [generated code guide](/reference/) for your -chosen language for more details about how defaults work in generated code. - -Because the default value for enums is the first defined enum value, take care -when adding a value to the beginning of an enum value list. See the -[Updating a Message Type](#updating) section for guidelines on how to safely -change definitions. - -## Enumerations {#enum} - -When you're defining a message type, you might want one of its fields to only -have one of a predefined list of values. For example, let's say you want to add -a `corpus` field for each `SearchRequest`, where the corpus can be `UNIVERSAL`, -`WEB`, `IMAGES`, `LOCAL`, `NEWS`, `PRODUCTS` or `VIDEO`. You can do this very -simply by adding an `enum` to your message definition with a constant for each -possible value. - -In the following example we've added an `enum` called `Corpus` with all the -possible values, and a field of type `Corpus`: - -```proto -enum Corpus { - CORPUS_UNSPECIFIED = 0; - CORPUS_UNIVERSAL = 1; - CORPUS_WEB = 2; - CORPUS_IMAGES = 3; - CORPUS_LOCAL = 4; - CORPUS_NEWS = 5; - CORPUS_PRODUCTS = 6; - CORPUS_VIDEO = 7; -} - -message SearchRequest { - optional string query = 1; - optional int32 page_number = 2; - optional int32 results_per_page = 3; - optional Corpus corpus = 4; -} -``` - -### Prefixing Enum Values {#prefixing-values} - -When prefixing enum values, the remainder of the name with the prefix stripped -should still be a legal and style-conformant enum name. For example, avoid the -following: - -```proto -enum DeviceTier { - DEVICE_TIER_UNKNOWN = 0; - DEVICE_TIER_1 = 1; - DEVICE_TIER_2 = 2; -} -``` - -Instead, use a value name like `DEVICE_TIER_TIER1`, where the `DEVICE_TIER_` -portion is viewed as scoping the enum value rather than as part of the -individual enum value name. Some Protobuf implementations automatically strip -the prefix that matches the containing enum name where it is safe to do so, but -could not in this example since a bare `1` is not a legal enum value name. - -We plan for a future Edition to add support for scoped enums, which will -eliminate the need to manually prefix each enum value and enable this to be -written succinctly as `TIER1 = 1`. - -### Enum Default Value {#enum-default} - -The default value for the `SearchRequest.corpus` field is `CORPUS_UNSPECIFIED` -because that is the first value defined in the enum. - -It is strongly recommended to define the first value of every enum as -`ENUM_TYPE_NAME_UNSPECIFIED = 0;` or `ENUM_TYPE_NAME_UNKNOWN = 0;`. This is -because of the way proto2 handles unknown values for enum fields. - -It is also recommended that this first, default value have no semantic meaning -other than "this value was unspecified". - -The default value for an enum field like `SearchRequest.corpus` field can be -explicitly overridden like this: - -``` - optional Corpus corpus = 4 [default = CORPUS_UNIVERSAL]; -``` - -### Enum Value Aliases {#enum-aliases} - -You can define aliases by assigning the same value to different enum constants. -To do this you need to set the `allow_alias` option to `true`. Otherwise, the -protocol buffer compiler generates a warning message when aliases are -found. Though all alias values are valid for serialization, only the first value -is used when deserializing. - -```proto -enum EnumAllowingAlias { - option allow_alias = true; - EAA_UNSPECIFIED = 0; - EAA_STARTED = 1; - EAA_RUNNING = 1; - EAA_FINISHED = 2; -} - -enum EnumNotAllowingAlias { - ENAA_UNSPECIFIED = 0; - ENAA_STARTED = 1; - // ENAA_RUNNING = 1; // Uncommenting this line will cause a warning message. - ENAA_FINISHED = 2; -} -``` - -Enumerator constants must be in the range of a 32-bit integer. Since `enum` -values use -[varint encoding](/programming-guides/encoding) on the -wire, negative values are inefficient and thus not recommended. You can define -`enum`s within a message definition, as in the earlier example, or outside – -these `enum`s can be reused in any message definition in your `.proto` file. You -can also use an `enum` type declared in one message as the type of a field in a -different message, using the syntax `_MessageType_._EnumType_`. - -When you run the protocol buffer compiler on a `.proto` that uses an `enum`, the -generated code will have a corresponding `enum` for Java, Kotlin, or C++, or a -special `EnumDescriptor` class for Python that's used to create a set of -symbolic constants with integer values in the runtime-generated class. - -{{% alert title="Important" color="warning" %}} The -generated code may be subject to language-specific limitations on the number of -enumerators (low thousands for one language). Review the -limitations for the languages you plan to use. -{{% /alert %}} - -{{% alert title="Important" color="warning" %}} For -information on how enums should work contrasted with how they currently work in -different languages, see -[Enum Behavior](/programming-guides/enum). -{{% /alert %}} - -Removing enum values is a breaking change for persisted protos. Instead of -removing a value, mark the value with the `reserved` keyword to prevent the enum -value from being code-generated, or keep the value but indicate that it will be -removed later by using the `deprecated` field option: - -```proto -enum PhoneType { - PHONE_TYPE_UNSPECIFIED = 0; - PHONE_TYPE_MOBILE = 1; - PHONE_TYPE_HOME = 2; - PHONE_TYPE_WORK = 3 [deprecated = true]; - reserved 4,5; -} -``` - -For more information about how to work with message `enum`s in your -applications, see the [generated code guide](/reference/) -for your chosen language. - -### Reserved Values {#reserved} - -If you [update](#updating) an enum type by entirely removing an enum entry, or -commenting it out, future users can reuse the numeric value when making their -own updates to the type. This can cause severe issues if they later load old -instances of the same `.proto`, including data corruption, privacy bugs, and so -on. One way to make sure this doesn't happen is to specify that the numeric -values (and/or names, which can also cause issues for JSON serialization) of -your deleted entries are `reserved`. The protocol buffer compiler will complain -if any future users try to use these identifiers. You can specify that your -reserved numeric value range goes up to the maximum possible value using the -`max` keyword. - -```proto -enum Foo { - reserved 2, 15, 9 to 11, 40 to max; - reserved "FOO", "BAR"; -} -``` - -Note that you can't mix field names and numeric values in the same `reserved` -statement. - -## Using Other Message Types {#other} - -You can use other message types as field types. For example, let's say you -wanted to include `Result` messages in each `SearchResponse` message – to do -this, you can define a `Result` message type in the same `.proto` and then -specify a field of type `Result` in `SearchResponse`: - -```proto -message SearchResponse { - repeated Result results = 1; -} - -message Result { - optional string url = 1; - optional string title = 2; - repeated string snippets = 3; -} -``` - -### Importing Definitions {#importing} - -In the earlier example, the `Result` message type is defined in the same file as -`SearchResponse` – what if the message type you want to use as a field type is -already defined in another `.proto` file? - -You can use definitions from other `.proto` files by *importing* them. To import -another `.proto`'s definitions, you add an import statement to the top of your -file: - -```proto -import "myproject/other_protos.proto"; -``` - -By default, you can use definitions only from directly imported `.proto` files. -However, sometimes you may need to move a `.proto` file to a new location. -Instead of moving the `.proto` file directly and updating all the call sites in -a single change, you can put a placeholder `.proto` file in the old location to -forward all the imports to the new location using the `import public` notion. - -**Note that the public import functionality is not available in Java, Kotlin, -TypeScript, JavaScript or GCL.** - -`import public` dependencies can be transitively relied upon by any code -importing the proto containing the `import public` statement. For example: - -```proto -// new.proto -// All definitions are moved here -``` - -```proto -// old.proto -// This is the proto that all clients are importing. -import public "new.proto"; -import "other.proto"; -``` - -```proto -// client.proto -import "old.proto"; -// You use definitions from old.proto and new.proto, but not other.proto -``` - -The protocol compiler searches for imported files in a set of directories -specified on the protocol compiler command line using the `-I`/`--proto_path` -flag. If no flag was given, it looks in the directory in which the compiler was -invoked. In general you should set the `--proto_path` flag to the root of your -project and use fully qualified names for all imports. - -### Using proto3 Message Types {#proto3} - -It's possible to import -[proto3](/programming-guides/proto3) and -[edition 2023](/programming-guides/editions) message -types and use them in your proto2 messages, and vice versa. However, proto2 -enums cannot be used directly in proto3 syntax (it's okay if an imported proto2 -message uses them). - -## Nested Types {#nested} - -You can define and use message types inside other message types, as in the -following example – here the `Result` message is defined inside the -`SearchResponse` message: - -```proto -message SearchResponse { - message Result { - optional string url = 1; - optional string title = 2; - repeated string snippets = 3; - } - repeated Result results = 1; -} -``` - -If you want to reuse this message type outside its parent message type, you -refer to it as `_Parent_._Type_`: - -```proto -message SomeOtherMessage { - optional SearchResponse.Result result = 1; -} -``` - -You can nest messages as deeply as you like. In the example below, note that the -two nested types named `Inner` are entirely independent, since they are defined -within different messages: - -```proto -message Outer { // Level 0 - message MiddleAA { // Level 1 - message Inner { // Level 2 - optional int64 ival = 1; - optional bool booly = 2; - } - } - message MiddleBB { // Level 1 - message Inner { // Level 2 - optional int32 ival = 1; - optional bool booly = 2; - } - } -} -``` - -### Groups {#groups} - -**Note that the groups feature is deprecated and should not be used when -creating new message types. Use nested message types instead.** - -Groups are another way to nest information in your message definitions. For -example, another way to specify a `SearchResponse` containing a number of -`Result`s is as follows: - -```proto -message SearchResponse { - repeated group Result = 1 { - optional string url = 1; - optional string title = 2; - repeated string snippets = 3; - } -} -``` - -A group simply combines a nested message type and a field into a single -declaration. In your code, you can treat this message just as if it had a -`Result` type field called `result` (the latter name is converted to lower-case -so that it does not conflict with the former). Therefore, this example is -exactly equivalent to the `SearchResponse` earlier, except that the message has -a different [wire format](/programming-guides/encoding). - -## Updating a Message Type {#updating} - -If an existing message type no longer meets all your needs – for example, you'd -like the message format to have an extra field – but you'd still like to use -code created with the old format, don't worry! It's very simple to update -message types without breaking any of your existing code when you use the binary -wire format. - -{{% alert title="Note" color="note" %}} If -you use ProtoJSON or -[proto text format](/reference/protobuf/textformat-spec) -to store your protocol buffer messages, the changes that you can make in your -proto definition are different. The ProtoJSON wire format safe changes are -described -[here](/programming-guides/json#json-wire-safety). -{{% /alert %}} - -Check -[Proto Best Practices](/best-practices/dos-donts) and the -following rules: - -### Binary Wire-unsafe Changes {#wire-unsafe-changes} - -Wire-unsafe changes are schema changes that will break if you use parse data -that was serialized using the old schema with a parser that is using the new -schema (or vice versa). Only make wire-unsafe changes if you know that all -serializers and deserializers of the data are using the new schema. - -* Changing field numbers for any existing field is not safe. - * Changing the field number is equivalent to deleting the field and adding - a new field with the same type. If you want to renumber a field, see the - instructions for [deleting a field](#deleting). -* Moving fields into an existing `oneof` is not safe. - -### Binary Wire-safe Changes {#wire-safe-changes} - -Wire-safe changes are ones where it is fully safe to evolve the schema in this -way without risk of data loss or new parse failures. - -Note that any wire-safe changes may be a breaking change to application code in -a given language. For example, adding a value to a preexisting enum would be a -compilation break for any code with an exhaustive switch on that enum. For that -reason, Google may avoid making some of these types of changes on public -messages: the AIPs contain guidance for which of these changes are safe to make -there. - -* Adding new fields is safe. - * If you add new fields, any messages serialized by code using your "old" - message format can still be parsed by your new generated code. You - should keep in mind the [default values](#default) for these elements so - that new code can properly interact with messages generated by old code. - Similarly, messages created by your new code can be parsed by your old - code: old binaries simply ignore the new field when parsing. See the - [Unknown Fields](#unknowns) section for details. -* Removing fields is safe. - * The same field number must not used again in your updated message type. - You may want to rename the field instead, perhaps adding the prefix - "OBSOLETE_", or make the field number [reserved](#fieldreserved), so - that future users of your `.proto` can't accidentally reuse the number. -* Adding additional values to an enum is safe. -* Changing a single explicit presence field or extension into a member of a - **new** `oneof` is safe. -* Changing a `oneof` which contains only one field to an explicit presence - field is safe. -* Changing a field into an extension of same number and type is safe. - -### Binary Wire-compatible Changes (Conditionally Safe) {#conditionally-safe-changes} - -Unlike Wire-safe changes, wire-compatible means that the same data can be parsed -both before and after a given change. However, a parse of the data may be lossy -under this shape of change. For example, changing an int32 to an int64 is a -compatible change, but if a value larger than INT32_MAX is written, a client -that reads it as an int32 will discard the high order bits of the number. - -You can make compatible changes to your schema only if you manage the roll out -to your system carefully. For example, you may change an int32 to an int64 but -ensure you continue to only write legal int32 values until the new schema is -deployed to all endpoints, and then subsequently start writing larger values -after that. - -If your schema is published outside of your organization, you should generally -not make wire-compatible changes, as you cannot manage the deployment of the new -schema to know when the different range of values may be safe to use. - -* `int32`, `uint32`, `int64`, `uint64`, and `bool` are all compatible. - * If a number is parsed from the wire which doesn't fit in the - corresponding type, you will get the same effect as if you had cast the - number to that type in C++ (for example, if a 64-bit number is read as - an int32, it will be truncated to 32 bits). -* `sint32` and `sint64` are compatible with each other but are *not* - compatible with the other integer types. - * If the value written was between INT_MIN and INT_MAX inclusive it will - parse as the same value with either type. If an sint64 value was written - outside of that range and parsed as an sint32, the varint is truncated - to 32 bits and then zigzag decoding occurs (which will cause a different - value to be observed). -* `string` and `bytes` are compatible as long as the bytes are valid UTF-8. -* Embedded messages are compatible with `bytes` if the bytes contain an - encoded instance of the message. -* `fixed32` is compatible with `sfixed32`, and `fixed64` with `sfixed64`. -* For `string`, `bytes`, and message fields, singular is compatible with - `repeated`. - * Given serialized data of a repeated field as input, clients that expect - this field to be singular will take the last input value if it's a - primitive type field or merge all input elements if it's a message type - field. Note that this is **not** generally safe for numeric types, - including bools and enums. Repeated fields of numeric types are - serialized in the - [packed](/programming-guides/encoding#packed) - format by default, which will not be parsed correctly when a singular - field is expected. -* `enum` is compatible with `int32`, `uint32`, `int64`, and `uint64` - * Be aware that client code may treat them differently when the message is - deserialized: for example, unrecognized proto3 `enum` values will be - preserved in the message, but how this is represented when the message - is deserialized is language-dependent. -* Changing a field between a `map` and the corresponding `repeated` - message field is binary compatible (see [Maps](#maps), below, for the - message layout and other restrictions). - * However, the safety of the change is application-dependent: when - deserializing and reserializing a message, clients using the `repeated` - field definition will produce a semantically identical result; however, - clients using the `map` field definition may reorder entries and drop - entries with duplicate keys. - -## Unknown Fields {#unknowns} - -Unknown fields are well-formed protocol buffer serialized data representing -fields that the parser does not recognize. For example, when an old binary -parses data sent by a new binary with new fields, those new fields become -unknown fields in the old binary. - -Proto2 messages preserve unknown fields and include them during parsing and in -the serialized output. - -### Retaining Unknown Fields {#retaining} - -Some actions can cause unknown fields to be lost. For example, if you do one of -the following, unknown fields are lost: - -* Serialize a proto to JSON. -* Iterate over all of the fields in a message to populate a new message. - -To avoid losing unknown fields, do the following: - -* Use binary; avoid using text formats for data exchange. -* Use message-oriented APIs, such as `CopyFrom()` and `MergeFrom()`, to copy data - rather than copying field-by-field - -TextFormat is a bit of a special case. Serializing to TextFormat prints unknown -fields using their field numbers. But parsing TextFormat data back into a binary -proto fails if there are entries that use field numbers. - -## Extensions {#extensions} - -An extension is a field defined outside of its container message; usually in a -`.proto` file separate from the container message's `.proto` file. - -### Why Use Extensions? {#why-ext} - -There are two main reasons to use extensions: - -* The container message's `.proto` file will have fewer imports/dependencies. - This can improve build times, break circular dependencies, and otherwise - promote loose coupling. Extensions are very good for this. -* Allow systems to attach data to a container message with minimal dependency - and coordination. Extensions are not a great solution for this because of - the limited field number space and the - [Consequences of Reusing Field Numbers](#consequences). If your use case - requires very low coordination for a large number of extensions, consider - using the - [`Any` message type](/reference/protobuf/google.protobuf#any) - instead. - -### Example Extension {#ext-example} - -Let's look at an example extension: - -```proto -// file kittens/video_ext.proto - -import "kittens/video.proto"; -import "media/user_content.proto"; - -package kittens; - -// This extension allows kitten videos in a media.UserContent message. -extend media.UserContent { - // Video is a message imported from kittens/video.proto - repeated Video kitten_videos = 126; -} -``` - -Note that the file defining the extension (`kittens/video_ext.proto`) imports -the container message's file (`media/user_content.proto`). - -The container message must reserve a subset of its field numbers for extensions. - -```proto -// file media/user_content.proto - -package media; - -// A container message to hold stuff that a user has created. -message UserContent { - // Set verification to `DECLARATION` to enforce extension declarations for all - // extensions in this range. - extensions 100 to 199 [verification = DECLARATION]; -} -``` - -The container message's file (`media/user_content.proto`) defines the message -`UserContent`, which reserves field numbers [100 to 199] for extensions. It is -recommended to set `verification = DECLARATION` for the range to require -declarations for all its extensions. - -When the new extension (`kittens/video_ext.proto`) is added, a corresponding -declaration should be added to `UserContent` and `verification` should be -removed. - -``` -// A container message to hold stuff that a user has created. -message UserContent { - extensions 100 to 199 [ - declaration = { - number: 126, - full_name: ".kittens.kitten_videos", - type: ".kittens.Video", - repeated: true - } - ]; -} -``` - -`UserContent` declares that field number `126` will be used by a `repeated` -extension field with the fully-qualified name `.kittens.kitten_videos` and the -fully-qualified type `.kittens.Video`. To learn more about extension -declarations see -[Extension Declarations](/programming-guides/extension_declarations). - -Note that the container message's file (`media/user_content.proto`) **does not** -import the kitten_video extension definition (`kittens/video_ext.proto`) - -There is no difference in the wire-format encoding of extension fields as -compared to a standard field with the same field number, type, and cardinality. -Therefore, it is safe to move a standard field out of its container to be an -extension or to move an extension field into its container message as a standard -field so long as the field number, type, and cardinality remain constant. - -However, because extensions are defined outside of the container message, no -specialized accessors are generated to get and set specific extension fields. -For our example, the protobuf compiler **will not generate** `AddKittenVideos()` -or `GetKittenVideos()` accessors. Instead, extensions are accessed through -parameterized functions like: `HasExtension()`, `ClearExtension()`, -`GetExtension()`, `MutableExtension()`, and `AddExtension()`. - -In C++, it would look something like: - -```cpp -UserContent user_content; -user_content.AddExtension(kittens::kitten_videos, new kittens::Video()); -assert(1 == user_content.GetExtensionCount(kittens::kitten_videos)); -user_content.GetExtension(kittens::kitten_videos, 0); -``` - -### Defining Extension Ranges {#defining-ranges} - -If you are the owner of a container message, you will need to define an -extension range for the extensions to your message. - -Field numbers allocated to extension fields cannot be reused for standard -fields. - -It is safe to expand an extension range after it is defined. A good default is -to allocate 1000 relatively small numbers, and densely populate that space using -extension declarations: - -```proto -message ModernExtendableMessage { - // All extensions in this range should use extension declarations. - extensions 1000 to 2000 [verification = DECLARATION]; -} -``` - -When adding a range for extension declarations before the actual extensions, you -should add `verification = DECLARATION` to enforce that declarations are used -for this new range. This placeholder can be removed once an actual declaration -is added. - -It is safe to split an existing extension range into separate ranges that cover -the same total range. This might be necessary for migrating a legacy message -type to -[Extension Declarations](/programming-guides/extension_declarations). -For example, before migration, the range might be defined as: - -```proto -message LegacyMessage { - extensions 1000 to max; -} -``` - -And after migration (splitting the range) it can be: - -```proto -message LegacyMessage { - // Legacy range that was using an unverified allocation scheme. - extensions 1000 to 524999999 [verification = UNVERIFIED]; - // Current range that uses extension declarations. - extensions 525000000 to max [verification = DECLARATION]; -} -``` - -It is not safe to increase the start field number nor decrease the end field -number to move or shrink an extension range. These changes can invalidate an -existing extension. - -Prefer using field numbers 1 to 15 for standard fields that are populated in -most instances of your proto. It is not recommended to use these numbers for -extensions. - -If your numbering convention might involve extensions having very large field -numbers, you can specify that your extension range goes up to the maximum -possible field number using the `max` keyword: - -```proto -message Foo { - extensions 1000 to max; -} -``` - -`max` is 229 - 1, or 536,870,911. - -### Choosing Extension Numbers {#choosing} - -Extensions are just fields that can be specified outside of their container -messages. All the same rules for [Assigning Field Numbers](#assigning) apply to -extension field numbers. The same -[Consequences of Reusing Field Numbers](#consequences) also apply to reusing -extension field numbers. - -Choosing unique extension field numbers is simple if the container message uses -[extension declarations](/programming-guides/extension_declarations). -When defining a new extension, choose the lowest field number above all other -declarations from the highest extension range defined in the container message. -For example, if a container message is defined like this: - -```proto -message Container { - // Legacy range that was using an unverified allocation scheme - extensions 1000 to 524999999; - // Current range that uses extension declarations. (highest extension range) - extensions 525000000 to max [ - declaration = { - number: 525000001, - full_name: ".bar.baz_ext", - type: ".bar.Baz" - } - // 525,000,002 is the lowest field number above all other declarations - ]; -} -``` - -The next extension of `Container` should add a new declaration with the number -`525000002`. - -#### Unverified Extension Number Allocation (not recommended) {#unverified} - -The owner of a container message may choose to forgo extension declarations in -favor of their own unverified extension number allocation strategy. - -An unverified allocation scheme uses a mechanism external to the protobuf -ecosystem to allocate extension field numbers within the selected extension -range. One example could be using a monorepo's commit number. This system is -"unverified" from the protobuf compiler's point of view since there is no way to -check that an extension is using a properly acquired extension field number. - -The benefit of an unverified system over a verified system like extension -declarations is the ability to define an extension without coordinating with the -container message owner. - -The downside of an unverified system is that the protobuf compiler cannot -protect participants from reusing extension field numbers. - -**Unverified extension field number allocation strategies are not recommended** -because the [Consequences of Reusing Field Numbers](#consequences) fall on all -extenders of a message (not just the developer that didn't follow the -recommendations). If your use case requires very low coordination, consider -using the -[`Any` message](/reference/protobuf/google.protobuf#any) -instead. - -Unverified extension field number allocation strategies are limited to the range -1 to 524,999,999. Field numbers 525,000,000 and above can only be used with -extension declarations. - -### Specifying Extension Types {#specifying-extension-types} - -Extensions can be of any field type except `oneof`s and `map`s. - -### Nested Extensions (not recommended) {#nested-exts} - -You can declare extensions in the scope of another message: - -```proto -import "common/user_profile.proto"; - -package puppies; - -message Photo { - extend common.UserProfile { - optional int32 likes_count = 111; - } - ... -} -``` - -In this case, the C++ code to access this extension is: - -```cpp -UserProfile user_profile; -user_profile.SetExtension(puppies::Photo::likes_count, 42); -``` - -In other words, the only effect is that `likes_count` is defined within the -scope of `puppies.Photo`. - -This is a common source of confusion: Declaring an `extend` block nested inside -a message type *does not* imply any relationship between the outer type and the -extended type. In particular, the earlier example *does not* mean that `Photo` -is any sort of subclass of `UserProfile`. All it means is that the symbol -`likes_count` is declared inside the scope of `Photo`; it's simply a static -member. - -A common pattern is to define extensions inside the scope of the extension's -field type - for example, here's an extension to `media.UserContent` of type -`puppies.Photo`, where the extension is defined as part of `Photo`: - -```proto -import "media/user_content.proto"; - -package puppies; - -message Photo { - extend media.UserContent { - optional Photo puppy_photo = 127; - } - ... -} -``` - -However, there is no requirement that an extension with a message type be -defined inside that type. You can also use the standard definition pattern: - -```proto -import "media/user_content.proto"; - -package puppies; - -message Photo { - ... -} - -// This can even be in a different file. -extend media.UserContent { - optional Photo puppy_photo = 127; -} -``` - -This **standard (file-level) syntax is preferred** to avoid confusion. The -nested syntax is often mistaken for subclassing by users who are not already -familiar with extensions. - -## Any {#any} - -The `Any` message type lets you use messages as embedded types without having -their .proto definition. An `Any` contains an arbitrary serialized message as -`bytes`, along with a URL that acts as a globally unique identifier for and -resolves to that message's type. To use the `Any` type, you need to -[import](#other) `google/protobuf/any.proto`. - -```proto -import "google/protobuf/any.proto"; - -message ErrorStatus { - string message = 1; - repeated google.protobuf.Any details = 2; -} -``` - -The default type URL for a given message type is -`type.googleapis.com/_packagename_._messagename_`. - -Different language implementations will support runtime library helpers to pack -and unpack `Any` values in a typesafe manner – for example, in Java, the `Any` -type will have special `pack()` and `unpack()` accessors, while in C++ there are -`PackFrom()` and `UnpackTo()` methods: - -```c++ -// Storing an arbitrary message type in Any. -NetworkErrorDetails details = ...; -ErrorStatus status; -status.add_details()->PackFrom(details); - -// Reading an arbitrary message from Any. -ErrorStatus status = ...; -for (const google::protobuf::Any& detail : status.details()) { - if (detail.Is()) { - NetworkErrorDetails network_error; - detail.UnpackTo(&network_error); - ... processing network_error ... - } -} -``` - -If you want to limit contained messages to a small number of types and to -require permission before adding new types to the list, consider using -[extensions](#extensions) with -[extension declarations](/programming-guides/extension_declarations) -instead of `Any` message types. - -## Oneof {#oneof} - -If you have a message with many optional fields and where at most one field will -be set at the same time, you can enforce this behavior and save memory by using -the oneof feature. - -Oneof fields are like optional fields except all the fields in a oneof share -memory, and at most one field can be set at the same time. Setting any member of -the oneof automatically clears all the other members. You can check which value -in a oneof is set (if any) using a special `case()` or `WhichOneof()` method, -depending on your chosen language. - -Note that if *multiple values are set, the last set value as determined by the -order in the proto will overwrite all previous ones*. - -Field numbers for oneof fields must be unique within the enclosing message. - -### Using Oneof {#using-oneof} - -To define a oneof in your `.proto` you use the `oneof` keyword followed by your -oneof name, in this case `test_oneof`: - -```proto -message SampleMessage { - oneof test_oneof { - string name = 4; - SubMessage sub_message = 9; - } -} -``` - -You then add your oneof fields to the oneof definition. You can add fields of -any type except `map` fields, but you cannot use the `required`, `optional`, or -`repeated` keywords. If you need to add a repeated field to a oneof, you can use -a message containing the repeated field. - -In your generated code, oneof fields have the same getters and setters as -regular `optional` fields. You also get a special method for checking which -value (if any) in the oneof is set. You can find out more about the oneof API -for your chosen language in the relevant -[API reference](/reference/). - -### Oneof Features {#oneof-features} - -* Setting a oneof field will automatically clear all other members of the - oneof. So if you set several oneof fields, only the *last* field you set - will still have a value. - - ```c++ - SampleMessage message; - message.set_name("name"); - CHECK(message.has_name()); - // Calling mutable_sub_message() will clear the name field and will set - // sub_message to a new instance of SubMessage with none of its fields set. - message.mutable_sub_message(); - CHECK(!message.has_name()); - ``` - -* If the parser encounters multiple members of the same oneof on the wire, - only the last member seen is used in the parsed message. When parsing data - on the wire, starting at the beginning of the bytes, evaluate the next - value, and apply the following parsing rules: - - * First, check if a *different* field in the same oneof is currently set, - and if so clear it. - - * Then apply the contents as though the field was not in a oneof: - - * A primitive will overwrite any value already set - * A message will merge into any value already set - -* Extensions are not supported for oneof. - -* A oneof cannot be `repeated`. - -* Reflection APIs work for oneof fields. - -* If you set a oneof field to the default value (such as setting an int32 - oneof field to 0), the "case" of that oneof field will be set, and the value - will be serialized on the wire. - -* If you're using C++, make sure your code doesn't cause memory crashes. The - following sample code will crash because `sub_message` was already deleted - by calling the `set_name()` method. - - ```c++ - SampleMessage message; - SubMessage* sub_message = message.mutable_sub_message(); - message.set_name("name"); // Will delete sub_message - sub_message->set_... // Crashes here - ``` - -* Again in C++, if you `Swap()` two messages with oneofs, each message will - end up with the other's oneof case: in the example below, `msg1` will have a - `sub_message` and `msg2` will have a `name`. - - ```c++ - SampleMessage msg1; - msg1.set_name("name"); - SampleMessage msg2; - msg2.mutable_sub_message(); - msg1.swap(&msg2); - CHECK(msg1.has_sub_message()); - CHECK(msg2.has_name()); - ``` - -### Backwards-compatibility issues {#backward} - -Be careful when adding or removing oneof fields. If checking the value of a -oneof returns `None`/`NOT_SET`, it could mean that the oneof has not been set or -it has been set to a field in a different version of the oneof. There is no way -to tell the difference, since there's no way to know if an unknown field on the -wire is a member of the oneof. - -#### Tag Reuse Issues {#reuse} - -* **Move optional fields into or out of a oneof**: You may lose some of your - information (some fields will be cleared) after the message is serialized - and parsed. However, you can safely move a single field into a **new** oneof - and may be able to move multiple fields if it is known that only one is ever - set. See [Updating A Message Type](#updating) for further details. -* **Delete a oneof field and add it back**: This may clear your currently set - oneof field after the message is serialized and parsed. -* **Split or merge oneof**: This has similar issues to moving `optional` - fields. - -## Maps {#maps} - -If you want to create an associative map as part of your data definition, -protocol buffers provides a handy shortcut syntax: - -```proto -map map_field = N; -``` - -...where the `key_type` can be any integral or string type (so, any -[scalar](#scalar) type except for floating point types and `bytes`). Note that -neither enum nor proto messages are valid for `key_type`. -The `value_type` can be any type except another map. - -So, for example, if you wanted to create a map of projects where each `Project` -message is associated with a string key, you could define it like this: - -```proto -map projects = 3; -``` - -### Maps Features {#maps-features} - -* Extensions are not supported for maps. -* Maps cannot be `repeated`, `optional`, or `required`. -* Wire format ordering and map iteration ordering of map values is undefined, - so you cannot rely on your map items being in a particular order. -* When generating text format for a `.proto`, maps are sorted by key. Numeric - keys are sorted numerically. -* When parsing from the wire or when merging, if there are duplicate map keys - the last key seen is used. When parsing a map from text format, parsing may - fail if there are duplicate keys. -* If you provide a key but no value for a map field, the behavior when the - field is serialized is language-dependent. In C++, Java, Kotlin, and Python - the default value for the type is serialized, while in other languages - nothing is serialized. -* No symbol `FooEntry` can exist in the same scope as a map `foo`, because - `FooEntry` is already used by the implementation of the map. - -The generated map API is currently available for all supported languages. You -can find out more about the map API for your chosen language in the relevant -[API reference](/reference/). - -### Backwards Compatibility {#backwards} - -The map syntax is equivalent to the following on the wire, so protocol buffers -implementations that do not support maps can still handle your data: - -```proto -message MapFieldEntry { - optional key_type key = 1; - optional value_type value = 2; -} - -repeated MapFieldEntry map_field = N; -``` - -Any protocol buffers implementation that supports maps must both produce and -accept data that can be accepted by the earlier definition. - -## Packages {#packages} - -You can add an optional `package` specifier to a `.proto` file to prevent name -clashes between protocol message types. - -```proto -package foo.bar; -message Open { ... } -``` - -You can then use the package specifier when defining fields of your message -type: - -```proto -message Foo { - ... - optional foo.bar.Open open = 1; - ... -} -``` - -The way a package specifier affects the generated code depends on your chosen -language: - -* In **C++** the generated classes are wrapped inside a C++ namespace. For - example, `Open` would be in the namespace `foo::bar`. -* In **Java** and **Kotlin**, the package is used as the Java package, unless - you explicitly provide an `option java_package` in your `.proto` file. -* In **Python**, the `package` directive is ignored, since Python modules are - organized according to their location in the file system. -* In **Go**, the `package` directive is ignored, and the generated `.pb.go` - file is in the package named after the corresponding `go_proto_library` - Bazel rule. For open source projects, you **must** provide either a `go_package` option or set the Bazel `-M` flag. -* In **Ruby**, the generated classes are wrapped inside nested Ruby - namespaces, converted to the required Ruby capitalization style (first - letter capitalized; if the first character is not a letter, `PB_` is - prepended). For example, `Open` would be in the namespace `Foo::Bar`. -* In **PHP** the package is used as the namespace after converting to - PascalCase, unless you explicitly provide an `option php_namespace` in your - `.proto` file. For example, `Open` would be in the namespace `Foo\Bar`. -* In **C#** the package is used as the namespace after converting to - PascalCase, unless you explicitly provide an `option csharp_namespace` in - your `.proto` file. For example, `Open` would be in the namespace `Foo.Bar`. - -Note that even when the `package` directive does not directly affect the -generated code, for example in Python, it is still strongly recommended to -specify the package for the `.proto` file, as otherwise it may lead to naming -conflicts in descriptors and make the proto not portable for other languages. - -### Packages and Name Resolution {#name-resolution} - -Type name resolution in the protocol buffer language works like C++: first the -innermost scope is searched, then the next-innermost, and so on, with each -package considered to be "inner" to its parent package. A leading '.' (for -example, `.foo.bar.Baz`) means to start from the outermost scope instead. - -The protocol buffer compiler resolves all type names by parsing the imported -`.proto` files. The code generator for each language knows how to refer to each -type in that language, even if it has different scoping rules. - -## Defining Services {#services} - -If you want to use your message types with an RPC (Remote Procedure Call) -system, you can define an RPC service interface in a `.proto` file and the -protocol buffer compiler will generate service interface code and stubs in your -chosen language. So, for example, if you want to define an RPC service with a -method that takes your `SearchRequest` and returns a `SearchResponse`, you can -define it in your `.proto` file as follows: - -```proto -service SearchService { - rpc Search(SearchRequest) returns (SearchResponse); -} -``` - -By default, the protocol compiler will then generate an abstract interface -called `SearchService` and a corresponding "stub" implementation. The stub -forwards all calls to an `RpcChannel`, which in turn is an abstract interface -that you must define yourself in terms of your own RPC system. For example, you -might implement an `RpcChannel` which serializes the message and sends it to a -server via HTTP. In other words, the generated stub provides a type-safe -interface for making protocol-buffer-based RPC calls, without locking you into -any particular RPC implementation. So, in C++, you might end up with code like -this: - -```c++ -using google::protobuf; - -protobuf::RpcChannel* channel; -protobuf::RpcController* controller; -SearchService* service; -SearchRequest request; -SearchResponse response; - -void DoSearch() { - // You provide classes MyRpcChannel and MyRpcController, which implement - // the abstract interfaces protobuf::RpcChannel and protobuf::RpcController. - channel = new MyRpcChannel("somehost.example.com:1234"); - controller = new MyRpcController; - - // The protocol compiler generates the SearchService class based on the - // definition given earlier. - service = new SearchService::Stub(channel); - - // Set up the request. - request.set_query("protocol buffers"); - - // Execute the RPC. - service->Search(controller, &request, &response, - protobuf::NewCallback(&Done)); -} - -void Done() { - delete service; - delete channel; - delete controller; -} -``` - -All service classes also implement the `Service` interface, which provides a way -to call specific methods without knowing the method name or its input and output -types at compile time. On the server side, this can be used to implement an RPC -server with which you could register services. - -```c++ -using google::protobuf; - -class ExampleSearchService : public SearchService { - public: - void Search(protobuf::RpcController* controller, - const SearchRequest* request, - SearchResponse* response, - protobuf::Closure* done) { - if (request->query() == "google") { - response->add_result()->set_url("http://www.google.com"); - } else if (request->query() == "protocol buffers") { - response->add_result()->set_url("http://protobuf.googlecode.com"); - } - done->Run(); - } -}; - -int main() { - // You provide class MyRpcServer. It does not have to implement any - // particular interface; this is just an example. - MyRpcServer server; - - protobuf::Service* service = new ExampleSearchService; - server.ExportOnPort(1234, service); - server.Run(); - - delete service; - return 0; -} -``` - -If you don't want to plug in your own existing RPC system, you can use -[gRPC](https://github.com/grpc/grpc-common): a language- and platform-neutral -open source RPC system developed at Google. gRPC works particularly well with -protocol buffers and lets you generate the relevant RPC code directly from your -`.proto` files using a special protocol buffer compiler plugin. However, as -there are potential compatibility issues between clients and servers generated -with proto2 and proto3, we recommend that you use proto3 or edition 2023 for -defining gRPC services. You can find out more about proto3 syntax in the -[Proto3 Language Guide](/programming-guides/proto3) and -about edition 2023 in -[Edition 2023 Language Guide](/programming-guides/editions). - -In addition to gRPC, there are also a number of ongoing third-party projects to -develop RPC implementations for Protocol Buffers. For a list of links to -projects we know about, see the -[third-party add-ons wiki page](https://github.com/protocolbuffers/protobuf/blob/master/docs/third_party.md). - -## JSON Mapping {#json} - -The standard protobuf binary wire format is the preferred serialization format -for communication between two systems that use protobufs. For communicating with -systems that use JSON rather than protobuf wire format, Protobuf supports a -canonical encoding in [JSON](/programming-guides/json). - -## Options {#options} - -Individual declarations in a `.proto` file can be annotated with a number of -*options*. Options do not change the overall meaning of a declaration, but may -affect the way it is handled in a particular context. The complete list of -available options is defined in [`/google/protobuf/descriptor.proto`](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto). - -Some options are file-level options, meaning they should be written at the -top-level scope, not inside any message, enum, or service definition. Some -options are message-level options, meaning they should be written inside message -definitions. Some options are field-level options, meaning they should be -written inside field definitions. Options can also be written on enum types, -enum values, oneof fields, service types, and service methods; however, no -useful options currently exist for any of these. - -Here are a few of the most commonly used options: - -* `java_package` (file option): The package you want to use for your generated - Java/Kotlin classes. If no explicit `java_package` option is given in the - `.proto` file, then by default the proto package (specified using the - "package" keyword in the `.proto` file) will be used. However, proto - packages generally do not make good Java packages since proto packages are - not expected to start with reverse domain names. If not generating Java or - Kotlin code, this option has no effect. - - ```proto - option java_package = "com.example.foo"; - ``` - -* `java_outer_classname` (file option): The class name (and hence the file - name) for the wrapper Java class you want to generate. If no explicit - `java_outer_classname` is specified in the `.proto` file, the class name - will be constructed by converting the `.proto` file name to camel-case (so - `foo_bar.proto` becomes `FooBar.java`). If the `java_multiple_files` option - is disabled, then all other classes/enums/etc. generated for the `.proto` - file will be generated *within* this outer wrapper Java class as nested - classes/enums/etc. If not generating Java code, this option has no effect. - - ```proto - option java_outer_classname = "Ponycopter"; - ``` - -* `java_multiple_files` (file option): If false, only a single `.java` file - will be generated for this `.proto` file, and all the Java - classes/enums/etc. generated for the top-level messages, services, and - enumerations will be nested inside of an outer class (see - `java_outer_classname`). If true, separate `.java` files will be generated - for each of the Java classes/enums/etc. generated for the top-level - messages, services, and enumerations, and the wrapper Java class generated - for this `.proto` file won't contain any nested classes/enums/etc. This is a - Boolean option which defaults to `false`. If not generating Java code, this - option has no effect. - - ```proto - option java_multiple_files = true; - ``` - -* `optimize_for` (file option): Can be set to `SPEED`, `CODE_SIZE`, or - `LITE_RUNTIME`. This affects the C++ and Java code generators (and possibly - third-party generators) in the following ways: - - * `SPEED` (default): The protocol buffer compiler will generate code for - serializing, parsing, and performing other common operations on your - message types. This code is highly optimized. - * `CODE_SIZE`: The protocol buffer compiler will generate minimal classes - and will rely on shared, reflection-based code to implement - serialization, parsing, and various other operations. The generated code - will thus be much smaller than with `SPEED`, but operations will be - slower. Classes will still implement exactly the same public API as they - do in `SPEED` mode. This mode is most useful in apps that contain a very - large number of `.proto` files and do not need all of them to be - blindingly fast. - * `LITE_RUNTIME`: The protocol buffer compiler will generate classes that - depend only on the "lite" runtime library (`libprotobuf-lite` instead of - `libprotobuf`). The lite runtime is much smaller than the full library - (around an order of magnitude smaller) but omits certain features like - descriptors and reflection. This is particularly useful for apps running - on constrained platforms like mobile phones. The compiler will still - generate fast implementations of all methods as it does in `SPEED` mode. - Generated classes will only implement the `MessageLite` interface in - each language, which provides only a subset of the methods of the full - `Message` interface. - - ```proto - option optimize_for = CODE_SIZE; - ``` - -* `cc_generic_services`, `java_generic_services`, `py_generic_services` (file - options): **Generic services are deprecated.** Whether or not the protocol - buffer compiler should generate abstract service code based on - [services definitions](#services) in C++, Java, and Python, respectively. - For legacy reasons, these default to `true`. However, as of version 2.3.0 - (January 2010), it is considered preferable for RPC implementations to - provide - [code generator plugins](/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb) - to generate code more specific to each system, rather than rely on the - "abstract" services. - - ```proto - // This file relies on plugins to generate service code. - option cc_generic_services = false; - option java_generic_services = false; - option py_generic_services = false; - ``` - -* `cc_enable_arenas` (file option): Enables - [arena allocation](/reference/cpp/arenas) for C++ - generated code. - -* `objc_class_prefix` (file option): Sets the Objective-C class prefix which - is prepended to all Objective-C generated classes and enums from this - .proto. There is no default. You should use prefixes that are between 3-5 - uppercase characters as - [recommended by Apple](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Conventions/Conventions.html#//apple_ref/doc/uid/TP40011210-CH10-SW4). - Note that all 2 letter prefixes are reserved by Apple. - -* `message_set_wire_format` (message option): If set to `true`, the message - uses a different binary format intended to be compatible with an old format - used inside Google called `MessageSet`. Users outside Google will probably - never need to use this option. The message must be declared exactly as - follows: - - ```proto - message Foo { - option message_set_wire_format = true; - extensions 4 to max; - } - ``` - -* `packed` (field option): If set to `true` on a repeated field of a basic - 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. 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]; - ``` - -* `deprecated` (field option): If set to `true`, indicates that the field is - deprecated and should not be used by new code. In most languages this has no - actual effect. In Java, this becomes a `@Deprecated` annotation. For C++, - clang-tidy will generate warnings whenever deprecated fields are used. In - the future, other language-specific code generators may generate deprecation - annotations on the field's accessors, which will in turn cause a warning to - be emitted when compiling code which attempts to use the field. If the field - is not used by anyone and you want to prevent new users from using it, - consider replacing the field declaration with a [reserved](#fieldreserved) - statement. - - ```proto - optional int32 old_field = 6 [deprecated = true]; - ``` - -### Enum Value Options {#enum-value-options} - -Enum value options are supported. You can use the `deprecated` option to -indicate that a value shouldn't be used anymore. You can also create custom -options using extensions. - -The following example shows the syntax for adding these options: - -```proto -import "google/protobuf/descriptor.proto"; - -extend google.protobuf.EnumValueOptions { - optional string string_name = 123456789; -} - -enum Data { - DATA_UNSPECIFIED = 0; - DATA_SEARCH = 1 [deprecated = true]; - DATA_DISPLAY = 2 [ - (string_name) = "display_value" - ]; -} -``` - -The C++ code to read the `string_name` option might look something like this: - -```cpp -const absl::string_view foo = proto2::GetEnumDescriptor() - ->FindValueByName("DATA_DISPLAY")->options().GetExtension(string_name); -``` - -See [Custom Options](#customoptions) to see how to apply custom options to enum -values and to fields. - -### Custom Options {#customoptions} - -Protocol Buffers also allows you to define and use your own options. Note that -this is an **advanced feature** which most people don't need. Since options are -defined by the messages defined in `google/protobuf/descriptor.proto` (like -`FileOptions` or `FieldOptions`), defining your own options is simply a matter -of [extending](#extensions) those messages. For example: - -```proto -import "google/protobuf/descriptor.proto"; - -extend google.protobuf.MessageOptions { - optional string my_option = 51234; -} - -message MyMessage { - option (my_option) = "Hello world!"; -} -``` - -Here we have defined a new message-level option by extending `MessageOptions`. -When we then use the option, the option name must be enclosed in parentheses to -indicate that it is an extension. We can now read the value of `my_option` in -C++ like so: - -```proto -string value = MyMessage::descriptor()->options().GetExtension(my_option); -``` - -Here, `MyMessage::descriptor()->options()` returns the `MessageOptions` protocol -message for `MyMessage`. Reading custom options from it is just like reading any -other [extension](#extensions). - -Similarly, in Java we would write: - -```java -String value = MyProtoFile.MyMessage.getDescriptor().getOptions() - .getExtension(MyProtoFile.myOption); -``` - -In Python it would be: - -```python -value = my_proto_file_pb2.MyMessage.DESCRIPTOR.GetOptions() - .Extensions[my_proto_file_pb2.my_option] -``` - -Custom options can be defined for every kind of construct in the Protocol -Buffers language. Here is an example that uses every kind of option: - -```proto -import "google/protobuf/descriptor.proto"; - -extend google.protobuf.FileOptions { - optional string my_file_option = 50000; -} -extend google.protobuf.MessageOptions { - optional int32 my_message_option = 50001; -} -extend google.protobuf.FieldOptions { - optional float my_field_option = 50002; -} -extend google.protobuf.OneofOptions { - optional int64 my_oneof_option = 50003; -} -extend google.protobuf.EnumOptions { - optional bool my_enum_option = 50004; -} -extend google.protobuf.EnumValueOptions { - optional uint32 my_enum_value_option = 50005; -} -extend google.protobuf.ServiceOptions { - optional MyEnum my_service_option = 50006; -} -extend google.protobuf.MethodOptions { - optional MyMessage my_method_option = 50007; -} - -option (my_file_option) = "Hello world!"; - -message MyMessage { - option (my_message_option) = 1234; - - optional int32 foo = 1 [(my_field_option) = 4.5]; - optional string bar = 2; - oneof qux { - option (my_oneof_option) = 42; - - string quux = 3; - } -} - -enum MyEnum { - option (my_enum_option) = true; - - FOO = 1 [(my_enum_value_option) = 321]; - BAR = 2; -} - -message RequestType {} -message ResponseType {} - -service MyService { - option (my_service_option) = FOO; - - rpc MyMethod(RequestType) returns(ResponseType) { - // Note: my_method_option has type MyMessage. We can set each field - // within it using a separate "option" line. - option (my_method_option).foo = 567; - option (my_method_option).bar = "Some string"; - } -} -``` - -Note that if you want to use a custom option in a package other than the one in -which it was defined, you must prefix the option name with the package name, -just as you would for type names. For example: - -```proto -// foo.proto -import "google/protobuf/descriptor.proto"; -package foo; -extend google.protobuf.MessageOptions { - optional string my_option = 51234; -} -``` - -```proto -// bar.proto -import "foo.proto"; -package bar; -message MyMessage { - option (foo.my_option) = "Hello world!"; -} -``` - -One last thing: Since custom options are extensions, they must be assigned field -numbers like any other field or extension. In the examples earlier, we have used -field numbers in the range 50000-99999\. This range is reserved for internal use -within individual organizations, so you can use numbers in this range freely for -in-house applications. If you intend to use custom options in public -applications, however, then it is important that you make sure that your field -numbers are globally unique. To obtain globally unique field numbers, send a -request to add an entry to -[protobuf global extension registry](https://github.com/protocolbuffers/protobuf/blob/master/docs/options.md). -Usually you only need one extension number. You can declare multiple options -with only one extension number by putting them in a sub-message: - -```proto -message FooOptions { - optional int32 opt1 = 1; - optional string opt2 = 2; -} - -extend google.protobuf.FieldOptions { - optional FooOptions foo_options = 1234; -} - -// usage: -message Bar { - optional int32 a = 1 [(foo_options).opt1 = 123, (foo_options).opt2 = "baz"]; - // alternative aggregate syntax (uses TextFormat): - optional int32 b = 2 [(foo_options) = { opt1: 123 opt2: "baz" }]; -} -``` - -Also, note that each option type (file-level, message-level, field-level, etc.) -has its own number space, so, for example, you could declare extensions of -FieldOptions and MessageOptions with the same number. - -### Option Retention {#option-retention} - -Options have a notion of *retention*, which controls whether an option is -retained in the generated code. Options have *runtime retention* by default, -meaning that they are retained in the generated code and are thus visible at -runtime in the generated descriptor pool. However, you can set `retention = -RETENTION_SOURCE` to specify that an option (or field within an option) must not -be retained at runtime. This is called *source retention*. - -Option retention is an advanced feature that most users should not need to worry -about, but it can be useful if you would like to use certain options without -paying the code size cost of retaining them in your binaries. Options with -source retention are still visible to `protoc` and `protoc` plugins, so code -generators can use them to customize their behavior. - -Retention can be set directly on an option, like this: - -```proto -extend google.protobuf.FileOptions { - optional int32 source_retention_option = 1234 - [retention = RETENTION_SOURCE]; -} -``` - -It can also be set on a plain field, in which case it takes effect only when -that field appears inside an option: - -```proto -message OptionsMessage { - optional int32 source_retention_field = 1 [retention = RETENTION_SOURCE]; -} -``` - -You can set `retention = RETENTION_RUNTIME` if you like, but this has no effect -since it is the default behavior. When a message field is marked -`RETENTION_SOURCE`, its entire contents are dropped; fields inside it cannot -override that by trying to set `RETENTION_RUNTIME`. - -{{% alert title="Note" color="note" %}} As -of Protocol Buffers 22.0, support for option retention is still in progress and -only C++ and Java are supported. Go has support starting from 1.29.0. Python -support is complete but has not made it into a release yet. -{{% /alert %}} - -### Option Targets {#option-targets} - -Fields have a `targets` option which controls the types of entities that the -field may apply to when used as an option. For example, if a field has -`targets = TARGET_TYPE_MESSAGE` then that field cannot be set in a custom option -on an enum (or any other non-message entity). Protoc enforces this and will -raise an error if there is a violation of the target constraints. - -At first glance, this feature may seem unnecessary given that every custom -option is an extension of the options message for a specific entity, which -already constrains the option to that one entity. However, option targets are -useful in the case where you have a shared options message applied to multiple -entity types and you want to control the usage of individual fields in that -message. For example: - -```proto -message MyOptions { - optional string file_only_option = 1 [targets = TARGET_TYPE_FILE]; - optional int32 message_and_enum_option = 2 [targets = TARGET_TYPE_MESSAGE, - targets = TARGET_TYPE_ENUM]; -} - -extend google.protobuf.FileOptions { - optional MyOptions file_options = 50000; -} - -extend google.protobuf.MessageOptions { - optional MyOptions message_options = 50000; -} - -extend google.protobuf.EnumOptions { - optional MyOptions enum_options = 50000; -} - -// OK: this field is allowed on file options -option (file_options).file_only_option = "abc"; - -message MyMessage { - // OK: this field is allowed on both message and enum options - option (message_options).message_and_enum_option = 42; -} - -enum MyEnum { - MY_ENUM_UNSPECIFIED = 0; - // Error: file_only_option cannot be set on an enum. - option (enum_options).file_only_option = "xyz"; -} -``` - -## Generating Your Classes {#generating} - -To generate the Java, Kotlin, Python, C++, Go, Ruby, Objective-C, or C# code -that you need to work with the message types defined in a `.proto` file, you -need to run the protocol buffer compiler `protoc` on the `.proto` file. If you -haven't installed the compiler, -[download the package](/downloads) and follow the -instructions in the README. For Go, you also need to install a special code -generator plugin for the compiler; you can find this and installation -instructions in the [golang/protobuf](https://github.com/golang/protobuf/) -repository on GitHub. - -The Protocol Compiler is invoked as follows: - -```sh -protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR --go_out=DST_DIR --ruby_out=DST_DIR --objc_out=DST_DIR --csharp_out=DST_DIR path/to/file.proto -``` - -* `IMPORT_PATH` specifies a directory in which to look for `.proto` files when - resolving `import` directives. If omitted, the current directory is used. - Multiple import directories can be specified by passing the `--proto_path` - option multiple times; they will be searched in order. `-I=_IMPORT_PATH_` - can be used as a short form of `--proto_path`. - -**Note:** File paths relative to their `proto_path` must be globally unique in a -given binary. For example, if you have `proto/lib1/data.proto` and -`proto/lib2/data.proto`, those two files cannot be used together with -`-I=proto/lib1 -I=proto/lib2` because it would be ambiguous which file `import -"data.proto"` will mean. Instead `-Iproto/` should be used and the global names -will be `lib1/data.proto` and `lib2/data.proto`. - -If you are publishing a library and other users may use your messages directly, -you should include a unique library name in the path that they are expected to -be used under to avoid file name collisions. If you have multiple directories in -one project, it is best practice to prefer setting one `-I` to a top level -directory of the project. - -* You can provide one or more *output directives*: - - * `--cpp_out` generates C++ code in `DST_DIR`. See the - [C++ generated code reference](/reference/cpp/cpp-generated) - for more. - * `--java_out` generates Java code in `DST_DIR`. See the - [Java generated code reference](/reference/java/java-generated) - for more. - * `--kotlin_out` generates additional Kotlin code in `DST_DIR`. See the - [Kotlin generated code reference](/reference/kotlin/kotlin-generated) - for more. - * `--python_out` generates Python code in `DST_DIR`. See the - [Python generated code reference](/reference/python/python-generated) - for more. - * `--go_out` generates Go code in `DST_DIR`. See the - [Go generated code reference](/reference/go/go-generated-opaque) - for more. - * `--ruby_out` generates Ruby code in `DST_DIR`. See the - [Ruby generated code reference](/reference/ruby/ruby-generated) - for more. - * `--objc_out` generates Objective-C code in `DST_DIR`. See the - [Objective-C generated code reference](/reference/objective-c/objective-c-generated) - for more. - * `--csharp_out` generates C# code in `DST_DIR`. See the - [C# generated code reference](/reference/csharp/csharp-generated) - for more. - * `--php_out` generates PHP code in `DST_DIR`. See the - [PHP generated code reference](/reference/php/php-generated) - for more. - - As an extra convenience, if the `DST_DIR` ends in `.zip` or `.jar`, the - compiler will write the output to a single ZIP-format archive file with the - given name. `.jar` outputs will also be given a manifest file as required by - the Java JAR specification. Note that if the output archive already exists, - it will be overwritten. - -* You must provide one or more `.proto` files as input. Multiple `.proto` - files can be specified at once. Although the files are named relative to the - current directory, each file must reside in one of the `IMPORT_PATH`s so - that the compiler can determine its canonical name. - -## File location {#location} - -Prefer not to put `.proto` files in the same -directory as other language sources. Consider -creating a subpackage `proto` for `.proto` files, under the root package for -your project. - -### Location Should be Language-agnostic {#location-language-agnostic} - -When working with Java code, it's handy to put related `.proto` files in the -same directory as the Java source. However, if any non-Java code ever uses the -same protos, the path prefix will no longer make sense. So in -general, put the protos in a related language-agnostic directory such as -`//myteam/mypackage`. - -The exception to this rule is when it's clear that the protos will be used only -in a Java context, such as for testing. - -## Supported Platforms {#platforms} - -For information about: - -* the operating systems, compilers, build systems, and C++ versions that are - supported, see - [Foundational C++ Support Policy](https://opensource.google/documentation/policies/cplusplus-support). -* the PHP versions that are supported, see - [Supported PHP versions](https://cloud.google.com/php/getting-started/supported-php-versions). diff --git a/content/programming-guides/proto3.md b/content/programming-guides/proto3.md deleted file mode 100644 index f9c0b5d27..000000000 --- a/content/programming-guides/proto3.md +++ /dev/null @@ -1,1879 +0,0 @@ -+++ -title = "Language Guide (proto 3)" -weight = 40 -description = "Covers how to use the proto3 revision of the Protocol Buffers language in your project." -type = "docs" -+++ - -This guide describes how to use the protocol buffer language to structure your -protocol buffer data, including `.proto` file syntax and how to generate data -access classes from your `.proto` files. It covers the **proto3** revision of -the protocol buffers language. - -For information on **editions** syntax, see the -[Protobuf Editions Language Guide](/programming-guides/editions). - -For information on the **proto2** syntax, see the -[Proto2 Language Guide](/programming-guides/proto2). - -This is a reference guide – for a step by step example that uses many of the -features described in this document, see the -[tutorial](/getting-started) -for your chosen language. - -## Defining A Message Type {#simple} - -First let's look at a very simple example. Let's say you want to define a search -request message format, where each search request has a query string, the -particular page of results you are interested in, and a number of results per -page. Here's the `.proto` file you use to define the message type. - -```proto -syntax = "proto3"; - -message SearchRequest { - string query = 1; - int32 page_number = 2; - int32 results_per_page = 3; -} -``` - -* The first line of the file specifies that you're using the proto3 revision - of the protobuf language spec. - - * The `edition` (or `syntax` for proto2/proto3) must be the first - non-empty, non-comment line of the file. - * If no `edition` or `syntax` is specified, the protocol buffer compiler - will assume you are using - [proto2](/programming-guides/proto2). - -* The `SearchRequest` message definition specifies three fields (name/value - pairs), one for each piece of data that you want to include in this type of - message. Each field has a name and a type. - -### Specifying Field Types {#specifying-types} - -In the earlier example, all the fields are [scalar types](#scalar): two integers -(`page_number` and `results_per_page`) and a string (`query`). You can also -specify [enumerations](#enum) and composite types like other message types for -your field. - -### Assigning Field Numbers {#assigning} - -You must give each field in your message definition a number between `1` and -`536,870,911` with the following restrictions: - -- The given number **must be unique** among all fields for that message. -- Field numbers `19,000` to `19,999` are reserved for the Protocol Buffers - implementation. The protocol buffer compiler will complain if you use one of - these reserved field numbers in your message. -- You cannot use any previously [reserved](#fieldreserved) field numbers or - any field numbers that have been allocated to - [extensions](/programming-guides/proto2#extensions). - -This number **cannot be changed once your message type is in use** because it -identifies the field in the -[message wire format](/programming-guides/encoding). -"Changing" a field number is equivalent to deleting that field and creating a -new field with the same type but a new number. See [Deleting Fields](#deleting) -for how to do this properly. - -Field numbers **should never be reused**. Never take a field number out of the -[reserved](#fieldreserved) list for reuse with a new field definition. See -[Consequences of Reusing Field Numbers](#consequences). - -You should use the field numbers 1 through 15 for the most-frequently-set -fields. Lower field number values take less space in the wire format. For -example, field numbers in the range 1 through 15 take one byte to encode. Field -numbers in the range 16 through 2047 take two bytes. You can find out more about -this in -[Protocol Buffer Encoding](/programming-guides/encoding#structure). - -#### Consequences of Reusing Field Numbers {#consequences} - -Reusing a field number makes decoding wire-format messages ambiguous. - -The protobuf wire format is lean and doesn't provide a way to detect fields -encoded using one definition and decoded using another. - -Encoding a field using one definition and then decoding that same field with a -different definition can lead to: - -- Developer time lost to debugging -- A parse/merge error (best case scenario) -- Leaked PII/SPII -- Data corruption - -Common causes of field number reuse: - -- renumbering fields (sometimes done to achieve a more aesthetically pleasing - number order for fields). Renumbering effectively deletes and re-adds all - the fields involved in the renumbering, resulting in incompatible - wire-format changes. -- deleting a field and not [reserving](#fieldreserved) the number to prevent - future reuse. - -The field number is limited to 29 bits rather than 32 bits because three bits -are used to specify the field's wire format. For more on this, see the -[Encoding topic](/programming-guides/encoding#structure). - - - -### Specifying Field Cardinality {#field-labels} - -Message fields can be one of the following: - -* *Singular*: - - In proto3, there are two types of singular fields: - - * `optional`: (recommended) An `optional` field is in one of two possible - states: - - * the field is set, and contains a value that was explicitly set or - parsed from the wire. It will be serialized to the wire. - * the field is unset, and will return the default value. It will not - be serialized to the wire. - - You can check to see if the value was explicitly set. - - `optional` is recommended over *implicit* fields for maximum - compatibility with protobuf editions and proto2. - - * *implicit*: (not recommended) An implicit field has no explicit - cardinality label and behaves as follows: - - * if the field is a message type, it behaves just like an `optional` - field. - * if the field is not a message, it has two states: - - * the field is set to a non-default (non-zero) value that was - explicitly set or parsed from the wire. It will be serialized to - the wire. - * the field is set to the default (zero) value. It will not be - serialized to the wire. In fact, you cannot determine whether - the default (zero) value was set or parsed from the wire or not - provided at all. For more on this subject, see - [Field Presence](/programming-guides/field_presence). - -* `repeated`: this field type can be repeated zero or more times in a - well-formed message. The order of the repeated values will be preserved. - -* `map`: this is a paired key/value field type. See - [Maps](/programming-guides/encoding#maps) for more on - this field type. - -#### Repeated Fields are Packed by Default {#use-packed} - -In proto3, `repeated` fields of scalar numeric types use `packed` encoding by -default. - -You can find out more about `packed` encoding in -[Protocol Buffer Encoding](/programming-guides/encoding#packed). - -#### Message Type Fields Always Have Field Presence {#field-presence} - -In proto3, message-type fields already have field presence. Because of this, -adding the `optional` modifier doesn't change the field presence for the field. - -The definitions for `Message2` and `Message3` in the following code sample -generate the same code for all languages, and there is no difference in -representation in binary, JSON, and TextFormat: - -```proto -syntax="proto3"; - -package foo.bar; - -message Message1 {} - -message Message2 { - Message1 foo = 1; -} - -message Message3 { - optional Message1 bar = 1; -} -``` - -#### Well-formed Messages {#well-formed} - -The term "well-formed," when applied to protobuf messages, refers to the bytes -serialized/deserialized. The protoc parser validates that a given proto -definition file is parseable. - -Singular fields can appear more than once in wire-format bytes. The parser will -accept the input, but only the last instance of that field will be accessible -through the generated bindings. See -[Last One Wins](/programming-guides/encoding#last-one-wins) -for more on this topic. - -### Adding More Message Types {#adding-types} - -Multiple message types can be defined in a single `.proto` file. This is useful -if you are defining multiple related messages – so, for example, if you wanted -to define the reply message format that corresponds to your `SearchResponse` -message type, you could add it to the same `.proto`: - -```proto -message SearchRequest { - string query = 1; - int32 page_number = 2; - int32 results_per_page = 3; -} - -message SearchResponse { - ... -} -``` - -**Combining Messages leads to bloat** While multiple message types (such as -message, enum, and service) can be defined in a single `.proto` file, it can -also lead to dependency bloat when large numbers of messages with varying -dependencies are defined in a single file. It's recommended to include as few -message types per `.proto` file as possible. - -### Adding Comments {#adding-comments} - -To add comments to your `.proto` files: - -* Prefer C/C++/Java line-end-style comments '//' on the line before the .proto - code element -* C-style inline/multi-line comments `/* ... */` are also accepted. - - * When using multi-line comments, a margin line of '*' is preferred. - -```proto -/** - * SearchRequest represents a search query, with pagination options to - * indicate which results to include in the response. - */ -message SearchRequest { - string query = 1; - - // Which page number do we want? - int32 page_number = 2; - - // Number of results to return per page. - int32 results_per_page = 3; -} -``` - -### Deleting Fields {#deleting} - -Deleting fields can cause serious problems if not done properly. - -When you no longer need a field and all references have been deleted from client -code, you may delete the field definition from the message. However, you -**must** [reserve the deleted field number](#fieldreserved). If you do not -reserve the field number, it is possible for a developer to reuse that number in -the future. - -You should also reserve the field name to allow JSON and TextFormat encodings of -your message to continue to parse. - - - -#### Reserved Field Numbers {#reserved-field-numbers} - -If you [update](#updating) a message type by entirely deleting a field, or -commenting it out, future developers can reuse the field number when making -their own updates to the type. This can cause severe issues, as described in -[Consequences of Reusing Field Numbers](#consequences). To make sure this -doesn't happen, add your deleted field number to the `reserved` list. - -The protoc compiler will generate error messages if any future developers try to -use these reserved field numbers. - -```proto -message Foo { - reserved 2, 15, 9 to 11; -} -``` - -Reserved field number ranges are inclusive (`9 to 11` is the same as `9, 10, -11`). - -#### Reserved Field Names {#reserved-field-names} - -Reusing an old field name later is generally safe, except when using TextProto -or JSON encodings where the field name is serialized. To avoid this risk, you -can add the deleted field name to the `reserved` list. - -Reserved names affect only the protoc compiler behavior and not runtime -behavior, with one exception: TextProto implementations may discard unknown -fields (without raising an error like with other unknown fields) with reserved -names at parse time (only the C++ and Go implementations do so today). Runtime -JSON parsing is not affected by reserved names. - -```proto -message Foo { - reserved 2, 15, 9 to 11; - reserved "foo", "bar"; -} -``` - -Note that you can't mix field names and field numbers in the same `reserved` -statement. - -### What's Generated from Your `.proto`? {#generated} - -When you run the [protocol buffer compiler](#generating) on a `.proto`, the -compiler generates the code in your chosen language you'll need to work with the -message types you've described in the file, including getting and setting field -values, serializing your messages to an output stream, and parsing your messages -from an input stream. - -* For **C++**, the compiler generates a `.h` and `.cc` file from each - `.proto`, with a class for each message type described in your file. -* For **Java**, the compiler generates a `.java` file with a class for each - message type, as well as a special `Builder` class for creating message - class instances. -* For **Kotlin**, in addition to the Java generated code, the compiler - generates a `.kt` file for each message type with an improved Kotlin API. - This includes a DSL that simplifies creating message instances, a nullable - field accessor, and a copy function. -* **Python** is a little different — the Python compiler generates a module - with a static descriptor of each message type in your `.proto`, which is - then used with a *metaclass* to create the necessary Python data access - class at runtime. -* For **Go**, the compiler generates a `.pb.go` file with a type for each - message type in your file. -* For **Ruby**, the compiler generates a `.rb` file with a Ruby module - containing your message types. -* For **Objective-C**, the compiler generates a `pbobjc.h` and `pbobjc.m` file - from each `.proto`, with a class for each message type described in your - file. -* For **C#**, the compiler generates a `.cs` file from each `.proto`, with a - class for each message type described in your file. -* For **PHP**, the compiler generates a `.php` message file for each message - type described in your file, and a `.php` metadata file for each `.proto` - file you compile. The metadata file is used to load the valid message types - into the descriptor pool. -* For **Dart**, the compiler generates a `.pb.dart` file with a class for each - message type in your file. - -You can find out more about using the APIs for each language by following the -tutorial for your chosen language. For even more API -details, see the relevant [API reference](/reference/). - -## Scalar Value Types {#scalar} - -A scalar message field can have one of the following types – the table shows the -type specified in the `.proto` file, and the corresponding type in the -automatically generated class: - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Proto TypeNotes
double - Uses IEEE 754 - double-precision format. -
float - Uses IEEE 754 - single-precision format. -
int32Uses variable-length encoding. Inefficient for encoding negative - numbers – if your field is likely to have negative values, use sint32 - instead.
int64Uses variable-length encoding. Inefficient for encoding negative - numbers – if your field is likely to have negative values, use sint64 - instead.
uint32Uses variable-length encoding.
uint64Uses variable-length encoding.
sint32Uses variable-length encoding. Signed int value. These more - efficiently encode negative numbers than regular int32s.
sint64Uses variable-length encoding. Signed int value. These more - efficiently encode negative numbers than regular int64s.
fixed32Always four bytes. More efficient than uint32 if values are often - greater than 228.
fixed64Always eight bytes. More efficient than uint64 if values are often - greater than 256.
sfixed32Always four bytes.
sfixed64Always eight bytes.
bool
stringA string must always contain UTF-8 encoded or 7-bit ASCII text, and cannot - be longer than 232.
bytesMay contain any arbitrary sequence of bytes no longer than 232.
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Proto TypeC++ TypeJava/Kotlin Type[1]Python Type[3]Go TypeRuby TypeC# TypePHP TypeDart TypeRust Type
doubledoubledoublefloatfloat64Floatdoublefloatdoublef64
floatfloatfloatfloatfloat32Floatfloatfloatdoublef32
int32int32_tintintint32Fixnum or Bignum (as required)intintegerinti32
int64int64_tlongint/long[4]int64Bignumlonginteger/string[6]Int64i64
uint32uint32_tint[2]int/long[4]uint32Fixnum or Bignum (as required)uintintegerintu32
uint64uint64_tlong[2]int/long[4]uint64Bignumulonginteger/string[6]Int64u64
sint32int32_tintintint32Fixnum or Bignum (as required)intintegerinti32
sint64int64_tlongint/long[4]int64Bignumlonginteger/string[6]Int64i64
fixed32uint32_tint[2]int/long[4]uint32Fixnum or Bignum (as required)uintintegerintu32
fixed64uint64_tlong[2]int/long[4]uint64Bignumulonginteger/string[6]Int64u64
sfixed32int32_tintintint32Fixnum or Bignum (as required)intintegerinti32
sfixed64int64_tlongint/long[4]int64Bignumlonginteger/string[6]Int64i64
boolboolbooleanboolboolTrueClass/FalseClassboolbooleanboolbool
stringstd::stringStringstr/unicode[5]stringString (UTF-8)stringstringStringProtoString
bytesstd::stringByteStringstr (Python 2), bytes (Python 3)[]byteString (ASCII-8BIT)ByteStringstringListProtoBytes
-
- -[1] Kotlin uses the corresponding types from Java, even for unsigned -types, to ensure compatibility in mixed Java/Kotlin codebases. - -[2] In Java, unsigned 32-bit and 64-bit integers are represented -using their signed counterparts, with the top bit simply being stored in the -sign bit. - -[3] In all cases, setting values to a field will perform type -checking to make sure it is valid. - -[4] 64-bit or unsigned 32-bit integers are always represented as long -when decoded, but can be an int if an int is given when setting the field. In -all cases, the value must fit in the type represented when set. See [2]. - -[5] Python strings are represented as unicode on decode but can be -str if an ASCII string is given (this is subject to change). - -[6] Integer is used on 64-bit machines and string is used on 32-bit -machines. - -You can find out more about how these types are encoded when you serialize your -message in -[Protocol Buffer Encoding](/programming-guides/encoding). - -## Default Field Values {#default} - -When a message is parsed, if the encoded message bytes do not contain a -particular field, accessing that field in the parsed object returns the default -value for that field. The default values are type-specific: - -* For strings, the default value is the empty string. -* For bytes, the default value is empty bytes. -* For bools, the default value is false. -* For numeric types, the default value is zero. -* For message fields, the field is not set. Its exact value is - language-dependent. See the - [generated code guide](/reference/) for details. -* For enums, the default value is the **first defined enum value**, which must - be 0. See [Enum Default Value](#enum-default). - -The default value for repeated fields is empty (generally an empty list in the -appropriate language). - -The default value for map fields is empty (generally an empty map in the -appropriate language). - -Note that for implicit-presence scalar fields, once a message is parsed there's -no way of telling whether that field was explicitly set to the default value -(for example whether a boolean was set to `false`) or just not set at all: you -should bear this in mind when defining your message types. For example, don't -have a boolean that switches on some behavior when set to `false` if you don't -want that behavior to also happen by default. Also note that if a scalar message -field **is** set to its default, the value will not be serialized on the wire. -If a float or double value is set to +0 it will not be serialized, but -0 is -considered distinct and will be serialized. - -See the [generated code guide](/reference/) for your -chosen language for more details about how defaults work in generated code. - -## Enumerations {#enum} - -When you're defining a message type, you might want one of its fields to only -have one of a predefined list of values. For example, let's say you want to add -a `corpus` field for each `SearchRequest`, where the corpus can be `UNIVERSAL`, -`WEB`, `IMAGES`, `LOCAL`, `NEWS`, `PRODUCTS` or `VIDEO`. You can do this very -simply by adding an `enum` to your message definition with a constant for each -possible value. - -In the following example we've added an `enum` called `Corpus` with all the -possible values, and a field of type `Corpus`: - -```proto -enum Corpus { - CORPUS_UNSPECIFIED = 0; - CORPUS_UNIVERSAL = 1; - CORPUS_WEB = 2; - CORPUS_IMAGES = 3; - CORPUS_LOCAL = 4; - CORPUS_NEWS = 5; - CORPUS_PRODUCTS = 6; - CORPUS_VIDEO = 7; -} - -message SearchRequest { - string query = 1; - int32 page_number = 2; - int32 results_per_page = 3; - Corpus corpus = 4; -} -``` - -### Prefixing Enum Values {#prefixing-values} - -When prefixing enum values, the remainder of the name with the prefix stripped -should still be a legal and style-conformant enum name. For example, avoid the -following: - -```proto -enum DeviceTier { - DEVICE_TIER_UNKNOWN = 0; - DEVICE_TIER_1 = 1; - DEVICE_TIER_2 = 2; -} -``` - -Instead, use a value name like `DEVICE_TIER_TIER1`, where the `DEVICE_TIER_` -portion is viewed as scoping the enum value rather than as part of the -individual enum value name. Some Protobuf implementations automatically strip -the prefix that matches the containing enum name where it is safe to do so, but -could not in this example since a bare `1` is not a legal enum value name. - -We plan for a future Edition to add support for scoped enums, which will -eliminate the need to manually prefix each enum value and enable this to be -written succinctly as `TIER1 = 1`. - -### Enum Default Value {#enum-default} - -The default value for the `SearchRequest.corpus` field is `CORPUS_UNSPECIFIED` -because that is the first value defined in the enum. - -In proto3, the first value defined in an enum definition **must** have the value -zero and should have the name `ENUM_TYPE_NAME_UNSPECIFIED` or -`ENUM_TYPE_NAME_UNKNOWN`. This is because: - -* There must be a zero value, so that we can use 0 as a numeric - [default value](#default). -* The zero value needs to be the first element, for compatibility with the - [proto2](/programming-guides/proto2) semantics where - the first enum value is the default unless a different value is explicitly - specified. - -It is also recommended that this first, default value have no semantic meaning -other than "this value was unspecified". - -### Enum Value Aliases {#enum-aliases} - -You can define aliases by assigning the same value to different enum constants. -To do this you need to set the `allow_alias` option to `true`. Otherwise, the -protocol buffer compiler generates a warning message when aliases are -found. Though all alias values are valid for serialization, only the first value -is used when deserializing. - -```proto -enum EnumAllowingAlias { - option allow_alias = true; - EAA_UNSPECIFIED = 0; - EAA_STARTED = 1; - EAA_RUNNING = 1; - EAA_FINISHED = 2; -} - -enum EnumNotAllowingAlias { - ENAA_UNSPECIFIED = 0; - ENAA_STARTED = 1; - // ENAA_RUNNING = 1; // Uncommenting this line will cause a warning message. - ENAA_FINISHED = 2; -} -``` - -Enumerator constants must be in the range of a 32-bit integer. Since `enum` -values use -[varint encoding](/programming-guides/encoding) on the -wire, negative values are inefficient and thus not recommended. You can define -`enum`s within a message definition, as in the earlier example, or outside – -these `enum`s can be reused in any message definition in your `.proto` file. You -can also use an `enum` type declared in one message as the type of a field in a -different message, using the syntax `_MessageType_._EnumType_`. - -When you run the protocol buffer compiler on a `.proto` that uses an `enum`, the -generated code will have a corresponding `enum` for Java, Kotlin, or C++, or a -special `EnumDescriptor` class for Python that's used to create a set of -symbolic constants with integer values in the runtime-generated class. - -{{% alert title="Important" color="warning" %}} The -generated code may be subject to language-specific limitations on the number of -enumerators (low thousands for one language). Review the -limitations for the languages you plan to use. -{{% /alert %}} - -During deserialization, unrecognized enum values will be preserved in the -message, though how this is represented when the message is deserialized is -language-dependent. In languages that support open enum types with values -outside the range of specified symbols, such as C++ and Go, the unknown enum -value is simply stored as its underlying integer representation. In languages -with closed enum types such as Java, a case in the enum is used to represent an -unrecognized value, and the underlying integer can be accessed with special -accessors. In either case, if the message is serialized the unrecognized value -will still be serialized with the message. - -{{% alert title="Important" color="warning" %}} For -information on how enums should work contrasted with how they currently work in -different languages, see -[Enum Behavior](/programming-guides/enum). -{{% /alert %}} - -For more information about how to work with message `enum`s in your -applications, see the [generated code guide](/reference/) -for your chosen language. - -### Reserved Values {#reserved} - -If you [update](#updating) an enum type by entirely removing an enum entry, or -commenting it out, future users can reuse the numeric value when making their -own updates to the type. This can cause severe issues if they later load old -instances of the same `.proto`, including data corruption, privacy bugs, and so -on. One way to make sure this doesn't happen is to specify that the numeric -values (and/or names, which can also cause issues for JSON serialization) of -your deleted entries are `reserved`. The protocol buffer compiler will complain -if any future users try to use these identifiers. You can specify that your -reserved numeric value range goes up to the maximum possible value using the -`max` keyword. - -```proto -enum Foo { - reserved 2, 15, 9 to 11, 40 to max; - reserved "FOO", "BAR"; -} -``` - -Note that you can't mix field names and numeric values in the same `reserved` -statement. - -## Using Other Message Types {#other} - -You can use other message types as field types. For example, let's say you -wanted to include `Result` messages in each `SearchResponse` message – to do -this, you can define a `Result` message type in the same `.proto` and then -specify a field of type `Result` in `SearchResponse`: - -```proto -message SearchResponse { - repeated Result results = 1; -} - -message Result { - string url = 1; - string title = 2; - repeated string snippets = 3; -} -``` - -### Importing Definitions {#importing} - -In the earlier example, the `Result` message type is defined in the same file as -`SearchResponse` – what if the message type you want to use as a field type is -already defined in another `.proto` file? - -You can use definitions from other `.proto` files by *importing* them. To import -another `.proto`'s definitions, you add an import statement to the top of your -file: - -```proto -import "myproject/other_protos.proto"; -``` - -The protobuf compiler searches for imported files in a set of directories -specified using the `-I`/`--proto_path` flag. The path given in an `import` -statement is resolved relative to these directories. For more information on -using the compiler, see [Generating Your Classes](#generating). - -For example, consider the following directory structure: - -``` -my_project/ -├── protos/ -│ ├── main.proto -│ └── common/ -│ └── timestamp.proto -``` - -To use definitions from `timestamp.proto` within `main.proto`, you would run the -compiler from the `my_project` directory and set `--proto_path=protos`. The -`import` statement in `main.proto` would then be: - -```proto -// Located in my_project/protos/main.proto -import "common/timestamp.proto"; -``` - -In general you should set the `--proto_path` flag to the highest-level directory -that contains protos. This is often the root of the project, but in this example -it's in a separate `/protos` directory. - -By default, you can use definitions only from directly imported `.proto` files. -However, sometimes you may need to move a `.proto` file to a new location. -Instead of moving the `.proto` file directly and updating all the call sites in -a single change, you can put a placeholder `.proto` file in the old location to -forward all the imports to the new location using the `import public` notion. - -**Note:** The public import functionality available in Java is most effective -when moving an entire .proto file or when using `java_multiple_files = true`. In -these cases, generated names remain stable, avoiding the need to update -references in your code. While technically functional when moving a subset of a -.proto file without `java_multiple_files = true`, doing so requires simultaneous -updates to many references, thus might not significantly ease migration. The -functionality is not available in Kotlin, TypeScript, JavaScript, or GCL. - -`import public` dependencies can be transitively relied upon by any code -importing the proto containing the `import public` statement. For example: - -```proto -// new.proto -// All definitions are moved here -``` - -```proto -// old.proto -// This is the proto that all clients are importing. -import public "new.proto"; -import "other.proto"; -``` - -```proto -// client.proto -import "old.proto"; -// You use definitions from old.proto and new.proto, but not other.proto -``` - -### Using proto2 Message Types {#proto2} - -It's possible to import -[proto2](/programming-guides/proto2) message types and -use them in your proto3 messages, and vice versa. However, proto2 enums cannot -be used directly in proto3 syntax (it's okay if an imported proto2 message uses -them). - -## Nested Types {#nested} - -You can define and use message types inside other message types, as in the -following example – here the `Result` message is defined inside the -`SearchResponse` message: - -```proto -message SearchResponse { - message Result { - string url = 1; - string title = 2; - repeated string snippets = 3; - } - repeated Result results = 1; -} -``` - -If you want to reuse this message type outside its parent message type, you -refer to it as `_Parent_._Type_`: - -```proto -message SomeOtherMessage { - SearchResponse.Result result = 1; -} -``` - -You can nest messages as deeply as you like. In the example below, note that the -two nested types named `Inner` are entirely independent, since they are defined -within different messages: - -```proto -message Outer { // Level 0 - message MiddleAA { // Level 1 - message Inner { // Level 2 - int64 ival = 1; - bool booly = 2; - } - } - message MiddleBB { // Level 1 - message Inner { // Level 2 - int32 ival = 1; - bool booly = 2; - } - } -} -``` - -## Updating A Message Type {#updating} - -If an existing message type no longer meets all your needs – for example, you'd -like the message format to have an extra field – but you'd still like to use -code created with the old format, don't worry! It's very simple to update -message types without breaking any of your existing code when you use the binary -wire format. - -{{% alert title="Note" color="note" %}} If -you use ProtoJSON or -[proto text format](/reference/protobuf/textformat-spec) -to store your protocol buffer messages, the changes that you can make in your -proto definition are different. The ProtoJSON wire format safe changes are -described -[here](/programming-guides/json#json-wire-safety). -{{% /alert %}} - -Check -[Proto Best Practices](/best-practices/dos-donts) and the -following rules: - -### Binary Wire-unsafe Changes {#wire-unsafe-changes} - -Wire-unsafe changes are schema changes that will break if you use parse data -that was serialized using the old schema with a parser that is using the new -schema (or vice versa). Only make wire-unsafe changes if you know that all -serializers and deserializers of the data are using the new schema. - -* Changing field numbers for any existing field is not safe. - * Changing the field number is equivalent to deleting the field and adding - a new field with the same type. If you want to renumber a field, see the - instructions for [deleting a field](#deleting). -* Moving fields into an existing `oneof` is not safe. - -### Binary Wire-safe Changes {#wire-safe-changes} - -Wire-safe changes are ones where it is fully safe to evolve the schema in this -way without risk of data loss or new parse failures. - -Note that any wire-safe changes may be a breaking change to application code in -a given language. For example, adding a value to a preexisting enum would be a -compilation break for any code with an exhaustive switch on that enum. For that -reason, Google may avoid making some of these types of changes on public -messages: the AIPs contain guidance for which of these changes are safe to make -there. - -* Adding new fields is safe. - * If you add new fields, any messages serialized by code using your "old" - message format can still be parsed by your new generated code. You - should keep in mind the [default values](#default) for these elements so - that new code can properly interact with messages generated by old code. - Similarly, messages created by your new code can be parsed by your old - code: old binaries simply ignore the new field when parsing. See the - [Unknown Fields](#unknowns) section for details. -* Removing fields is safe. - * The same field number must not used again in your updated message type. - You may want to rename the field instead, perhaps adding the prefix - "OBSOLETE_", or make the field number [reserved](#fieldreserved), so - that future users of your `.proto` can't accidentally reuse the number. -* Adding additional values to an enum is safe. -* Changing a single explicit presence field or extension into a member of a - **new** `oneof` is safe. -* Changing a `oneof` which contains only one field to an explicit presence - field is safe. -* Changing a field into an extension of same number and type is safe. - -### Binary Wire-compatible Changes (Conditionally Safe) {#conditionally-safe-changes} - -Unlike Wire-safe changes, wire-compatible means that the same data can be parsed -both before and after a given change. However, a parse of the data may be lossy -under this shape of change. For example, changing an int32 to an int64 is a -compatible change, but if a value larger than INT32_MAX is written, a client -that reads it as an int32 will discard the high order bits of the number. - -You can make compatible changes to your schema only if you manage the roll out -to your system carefully. For example, you may change an int32 to an int64 but -ensure you continue to only write legal int32 values until the new schema is -deployed to all endpoints, and then subsequently start writing larger values -after that. - -If your schema is published outside of your organization, you should generally -not make wire-compatible changes, as you cannot manage the deployment of the new -schema to know when the different range of values may be safe to use. - -* `int32`, `uint32`, `int64`, `uint64`, and `bool` are all compatible. - * If a number is parsed from the wire which doesn't fit in the - corresponding type, you will get the same effect as if you had cast the - number to that type in C++ (for example, if a 64-bit number is read as - an int32, it will be truncated to 32 bits). -* `sint32` and `sint64` are compatible with each other but are *not* - compatible with the other integer types. - * If the value written was between INT_MIN and INT_MAX inclusive it will - parse as the same value with either type. If an sint64 value was written - outside of that range and parsed as an sint32, the varint is truncated - to 32 bits and then zigzag decoding occurs (which will cause a different - value to be observed). -* `string` and `bytes` are compatible as long as the bytes are valid UTF-8. -* Embedded messages are compatible with `bytes` if the bytes contain an - encoded instance of the message. -* `fixed32` is compatible with `sfixed32`, and `fixed64` with `sfixed64`. -* For `string`, `bytes`, and message fields, singular is compatible with - `repeated`. - * Given serialized data of a repeated field as input, clients that expect - this field to be singular will take the last input value if it's a - primitive type field or merge all input elements if it's a message type - field. Note that this is **not** generally safe for numeric types, - including bools and enums. Repeated fields of numeric types are - serialized in the - [packed](/programming-guides/encoding#packed) - format by default, which will not be parsed correctly when a singular - field is expected. -* `enum` is compatible with `int32`, `uint32`, `int64`, and `uint64` - * Be aware that client code may treat them differently when the message is - deserialized: for example, unrecognized proto3 `enum` values will be - preserved in the message, but how this is represented when the message - is deserialized is language-dependent. -* Changing a field between a `map` and the corresponding `repeated` - message field is binary compatible (see [Maps](#maps), below, for the - message layout and other restrictions). - * However, the safety of the change is application-dependent: when - deserializing and reserializing a message, clients using the `repeated` - field definition will produce a semantically identical result; however, - clients using the `map` field definition may reorder entries and drop - entries with duplicate keys. - -## Unknown Fields {#unknowns} - -Unknown fields are well-formed protocol buffer serialized data representing -fields that the parser does not recognize. For example, when an old binary -parses data sent by a new binary with new fields, those new fields become -unknown fields in the old binary. - -Proto3 messages preserve unknown fields and include them during parsing and in -the serialized output, which matches proto2 behavior. - -### Retaining Unknown Fields {#retaining} - -Some actions can cause unknown fields to be lost. For example, if you do one of -the following, unknown fields are lost: - -* Serialize a proto to JSON. -* Iterate over all of the fields in a message to populate a new message. - -To avoid losing unknown fields, do the following: - -* Use binary; avoid using text formats for data exchange. -* Use message-oriented APIs, such as `CopyFrom()` and `MergeFrom()`, to copy data - rather than copying field-by-field - -TextFormat is a bit of a special case. Serializing to TextFormat prints unknown -fields using their field numbers. But parsing TextFormat data back into a binary -proto fails if there are entries that use field numbers. - -## Any {#any} - -The `Any` message type lets you use messages as embedded types without having -their .proto definition. An `Any` contains an arbitrary serialized message as -`bytes`, along with a URL that acts as a globally unique identifier for and -resolves to that message's type. To use the `Any` type, you need to -[import](#other) `google/protobuf/any.proto`. - -```proto -import "google/protobuf/any.proto"; - -message ErrorStatus { - string message = 1; - repeated google.protobuf.Any details = 2; -} -``` - -The default type URL for a given message type is -`type.googleapis.com/_packagename_._messagename_`. - -Different language implementations will support runtime library helpers to pack -and unpack `Any` values in a typesafe manner – for example, in Java, the `Any` -type will have special `pack()` and `unpack()` accessors, while in C++ there are -`PackFrom()` and `UnpackTo()` methods: - -```cpp -// Storing an arbitrary message type in Any. -NetworkErrorDetails details = ...; -ErrorStatus status; -status.add_details()->PackFrom(details); - -// Reading an arbitrary message from Any. -ErrorStatus status = ...; -for (const google::protobuf::Any& detail : status.details()) { - if (detail.Is()) { - NetworkErrorDetails network_error; - detail.UnpackTo(&network_error); - ... processing network_error ... - } -} -``` - -## Oneof {#oneof} - -If you have a message with many singular fields and where at most one field will -be set at the same time, you can enforce this behavior and save memory by using -the oneof feature. - -Oneof fields are like optional fields except all the fields in a oneof share -memory, and at most one field can be set at the same time. Setting any member of -the oneof automatically clears all the other members. You can check which value -in a oneof is set (if any) using a special `case()` or `WhichOneof()` method, -depending on your chosen language. - -Note that if *multiple values are set, the last set value as determined by the -order in the proto will overwrite all previous ones*. - -Field numbers for oneof fields must be unique within the enclosing message. - -### Using Oneof {#using-oneof} - -To define a oneof in your `.proto` you use the `oneof` keyword followed by your -oneof name, in this case `test_oneof`: - -```proto -message SampleMessage { - oneof test_oneof { - string name = 4; - SubMessage sub_message = 9; - } -} -``` - -You then add your oneof fields to the oneof definition. You can add fields of -any type, except `map` fields and `repeated` fields. If you need to add a -repeated field to a oneof, you can use a message containing the repeated field. - -In your generated code, oneof fields have the same getters and setters as -regular fields. You also get a special method for checking which value (if any) -in the oneof is set. You can find out more about the oneof API for your chosen -language in the relevant [API reference](/reference/). - -### Oneof Features {#oneof-features} - -* Setting a oneof field will automatically clear all other members of the - oneof. So if you set several oneof fields, only the *last* field you set - will still have a value. - - ```cpp - SampleMessage message; - message.set_name("name"); - CHECK_EQ(message.name(), "name"); - // Calling mutable_sub_message() will clear the name field and will set - // sub_message to a new instance of SubMessage with none of its fields set. - message.mutable_sub_message(); - CHECK(message.name().empty()); - ``` - -* If the parser encounters multiple members of the same oneof on the wire, - only the last member seen is used in the parsed message. When parsing data - on the wire, starting at the beginning of the bytes, evaluate the next - value, and apply the following parsing rules: - - * First, check if a *different* field in the same oneof is currently set, - and if so clear it. - - * Then apply the contents as though the field was not in a oneof: - - * A primitive will overwrite any value already set - * A message will merge into any value already set - -* A oneof cannot be `repeated`. - -* Reflection APIs work for oneof fields. - -* If you set a oneof field to the default value (such as setting an int32 - oneof field to 0), the "case" of that oneof field will be set, and the value - will be serialized on the wire. - -* If you're using C++, make sure your code doesn't cause memory crashes. The - following sample code will crash because `sub_message` was already deleted - by calling the `set_name()` method. - - ```cpp - SampleMessage message; - SubMessage* sub_message = message.mutable_sub_message(); - message.set_name("name"); // Will delete sub_message - sub_message->set_... // Crashes here - ``` - -* Again in C++, if you `Swap()` two messages with oneofs, each message will - end up with the other's oneof case: in the example below, `msg1` will have a - `sub_message` and `msg2` will have a `name`. - - ```cpp - SampleMessage msg1; - msg1.set_name("name"); - SampleMessage msg2; - msg2.mutable_sub_message(); - msg1.swap(&msg2); - CHECK(msg1.has_sub_message()); - CHECK_EQ(msg2.name(), "name"); - ``` - -### Backwards-compatibility issues {#backward} - -Be careful when adding or removing oneof fields. If checking the value of a -oneof returns `None`/`NOT_SET`, it could mean that the oneof has not been set or -it has been set to a field in a different version of the oneof. There is no way -to tell the difference, since there's no way to know if an unknown field on the -wire is a member of the oneof. - -#### Tag Reuse Issues {#reuse} - -* **Move singular fields into or out of a oneof**: You may lose some of your - information (some fields will be cleared) after the message is serialized - and parsed. However, you can safely move a single field into a **new** oneof - and may be able to move multiple fields if it is known that only one is ever - set. See [Updating A Message Type](#updating) for further details. -* **Delete a oneof field and add it back**: This may clear your currently set - oneof field after the message is serialized and parsed. -* **Split or merge oneof**: This has similar issues to moving singular fields. - -## Maps {#maps} - -If you want to create an associative map as part of your data definition, -protocol buffers provides a handy shortcut syntax: - -```proto -map map_field = N; -``` - -...where the `key_type` can be any integral or string type (so, any -[scalar](#scalar) type except for floating point types and `bytes`). Note that -neither enum nor proto messages are valid for `key_type`. -The `value_type` can be any type except another map. - -So, for example, if you wanted to create a map of projects where each `Project` -message is associated with a string key, you could define it like this: - -```proto -map projects = 3; -``` - -### Maps Features {#maps-features} - -* Map fields cannot be `repeated`. -* Wire format ordering and map iteration ordering of map values is undefined, - so you cannot rely on your map items being in a particular order. -* When generating text format for a `.proto`, maps are sorted by key. Numeric - keys are sorted numerically. -* When parsing from the wire or when merging, if there are duplicate map keys - the last key seen is used. When parsing a map from text format, parsing may - fail if there are duplicate keys. -* If you provide a key but no value for a map field, the behavior when the - field is serialized is language-dependent. In C++, Java, Kotlin, and Python - the default value for the type is serialized, while in other languages - nothing is serialized. -* No symbol `FooEntry` can exist in the same scope as a map `foo`, because - `FooEntry` is already used by the implementation of the map. - -The generated map API is currently available for all supported languages. You -can find out more about the map API for your chosen language in the relevant -[API reference](/reference/). - -### Backwards Compatibility {#backwards} - -The map syntax is equivalent to the following on the wire, so protocol buffers -implementations that do not support maps can still handle your data: - -```proto -message MapFieldEntry { - key_type key = 1; - value_type value = 2; -} - -repeated MapFieldEntry map_field = N; -``` - -Any protocol buffers implementation that supports maps must both produce and -accept data that can be accepted by the earlier definition. - -## Packages {#packages} - -You can add an optional `package` specifier to a `.proto` file to prevent name -clashes between protocol message types. - -```proto -package foo.bar; -message Open { ... } -``` - -You can then use the package specifier when defining fields of your message -type: - -```proto -message Foo { - ... - foo.bar.Open open = 1; - ... -} -``` - -The way a package specifier affects the generated code depends on your chosen -language: - -* In **C++** the generated classes are wrapped inside a C++ namespace. For - example, `Open` would be in the namespace `foo::bar`. -* In **Java** and **Kotlin**, the package is used as the Java package, unless - you explicitly provide an `option java_package` in your `.proto` file. -* In **Python**, the `package` directive is ignored, since Python modules are - organized according to their location in the file system. -* In **Go**, the `package` directive is ignored, and the generated `.pb.go` - file is in the package named after the corresponding `go_proto_library` - Bazel rule. For open source projects, you **must** provide either a `go_package` option or set the Bazel `-M` flag. -* In **Ruby**, the generated classes are wrapped inside nested Ruby - namespaces, converted to the required Ruby capitalization style (first - letter capitalized; if the first character is not a letter, `PB_` is - prepended). For example, `Open` would be in the namespace `Foo::Bar`. -* In **PHP** the package is used as the namespace after converting to - PascalCase, unless you explicitly provide an `option php_namespace` in your - `.proto` file. For example, `Open` would be in the namespace `Foo\Bar`. -* In **C#** the package is used as the namespace after converting to - PascalCase, unless you explicitly provide an `option csharp_namespace` in - your `.proto` file. For example, `Open` would be in the namespace `Foo.Bar`. - -Note that even when the `package` directive does not directly affect the -generated code, for example in Python, it is still strongly recommended to -specify the package for the `.proto` file, as otherwise it may lead to naming -conflicts in descriptors and make the proto not portable for other languages. - -### Packages and Name Resolution {#name-resolution} - -Type name resolution in the protocol buffer language works like C++: first the -innermost scope is searched, then the next-innermost, and so on, with each -package considered to be "inner" to its parent package. A leading '.' (for -example, `.foo.bar.Baz`) means to start from the outermost scope instead. - -The protocol buffer compiler resolves all type names by parsing the imported -`.proto` files. The code generator for each language knows how to refer to each -type in that language, even if it has different scoping rules. - -## Defining Services {#services} - -If you want to use your message types with an RPC (Remote Procedure Call) -system, you can define an RPC service interface in a `.proto` file and the -protocol buffer compiler will generate service interface code and stubs in your -chosen language. So, for example, if you want to define an RPC service with a -method that takes your `SearchRequest` and returns a `SearchResponse`, you can -define it in your `.proto` file as follows: - -```proto -service SearchService { - rpc Search(SearchRequest) returns (SearchResponse); -} -``` - -The most straightforward RPC system to use with protocol buffers is -[gRPC](https://grpc.io): a language- and platform-neutral open source RPC system -developed at Google. gRPC works particularly well with protocol buffers and lets -you generate the relevant RPC code directly from your `.proto` files using a -special protocol buffer compiler plugin. - -If you don't want to use gRPC, it's also possible to use protocol buffers with -your own RPC implementation. You can find out more about this in the -[Proto2 Language Guide](/programming-guides/proto2#services). - -There are also a number of ongoing third-party projects to develop RPC -implementations for Protocol Buffers. For a list of links to projects we know -about, see the -[third-party add-ons wiki page](https://github.com/protocolbuffers/protobuf/blob/master/docs/third_party.md). - -## JSON Mapping {#json} - -The standard protobuf binary wire format is the preferred serialization format -for communication between two systems that use protobufs. For communicating with -systems that use JSON rather than protobuf wire format, Protobuf supports a -canonical encoding in [JSON](/programming-guides/json). - -## Options {#options} - -Individual declarations in a `.proto` file can be annotated with a number of -*options*. Options do not change the overall meaning of a declaration, but may -affect the way it is handled in a particular context. The complete list of -available options is defined in [`/google/protobuf/descriptor.proto`](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto). - -Some options are file-level options, meaning they should be written at the -top-level scope, not inside any message, enum, or service definition. Some -options are message-level options, meaning they should be written inside message -definitions. Some options are field-level options, meaning they should be -written inside field definitions. Options can also be written on enum types, -enum values, oneof fields, service types, and service methods; however, no -useful options currently exist for any of these. - -Here are a few of the most commonly used options: - -* `java_package` (file option): The package you want to use for your generated - Java/Kotlin classes. If no explicit `java_package` option is given in the - `.proto` file, then by default the proto package (specified using the - "package" keyword in the `.proto` file) will be used. However, proto - packages generally do not make good Java packages since proto packages are - not expected to start with reverse domain names. If not generating Java or - Kotlin code, this option has no effect. - - ```proto - option java_package = "com.example.foo"; - ``` - -* `java_outer_classname` (file option): The class name (and hence the file - name) for the wrapper Java class you want to generate. If no explicit - `java_outer_classname` is specified in the `.proto` file, the class name - will be constructed by converting the `.proto` file name to camel-case (so - `foo_bar.proto` becomes `FooBar.java`). If the `java_multiple_files` option - is disabled, then all other classes/enums/etc. generated for the `.proto` - file will be generated *within* this outer wrapper Java class as nested - classes/enums/etc. If not generating Java code, this option has no effect. - - ```proto - option java_outer_classname = "Ponycopter"; - ``` - -* `java_multiple_files` (file option): If false, only a single `.java` file - will be generated for this `.proto` file, and all the Java - classes/enums/etc. generated for the top-level messages, services, and - enumerations will be nested inside of an outer class (see - `java_outer_classname`). If true, separate `.java` files will be generated - for each of the Java classes/enums/etc. generated for the top-level - messages, services, and enumerations, and the wrapper Java class generated - for this `.proto` file won't contain any nested classes/enums/etc. This is a - Boolean option which defaults to `false`. If not generating Java code, this - option has no effect. - - ```proto - option java_multiple_files = true; - ``` - -* `optimize_for` (file option): Can be set to `SPEED`, `CODE_SIZE`, or - `LITE_RUNTIME`. This affects the C++ and Java code generators (and possibly - third-party generators) in the following ways: - - * `SPEED` (default): The protocol buffer compiler will generate code for - serializing, parsing, and performing other common operations on your - message types. This code is highly optimized. - * `CODE_SIZE`: The protocol buffer compiler will generate minimal classes - and will rely on shared, reflection-based code to implement - serialization, parsing, and various other operations. The generated code - will thus be much smaller than with `SPEED`, but operations will be - slower. Classes will still implement exactly the same public API as they - do in `SPEED` mode. This mode is most useful in apps that contain a very - large number of `.proto` files and do not need all of them to be - blindingly fast. - * `LITE_RUNTIME`: The protocol buffer compiler will generate classes that - depend only on the "lite" runtime library (`libprotobuf-lite` instead of - `libprotobuf`). The lite runtime is much smaller than the full library - (around an order of magnitude smaller) but omits certain features like - descriptors and reflection. This is particularly useful for apps running - on constrained platforms like mobile phones. The compiler will still - generate fast implementations of all methods as it does in `SPEED` mode. - Generated classes will only implement the `MessageLite` interface in - each language, which provides only a subset of the methods of the full - `Message` interface. - - ```proto - option optimize_for = CODE_SIZE; - ``` - -* `cc_generic_services`, `java_generic_services`, `py_generic_services` (file - options): **Generic services are deprecated.** Whether or not the protocol - buffer compiler should generate abstract service code based on - [services definitions](#services) in C++, Java, and Python, respectively. - For legacy reasons, these default to `true`. However, as of version 2.3.0 - (January 2010), it is considered preferable for RPC implementations to - provide - [code generator plugins](/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb) - to generate code more specific to each system, rather than rely on the - "abstract" services. - - ```proto - // This file relies on plugins to generate service code. - option cc_generic_services = false; - option java_generic_services = false; - option py_generic_services = false; - ``` - -* `cc_enable_arenas` (file option): Enables - [arena allocation](/reference/cpp/arenas) for C++ - generated code. - -* `objc_class_prefix` (file option): Sets the Objective-C class prefix which - is prepended to all Objective-C generated classes and enums from this - .proto. There is no default. You should use prefixes that are between 3-5 - uppercase characters as - [recommended by Apple](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Conventions/Conventions.html#//apple_ref/doc/uid/TP40011210-CH10-SW4). - Note that all 2 letter prefixes are reserved by Apple. - -* `packed` (field option): Defaults to `true` on a repeated field of a basic - numeric type, causing a more compact - [encoding](/programming-guides/encoding#packed) to be - used. To use unpacked wireformat, it can be set to `false`. This provides - compatibility with parsers prior to version 2.3.0 (rarely needed) as shown - in the following example: - - ```proto - repeated int32 samples = 4 [packed = false]; - ``` - -* `deprecated` (field option): If set to `true`, indicates that the field is - deprecated and should not be used by new code. In most languages this has no - actual effect. In Java, this becomes a `@Deprecated` annotation. For C++, - clang-tidy will generate warnings whenever deprecated fields are used. In - the future, other language-specific code generators may generate deprecation - annotations on the field's accessors, which will in turn cause a warning to - be emitted when compiling code which attempts to use the field. If the field - is not used by anyone and you want to prevent new users from using it, - consider replacing the field declaration with a [reserved](#fieldreserved) - statement. - - ```proto - int32 old_field = 6 [deprecated = true]; - ``` - -### Enum Value Options {#enum-value-options} - -Enum value options are supported. You can use the `deprecated` option to -indicate that a value shouldn't be used anymore. You can also create custom -options using extensions. - -The following example shows the syntax for adding these options: - -```proto -import "google/protobuf/descriptor.proto"; - -extend google.protobuf.EnumValueOptions { - optional string string_name = 123456789; -} - -enum Data { - DATA_UNSPECIFIED = 0; - DATA_SEARCH = 1 [deprecated = true]; - DATA_DISPLAY = 2 [ - (string_name) = "display_value" - ]; -} -``` - -The C++ code to read the `string_name` option might look something like this: - -```cpp -const absl::string_view foo = proto2::GetEnumDescriptor() - ->FindValueByName("DATA_DISPLAY")->options().GetExtension(string_name); -``` - -See [Custom Options](#customoptions) to see how to apply custom options to enum -values and to fields. - -### Custom Options {#customoptions} - -Protocol Buffers also allows you to define and use your own options. Note that -this is an **advanced feature** which most people don't need. If you do think -you need to create your own options, see the -[Proto2 Language Guide](/programming-guides/proto2#customoptions) -for details. Note that creating custom options uses -[extensions](/programming-guides/proto2#extensions), -which are permitted only for custom options in proto3. - -### Option Retention {#option-retention} - -Options have a notion of *retention*, which controls whether an option is -retained in the generated code. Options have *runtime retention* by default, -meaning that they are retained in the generated code and are thus visible at -runtime in the generated descriptor pool. However, you can set `retention = -RETENTION_SOURCE` to specify that an option (or field within an option) must not -be retained at runtime. This is called *source retention*. - -Option retention is an advanced feature that most users should not need to worry -about, but it can be useful if you would like to use certain options without -paying the code size cost of retaining them in your binaries. Options with -source retention are still visible to `protoc` and `protoc` plugins, so code -generators can use them to customize their behavior. - -Retention can be set directly on an option, like this: - -```proto -extend google.protobuf.FileOptions { - optional int32 source_retention_option = 1234 - [retention = RETENTION_SOURCE]; -} -``` - -It can also be set on a plain field, in which case it takes effect only when -that field appears inside an option: - -```proto -message OptionsMessage { - int32 source_retention_field = 1 [retention = RETENTION_SOURCE]; -} -``` - -You can set `retention = RETENTION_RUNTIME` if you like, but this has no effect -since it is the default behavior. When a message field is marked -`RETENTION_SOURCE`, its entire contents are dropped; fields inside it cannot -override that by trying to set `RETENTION_RUNTIME`. - -{{% alert title="Note" color="note" %}} As -of Protocol Buffers 22.0, support for option retention is still in progress and -only C++ and Java are supported. Go has support starting from 1.29.0. Python -support is complete but has not made it into a release yet. -{{% /alert %}} - -### Option Targets {#option-targets} - -Fields have a `targets` option which controls the types of entities that the -field may apply to when used as an option. For example, if a field has -`targets = TARGET_TYPE_MESSAGE` then that field cannot be set in a custom option -on an enum (or any other non-message entity). Protoc enforces this and will -raise an error if there is a violation of the target constraints. - -At first glance, this feature may seem unnecessary given that every custom -option is an extension of the options message for a specific entity, which -already constrains the option to that one entity. However, option targets are -useful in the case where you have a shared options message applied to multiple -entity types and you want to control the usage of individual fields in that -message. For example: - -```proto -message MyOptions { - string file_only_option = 1 [targets = TARGET_TYPE_FILE]; - int32 message_and_enum_option = 2 [targets = TARGET_TYPE_MESSAGE, - targets = TARGET_TYPE_ENUM]; -} - -extend google.protobuf.FileOptions { - optional MyOptions file_options = 50000; -} - -extend google.protobuf.MessageOptions { - optional MyOptions message_options = 50000; -} - -extend google.protobuf.EnumOptions { - optional MyOptions enum_options = 50000; -} - -// OK: this field is allowed on file options -option (file_options).file_only_option = "abc"; - -message MyMessage { - // OK: this field is allowed on both message and enum options - option (message_options).message_and_enum_option = 42; -} - -enum MyEnum { - MY_ENUM_UNSPECIFIED = 0; - // Error: file_only_option cannot be set on an enum. - option (enum_options).file_only_option = "xyz"; -} -``` - -## Generating Your Classes {#generating} - -To generate the Java, Kotlin, Python, C++, Go, Ruby, Objective-C, or C# code -that you need to work with the message types defined in a `.proto` file, you -need to run the protocol buffer compiler `protoc` on the `.proto` file. If you -haven't installed the compiler, -[download the package](/downloads) and follow the -instructions in the README. For Go, you also need to install a special code -generator plugin for the compiler; you can find this and installation -instructions in the [golang/protobuf](https://github.com/golang/protobuf/) -repository on GitHub. - -The protobuf compiler is invoked as follows: - -```sh -protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR --go_out=DST_DIR --ruby_out=DST_DIR --objc_out=DST_DIR --csharp_out=DST_DIR path/to/file.proto -``` - -* `IMPORT_PATH` specifies a directory in which to look for `.proto` files when - resolving `import` directives. If omitted, the current directory is used. - Multiple import directories can be specified by passing the `--proto_path` - option multiple times. `-I=_IMPORT_PATH_` can be used as a short form of - `--proto_path`. - -**Note:** File paths relative to their `proto_path` must be globally unique in a -given binary. For example, if you have `proto/lib1/data.proto` and -`proto/lib2/data.proto`, those two files cannot be used together with -`-I=proto/lib1 -I=proto/lib2` because it would be ambiguous which file `import -"data.proto"` will mean. Instead `-Iproto/` should be used and the global names -will be `lib1/data.proto` and `lib2/data.proto`. - -If you are publishing a library and other users may use your messages directly, -you should include a unique library name in the path that they are expected to -be used under to avoid file name collisions. If you have multiple directories in -one project, it is best practice to prefer setting one `-I` to a top level -directory of the project. - -* You can provide one or more *output directives*: - - * `--cpp_out` generates C++ code in `DST_DIR`. See the - [C++ generated code reference](/reference/cpp/cpp-generated) - for more. - * `--java_out` generates Java code in `DST_DIR`. See the - [Java generated code reference](/reference/java/java-generated) - for more. - * `--kotlin_out` generates additional Kotlin code in `DST_DIR`. See the - [Kotlin generated code reference](/reference/kotlin/kotlin-generated) - for more. - * `--python_out` generates Python code in `DST_DIR`. See the - [Python generated code reference](/reference/python/python-generated) - for more. - * `--go_out` generates Go code in `DST_DIR`. See the - [Go generated code reference](/reference/go/go-generated-opaque) - for more. - * `--ruby_out` generates Ruby code in `DST_DIR`. See the - [Ruby generated code reference](/reference/ruby/ruby-generated) - for more. - * `--objc_out` generates Objective-C code in `DST_DIR`. See the - [Objective-C generated code reference](/reference/objective-c/objective-c-generated) - for more. - * `--csharp_out` generates C# code in `DST_DIR`. See the - [C# generated code reference](/reference/csharp/csharp-generated) - for more. - * `--php_out` generates PHP code in `DST_DIR`. See the - [PHP generated code reference](/reference/php/php-generated) - for more. - - As an extra convenience, if the `DST_DIR` ends in `.zip` or `.jar`, the - compiler will write the output to a single ZIP-format archive file with the - given name. `.jar` outputs will also be given a manifest file as required by - the Java JAR specification. Note that if the output archive already exists, - it will be overwritten. - -* You must provide one or more `.proto` files as input. Multiple `.proto` - files can be specified at once. Although the files are named relative to the - current directory, each file must reside in one of the `IMPORT_PATH`s so - that the compiler can determine its canonical name. - -## File location {#location} - -Prefer not to put `.proto` files in the same -directory as other language sources. Consider -creating a subpackage `proto` for `.proto` files, under the root package for -your project. - -### Location Should be Language-agnostic {#location-language-agnostic} - -When working with Java code, it's handy to put related `.proto` files in the -same directory as the Java source. However, if any non-Java code ever uses the -same protos, the path prefix will no longer make sense. So in -general, put the protos in a related language-agnostic directory such as -`//myteam/mypackage`. - -The exception to this rule is when it's clear that the protos will be used only -in a Java context, such as for testing. - -## Supported Platforms {#platforms} - -For information about: - -* the operating systems, compilers, build systems, and C++ versions that are - supported, see - [Foundational C++ Support Policy](https://opensource.google/documentation/policies/cplusplus-support). -* the PHP versions that are supported, see - [Supported PHP versions](https://cloud.google.com/php/getting-started/supported-php-versions). diff --git a/content/programming-guides/serialization-not-canonical.md b/content/programming-guides/serialization-not-canonical.md deleted file mode 100644 index 7ba9ae95c..000000000 --- a/content/programming-guides/serialization-not-canonical.md +++ /dev/null @@ -1,75 +0,0 @@ -+++ -title = "Proto Serialization Is Not Canonical" -weight = 88 -description = "Explains how serialization works and why it is not canonical." -type = "docs" -+++ - - - -Many people want a serialized proto to canonically represent the contents of -that proto. Use cases include: - -* using a serialized proto as a key in a hash table -* taking a fingerprint or checksum of a serialized proto -* comparing serialized payloads as a way of checking message equality - -Unfortunately, *protobuf serialization is not (and cannot be) canonical*. There -are a few notable exceptions, such as MapReduce, but in general you should -generally think of proto serialization as unstable. This page explains why. - -## Deterministic is not Canonical - -Deterministic serialization is not canonical. The serializer can generate -different output for many reasons, including but not limited to the following -variations: - -1. The protobuf schema changes in any way. -1. The application being built changes in any way. -1. The binary is built with different flags (eg. opt vs. debug). -1. The protobuf library is updated. - -This means that hashes of serialized protos are fragile and not stable across -time or space. - -There are many reasons why the serialized output can change. The above list is -not exhaustive. Some of them are inherent difficulties in the problem space that -would make it inefficient or impossible to guarantee canonical serialization -even if we wanted to. Others are things we intentionally leave undefined to -allow for optimization opportunities. - -## Inherent Barriers to Stable Serialization - -Protobuf objects preserve unknown fields to provide forward and backward -compatibility. The handling of unknown fields is a primary obstacle to canonical -serialization. - -In the wire format, bytes fields and nested sub-messages use the same wire type. -This ambiguity makes it impossible to correctly canonicalize messages stored in -the unknown field set. Since the exact same contents may be either one, it is -impossible to know whether to treat it as a message and recurse down or not. - -For efficiency, implementations typically serialize unknown fields after known -fields. Canonical serialization, however, would require interleaving unknown -fields with known fields according to field number. This would impose -significant efficiency and code size costs on all users, even those not -requiring this feature. - -## Things Intentionally Left Undefined - -Even if canonical serialization was feasible (that is, if we could solve the -unknown field problem), we intentionally leave serialization order undefined to -allow for more optimization opportunities: - -1. If we can prove a field is never used in a binary, we can remove it from the - schema completely and process it as an unknown field. This saves substantial - code size and CPU cycles. -2. There may be opportunities to optimize by serializing vectors of the same - field together, even though this would break field number order. - -To leave room for optimizations like this, we want to intentionally scramble -field order in some configurations, so that applications do not inappropriately -depend on field order. diff --git a/content/programming-guides/style.md b/content/programming-guides/style.md deleted file mode 100644 index 73b24a211..000000000 --- a/content/programming-guides/style.md +++ /dev/null @@ -1,300 +0,0 @@ -+++ -title = "Style Guide" -weight = 50 -description = "Provides direction for how best to structure your proto definitions." -type = "docs" -+++ - -This document provides a style guide for `.proto` files. By following these -conventions, you'll make your protocol buffer message definitions and their -corresponding classes consistent and easy to read. - -Enforcement of the following style guidelines is controlled via -[enforce_naming_style](/editions/features#enforce-naming). - -## Standard File Formatting {#standard-file-formatting} - -* Keep the line length to 80 characters. -* Use an indent of 2 spaces. -* Prefer the use of double quotes for strings. - -## File Structure {#file-structure} - -Files should be named `lower_snake_case.proto`. - -All files should be ordered in the following manner: - -1. License header (if applicable) -1. File overview -1. Syntax or edition -1. Package -1. Imports (sorted) -1. File options -1. Everything else - -## Identifier naming styles {#identifier} - -Protobuf identifiers use one of the following naming styles: - -1. TitleCase - * Contains uppercase letters, lowercase letters, and numbers - * The initial character is an uppercase letter - * The initial letter of each word is capitalized -1. lower_snake_case - * Contains lowercase letters, underscores, and numbers - * Words are separated by a single underscore -1. UPPER_SNAKE_CASE - * Contains uppercase letters, underscores, and numbers - * Words are separated by a single underscore -1. camelCase - * Contains uppercase letters, lowercase letters, and numbers - * The initial character is an lowercase letter - * The initial letter of each subsequent word is capitalized - * **Note:** The style guide below does not use camelCase for any - identifier in .proto files; the terminology is only clarified here since - some language's generated code may transform identifiers into this - style. - -In all cases, treat abbreviations as though they are single words: use -`GetDnsRequest` rather than `GetDNSRequest`, `dns_request` rather than -`d_n_s_request`. - -#### Underscores in Identifiers {#underscores} - -Don't use underscores as the initial or final character of a name. Any -underscore should always be followed by a letter (not a number or a second -underscore). - -The motivation for this rule is that each protobuf language implementation may -convert identifiers into the local language style: a name of `song_id` in a -.proto file may end up having accessors for the field which are capitalized as -`SongId`, `songId` or `song_id` depending on the language. - -By using underscores only before letters, it avoids situations where names may -be distinct in one style, but would collide after they are transformed into one -of the other styles. - -For example, both `DNS2` and `DNS_2` would both transform into TitleCase as -`Dns2`. Allowing either of those names can be lead to painful situations when a -message is used only in some languages where the generated code keeps the -original UPPER_SNAKE_CASE style, becomes widely established, and then is only -later used in a language where names are transformed to TitleCase where they -collide. - -When applied, this style rule means that you should use `XYZ2` or `XYZ_V2` -rather than `XYZ_2` or `XYZ_2V`. - -## Packages {#packages} - -Packages names should be a dot-delimited sequence of lower_snake_case names. -They should not contain uppercase letters. - -Multi-word package names may be lower_snake_case or dot.delimited (dot-delimited -package names are emitted as nested packages/namespaces in most languages). - -Package names should attempt to be a short but unique name based on the project -name. The package should not be coupled with the directory path, especially when -the files are in a deeply nested path. - -Package names should not be Java packages (`com.company.x.y`); instead use `x.y` -as the package and use the `java_package` option. - -## Message Names {#message-names} - -Use TitleCase for message names. - -```proto -message SongRequest { -} -``` - -## Field Names {#field-names} - -Use snake_case for field names, including extensions. - -Use pluralized names for repeated fields. - -```proto -string song_name = 1; -repeated Song songs = 2; -``` - -## Oneof Names {#oneof-names} - -Use lower_snake_case for oneof names. - -```proto -oneof song_id { - string song_human_readable_id = 1; - int64 song_machine_id = 2; -} -``` - -## Enums {#enums} - -Use TitleCase for enum type names. - -Use UPPER_SNAKE_CASE for enum value names. - -```proto -enum FooBar { - FOO_BAR_UNSPECIFIED = 0; - FOO_BAR_FIRST_VALUE = 1; - FOO_BAR_SECOND_VALUE = 2; -} -``` - -The first listed value should be a zero value enum and have the suffix of either -`_UNSPECIFIED` or `_UNKNOWN`. This value may be used as an unknown/default value -and should be distinct from any of the semantic values you expect to be -explicitly set. For more information on the unspecified enum value, see -[the Proto Best Practices page](/best-practices/dos-donts#unspecified-enum). - -Assign the number used for each value densely and sequentially increasing. Gaps -in numbering should only occur when a previously used enum value is removed. -Avoid using negative values. - -#### Enum Value Prefixing {#enum-value-prefixing} - -Enum values are semantically considered to not be scoped by their containing -enum name, so the same name in two sibling enums is not allowed. For example, -the following would be rejected by protoc since the `SET` value defined in the -two enums are considered to be in the same scope: - -```proto {.bad} -enum CollectionType { - COLLECTION_TYPE_UNSPECIFIED = 0; - SET = 1; - MAP = 2; - ARRAY = 3; -} - -// Won't compile - `SET` enum name will clash -// with the one defined in `CollectionType` enum. -enum TennisVictoryType { - TENNIS_VICTORY_TYPE_UNSPECIFIED = 0; - GAME = 1; - SET = 2; - MATCH = 3; -} -``` - -Name collisions are a high risk when enums are defined at the top level of a -file (not nested inside a message definition); in that case the siblings include -enums defined in other files that set the same package, where protoc may not be -able to detect the collision has occurred at code generation time. - -To avoid these risks, it is strongly recommended to do one of: - -* Prefix every value with the enum name (converted to UPPER_SNAKE_CASE) -* Nest the enum inside a containing message - -Either option is enough to mitigate collision risks, but prefer top-level enums -with prefixed values over creating a message simply to mitigate the issue. Since -some languages don't support an enum being defined inside a "struct" type, -preferring prefixed values ensures a consistent approach across binding -languages. - -When prefixing enum values, the remainder of the name with the prefix stripped -should still be a legal and style-conformant enum name. For example, avoid the -following: - -``` -enum DeviceTier { - DEVICE_TIER_UNKNOWN = 0; - DEVICE_TIER_1 = 1; - DEVICE_TIER_2 = 2; -} -``` - -Instead, use a value name like `DEVICE_TIER_TIER1`, where the `DEVICE_TIER_` -portion is viewed as scoping the enum value rather than as part of the -individual enum value name. Some Protobuf implementations automatically strip -the prefix that matches the containing enum name where it is safe to do so, but -could not in this example since a bare `1` is not a legal enum value name. - -A future Edition will add support for scoped enums, which will eliminate the -need to manually prefix each enum value and enable this to be written succinctly -as `TIER1 = 1`. - -## Services {#services} - -Use TitleCase for service names and method names. - -```proto -service FooService { - rpc GetSomething(GetSomethingRequest) returns (GetSomethingResponse); - rpc ListSomething(ListSomethingRequest) returns (ListSomethingResponse); -} -``` - -## Things to Avoid {#avoid} - -### Avoid confusing relative packages on field types {#confusing-relative-packages} - -The .proto syntax allows you to reference types that are defined in a different -package in a relative manner. Resolution will search up the parent packages to -resolve a relative name. For example: - -``` -// File: a.proto -package a.b; -message C {} -``` - -``` -// File: x.proto -package a.x; -message SomeMsg { - // Since we are in a.x.SomeMsg, this name is searched for in this order: - // .a.x.SomeMsg.b.C - // .a.x.b.C - // .a.b.C - // .b.C - b.C field3 = 1; -} -``` - -Relying on the "relative to a parent package" functionality when referencing -types defined in a different package is supported but can be confusing: in this -example the spelling `a.b.C` should be used. - -Naming other types in the current package (for example, sibling messages) -without writing the package is idiomatic. - -You can write a fully qualified name by using a leading period to avoid any -ambiguity concerns, but is commonly omitted in most cases even if the package is -fully written out. - -### Required Fields {#required} - -Required fields are a way to enforce that a given field must be set when parsing -wire bytes, and otherwise refuse to parse the message. The required invariant is -generally not enforced on messages constructed in memory. Required fields were -removed in proto3. Proto2 `required` fields that have been migrated to editions -2023 can use the `field_presence` feature set to `LEGACY_REQUIRED` to -accommodate. - -While enforcement of required fields at the schema level is intuitively -desirable, one of the primary design goals of protobuf is to support long term -schema evolution. No matter how obviously required a given field seems to be -today, there is a plausible future where the field should no longer be set (e.g. -an `int64 user_id` may need to migrate to a `UserId user_id` in the future). - -Especially in the case of middleware servers that may forward messages that they -don't really need to process, the semantics of `required` has proven too harmful -for those long-term evolution goals, and so is now very strongly discouraged. - -See -[Required is Strongly Deprecated](/programming-guides/proto2#required-deprecated). - -### Groups {#groups} - -Groups is an alternate syntax and wire format for nested messages. Groups are -considered deprecated in proto2, were removed from proto3, and are converted to -a delimited representation in edition 2023. You can use a nested message -definition and field of that type instead of using the group syntax, using the -[`message_encoding`](/editions/features#message_encoding) -feature for wire-compatibility. - -See [groups](/programming-guides/proto2#groups). diff --git a/content/programming-guides/symbol_visibility.md b/content/programming-guides/symbol_visibility.md deleted file mode 100644 index e5f4a4020..000000000 --- a/content/programming-guides/symbol_visibility.md +++ /dev/null @@ -1,303 +0,0 @@ -+++ -title = "Symbol Visibility" -weight = 85 -linkTitle = "Symbol Visibility" -description = "Explains the terminology and functionality of visibility, introduced in edition 2024." -type = "docs" -+++ - -This document describes the terminology and functionality of the symbol -visibility system introduced in proto `edition = "2024"` - -## Glossary {#glossary} - -* **Symbol**: Any of `message`, `enum`, `service` or `extend `, the - allowed **Top-Level** types in a `.proto` file. -* **Top-Level**: A **Symbol** defined at the root of a `.proto` file. This - includes all `service` definitions and any `message`, `enum`, or `extend` - block not nested in `message`. -* **Visibility**: Property of a **Symbol** that controls whether it can be - imported into another `.proto` file. Either set explicitly or derived from - file defaults. -* **Entry-Point**: A **Symbol** in a `.proto` file, which acts as the root of - a local sub-graph of **Symbol**s in that file, through which either - generated code or other `.proto` files "enter" the file. -* **Symbol Waste**: For a given **Symbol** 'X', the set of waste **Symbol**s - are those unreachable from 'X', but defined in files which are transitively - imported to satisfy the processing of the file in which 'X' is defined. - -## Introduction {#introduction} - -Visibility in Edition 2024 and later provides a way for authors to use access -modifiers for `message` and `enum` declarations. The visibility of a symbol -controls the ability to reference that symbol from another `.proto` file via -`import`. When a symbol is not visible outside of a given file, then references -to it from another `.proto` file will fail with a compiler error. - -This feature allows authors to control access to their symbols from external -users and encourages smaller files, which may lead to a smaller code footprint -when only a subset of defined symbols are required. - -Visibility applies to any `message` or `enum` referenced via: - -* `message` and `extend` field definitions. -* `extend ` -* `service` method request and response types. - -Symbol visibility applies **only** to the proto language, controlling the proto -compiler's ability to reference that symbol from another proto file. Visibility -must not be reflected into any language-specific generated code. - -## Detailed Usage {#syntax} - -Visibility introduces a set of new file-level options and two new Protobuf -keywords, `local` and `export`, which can be prefixed to `message` and `enum` -types. - -```proto -local message MyLocal {...} - -export enum MyExported {...} -``` - -Each `.proto` file also has a default visibility controlled by the edition's -defaults or file-level `option features.default_symbol_visibility`. This -visibility impacts all `message` and `enum` definitions in the file. - -**Values available:** - -* `EXPORT_ALL`: This is the default prior to Edition 2024. All messages and - enums are exported by default. -* `EXPORT_TOP_LEVEL`: All top-level symbols default to `export`; nested - default to `local`. -* `LOCAL_ALL`: All symbols default to `local`. -* `STRICT`: All symbols default to `local` and visibility keywords are only - valid on top-level `message` and `enum` types. Nested types can no longer - use those keywords are are always treated as `local` - -**Default behavior per syntax/edition:** - -Syntax/edition | Default --------------- | ------------------ -2024 | `EXPORT_TOP_LEVEL` -2023 | `EXPORT_ALL` -proto3 | `EXPORT_ALL` -proto2 | `EXPORT_ALL` - -Any top-level `message` and `enum` definitions can be annotated with explicit -`local` or `export` keywords to indicate their intended use. Symbols nested in -`message` may allow those keywords. - -Example: - -```proto -// 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 -local 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; -} -``` - -### STRICT default_symbol_visibility {#strict} - -When `default_symbol_visibility` is set to `STRICT`, more restrictive visibility -rules are applied to the file. This mode is intended as a more optimal, but -invasive type of visibility where nested types are not to be used outside their -own file. In `STRICT` mode: - -1. All symbols default to `local`. -2. `local` and `export` may be used only on top-level `message` and `enum` - declarations. -3. `local` and `export` keywords on nested symbols will result in a syntax - error. - -A single carve-out exception to nested visibility keywords is made for specific -wrapper `message` types used to address C++ namespace pollution. In this case a -`export enum` is supported iff: - -1. The top-level `message` is `local` -2. All fields are `reserved`, preventing any field definitions, using `reserved - 1 to max;` - -Example: - -```proto -local message MyNamespaceMessage { - export enum Enum { - MY_VAL = 1; - } - - // Ensure no fields are added to the message. - reserved 1 to max; -} -``` - -## Purpose of Visibility {#purpose} - -There are two purposes for the visibility feature. The first introduces access -modifiers, a common feature of many popular programming languages, used to -communicate and enforce the intent of authors about the usage of a given API. -Visibility allows protos to have a limited set of proto-specific access control, -giving proto authors some additional controls about the parts of their API that -can be reused and defining the API's entry-points. - -The second purpose is to encourage limiting the scope of a `.proto` file to a -narrow set of definitions to reduce the need to process unnecessary definitions. -The protobuf language definition requires that `Descriptor` type data be bundled -at the `FileDescriptorSet` and `FileDescriptor` level. This means that all -definitions in a single file, and its transitive dependencies via imports, are -unconditionally processed whenever that `.proto` file is processed. In large -definition sets, this can become a significant source of large unused blocks of -definitions that both slow down processing and generate a large set of unused -generated code. The best way to combat this sort of anti-pattern is to keep -`.proto` files narrowly scoped, containing only the symbols needed for a given -sub-graph located in the same file. With visibility added to `message` and -`enum` types, we can enumerate the set of entry-points in a given file and -determine where unrelated definitions can be split into different files to -provide fine-grained dependencies. - -## Entry-Points {#entry-point} - -A `.proto` file entry-point is any symbol that acts as a starting point for a -sub-graph of the full transitive closure of proto symbols processed for a given -file. That sub-graph represents the full transitive closure of types required -for the definition of that entry-point symbol, which is a subset of the symbols -required to process the file in which the entry-point is defined. - -There are generally 3 types of entry-points. - -### Simple-type Entry-Point {#simple-entry-point} - -`message` and `enum` types that have a visibility of `export` both can act as -entry-points in a symbol graph. In the case of `enum`, that sub-graph is the -null set, which means any other type definitions in the same file as that -`export enum Type {}` can be considered 'waste' in reference to the symbol graph -required for importing the enum. - -For `message` types the message acts as an entry-point for the full transitive -closure of types for the `message`'s field definitions and the recursive set of -field definitions of any sub-messages referenced by the entry-point. - -Importantly for both `enum` and `message` any `service` or `extend` definitions -in the same file are unreferencable and can be considered 'waste' for users of -those `message` and `enum` definitions. - -When a `.proto` file contains multiple `local` messages with no shared -dependencies, it is possible they can all act as independent entry-points when -used from generated code. The Protobuf compiler and static analysis system have -no way to determine the optimal entry-point layout of such a file. Without that -context we assume that `local` messages in the same file are optimal for the -intended generated code use-cases. - -### Service Entry-Points {#service-entry-point} - -`service` definitions act as an entry-point for all symbols referenced -transitively from that `service`, which includes the full transitive closure of -`message` and `enum` types for all `rpc` method definitions. - -Service definitions cannot be referenced in any meaningful way from another -proto, which means when a `.proto` file is imported and it contains a `service` -definition, it and its transitive closure of method types can be considered a -waste. This is true even if all `method` input and output types are referenced -from the importing file. - -### Extension Entry-Points {#extend-entry-point} - -`extend ` is an Extend type entry-point. Similar to `service` there is -no way to reference an extension field from a `message` or `enum`. An extension -requires `import`-ing both the Extendee type for an `extend ExtendeeType` and -the Extender type for `ExtenderType my_ext = ...`, which requires depending on -the full transitive closure of symbols required for both `ExtendeeType` and -`ExtenderType`. The symbols for `ExtendeeType` can be considered waste to any -other entry-points in the same file as the `extend`. - -Extensions exist to decouple the Extender type from the Extendee type, however -when extensions are defined in the same file as other entry-points this creates -a dependency inversion, forcing the other entry-points in the same file to -depend on the Extendee type. - -This dependency inversion can be harmless when the Extendee type is trivial, -containing no imports or non-primitive types, but can also be a source of -tremendous waste if the Extendee has a large transitive dependency set. - -In some generated code, nesting extensions inside of a `message` provides a -useful namespace. This can be accomplished safely with the use of visibility -keywords in one of two ways. Example: - -```proto -import "expensive/extendee_type.proto"; - -// You can define a local message for your extension. -local message ExtenderType { - extend expensive.ExtendeeType { - ExtenderType ext = 12345; - } - - string one = 1; - int two = 2; -} -``` - -Alternatively, if you have a symbol you both want to use as an extension field -and have that same type be used as a normal field in another messages, then that -message should be defined in its own file and the `extend` defined in its own -isolated file. You can still provide a friendly namespace, which is especially -useful for languages like C++, for the extension with a `local` wrapper message -with no fields: - -```proto -package my.pkg; - -import "expensive/extendee_type.proto"; -import "other/foo_type.proto"; - -// Exclusively used to bind other.FooType as an extension to -// expensive.ExtendeeType giving it a useful namespaced name -for `ext` as `my.pkg.WrapperForFooMsg.ext` -local message WrapperForFooMsg { - extend expensive.ExtendeeType { - other.FooMsg ext = 45678; - } - - // reserve all fields to ensure nothing ever uses this except for wrapping the - // extension. - reserved 1 to max; -} - -``` - -### Best-Practice: Maintain 1 Entry-Point per File - -In general to avoid proto symbol waste striving for a 1:1 ratio between `.proto` -files and entry-points can ensure that no excess proto compiler processing or -code generation is being performed for any given symbol. This can be further -extended to build systems by ensuring that a build step is only processing a -single `.proto` file at a time. In Bazel, this would correspond to having only a -single `.proto` file per `proto_library` rule. diff --git a/content/programming-guides/techniques.md b/content/programming-guides/techniques.md deleted file mode 100644 index f192008e2..000000000 --- a/content/programming-guides/techniques.md +++ /dev/null @@ -1,93 +0,0 @@ -+++ -title = "Techniques" -weight = 70 -description = "Describes some commonly-used design patterns for dealing with Protocol Buffers." -type = "docs" -+++ - -You can also send design and usage questions to -the -[Protocol Buffers discussion group](http://groups.google.com/group/protobuf). - -## Common Filename Suffixes {#suffixes} - -It is fairly common to write messages to files in several different formats. We -recommend using the following file extensions for these files. - -Content | Extension -------------------------------------------------------------------------- | --------- -[Text Format](/reference/protobuf/textformat-spec) | `.txtpb` -[Wire Format](/programming-guides/encoding) | `.binpb` -[JSON Format](/programming-guides/proto3#json) | `.json` - -For Text Format specifically, `.textproto` is also fairly common, but we -recommend `.txtpb` for its brevity. - -## Streaming Multiple Messages {#streaming} - -If you want to write multiple messages to a single file or stream, it is up to -you to keep track of where one message ends and the next begins. The Protocol -Buffer wire format is not self-delimiting, so protocol buffer parsers cannot -determine where a message ends on their own. The easiest way to solve this -problem is to write the size of each message before you write the message -itself. When you read the messages back in, you read the size, then read the -bytes into a separate buffer, then parse from that buffer. (If you want to avoid -copying bytes to a separate buffer, check out the `CodedInputStream` class (in -both C++ and Java) which can be told to limit reads to a certain number of -bytes.) - -## Large Data Sets {#large-data} - -Protocol Buffers are not designed to handle large messages. As a general rule of -thumb, if you are dealing in messages larger than a megabyte each, it may be -time to consider an alternate strategy. - -That said, Protocol Buffers are great for handling individual messages *within* -a large data set. Usually, large data sets are a collection of small pieces, -where each small piece is structured data. Even though Protocol Buffers cannot -handle the entire set at once, using Protocol Buffers to encode each piece -greatly simplifies your problem: now all you need is to handle a set of byte -strings rather than a set of structures. - -Protocol Buffers do not include any built-in support for large data sets because -different situations call for different solutions. Sometimes a simple list of -records will do while other times you want something more like a database. Each -solution should be developed as a separate library, so that only those who need -it need pay the costs. - -## Self-describing Messages {#self-description} - -Protocol Buffers do not contain descriptions of their own types. Thus, given -only a raw message without the corresponding `.proto` file defining its type, it -is difficult to extract any useful data. - -However, the contents of a .proto file can itself be represented using protocol -buffers. The file `src/google/protobuf/descriptor.proto` in the source code -package defines the message types involved. `protoc` can output a -`FileDescriptorSet`—which represents a set of .proto files—using the -`--descriptor_set_out` option. With this, you can define a self-describing -protocol message like so: - -```proto -syntax = "proto3"; - -import "google/protobuf/any.proto"; -import "google/protobuf/descriptor.proto"; - -message SelfDescribingMessage { - // Set of FileDescriptorProtos which describe the type and its dependencies. - google.protobuf.FileDescriptorSet descriptor_set = 1; - - // The message and its type, encoded as an Any message. - google.protobuf.Any message = 2; -} -``` - -By using classes like `DynamicMessage` (available in C++ and Java), you can then -write tools which can manipulate `SelfDescribingMessage`s. - -All that said, the reason that this functionality is not included in the -Protocol Buffer library is because we have never had a use for it inside Google. - -This technique requires support for dynamic messages using descriptors. Check -that your platforms support this feature before using self-describing messages. diff --git a/content/reference/_index.md b/content/reference/_index.md deleted file mode 100644 index ccfc64524..000000000 --- a/content/reference/_index.md +++ /dev/null @@ -1,18 +0,0 @@ -+++ -title = "Reference Guides" -weight = 490 -description = "Reference documentation for working with protocol buffer classes in C++, Java, Python, Go, C#, Objective-C, Ruby, PHP, and Dart, as well as some reference documentation for Protocol Buffers itself." -type = "docs" -+++ - -This section contains reference documentation for working with protocol buffer -classes in C++, Java, Python, Go, C\#, Objective-C, Ruby, PHP, and Dart, as well -as some reference documentation for Protocol Buffers itself. The documentation -for each language includes (where available): - -- A reference guide to the code generated by the protocol buffer compiler from - your `.proto` files. -- Generated API documentation for the provided source code. - -Note that there are APIs for several more languages in the pipeline -- for -details, see [Other Languages](/reference/other). diff --git a/content/reference/cpp/_index.md b/content/reference/cpp/_index.md deleted file mode 100644 index 0321844c5..000000000 --- a/content/reference/cpp/_index.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "C++ Reference" -weight = 500 -linkTitle = "C++" -description = "Reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ diff --git a/content/reference/cpp/abseil.md b/content/reference/cpp/abseil.md deleted file mode 100644 index 63cb44641..000000000 --- a/content/reference/cpp/abseil.md +++ /dev/null @@ -1,61 +0,0 @@ -+++ -title = "Abseil Support" -weight = 530 -linkTitle = "Abseil Support" -description = "The C++ implementation of Protocol Buffers has an explicit dependency on Abseil." -type = "docs" -+++ - -In [version 22.x](/news/v22#abseil-dep), C++ protobuf -added an explicit dependency on Abseil. - -## Bazel Support {#bazel} - -If you are using Bazel, to determine the version of Abseil that your protobuf -version supports, you can use the `bazel mod` command: - -```shell -$ bazel mod deps abseil-cpp --enable_bzlmod - (protobuf@30.0-dev) -└───abseil-cpp@20240722.0 - ├───bazel_skylib@1.7.1 - ├───googletest@1.15.2 - └───platforms@0.0.10 -``` - -`bazel mod graph` produces the full output: - -```shell -$ bazel mod graph --enable_bzlmod - (protobuf@30.0-dev) -├───abseil-cpp@20240722.0 -│ ├───bazel_skylib@1.7.1 (*) -│ ├───googletest@1.15.2 (*) -│ └───platforms@0.0.10 (*) -├───bazel_features@1.18.0 -│ └───bazel_skylib@1.7.1 (*) -├───bazel_skylib@1.7.1 -│ ├───platforms@0.0.10 (*) -│ └───rules_license@1.0.0 (*) -├───googletest@1.15.2 -│ ├───abseil-cpp@20240722.0 (*) -│ ├───platforms@0.0.10 (*) -│ └───re2@2024-07-02 -... -``` - -## CMake Support {#cmake} - -Our CMake support is best-effort compared to Bazel. To check for support, try -the following steps: - -1. Run the `cmake .` command. -2. Open `_deps/absl-src/CMakeLists.txt`. - -Look for the following line: - -``` -project(absl LANGUAGES CXX VERSION 20240722) -set(ABSL_SOVERSION "2407.0.0") -include(CTest) -``` diff --git a/content/reference/cpp/api-docs-link.md b/content/reference/cpp/api-docs-link.md deleted file mode 100644 index d02a4af72..000000000 --- a/content/reference/cpp/api-docs-link.md +++ /dev/null @@ -1,8 +0,0 @@ - - ---- -title: "C++ API" -manualLink: "/reference/cpp/api-docs/" -manualLinkTarget: "_blank" -weight: 530 ---- \ No newline at end of file diff --git a/content/reference/cpp/api-docs/_index.md b/content/reference/cpp/api-docs/_index.md deleted file mode 100644 index d049869b0..000000000 --- a/content/reference/cpp/api-docs/_index.md +++ /dev/null @@ -1,18 +0,0 @@ - - -+++ -title = "C++ Reference" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

Packages

Auxiliary classes used for I/O.
Utility classes.
Implementation of the Protocol Buffer compiler.

google::protobuf

Files

This file defines an Arena allocator for better allocation performance.
This file contains classes which describe a type of protocol message.
Protocol buffer representations of descriptors.
Interface for manipulating databases of descriptors.
Defines an implementation of Message which can emulate types which are not known at compile-time.
This file defines the map container and its helpers to support protobuf maps.
Defines Message, the abstract interface implemented by non-lite protocol message objects.
Defines MessageLite, the abstract interface implemented by all (lite and non-lite) protocol message objects.
RepeatedField and RepeatedPtrField are used by generated protocol message classes to manipulate repeated fields.
DEPRECATED: This module declares the abstract interfaces underlying proto2 RPC services.
Utilities for printing and parsing protocol messages in a human-readable, text-based format.
Contains classes used to keep track of unrecognized fields seen while parsing a protocol message.

google::protobuf::io

Auxiliary classes used for I/O.

The Protocol Buffer library uses the classes in this package to deal with I/O and encoding/decoding raw bytes. Most users will not need to deal with this package. However, users who want to adapt the system to work with their own I/O abstractions – e.g., to allow Protocol Buffers to be read from a different kind of input stream without the need for a temporary buffer – should take a closer look.

-

Files

This file contains the CodedInputStream and CodedOutputStream classes, which wrap a ZeroCopyInputStream or ZeroCopyOutputStream, respectively, and allow you to read or write individual pieces of data in various formats.
Utility class for writing text to a ZeroCopyOutputStream.
Class for parsing tokenized text from a ZeroCopyInputStream.
This file contains the ZeroCopyInputStream and ZeroCopyOutputStream interfaces, which represent abstract I/O streams to and from which protocol buffers can be read and written.
This file contains common implementations of the interfaces defined in zero_copy_stream.h which are only included in the full (non-lite) protobuf library.
This file contains common implementations of the interfaces defined in zero_copy_stream.h which are included in the "lite" protobuf library.

google::protobuf::util

Utility classes.

This package contains various utilities for message comparison, JSON conversion, well known types, etc.

-

Files

Defines classes for field comparison.
Defines utilities for the FieldMask well known type.
Utility functions to convert between protobuf binary format and proto3 JSON format.
This file defines static methods and classes for comparing Protocol Messages.
Defines utilities for the Timestamp and Duration well known types.
Defines a TypeResolver for the Any message.
Defines utilities for the TypeResolver.

google::protobuf::compiler

Implementation of the Protocol Buffer compiler.

This package contains code for parsing .proto files and generating code based on them. There are two reasons you might be interested in this package:

-
    -
  • You want to parse .proto files at runtime. In this case, you should look at importer.h. Since this functionality is widely useful, it is included in the libprotobuf base library; you do not have to link against libprotoc.
  • -
  • You want to write a custom protocol compiler which generates different kinds of code, e.g. code in a different language which is not supported by the official compiler. For this purpose, command_line_interface.h provides you with a complete compiler front-end, so all you need to do is write a custom implementation of CodeGenerator and a trivial main() function. You can even make your compiler support the official languages in addition to your own. Since this functionality is only useful to those writing custom compilers, it is in a separate library called "libprotoc" which you will have to link against.
  • -
-

Files

Defines the abstract interface implemented by each of the language-specific code generators.
Implements the Protocol Compiler front-end such that it may be reused by custom compilers written to support other languages.
This file is the public interface to the .proto file parser.
Implements parsing of .proto files to FileDescriptorProtos.
Front-end for protoc code generator plugins written in C++.
API for protoc plugins.
Generates C++ code for a given .proto file.
Generates C# code for a given .proto file.
Provides a mechanism for mapping a descriptor to the fully-qualified name of the corresponding C# class.
Generates Java code for a given .proto file.
Provides a mechanism for mapping a descriptor to the fully-qualified name of the corresponding Java class.
Generates JavaScript code for a given .proto file.
Generates ObjectiveC code for a given .proto file.
Helper functions for generating ObjectiveC code.
Generates Python code for a given .proto file.
Generates Ruby code for a given .proto file.
diff --git a/content/reference/cpp/api-docs/google.protobuf.arena.md b/content/reference/cpp/api-docs/google.protobuf.arena.md deleted file mode 100644 index de2992881..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.arena.md +++ /dev/null @@ -1,58 +0,0 @@ - - -+++ -title = "arena.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/arena.h>
namespace google::protobuf

This file defines an Arena allocator for better allocation performance.

Classes in this file

ArenaOptions provides optional additional parameters to arena construction that control its block-allocation behavior.
Arena allocator.
Helper typetraits that indicates support for arenas in a type T at compile time.

struct ArenaOptions

#include <google/protobuf/arena.h>
namespace google::protobuf

ArenaOptions provides optional additional parameters to arena construction that control its block-allocation behavior.

Members

size_t
start_block_size
This defines the size of the first block requested from the system malloc. more...
size_t
max_block_size
This defines the maximum block size requested from system malloc (unless an individual arena allocation request occurs with a size larger than this maximum). more...
char *
initial_block
An initial block of memory for the arena to use, or NULL for none. more...
size_t
initial_block_size
The size of the initial block, if provided.
void *(*
block_alloc
A function pointer to an alloc method that returns memory blocks of size requested. more...
void(*
block_dealloc
A function pointer to a dealloc method that takes ownership of the blocks from the arena. more...
ArenaOptions()

size_t ArenaOptions::start_block_size

This defines the size of the first block requested from the system malloc.

Subsequent block sizes will increase in a geometric series up to a maximum.

-

size_t ArenaOptions::max_block_size

This defines the maximum block size requested from system malloc (unless an individual arena allocation request occurs with a size larger than this maximum).

Requested block sizes increase up to this value, then remain here.

-

char * ArenaOptions::initial_block

An initial block of memory for the arena to use, or NULL for none.

If provided, the block must live at least as long as the arena itself. The creator of the Arena retains ownership of the block after the Arena is destroyed.

-

void *(* ArenaOptions::block_alloc

A function pointer to an alloc method that returns memory blocks of size requested.

By default, it contains a ptr to the malloc function.

- -

NOTE: block_alloc and dealloc functions are expected to behave like malloc and free, including Asan poisoning.

-

void(* ArenaOptions::block_dealloc

A function pointer to a dealloc method that takes ownership of the blocks from the arena.

By default, it contains a ptr to a wrapper function that calls free.

-

class Arena

#include <google/protobuf/arena.h>
namespace google::protobuf

Arena allocator.

Arena allocation replaces ordinary (heap-based) allocation with new/delete, and improves performance by aggregating allocations into larger blocks and freeing allocations all at once. Protocol messages are allocated on an arena by using Arena::CreateMessage<T>(Arena*), below, and are automatically freed when the arena is destroyed.

- -

This is a thread-safe implementation: multiple threads may allocate from the arena concurrently. Destruction is not thread-safe and the destructing thread must synchronize with users of the arena first.

- -

An arena provides two allocation interfaces: CreateMessage<T>, which works for arena-enabled proto2 message types as well as other types that satisfy the appropriate protocol (described below), and Create<T>, which works for any arbitrary type T. CreateMessage<T> is better when the type T supports it, because this interface (i) passes the arena pointer to the created object so that its sub-objects and internal allocations can use the arena too, and (ii) elides the object's destructor call when possible. Create<T> does not place any special requirements on the type T, and will invoke the object's destructor when the arena is destroyed.

- -

The arena message allocation protocol, required by CreateMessage<T>(Arena* arena, Args&&... args), is as follows:

- -
    -
  • The type T must have (at least) two constructors: a constructor callable with args (without arena), called when a T is allocated on the heap; and a constructor callable with Arena* arena, Args&&... args, called when a T is allocated on an arena. If the second constructor is called with a NULL arena pointer, it must be equivalent to invoking the first (args-only) constructor.
  • -
  • The type T must have a particular type trait: a nested type |InternalArenaConstructable_|. This is usually a typedef to |void|. If no such type trait exists, then the instantiation CreateMessage<T> will fail to compile.
  • -
  • The type T may have the type trait |DestructorSkippable_|. If this type trait is present in the type, then its destructor will not be called if and only if it was passed a non-NULL arena pointer. If this type trait is not present on the type, then its destructor is always called when the containing arena is destroyed.
  • -
- -

This protocol is implemented by all arena-enabled proto2 message classes as well as protobuf container types like RepeatedPtrField and Map. The protocol is internal to protobuf and is not guaranteed to be stable. Non-proto types should not rely on this protocol.

- -

Members

const size_t
kBlockOverhead = = - internal::ThreadSafeArena::kBlockHeaderSize + - internal::ThreadSafeArena::kSerialArenaSize
Block overhead. more...
Arena()
Default constructor with sensible default options, tuned for average use-cases.
Arena(char * initial_block, size_t initial_block_size)
Construct an arena with default options, except for the supplied initial block. more...
explicit
Arena(const ArenaOptions & options)
Arena constructor taking custom options. more...
~Arena()
void
Init(const ArenaOptions & )
uint64
SpaceAllocated() const
The following are routines are for monitoring. more...
uint64
SpaceUsed() const
Returns the total space used by the arena. more...
uint64
Reset()
Frees all storage allocated by this arena after calling destructors registered with OwnDestructor() and freeing objects registered with Own(). more...
template void
Own(T * object)
Adds |object| to a list of heap-allocated objects to be freed with |delete| when the arena is destroyed or reset.
template void
OwnDestructor(T * object)
Adds |object| to a list of objects whose destructors will be manually called when the arena is destroyed or reset. more...
void
OwnCustomDestructor(void * object, void(*)(void *) destruct)
Adds a custom member function on an object to the list of destructors that will be manually called when the arena is destroyed or reset. more...
template static T *
CreateMessage(Arena * arena, Args &&... args)
API to create proto2 message objects on the arena. more...
template static PROTOBUF_NDEBUG_INLINE T *
Create(Arena * arena, Args &&... args)
API to create any objects on the arena. more...
template static PROTOBUF_NDEBUG_INLINE T *
CreateArray(Arena * arena, size_t num_elements)
Create an array of object type T on the arena without invoking the constructor of T. more...
template static Arena *
GetArena(const T * value)
Retrieves the arena associated with |value| if |value| is an arena-capable message, or NULL otherwise. more...

const size_t Arena::kBlockOverhead = = - internal::ThreadSafeArena::kBlockHeaderSize + - internal::ThreadSafeArena::kSerialArenaSize

Block overhead.

Use this as a guide for how much to over-allocate the initial block if you want an allocation of size N to fit inside it.

-

WARNING: if you allocate multiple objects, it is difficult to guarantee that a series of allocations will fit in the initial block, especially if Arena changes its alignment guarantees in the future!

-

Arena::Arena(
        char * initial_block,
        size_t initial_block_size)

Construct an arena with default options, except for the supplied initial block.

It is more efficient to use this constructor instead of passing ArenaOptions if the only configuration needed by the caller is supplying an initial block.

-

explicit Arena::Arena(
        const ArenaOptions & options)

Arena constructor taking custom options.

See ArenaOptions above for descriptions of the options available.

-

uint64 Arena::SpaceAllocated() const

The following are routines are for monitoring.

They will approximate the total sum allocated and used memory, but the exact value is an implementation deal. For instance allocated space depends on growth policies. Do not use these in unit tests. Returns the total space allocated by the arena, which is the sum of the sizes of the underlying blocks.

-

uint64 Arena::SpaceUsed() const

Returns the total space used by the arena.

Similar to SpaceAllocated but does not include free space and block overhead. The total space returned may not include space used by other threads executing concurrently with the call to this method.

-

uint64 Arena::Reset()

Frees all storage allocated by this arena after calling destructors registered with OwnDestructor() and freeing objects registered with Own().

Any objects allocated on this arena are unusable after this call. It also returns the total space used by the arena which is the sums of the sizes of the allocated blocks. This method is not thread-safe.

-

template void Arena::OwnDestructor(
        T * object)

Adds |object| to a list of objects whose destructors will be manually called when the arena is destroyed or reset.

This differs from Own() in that it does not free the underlying memory with |delete|; hence, it is normally only used for objects that are placement-newed into arena-allocated memory.

-

void Arena::OwnCustomDestructor(
        void * object,
        void(*)(void *) destruct)

Adds a custom member function on an object to the list of destructors that will be manually called when the arena is destroyed or reset.

This differs from OwnDestructor() in that any member function may be specified, not only the class destructor.

-

template static T * Arena::CreateMessage(
        Arena * arena,
        Args &&... args)

API to create proto2 message objects on the arena.

If the arena passed in is NULL, then a heap allocated object is returned. Type T must be a message defined in a .proto file with cc_enable_arenas set to true, otherwise a compilation error will occur.

-

RepeatedField and RepeatedPtrField may also be instantiated directly on an arena with this method.

-

This function also accepts any type T that satisfies the arena message allocation protocol, documented above.

-

template static PROTOBUF_NDEBUG_INLINE T *
    Arena::Create(
        Arena * arena,
        Args &&... args)

API to create any objects on the arena.

Note that only the object will be created on the arena; the underlying ptrs (in case of a proto2 message) will be still heap allocated. Proto messages should usually be allocated with CreateMessage<T>() instead.

-

Note that even if T satisfies the arena message construction protocol (InternalArenaConstructable_ trait and optional DestructorSkippable_ trait), as described above, this function does not follow the protocol; instead, it treats T as a black-box type, just as if it did not have these traits. Specifically, T's constructor arguments will always be only those passed to Create<T>() – no additional arena pointer is implicitly added. Furthermore, the destructor will always be called at arena destruction time (unless the destructor is trivial). Hence, from T's point of view, it is as if the object were allocated on the heap (except that the underlying memory is obtained from the arena).

-

template static PROTOBUF_NDEBUG_INLINE T *
    Arena::CreateArray(
        Arena * arena,
        size_t num_elements)

Create an array of object type T on the arena without invoking the constructor of T.

If arena is null, then the return value should be freed with delete[] x; (or ::operator delete[](x);). To ensure safe uses, this function checks at compile time (when compiled as C++11) that T is trivially default-constructible and trivially destructible.

-

template static Arena * Arena::GetArena(
        const T * value)

Retrieves the arena associated with |value| if |value| is an arena-capable message, or NULL otherwise.

If possible, the call resolves at compile time. Note that we can often devirtualize calls to value->GetArena() so usually calling this method is unnecessary.

-

template class Arena::InternalHelper

#include <google/protobuf/arena.h>
namespace google::protobuf

template <typename >

Members

static Arena *
GetOwningArena(const T * p)
Provides access to protected GetOwningArena to generated messages.
static Arena *
GetArenaForAllocation(const T * p)
Provides access to protected GetArenaForAllocation to generated messages.

template struct Arena::is_arena_constructable

#include <google/protobuf/arena.h>
namespace google::protobuf

template <typename >

Helper typetraits that indicates support for arenas in a type T at compile time.

This is public only to allow construction of higher-level templated utilities.

-

is_arena_constructable<T>::value is true if the message type T has arena support enabled, and false otherwise.

-

is_destructor_skippable<T>::value is true if the message type T has told the arena that it is safe to skip the destructor, and false otherwise.

-

This is inside Arena because only Arena has the friend relationships necessary to see the underlying generated code traits.

-

Members

template struct Arena::is_destructor_skippable

#include <google/protobuf/arena.h>
namespace google::protobuf

template <typename >

Members

diff --git a/content/reference/cpp/api-docs/google.protobuf.common.md b/content/reference/cpp/api-docs/google.protobuf.common.md deleted file mode 100644 index abd2f99d7..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.common.md +++ /dev/null @@ -1,9 +0,0 @@ -+++ -title = "common.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/stubs/common.h>
namespace google::protobuf

Contains basic types and utilities used by the rest of the library.

Classes in this file

diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.code_generator.md b/content/reference/cpp/api-docs/google.protobuf.compiler.code_generator.md deleted file mode 100644 index 9ca8ebba6..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.code_generator.md +++ /dev/null @@ -1,30 +0,0 @@ -+++ -title = "code_generator.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/code_generator.h>
namespace google::protobuf::compiler

Defines the abstract interface implemented by each of the language-specific code generators.

Classes in this file

The abstract interface to a class which generates code implementing a particular proto file in a particular language.
CodeGenerators generate one or more files in a given directory.

File Members

These definitions are not part of any class.
typedef
GeneratorContext OutputDirectory
The type GeneratorContext was once called OutputDirectory. more...
void
ParseGeneratorParameter(const std::string & , std::vector< std::pair< std::string, std::string > > * )
Several code generators treat the parameter argument as holding a list of options separated by commas. more...
std::string
StripProto(const std::string & filename)
Strips ".proto" or ".protodevel" from the end of a filename.

typedef compiler::OutputDirectory

The type GeneratorContext was once called OutputDirectory.

This typedef provides backward compatibility.

-

void compiler::ParseGeneratorParameter(
        const std::string & ,
        std::vector< std::pair< std::string, std::string > > * )

Several code generators treat the parameter argument as holding a list of options separated by commas.

This helper function parses a set of comma-delimited name/value pairs: e.g., "foo=bar,baz,qux=corge" parses to the pairs:

- -
("foo", "bar"), ("baz", ""), ("qux", "corge")
- -

class CodeGenerator

#include <google/protobuf/compiler/code_generator.h>
namespace google::protobuf::compiler

The abstract interface to a class which generates code implementing a particular proto file in a particular language.

A number of these may be registered with CommandLineInterface to support various languages.

-

Known subclasses:

Members

enum
Feature
Sync with plugin.proto. more...
CodeGenerator()
virtual
~CodeGenerator()
virtual bool
Generate(const FileDescriptor * file, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const = 0
Generates code for the given proto file, generating one or more files in the given output directory. more...
virtual bool
GenerateAll(const std::vector< const FileDescriptor * > & files, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
Generates code for all given proto files. more...
virtual uint64_t
GetSupportedFeatures() const
Implement this to indicate what features this code generator supports. more...
virtual bool
HasGenerateAll() const
This is no longer used, but this class is part of the opensource protobuf library, so it has to remain to keep vtables the same for the current version of the library. more...

enum CodeGenerator::Feature {
  FEATURE_PROTO3_OPTIONAL = = 1
}

Sync with plugin.proto.

FEATURE_PROTO3_OPTIONAL

virtual bool CodeGenerator::Generate(
        const FileDescriptor * file,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const = 0

Generates code for the given proto file, generating one or more files in the given output directory.

A parameter to be passed to the generator can be specified on the command line. This is intended to be used to pass generator specific parameters. It is empty if no parameter was given. ParseGeneratorParameter (below), can be used to accept multiple parameters within the single parameter command line flag.

-

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.

-

virtual bool CodeGenerator::GenerateAll(
        const std::vector< const FileDescriptor * > & files,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const

Generates code for all given proto files.

WARNING: The canonical code generator design produces one or two output files per input .proto file, and we do not wish to encourage alternate designs.

-

A parameter is given as passed on the command line, as in |Generate()| above.

-

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.

-

virtual uint64_t CodeGenerator::GetSupportedFeatures() const

Implement this to indicate what features this code generator supports.

This should be a bitwise OR of features from the Features enum in plugin.proto.

-

virtual bool CodeGenerator::HasGenerateAll() const

This is no longer used, but this class is part of the opensource protobuf library, so it has to remain to keep vtables the same for the current version of the library.

When protobufs does a api breaking change, the method can be removed.

-

class GeneratorContext

#include <google/protobuf/compiler/code_generator.h>
namespace google::protobuf::compiler

CodeGenerators generate one or more files in a given directory.

This abstract interface represents the directory to which the CodeGenerator is to write and other information about the context in which the Generator runs.

-

Members

GeneratorContext()
virtual
~GeneratorContext()
virtual io::ZeroCopyOutputStream *
Open(const std::string & filename) = 0
Opens the given file, truncating it if it exists, and returns a ZeroCopyOutputStream that writes to the file. more...
virtual io::ZeroCopyOutputStream *
OpenForAppend(const std::string & filename)
Similar to Open() but the output will be appended to the file if exists.
virtual io::ZeroCopyOutputStream *
OpenForInsert(const std::string & filename, const std::string & insertion_point)
Creates a ZeroCopyOutputStream which will insert code into the given file at the given insertion point. more...
virtual io::ZeroCopyOutputStream *
OpenForInsertWithGeneratedCodeInfo(const std::string & filename, const std::string & insertion_point, const google::protobuf::GeneratedCodeInfo & info)
Similar to OpenForInsert, but if info is non-empty, will open (or create) filename.pb.meta and insert info at the appropriate place with the necessary shifts. more...
virtual void
ListParsedFiles(std::vector< const FileDescriptor * > * output)
Returns a vector of FileDescriptors for all the files being compiled in this run. more...
virtual void
GetCompilerVersion(Version * version) const
Retrieves the version number of the protocol compiler associated with this GeneratorContext.

virtual io::ZeroCopyOutputStream *
    GeneratorContext::Open(
        const std::string & filename) = 0

Opens the given file, truncating it if it exists, and returns a ZeroCopyOutputStream that writes to the file.

The caller takes ownership of the returned object. This method never fails (a dummy stream will be returned instead).

-

The filename given should be relative to the root of the source tree. E.g. the C++ generator, when generating code for "foo/bar.proto", will generate the files "foo/bar.pb.h" and "foo/bar.pb.cc"; note that "foo/" is included in these filenames. The filename is not allowed to contain "." or ".." components.

-

virtual io::ZeroCopyOutputStream *
    GeneratorContext::OpenForInsert(
        const std::string & filename,
        const std::string & insertion_point)

Creates a ZeroCopyOutputStream which will insert code into the given file at the given insertion point.

See plugin.proto (plugin.pb.h) for more information on insertion points. The default implementation assert-fails – it exists only for backwards-compatibility.

-

WARNING: This feature is currently EXPERIMENTAL and is subject to change.

-

virtual io::ZeroCopyOutputStream *
    GeneratorContext::OpenForInsertWithGeneratedCodeInfo(
        const std::string & filename,
        const std::string & insertion_point,
        const google::protobuf::GeneratedCodeInfo & info)

Similar to OpenForInsert, but if info is non-empty, will open (or create) filename.pb.meta and insert info at the appropriate place with the necessary shifts.

The default implementation ignores info.

-

WARNING: This feature will be REMOVED in the near future.

-

virtual void GeneratorContext::ListParsedFiles(
        std::vector< const FileDescriptor * > * output)

Returns a vector of FileDescriptors for all the files being compiled in this run.

Useful for languages, such as Go, that treat files differently when compiled as a set rather than individually.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.command_line_interface.md b/content/reference/cpp/api-docs/google.protobuf.compiler.command_line_interface.md deleted file mode 100644 index 0dbfe78ed..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.command_line_interface.md +++ /dev/null @@ -1,67 +0,0 @@ -+++ -title = "command_line_interface.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/command_line_interface.h>
namespace google::protobuf::compiler

Implements the Protocol Compiler front-end such that it may be reused by custom compilers written to support other languages.

Classes in this file

This class implements the command-line interface to the protocol compiler.

class CommandLineInterface

#include <google/protobuf/compiler/command_line_interface.h>
namespace google::protobuf::compiler

This class implements the command-line interface to the protocol compiler.

It is designed to make it very easy to create a custom protocol compiler supporting the languages of your choice. For example, if you wanted to create a custom protocol compiler binary which includes both the regular C++ support plus support for your own custom output "Foo", you would write a class "FooGenerator" which implements the CodeGenerator interface, then write a main() procedure like this:

- -
int main(int argc, char* argv[]) {
-  google::protobuf::compiler::CommandLineInterface cli;
-
-  // Support generation of C++ source and headers.
-  google::protobuf::compiler::cpp::CppGenerator cpp_generator;
-  cli.RegisterGenerator("--cpp_out", &cpp_generator,
-    "Generate C++ source and header.");
-
-  // Support generation of Foo code.
-  FooGenerator foo_generator;
-  cli.RegisterGenerator("--foo_out", &foo_generator,
-    "Generate Foo file.");
-
-  return cli.Run(argc, argv);
-}
- -

The compiler is invoked with syntax like:

- -
protoc --cpp_out=outdir --foo_out=outdir --proto_path=src src/foo.proto
- -

The .proto file to compile can be specified on the command line using either its physical file path, or a virtual path relative to a directory specified in –proto_path. For example, for src/foo.proto, the following two protoc invocations work the same way:

- -
1. protoc --proto_path=src src/foo.proto (physical file path)
-2. protoc --proto_path=src foo.proto (virtual path relative to src)
- -

If a file path can be interpreted both as a physical file path and as a relative virtual path, the physical file path takes precedence.

- -

For a full description of the command-line syntax, invoke it with –help.

- -

Members

const char *const
kPathSeparator
CommandLineInterface()
~CommandLineInterface()
void
RegisterGenerator(const std::string & flag_name, CodeGenerator * generator, const std::string & help_text)
Register a code generator for a language. more...
void
RegisterGenerator(const std::string & flag_name, const std::string & option_flag_name, CodeGenerator * generator, const std::string & help_text)
Register a code generator for a language. more...
void
AllowPlugins(const std::string & exe_name_prefix)
Enables "plugins". more...
int
Run(int argc, const char *const argv)
Run the Protocol Compiler with the given command-line parameters. more...
void
SetInputsAreProtoPathRelative(bool )
DEPRECATED. more...
void
SetVersionInfo(const std::string & text)
Provides some text which will be printed when the –version flag is used. more...

void CommandLineInterface::RegisterGenerator(
        const std::string & flag_name,
        CodeGenerator * generator,
        const std::string & help_text)

Register a code generator for a language.

Parameters:

-
    -
  • flag_name: The command-line flag used to specify an output file of this type. The name must start with a '-'. If the name is longer than one letter, it must start with two '-'s.
  • -
  • generator: The CodeGenerator which will be called to generate files of this type.
  • -
  • help_text: Text describing this flag in the –help output.
  • -
-

Some generators accept extra parameters. You can specify this parameter on the command-line by placing it before the output directory, separated by a colon:

-
protoc --foo_out=enable_bar:outdir
-

The text before the colon is passed to CodeGenerator::Generate() as the "parameter".

-

void CommandLineInterface::RegisterGenerator(
        const std::string & flag_name,
        const std::string & option_flag_name,
        CodeGenerator * generator,
        const std::string & help_text)

Register a code generator for a language.

Besides flag_name you can specify another option_flag_name that could be used to pass extra parameters to the registered code generator. Suppose you have registered a generator by calling:

-
command_line_interface.RegisterGenerator("--foo_out", "--foo_opt", ...)
-

Then you could invoke the compiler with a command like:

-
protoc --foo_out=enable_bar:outdir --foo_opt=enable_baz
-

This will pass "enable_bar,enable_baz" as the parameter to the generator.

-

void CommandLineInterface::AllowPlugins(
        const std::string & exe_name_prefix)

Enables "plugins".

In this mode, if a command-line flag ends with "_out" but does not match any registered generator, the compiler will attempt to find a "plugin" to implement the generator. Plugins are just executables. They should live somewhere in the PATH.

-

The compiler determines the executable name to search for by concatenating exe_name_prefix with the unrecognized flag name, removing "_out". So, for example, if exe_name_prefix is "protoc-" and you pass the flag –foo_out, the compiler will try to run the program "protoc-gen-foo".

-

The plugin program should implement the following usage:

-
plugin [--out=OUTDIR] [--parameter=PARAMETER] PROTO_FILES < DESCRIPTORS
-

–out indicates the output directory (as passed to the –foo_out parameter); if omitted, the current directory should be used. –parameter gives the generator parameter, if any was provided (see below). The PROTO_FILES list the .proto files which were given on the compiler command-line; these are the files for which the plugin is expected to generate output code. Finally, DESCRIPTORS is an encoded FileDescriptorSet (as defined in descriptor.proto). This is piped to the plugin's stdin. The set will include descriptors for all the files listed in PROTO_FILES as well as all files that they import. The plugin MUST NOT attempt to read the PROTO_FILES directly – it must use the FileDescriptorSet.

-

The plugin should generate whatever files are necessary, as code generators normally do. It should write the names of all files it generates to stdout. The names should be relative to the output directory, NOT absolute names or relative to the current directory. If any errors occur, error messages should be written to stderr. If an error is fatal, the plugin should exit with a non-zero exit code.

-

Plugins can have generator parameters similar to normal built-in generators. Extra generator parameters can be passed in via a matching "_opt" parameter. For example:

-
protoc --plug_out=enable_bar:outdir --plug_opt=enable_baz
-

This will pass "enable_bar,enable_baz" as the parameter to the plugin.

-

int CommandLineInterface::Run(
        int argc,
        const char *const argv)

Run the Protocol Compiler with the given command-line parameters.

Returns the error code which should be returned by main().

-

It may not be safe to call Run() in a multi-threaded environment because it calls strerror(). I'm not sure why you'd want to do this anyway.

-

void CommandLineInterface::SetInputsAreProtoPathRelative(
        bool )

DEPRECATED.

Calling this method has no effect. Protocol compiler now always try to find the .proto file relative to the current directory first and if the file is not found, it will then treat the input path as a virtual path.

-

void CommandLineInterface::SetVersionInfo(
        const std::string & text)

Provides some text which will be printed when the –version flag is used.

The version of libprotoc will also be printed on the next line after this text.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.cpp_generator.md b/content/reference/cpp/api-docs/google.protobuf.compiler.cpp_generator.md deleted file mode 100644 index d29feb4f1..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.cpp_generator.md +++ /dev/null @@ -1,20 +0,0 @@ -+++ -title = "cpp_generator.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/cpp/cpp_generator.h>
namespace google::protobuf::compiler::cpp

Generates C++ code for a given .proto file.

Classes in this file

CodeGenerator implementation which generates a C++ source file and header.

class CppGenerator: public CodeGenerator

#include <google/protobuf/compiler/cpp/cpp_generator.h>
namespace google::protobuf::compiler::cpp

CodeGenerator implementation which generates a C++ source file and header.

If you create your own protocol compiler binary and you want it to support C++ output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.

- -

Members

enum
Runtime
CppGenerator()
~CppGenerator()
void
set_opensource_runtime(bool opensource)
void
set_runtime_include_base(const std::string & base)
If set to a non-empty string, generated code will do: more...

implements CodeGenerator

virtual bool
Generate(const FileDescriptor * file, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
Generates code for the given proto file, generating one or more files in the given output directory. more...
virtual uint64_t
GetSupportedFeatures() const
Implement this to indicate what features this code generator supports. more...

enum CppGenerator::Runtime {
  kGoogle3,
  kOpensource,
  kOpensourceGoogle3
}

kGoogle3Use the internal google3 runtime.
kOpensourceUse the open-source runtime.
kOpensourceGoogle3

Use the open-source runtime with google3 #include paths.

We make these absolute to avoid ambiguity, so the runtime will be #included like:

-

-

void CppGenerator::set_runtime_include_base(
        const std::string & base)

If set to a non-empty string, generated code will do:

/google/protobuf/message.h"
-

instead of:

-

-

This has no effect if opensource_runtime = false.

-

virtual bool CppGenerator::Generate(
        const FileDescriptor * file,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const

Generates code for the given proto file, generating one or more files in the given output directory.

A parameter to be passed to the generator can be specified on the command line. This is intended to be used to pass generator specific parameters. It is empty if no parameter was given. ParseGeneratorParameter (below), can be used to accept multiple parameters within the single parameter command line flag.

-

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.

-

virtual uint64_t CppGenerator::GetSupportedFeatures() const

Implement this to indicate what features this code generator supports.

This should be a bitwise OR of features from the Features enum in plugin.proto.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.csharp_generator.md b/content/reference/cpp/api-docs/google.protobuf.compiler.csharp_generator.md deleted file mode 100644 index 86881202d..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.csharp_generator.md +++ /dev/null @@ -1,14 +0,0 @@ -+++ -title = "csharp_generator.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/csharp/csharp_generator.h>
namespace google::protobuf::compiler::csharp

Generates C# code for a given .proto file.

Classes in this file

CodeGenerator implementation which generates a C# source file and header.

class Generator: public CodeGenerator

#include <google/protobuf/compiler/csharp/csharp_generator.h>
namespace google::protobuf::compiler::csharp

CodeGenerator implementation which generates a C# source file and header.

If you create your own protocol compiler binary and you want it to support C# output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.

- -

Members

Generator()
~Generator()
virtual bool
Generate(const FileDescriptor * file, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
Generates code for the given proto file, generating one or more files in the given output directory. more...
virtual uint64_t
GetSupportedFeatures() const
Implement this to indicate what features this code generator supports. more...

virtual bool Generator::Generate(
        const FileDescriptor * file,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const

Generates code for the given proto file, generating one or more files in the given output directory.

A parameter to be passed to the generator can be specified on the command line. This is intended to be used to pass generator specific parameters. It is empty if no parameter was given. ParseGeneratorParameter (below), can be used to accept multiple parameters within the single parameter command line flag.

-

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.

-

virtual uint64_t Generator::GetSupportedFeatures() const

Implement this to indicate what features this code generator supports.

This should be a bitwise OR of features from the Features enum in plugin.proto.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.csharp_names.md b/content/reference/cpp/api-docs/google.protobuf.compiler.csharp_names.md deleted file mode 100644 index 529e48e62..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.csharp_names.md +++ /dev/null @@ -1,36 +0,0 @@ -+++ -title = "csharp_names.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/csharp/csharp_names.h>
namespace google::protobuf::compiler::csharp

Provides a mechanism for mapping a descriptor to the fully-qualified name of the corresponding C# class.

Classes in this file

File Members

These definitions are not part of any class.
std::string
GetFileNamespace(const FileDescriptor * descriptor)
Requires: more...
std::string
GetClassName(const Descriptor * descriptor)
Requires: more...
std::string
GetReflectionClassName(const FileDescriptor * descriptor)
Requires: more...
std::string
GetOutputFile(const FileDescriptor * descriptor, const std::string file_extension, const bool generate_directories, const std::string base_namespace, std::string * error)
Generates output file name for given file descriptor. more...

std::string csharp::GetFileNamespace(
        const FileDescriptor * descriptor)

Requires:

descriptor != NULL
-

Returns:

- -
The namespace to use for given file descriptor.
-

std::string csharp::GetClassName(
        const Descriptor * descriptor)

Requires:

descriptor != NULL
- -

Returns:

- -
The fully-qualified C# class name.
-

std::string csharp::GetReflectionClassName(
        const FileDescriptor * descriptor)

Requires:

descriptor != NULL
- -

Returns:

- -
The fully-qualified name of the C# class that provides
-access to the file descriptor. Proto compiler generates
-such class for each .proto file processed.
-

std::string csharp::GetOutputFile(
        const FileDescriptor * descriptor,
        const std::string file_extension,
        const bool generate_directories,
        const std::string base_namespace,
        std::string * error)

Generates output file name for given file descriptor.

If generate_directories is true, the output file will be put under directory corresponding to file's namespace. base_namespace can be used to strip some of the top level directories. E.g. for file with namespace "Bar.Foo" and base_namespace="Bar", the resulting file will be put under directory "Foo" (and not "Bar/Foo").

-

Requires:

-
descriptor != NULL
-error != NULL
- -

Returns:

- -
The file name to use as output file for given file descriptor. In case
-of failure, this function will return empty string and error parameter
-will contain the error message.
- -
diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.importer.md b/content/reference/cpp/api-docs/google.protobuf.compiler.importer.md deleted file mode 100644 index 2df4c25fa..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.importer.md +++ /dev/null @@ -1,45 +0,0 @@ -+++ -title = "importer.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/importer.h>
namespace google::protobuf::compiler

This file is the public interface to the .proto file parser.

Classes in this file

An implementation of DescriptorDatabase which loads files from a SourceTree and parses them.
Simple interface for parsing .proto files.
If the importer encounters problems while trying to import the proto files, it reports them to a MultiFileErrorCollector.
Abstract interface which represents a directory tree containing proto files.
An implementation of SourceTree which loads files from locations on disk.

class SourceTreeDescriptorDatabase: public DescriptorDatabase

#include <google/protobuf/compiler/importer.h>
namespace google::protobuf::compiler

An implementation of DescriptorDatabase which loads files from a SourceTree and parses them.

Note: This class is not thread-safe since it maintains a table of source code locations for error reporting. However, when a DescriptorPool wraps a DescriptorDatabase, it uses mutex locking to make sure only one method of the database is called at a time, even if the DescriptorPool is used from multiple threads. Therefore, there is only a problem if you create multiple DescriptorPools wrapping the same SourceTreeDescriptorDatabase and use them from multiple threads.

- -

Note: This class does not implement FindFileContainingSymbol() or FindFileContainingExtension(); these will always return false.

- -

Members

SourceTreeDescriptorDatabase(SourceTree * source_tree)
SourceTreeDescriptorDatabase(SourceTree * source_tree, DescriptorDatabase * fallback_database)
If non-NULL, fallback_database will be checked if a file doesn't exist in the specified source_tree.
~SourceTreeDescriptorDatabase()
void
RecordErrorsTo(MultiFileErrorCollector * error_collector)
Instructs the SourceTreeDescriptorDatabase to report any parse errors to the given MultiFileErrorCollector. more...
DescriptorPool::ErrorCollector *
GetValidationErrorCollector()
Gets a DescriptorPool::ErrorCollector which records errors to the MultiFileErrorCollector specified with RecordErrorsTo(). more...

implements DescriptorDatabase

virtual bool
FindFileByName(const std::string & filename, FileDescriptorProto * output)
Find a file by file name. more...
virtual bool
FindFileContainingSymbol(const std::string & symbol_name, FileDescriptorProto * output)
Find the file that declares the given fully-qualified symbol name. more...
virtual bool
FindFileContainingExtension(const std::string & containing_type, int field_number, FileDescriptorProto * output)
Find the file which defines an extension extending the given message type with the given field number. more...

void SourceTreeDescriptorDatabase::RecordErrorsTo(
        MultiFileErrorCollector * error_collector)

Instructs the SourceTreeDescriptorDatabase to report any parse errors to the given MultiFileErrorCollector.

This should be called before parsing. error_collector must remain valid until either this method is called again or the SourceTreeDescriptorDatabase is destroyed.

-

DescriptorPool::ErrorCollector *
    SourceTreeDescriptorDatabase::GetValidationErrorCollector()

Gets a DescriptorPool::ErrorCollector which records errors to the MultiFileErrorCollector specified with RecordErrorsTo().

This collector has the ability to determine exact line and column numbers of errors from the information given to it by the DescriptorPool.

-

virtual bool SourceTreeDescriptorDatabase::FindFileByName(
        const std::string & filename,
        FileDescriptorProto * output)

Find a file by file name.

Fills in in *output and returns true if found. Otherwise, returns false, leaving the contents of *output undefined.

-

virtual bool SourceTreeDescriptorDatabase::FindFileContainingSymbol(
        const std::string & symbol_name,
        FileDescriptorProto * output)

Find the file that declares the given fully-qualified symbol name.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined.

-

virtual bool SourceTreeDescriptorDatabase::FindFileContainingExtension(
        const std::string & containing_type,
        int field_number,
        FileDescriptorProto * output)

Find the file which defines an extension extending the given message type with the given field number.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined. containing_type must be a fully-qualified type name.

-

class Importer

#include <google/protobuf/compiler/importer.h>
namespace google::protobuf::compiler

Simple interface for parsing .proto files.

This wraps the process of opening the file, parsing it with a Parser, recursively parsing all its imports, and then cross-linking the results to produce a FileDescriptor.

-

This is really just a thin wrapper around SourceTreeDescriptorDatabase. You may find that SourceTreeDescriptorDatabase is more flexible.

-

Members

Importer(SourceTree * source_tree, MultiFileErrorCollector * error_collector)
~Importer()
const FileDescriptor *
Import(const std::string & filename)
Import the given file and build a FileDescriptor representing it. more...
const DescriptorPool *
pool() const
The DescriptorPool in which all imported FileDescriptors and their contents are stored.
void
AddUnusedImportTrackFile(const std::string & file_name, bool is_error = false)
void
ClearUnusedImportTrackFiles()

const FileDescriptor *
    Importer::Import(
        const std::string & filename)

Import the given file and build a FileDescriptor representing it.

If the file is already in the DescriptorPool, the existing FileDescriptor will be returned. The FileDescriptor is property of the DescriptorPool, and will remain valid until it is destroyed. If any errors occur, they will be reported using the error collector and Import() will return NULL.

-

A particular Importer object will only report errors for a particular file once. All future attempts to import the same file will return NULL without reporting any errors. The idea is that you might want to import a lot of files without seeing the same errors over and over again. If you want to see errors for the same files repeatedly, you can use a separate Importer object to import each one (but use the same DescriptorPool so that they can be cross-linked).

-

class MultiFileErrorCollector

#include <google/protobuf/compiler/importer.h>
namespace google::protobuf::compiler

If the importer encounters problems while trying to import the proto files, it reports them to a MultiFileErrorCollector.

Members

MultiFileErrorCollector()
virtual
~MultiFileErrorCollector()
virtual void
AddError(const std::string & filename, int line, int column, const std::string & message) = 0
Line and column numbers are zero-based. more...
virtual void
AddWarning(const std::string & , int , int , const std::string & )

virtual void MultiFileErrorCollector::AddError(
        const std::string & filename,
        int line,
        int column,
        const std::string & message) = 0

Line and column numbers are zero-based.

A line number of -1 indicates an error with the entire file (e.g. "not found").

-

class SourceTree

#include <google/protobuf/compiler/importer.h>
namespace google::protobuf::compiler

Abstract interface which represents a directory tree containing proto files.

Used by the default implementation of Importer to resolve import statements Most users will probably want to use the DiskSourceTree implementation, below.

-

Known subclasses:

Members

SourceTree()
virtual
~SourceTree()
virtual io::ZeroCopyInputStream *
Open(const std::string & filename) = 0
Open the given file and return a stream that reads it, or NULL if not found. more...
virtual std::string
GetLastErrorMessage()
If Open() returns NULL, calling this method immediately will return an description of the error. more...

virtual io::ZeroCopyInputStream *
    SourceTree::Open(
        const std::string & filename) = 0

Open the given file and return a stream that reads it, or NULL if not found.

The caller takes ownership of the returned object. The filename must be a path relative to the root of the source tree and must not contain "." or ".." components.

-

virtual std::string SourceTree::GetLastErrorMessage()

If Open() returns NULL, calling this method immediately will return an description of the error.

Subclasses should implement this method and return a meaningful value for better error reporting.

-

class DiskSourceTree: public SourceTree

#include <google/protobuf/compiler/importer.h>
namespace google::protobuf::compiler

An implementation of SourceTree which loads files from locations on disk.

Multiple mappings can be set up to map locations in the DiskSourceTree to locations in the physical filesystem.

-

Members

enum
DiskFileToVirtualFileResult
DiskSourceTree()
~DiskSourceTree()
void
MapPath(const std::string & virtual_path, const std::string & disk_path)
Map a path on disk to a location in the SourceTree. more...
DiskFileToVirtualFileResult
DiskFileToVirtualFile(const std::string & disk_file, std::string * virtual_file, std::string * shadowing_disk_file)
Given a path to a file on disk, find a virtual path mapping to that file. more...
bool
VirtualFileToDiskFile(const std::string & virtual_file, std::string * disk_file)
Given a virtual path, find the path to the file on disk. more...

implements SourceTree

virtual io::ZeroCopyInputStream *
Open(const std::string & filename)
Open the given file and return a stream that reads it, or NULL if not found. more...
virtual std::string
GetLastErrorMessage()
If Open() returns NULL, calling this method immediately will return an description of the error. more...

enum DiskSourceTree::DiskFileToVirtualFileResult {
  SUCCESS,
  SHADOWED,
  CANNOT_OPEN,
  NO_MAPPING
}

Return type for DiskFileToVirtualFile().

SUCCESS
SHADOWED
CANNOT_OPEN
NO_MAPPING

void DiskSourceTree::MapPath(
        const std::string & virtual_path,
        const std::string & disk_path)

Map a path on disk to a location in the SourceTree.

The path may be either a file or a directory. If it is a directory, the entire tree under it will be mapped to the given virtual location. To map a directory to the root of the source tree, pass an empty string for virtual_path.

-

If multiple mapped paths apply when opening a file, they will be searched in order. For example, if you do:

-
MapPath("bar", "foo/bar");
-MapPath("", "baz");
-

and then you do:

-
Open("bar/qux");
-

the DiskSourceTree will first try to open foo/bar/qux, then baz/bar/qux, returning the first one that opens successfully.

-

disk_path may be an absolute path or relative to the current directory, just like a path you'd pass to open().

-

DiskFileToVirtualFileResult
    DiskSourceTree::DiskFileToVirtualFile(
        const std::string & disk_file,
        std::string * virtual_file,
        std::string * shadowing_disk_file)

Given a path to a file on disk, find a virtual path mapping to that file.

The first mapping created with MapPath() whose disk_path contains the filename is used. However, that virtual path may not actually be usable to open the given file. Possible return values are:

-
    -
  • SUCCESS: The mapping was found. *virtual_file is filled in so that calling Open(*virtual_file) will open the file named by disk_file.
  • -
  • SHADOWED: A mapping was found, but using Open() to open this virtual path will end up returning some different file. This is because some other mapping with a higher precedence also matches this virtual path and maps it to a different file that exists on disk. *virtual_file is filled in as it would be in the SUCCESS case. *shadowing_disk_file is filled in with the disk path of the file which would be opened if you were to call Open(*virtual_file).
  • -
  • CANNOT_OPEN: The mapping was found and was not shadowed, but the file specified cannot be opened. When this value is returned, errno will indicate the reason the file cannot be opened. *virtual_file will be set to the virtual path as in the SUCCESS case, even though it is not useful.
  • -
  • NO_MAPPING: Indicates that no mapping was found which contains this file.
  • -
-

bool DiskSourceTree::VirtualFileToDiskFile(
        const std::string & virtual_file,
        std::string * disk_file)

Given a virtual path, find the path to the file on disk.

Return true and update disk_file with the on-disk path if the file exists. Return false and leave disk_file untouched if the file doesn't exist.

-

virtual io::ZeroCopyInputStream *
    DiskSourceTree::Open(
        const std::string & filename)

Open the given file and return a stream that reads it, or NULL if not found.

The caller takes ownership of the returned object. The filename must be a path relative to the root of the source tree and must not contain "." or ".." components.

-

virtual std::string DiskSourceTree::GetLastErrorMessage()

If Open() returns NULL, calling this method immediately will return an description of the error.

Subclasses should implement this method and return a meaningful value for better error reporting.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.java_generator.md b/content/reference/cpp/api-docs/google.protobuf.compiler.java_generator.md deleted file mode 100644 index 98c6536a4..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.java_generator.md +++ /dev/null @@ -1,14 +0,0 @@ -+++ -title = "java_generator.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/java/java_generator.h>
namespace google::protobuf::compiler::java

Generates Java code for a given .proto file.

Classes in this file

CodeGenerator implementation which generates Java code.

class JavaGenerator: public CodeGenerator

#include <google/protobuf/compiler/java/java_generator.h>
namespace google::protobuf::compiler::java

CodeGenerator implementation which generates Java code.

If you create your own protocol compiler binary and you want it to support Java output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.

- -

Members

JavaGenerator()
~JavaGenerator()

implements CodeGenerator

virtual bool
Generate(const FileDescriptor * file, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
Generates code for the given proto file, generating one or more files in the given output directory. more...
virtual uint64_t
GetSupportedFeatures() const
Implement this to indicate what features this code generator supports. more...

virtual bool JavaGenerator::Generate(
        const FileDescriptor * file,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const

Generates code for the given proto file, generating one or more files in the given output directory.

A parameter to be passed to the generator can be specified on the command line. This is intended to be used to pass generator specific parameters. It is empty if no parameter was given. ParseGeneratorParameter (below), can be used to accept multiple parameters within the single parameter command line flag.

-

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.

-

virtual uint64_t JavaGenerator::GetSupportedFeatures() const

Implement this to indicate what features this code generator supports.

This should be a bitwise OR of features from the Features enum in plugin.proto.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.java_names.md b/content/reference/cpp/api-docs/google.protobuf.compiler.java_names.md deleted file mode 100644 index 9a1103b96..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.java_names.md +++ /dev/null @@ -1,39 +0,0 @@ -+++ -title = "java_names.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/java/java_names.h>
namespace google::protobuf::compiler::java

Provides a mechanism for mapping a descriptor to the fully-qualified name of the corresponding Java class.

Classes in this file

File Members

These definitions are not part of any class.
std::string
ClassName(const Descriptor * descriptor)
Requires: more...
std::string
ClassName(const EnumDescriptor * descriptor)
Requires: more...
std::string
ClassName(const FileDescriptor * descriptor)
Requires: more...
std::string
ClassName(const ServiceDescriptor * descriptor)
Requires: more...
std::string
FileJavaPackage(const FileDescriptor * descriptor)
Requires: more...
std::string
CapitalizedFieldName(const FieldDescriptor * descriptor)
Requires: more...

std::string java::ClassName(
        const Descriptor * descriptor)

Requires:

descriptor != NULL
-

Returns:

- -
The fully-qualified Java class name.
-

std::string java::ClassName(
        const EnumDescriptor * descriptor)

Requires:

descriptor != NULL
- -

Returns:

- -
The fully-qualified Java class name.
-

std::string java::ClassName(
        const FileDescriptor * descriptor)

Requires:

descriptor != NULL
- -

Returns:

- -
The fully-qualified Java class name.
-

std::string java::ClassName(
        const ServiceDescriptor * descriptor)

Requires:

descriptor != NULL
- -

Returns:

- -
The fully-qualified Java class name.
-

std::string java::FileJavaPackage(
        const FileDescriptor * descriptor)

Requires:

descriptor != NULL
- -

Returns:

- -
Java package name.
-

std::string java::CapitalizedFieldName(
        const FieldDescriptor * descriptor)

Requires:

descriptor != NULL
- -

Returns:

- -
Capitalized camel case name field name.
- -
diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.javanano_generator.md b/content/reference/cpp/api-docs/google.protobuf.compiler.javanano_generator.md deleted file mode 100644 index 7ec4bac30..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.javanano_generator.md +++ /dev/null @@ -1,13 +0,0 @@ -+++ -title = "javanano_generator.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/javanano/javanano_generator.h>
namespace google::protobuf::compiler::javanano

Generates Java nano code for a given .proto file.

Classes in this file

CodeGenerator implementation which generates Java nano code.

class JavaNanoGenerator: public CodeGenerator

#include <google/protobuf/compiler/javanano/javanano_generator.h>
namespace google::protobuf::compiler::javanano

CodeGenerator implementation which generates Java nano code.

If you create your own protocol compiler binary and you want it to support Java output for the nano runtime, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.

- -

Members

JavaNanoGenerator()
~JavaNanoGenerator()

implements CodeGenerator

virtual bool
Generate(const FileDescriptor * file, const string & parameter, GeneratorContext * generator_context, string * error) const
Generates code for the given proto file, generating one or more files in the given output directory. more...

virtual bool JavaNanoGenerator::Generate(
        const FileDescriptor * file,
        const string & parameter,
        GeneratorContext * generator_context,
        string * error) const

Generates code for the given proto file, generating one or more files in the given output directory.

A parameter to be passed to the generator can be specified on the command line. This is intended to be used to pass generator specific parameters. It is empty if no parameter was given. ParseGeneratorParameter (below), can be used to accept multiple parameters within the single parameter command line flag.

-

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.js_generator.md b/content/reference/cpp/api-docs/google.protobuf.compiler.js_generator.md deleted file mode 100644 index 2fc00b01b..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.js_generator.md +++ /dev/null @@ -1,20 +0,0 @@ -+++ -title = "js_generator.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/js/js_generator.h>
namespace google::protobuf::compiler::js

Generates JavaScript code for a given .proto file.

Classes in this file

CodeGenerator implementation which generates a JavaScript source file and header.

struct GeneratorOptions

#include <google/protobuf/compiler/js/js_generator.h>
namespace google::protobuf::compiler::js

Members

enum
ImportStyle
What style of imports should be used. more...
enum
OutputMode
std::string
output_dir
Output path.
std::string
namespace_prefix
Namespace prefix.
bool
binary
Enable binary-format support?
enum google::protobuf::compiler::js::GeneratorOptions::ImportStyle
import_style
bool
add_require_for_enums
Add a goog.requires() call for each enum type used. more...
bool
testonly
Set this as a test-only module via goog.setTestOnly();.
std::string
library
Create a library with name <name>_lib.js rather than a separate .js file per type?
bool
error_on_name_conflict
Error if there are two types that would generate the same output file?
std::string
extension
The extension to use for output file names.
bool
one_output_file_per_input_file
Create a separate output file for each input file?
bool
annotate_code
If true, we should append annotations as comments on the last line for generated .js file. more...
GeneratorOptions()
bool
ParseFromOptions(const std::vector< std::pair< std::string, std::string > > & options, std::string * error)
std::string
GetFileNameExtension() const
Returns the file name extension to use for generated code.
OutputMode
output_mode() const
Indicates how to output the generated code based on the provided options.

enum GeneratorOptions::ImportStyle {
  kImportClosure,
  kImportCommonJs,
  kImportCommonJsStrict,
  kImportBrowser,
  kImportEs6
}

What style of imports should be used.

kImportClosuregoog.require()
kImportCommonJsrequire()
kImportCommonJsStrictrequire() with no global export
kImportBrowserno import statements
kImportEs6import { member } from ''

enum GeneratorOptions::OutputMode {
  kOneOutputFilePerInputFile,
  kOneOutputFilePerSCC,
  kEverythingInOneFile
}

kOneOutputFilePerInputFileCreate an output file for each input .proto file.
kOneOutputFilePerSCCCreate an output file for each type.
kEverythingInOneFilePut everything in a single file named by the library option.

bool GeneratorOptions::add_require_for_enums

Add a goog.requires() call for each enum type used.

If not set, a forward declaration with goog.forwardDeclare is produced instead.

-

bool GeneratorOptions::annotate_code

If true, we should append annotations as comments on the last line for generated .js file.

Annotations used by tools like to provide cross-references between .js and .proto files. Annotations are encoded as base64 proto of GeneratedCodeInfo message (see descriptor.proto).

-

class Generator: public CodeGenerator

#include <google/protobuf/compiler/js/js_generator.h>
namespace google::protobuf::compiler::js

CodeGenerator implementation which generates a JavaScript source file and header.

If you create your own protocol compiler binary and you want it to support JavaScript output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.

- -

Members

Generator()
virtual
~Generator()
virtual bool
Generate(const FileDescriptor * file, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
Generates code for the given proto file, generating one or more files in the given output directory. more...
virtual bool
HasGenerateAll() const
This is no longer used, but this class is part of the opensource protobuf library, so it has to remain to keep vtables the same for the current version of the library. more...
virtual bool
GenerateAll(const std::vector< const FileDescriptor * > & files, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
Generates code for all given proto files. more...
virtual uint64
GetSupportedFeatures() const
Implement this to indicate what features this code generator supports. more...

virtual bool Generator::Generate(
        const FileDescriptor * file,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const

Generates code for the given proto file, generating one or more files in the given output directory.

A parameter to be passed to the generator can be specified on the command line. This is intended to be used to pass generator specific parameters. It is empty if no parameter was given. ParseGeneratorParameter (below), can be used to accept multiple parameters within the single parameter command line flag.

-

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.

-

virtual bool Generator::HasGenerateAll() const

This is no longer used, but this class is part of the opensource protobuf library, so it has to remain to keep vtables the same for the current version of the library.

When protobufs does a api breaking change, the method can be removed.

-

virtual bool Generator::GenerateAll(
        const std::vector< const FileDescriptor * > & files,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const

Generates code for all given proto files.

WARNING: The canonical code generator design produces one or two output files per input .proto file, and we do not wish to encourage alternate designs.

-

A parameter is given as passed on the command line, as in |Generate()| above.

-

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.

-

virtual uint64 Generator::GetSupportedFeatures() const

Implement this to indicate what features this code generator supports.

This should be a bitwise OR of features from the Features enum in plugin.proto.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.objectivec_generator.md b/content/reference/cpp/api-docs/google.protobuf.compiler.objectivec_generator.md deleted file mode 100644 index ad236a33c..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.objectivec_generator.md +++ /dev/null @@ -1,18 +0,0 @@ -+++ -title = "objectivec_generator.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/objectivec/objectivec_generator.h>
namespace google::protobuf::compiler::objectivec

Generates ObjectiveC code for a given .proto file.

Classes in this file

CodeGenerator implementation which generates a ObjectiveC source file and header.

class ObjectiveCGenerator: public CodeGenerator

#include <google/protobuf/compiler/objectivec/objectivec_generator.h>
namespace google::protobuf::compiler::objectivec

CodeGenerator implementation which generates a ObjectiveC source file and header.

If you create your own protocol compiler binary and you want it to support ObjectiveC output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.

- -

Members

ObjectiveCGenerator()
~ObjectiveCGenerator()
ObjectiveCGenerator(const ObjectiveCGenerator & )
ObjectiveCGenerator &
operator=(const ObjectiveCGenerator & )

implements CodeGenerator

virtual bool
HasGenerateAll() const
This is no longer used, but this class is part of the opensource protobuf library, so it has to remain to keep vtables the same for the current version of the library. more...
virtual bool
Generate(const FileDescriptor * file, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
Generates code for the given proto file, generating one or more files in the given output directory. more...
virtual bool
GenerateAll(const std::vector< const FileDescriptor * > & files, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
Generates code for all given proto files. more...
virtual uint64_t
GetSupportedFeatures() const
Implement this to indicate what features this code generator supports. more...

virtual bool ObjectiveCGenerator::HasGenerateAll() const

This is no longer used, but this class is part of the opensource protobuf library, so it has to remain to keep vtables the same for the current version of the library.

When protobufs does a api breaking change, the method can be removed.

-

virtual bool ObjectiveCGenerator::Generate(
        const FileDescriptor * file,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const

Generates code for the given proto file, generating one or more files in the given output directory.

A parameter to be passed to the generator can be specified on the command line. This is intended to be used to pass generator specific parameters. It is empty if no parameter was given. ParseGeneratorParameter (below), can be used to accept multiple parameters within the single parameter command line flag.

-

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.

-

virtual bool ObjectiveCGenerator::GenerateAll(
        const std::vector< const FileDescriptor * > & files,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const

Generates code for all given proto files.

WARNING: The canonical code generator design produces one or two output files per input .proto file, and we do not wish to encourage alternate designs.

-

A parameter is given as passed on the command line, as in |Generate()| above.

-

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.

-

virtual uint64_t ObjectiveCGenerator::GetSupportedFeatures() const

Implement this to indicate what features this code generator supports.

This should be a bitwise OR of features from the Features enum in plugin.proto.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.objectivec_helpers.md b/content/reference/cpp/api-docs/google.protobuf.compiler.objectivec_helpers.md deleted file mode 100644 index ba401a92f..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.objectivec_helpers.md +++ /dev/null @@ -1,14 +0,0 @@ -+++ -title = "objectivec_helpers.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
namespace google::protobuf::compiler::objectivec

Helper functions for generating ObjectiveC code.

Classes in this file

Generator options (see objectivec_generator.cc for a description of each):
Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform the input into the expected output.
Helper for parsing simple files.
Helper class for parsing framework import mappings and generating import statements.

File Members

These definitions are not part of any class.
enum
ObjectiveCType
enum
FlagType
const char *const
ProtobufLibraryFrameworkName
The name the commonly used by the library when built as a framework. more...
std::string
EscapeTrigraphs(const std::string & to_escape)
Escape C++ trigraphs by escaping question marks to "\?".
void
TrimWhitespace(StringPiece * input)
Remove white space from either end of a StringPiece.
bool
IsRetainedName(const std::string & name)
Returns true if the name requires a ns_returns_not_retained attribute applied to it.
bool
IsInitName(const std::string & name)
Returns true if the name starts with "init" and will need to have special handling under ARC.
std::string
FileClassPrefix(const FileDescriptor * file)
Gets the objc_class_prefix.
std::string
FilePath(const FileDescriptor * file)
Gets the path of the file we're going to generate (sans the .pb.h extension). more...
std::string
FilePathBasename(const FileDescriptor * file)
Just like FilePath(), but without the directory part.
std::string
FileClassName(const FileDescriptor * file)
Gets the name of the root class we'll generate in the file. more...
std::string
ClassName(const Descriptor * descriptor)
These return the fully-qualified class name corresponding to the given descriptor.
std::string
ClassName(const Descriptor * descriptor, std::string * out_suffix_added)
std::string
EnumName(const EnumDescriptor * descriptor)
std::string
EnumValueName(const EnumValueDescriptor * descriptor)
Returns the fully-qualified name of the enum value corresponding to the the descriptor.
std::string
EnumValueShortName(const EnumValueDescriptor * descriptor)
Returns the name of the enum value corresponding to the descriptor.
std::string
UnCamelCaseEnumShortName(const std::string & name)
Reverse what an enum does.
std::string
ExtensionMethodName(const FieldDescriptor * descriptor)
Returns the name to use for the extension (used as the method off the file's Root class).
std::string
FieldName(const FieldDescriptor * field)
Returns the transformed field name.
std::string
FieldNameCapitalized(const FieldDescriptor * field)
std::string
OneofEnumName(const OneofDescriptor * descriptor)
Returns the transformed oneof name.
std::string
OneofName(const OneofDescriptor * descriptor)
std::string
OneofNameCapitalized(const OneofDescriptor * descriptor)
std::string
ObjCClass(const std::string & class_name)
Returns a symbol that can be used in C code to refer to an Objective C class without initializing the class.
std::string
ObjCClassDeclaration(const std::string & class_name)
Declares an Objective C class without initializing the class so that it can be refrerred to by ObjCClass.
bool
HasPreservingUnknownEnumSemantics(const FileDescriptor * file)
bool
IsMapEntryMessage(const Descriptor * descriptor)
std::string
UnCamelCaseFieldName(const std::string & name, const FieldDescriptor * field)
Reverse of the above.
template std::string
GetOptionalDeprecatedAttribute(const TDescriptor * descriptor, const FileDescriptor * file = NULL, bool preSpace = true, bool postNewline = false)
std::string
GetCapitalizedType(const FieldDescriptor * field)
ObjectiveCType
GetObjectiveCType(FieldDescriptor::Type field_type)
ObjectiveCType
GetObjectiveCType(const FieldDescriptor * field)
bool
IsPrimitiveType(const FieldDescriptor * field)
bool
IsReferenceType(const FieldDescriptor * field)
std::string
GPBGenericValueFieldName(const FieldDescriptor * field)
std::string
DefaultValue(const FieldDescriptor * field)
bool
HasNonZeroDefaultValue(const FieldDescriptor * field)
std::string
BuildFlagsString(const FlagType type, const std::vector< std::string > & strings)
std::string
BuildCommentsString(const SourceLocation & location, bool prefer_single_line)
Builds HeaderDoc/appledoc style comments out of the comments in the .proto file.
std::string
ProtobufFrameworkImportSymbol(const std::string & framework_name)
Returns the CPP symbol name to use as the gate for framework style imports for the given framework name to use.
bool
IsProtobufLibraryBundledProtoFile(const FileDescriptor * file)
Checks if the file is one of the proto's bundled with the library.
bool
ValidateObjCClassPrefixes(const std::vector< const FileDescriptor * > & files, const Options & generation_options, std::string * out_error)
Checks the prefix for the given files and outputs any warnings as needed. more...
bool
ParseSimpleFile(const std::string & path, LineConsumer * line_consumer, std::string * out_error)

enum objectivec::ObjectiveCType {
  OBJECTIVECTYPE_INT32,
  OBJECTIVECTYPE_UINT32,
  OBJECTIVECTYPE_INT64,
  OBJECTIVECTYPE_UINT64,
  OBJECTIVECTYPE_FLOAT,
  OBJECTIVECTYPE_DOUBLE,
  OBJECTIVECTYPE_BOOLEAN,
  OBJECTIVECTYPE_STRING,
  OBJECTIVECTYPE_DATA,
  OBJECTIVECTYPE_ENUM,
  OBJECTIVECTYPE_MESSAGE
}

OBJECTIVECTYPE_INT32
OBJECTIVECTYPE_UINT32
OBJECTIVECTYPE_INT64
OBJECTIVECTYPE_UINT64
OBJECTIVECTYPE_FLOAT
OBJECTIVECTYPE_DOUBLE
OBJECTIVECTYPE_BOOLEAN
OBJECTIVECTYPE_STRING
OBJECTIVECTYPE_DATA
OBJECTIVECTYPE_ENUM
OBJECTIVECTYPE_MESSAGE

enum objectivec::FlagType {
  FLAGTYPE_DESCRIPTOR_INITIALIZATION,
  FLAGTYPE_EXTENSION,
  FLAGTYPE_FIELD
}

FLAGTYPE_DESCRIPTOR_INITIALIZATION
FLAGTYPE_EXTENSION
FLAGTYPE_FIELD

const char *const objectivec::ProtobufLibraryFrameworkName

The name the commonly used by the library when built as a framework.

This lines up to the name used in the CocoaPod.

- -

std::string objectivec::FilePath(
        const FileDescriptor * file)

Gets the path of the file we're going to generate (sans the .pb.h extension).

The path will be dependent on the objectivec package declared in the proto package.

-

std::string objectivec::FileClassName(
        const FileDescriptor * file)

Gets the name of the root class we'll generate in the file.

This class is not meant for external consumption, but instead contains helpers that the rest of the classes need

-

bool objectivec::ValidateObjCClassPrefixes(
        const std::vector< const FileDescriptor * > & files,
        const Options & generation_options,
        std::string * out_error)

Checks the prefix for the given files and outputs any warnings as needed.

If there are flat out errors, then out_error is filled in with the first error and the result is false.

-

struct Options

#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
namespace google::protobuf::compiler::objectivec

Generator options (see objectivec_generator.cc for a description of each):

Members

std::string
expected_prefixes_path
std::vector< std::string >
expected_prefixes_suppressions
std::string
generate_for_named_framework
std::string
named_framework_to_proto_path_mappings_path
std::string
runtime_import_prefix
Options()

class TextFormatDecodeData

#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
namespace google::protobuf::compiler::objectivec

Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform the input into the expected output.

Members

TextFormatDecodeData()
~TextFormatDecodeData()
TextFormatDecodeData(const TextFormatDecodeData & )
TextFormatDecodeData &
operator=(const TextFormatDecodeData & )
void
AddString(int32 key, const std::string & input_for_decode, const std::string & desired_output)
size_t
num_entries() const
std::string
Data() const
static std::string
DecodeDataForString(const std::string & input_for_decode, const std::string & desired_output)

class LineConsumer

#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
namespace google::protobuf::compiler::objectivec

Helper for parsing simple files.

Members

LineConsumer()
virtual
~LineConsumer()
virtual bool
ConsumeLine(const StringPiece & line, std::string * out_error) = 0

class ImportWriter

#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
namespace google::protobuf::compiler::objectivec

Helper class for parsing framework import mappings and generating import statements.

Members

ImportWriter(const std::string & generate_for_named_framework, const std::string & named_framework_to_proto_path_mappings_path, const std::string & runtime_import_prefix, bool include_wkt_imports)
~ImportWriter()
void
AddFile(const FileDescriptor * file, const std::string & header_extension)
void
Print(io::Printer * printer) const
static void
PrintRuntimeImports(io::Printer * printer, const std::vector< std::string > & header_to_import, const std::string & runtime_import_prefix, bool default_cpp_symbol = false)
diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.parser.md b/content/reference/cpp/api-docs/google.protobuf.compiler.parser.md deleted file mode 100644 index cba5c8eda..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.parser.md +++ /dev/null @@ -1,19 +0,0 @@ -+++ -title = "parser.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/parser.h>
namespace google::protobuf::compiler

Implements parsing of .proto files to FileDescriptorProtos.

Classes in this file

Implements parsing of protocol definitions (such as .proto files).
A table mapping (descriptor, ErrorLocation) pairs – as reported by DescriptorPool when validating descriptors – to line and column numbers within the original source code.

class Parser

#include <google/protobuf/compiler/parser.h>
namespace google::protobuf::compiler

Implements parsing of protocol definitions (such as .proto files).

Note that most users will be more interested in the Importer class. Parser is a lower-level class which simply converts a single .proto file to a FileDescriptorProto. It does not resolve import directives or perform many other kinds of validation needed to construct a complete FileDescriptor.

- -

Members

Parser()
~Parser()
bool
Parse(io::Tokenizer * input, FileDescriptorProto * file)
Parse the entire input and construct a FileDescriptorProto representing it. more...
void
RecordSourceLocationsTo(SourceLocationTable * location_table)
DEPRECATED: New code should use the SourceCodeInfo embedded in the FileDescriptorProto. more...
void
RecordErrorsTo(io::ErrorCollector * error_collector)
Requests that errors be recorded to the given ErrorCollector while parsing. more...
const std::string &
GetSyntaxIdentifier()
Returns the identifier used in the "syntax = " declaration, if one was seen during the last call to Parse(), or the empty string otherwise.
void
SetRequireSyntaxIdentifier(bool value)
If set true, input files will be required to begin with a syntax identifier. more...
void
SetStopAfterSyntaxIdentifier(bool value)
Call SetStopAfterSyntaxIdentifier(true) to tell the parser to stop parsing as soon as it has seen the syntax identifier, or lack thereof. more...

bool Parser::Parse(
        io::Tokenizer * input,
        FileDescriptorProto * file)

Parse the entire input and construct a FileDescriptorProto representing it.

Returns true if no errors occurred, false otherwise.

-

void Parser::RecordSourceLocationsTo(
        SourceLocationTable * location_table)

DEPRECATED: New code should use the SourceCodeInfo embedded in the FileDescriptorProto.

Requests that locations of certain definitions be recorded to the given SourceLocationTable while parsing. This can be used to look up exact line and column numbers for errors reported by DescriptorPool during validation. Set to NULL (the default) to discard source location information.

-

void Parser::RecordErrorsTo(
        io::ErrorCollector * error_collector)

Requests that errors be recorded to the given ErrorCollector while parsing.

Set to NULL (the default) to discard error messages.

-

void Parser::SetRequireSyntaxIdentifier(
        bool value)

If set true, input files will be required to begin with a syntax identifier.

Otherwise, files may omit this. If a syntax identifier is provided, it must be 'syntax = "proto2";' and must appear at the top of this file regardless of whether or not it was required.

-

void Parser::SetStopAfterSyntaxIdentifier(
        bool value)

Call SetStopAfterSyntaxIdentifier(true) to tell the parser to stop parsing as soon as it has seen the syntax identifier, or lack thereof.

This is useful for quickly identifying the syntax of the file without parsing the whole thing. If this is enabled, no error will be recorded if the syntax identifier is something other than "proto2" (since presumably the caller intends to deal with that), but other kinds of errors (e.g. parse errors) will still be reported. When this is enabled, you may pass a NULL FileDescriptorProto to Parse().

-

class SourceLocationTable

#include <google/protobuf/compiler/parser.h>
namespace google::protobuf::compiler

A table mapping (descriptor, ErrorLocation) pairs – as reported by DescriptorPool when validating descriptors – to line and column numbers within the original source code.

This is semi-obsolete: FileDescriptorProto.source_code_info now contains far more complete information about source locations. However, as of this writing you still need to use SourceLocationTable when integrating with DescriptorPool.

-

Members

SourceLocationTable()
~SourceLocationTable()
bool
Find(const Message * descriptor, DescriptorPool::ErrorCollector::ErrorLocation location, int * line, int * column) const
Finds the precise location of the given error and fills in *line and *column with the line and column numbers. more...
bool
FindImport(const Message * descriptor, const std::string & name, int * line, int * column) const
void
Add(const Message * descriptor, DescriptorPool::ErrorCollector::ErrorLocation location, int line, int column)
Adds a location to the table.
void
AddImport(const Message * descriptor, const std::string & name, int line, int column)
void
Clear()
Clears the contents of the table.

bool SourceLocationTable::Find(
        const Message * descriptor,
        DescriptorPool::ErrorCollector::ErrorLocation location,
        int * line,
        int * column) const

Finds the precise location of the given error and fills in *line and *column with the line and column numbers.

If not found, sets *line to -1 and *column to 0 (since line = -1 is used to mean "error has no exact -location" in the ErrorCollector interface). Returns true if found, false otherwise.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.plugin.md b/content/reference/cpp/api-docs/google.protobuf.compiler.plugin.md deleted file mode 100644 index 6e69a5124..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.plugin.md +++ /dev/null @@ -1,33 +0,0 @@ -+++ -title = "plugin.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/plugin.h>
namespace google::protobuf::compiler

Front-end for protoc code generator plugins written in C++.

To implement a protoc plugin in C++, simply write an implementation of CodeGenerator, then create a main() function like:

- -
int main(int argc, char* argv[]) {
-  MyCodeGenerator generator;
-  return google::protobuf::compiler::PluginMain(argc, argv, &generator);
-}
- -

You must link your plugin against libprotobuf and libprotoc.

- -

The core part of PluginMain is to invoke the given CodeGenerator on a CodeGeneratorRequest to generate a CodeGeneratorResponse. This part is abstracted out and made into function GenerateCode so that it can be reused, for example, to implement a variant of PluginMain that does some preprocessing on the input CodeGeneratorRequest before feeding the request to the given code generator.

- -

To get protoc to use the plugin, do one of the following:

- -
    -
  • Place the plugin binary somewhere in the PATH and give it the name "protoc-gen-NAME" (replacing "NAME" with the name of your plugin). If you then invoke protoc with the parameter –NAME_out=OUT_DIR (again, replace "NAME" with your plugin's name), protoc will invoke your plugin to generate the output, which will be placed in OUT_DIR.
  • -
  • -

    Place the plugin binary anywhere, with any name, and pass the –plugin parameter to protoc to direct it to your plugin like so:

    -
    protoc --plugin=protoc-gen-NAME=path/to/mybinary --NAME_out=OUT_DIR
    -

    On Windows, make sure to include the .exe suffix:

    -
    protoc --plugin=protoc-gen-NAME=path/to/mybinary.exe --NAME_out=OUT_DIR
    -
  • -
- -

Classes in this file

File Members

These definitions are not part of any class.
int
PluginMain(int argc, char * argv, const CodeGenerator * generator)
Implements main() for a protoc plugin exposing the given code generator.
bool
GenerateCode(const CodeGeneratorRequest & request, const CodeGenerator & generator, CodeGeneratorResponse * response, std::string * error_msg)
Generates code using the given code generator. more...

bool compiler::GenerateCode(
        const CodeGeneratorRequest & request,
        const CodeGenerator & generator,
        CodeGeneratorResponse * response,
        std::string * error_msg)

Generates code using the given code generator.

Returns true if the code generation is successful. If the code generation fails, error_msg may be populated to describe the failure cause.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb.md b/content/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb.md deleted file mode 100644 index 77771358d..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb.md +++ /dev/null @@ -1,195 +0,0 @@ -+++ -title = "plugin.pb.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/plugin.pb.h>
namespace google::protobuf::compiler

API for protoc plugins.

This file defines a set of protocol message classes which make up the API to protoc code generator plugins. Plugins written in C++ should probably build on the API in plugin.h instead of dealing with the protobuf-level API, but plugins in other languages will need to deal with the raw messages as defined below.

The protocol compiler currently doesn't support auto-generated documentation, hence this page contains no descriptions. This file was generated by the protocol compiler from plugin.proto, whose contents are as follows:

- -
// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: kenton@google.com (Kenton Varda)
-//
-// WARNING:  The plugin interface is currently EXPERIMENTAL and is subject to
-//   change.
-//
-// protoc (aka the Protocol Compiler) can be extended via plugins.  A plugin is
-// just a program that reads a CodeGeneratorRequest from stdin and writes a
-// CodeGeneratorResponse to stdout.
-//
-// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead
-// of dealing with the raw protocol defined here.
-//
-// A plugin executable needs only to be placed somewhere in the path.  The
-// plugin should be named "protoc-gen-$NAME", and will then be used when the
-// flag "--${NAME}_out" is passed to protoc.
-
-syntax = "proto2";
-
-package google.protobuf.compiler;
-option java_package = "com.google.protobuf.compiler";
-option java_outer_classname = "PluginProtos";
-
-option go_package = "google.golang.org/protobuf/types/pluginpb";
-
-import "google/protobuf/descriptor.proto";
-
-// The version number of protocol compiler.
-message Version {
-  optional int32 major = 1;
-  optional int32 minor = 2;
-  optional int32 patch = 3;
-  // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should
-  // be empty for mainline stable releases.
-  optional string suffix = 4;
-}
-
-// An encoded CodeGeneratorRequest is written to the plugin's stdin.
-message CodeGeneratorRequest {
-  // The .proto files that were explicitly listed on the command-line.  The
-  // code generator should generate code only for these files.  Each file's
-  // descriptor will be included in proto_file, below.
-  repeated string file_to_generate = 1;
-
-  // The generator parameter passed on the command-line.
-  optional string parameter = 2;
-
-  // FileDescriptorProtos for all files in files_to_generate and everything
-  // they import.  The files will appear in topological order, so each file
-  // appears before any file that imports it.
-  //
-  // protoc guarantees that all proto_files will be written after
-  // the fields above, even though this is not technically guaranteed by the
-  // protobuf wire format.  This theoretically could allow a plugin to stream
-  // in the FileDescriptorProtos and handle them one by one rather than read
-  // the entire set into memory at once.  However, as of this writing, this
-  // is not similarly optimized on protoc's end -- it will store all fields in
-  // memory at once before sending them to the plugin.
-  //
-  // Type names of fields and extensions in the FileDescriptorProto are always
-  // fully qualified.
-  repeated FileDescriptorProto proto_file = 15;
-
-  // The version number of protocol compiler.
-  optional Version compiler_version = 3;
-
-}
-
-// The plugin writes an encoded CodeGeneratorResponse to stdout.
-message CodeGeneratorResponse {
-  // Error message.  If non-empty, code generation failed.  The plugin process
-  // should exit with status code zero even if it reports an error in this way.
-  //
-  // This should be used to indicate errors in .proto files which prevent the
-  // code generator from generating correct code.  Errors which indicate a
-  // problem in protoc itself -- such as the input CodeGeneratorRequest being
-  // unparseable -- should be reported by writing a message to stderr and
-  // exiting with a non-zero status code.
-  optional string error = 1;
-
-  // A bitmask of supported features that the code generator supports.
-  // This is a bitwise "or" of values from the Feature enum.
-  optional uint64 supported_features = 2;
-
-  // Sync with code_generator.h.
-  enum Feature {
-    FEATURE_NONE = 0;
-    FEATURE_PROTO3_OPTIONAL = 1;
-  }
-
-  // Represents a single generated file.
-  message File {
-    // The file name, relative to the output directory.  The name must not
-    // contain "." or ".." components and must be relative, not be absolute (so,
-    // the file cannot lie outside the output directory).  "/" must be used as
-    // the path separator, not "\".
-    //
-    // If the name is omitted, the content will be appended to the previous
-    // file.  This allows the generator to break large files into small chunks,
-    // and allows the generated text to be streamed back to protoc so that large
-    // files need not reside completely in memory at one time.  Note that as of
-    // this writing protoc does not optimize for this -- it will read the entire
-    // CodeGeneratorResponse before writing files to disk.
-    optional string name = 1;
-
-// If non-empty, indicates that the named file should already exist, and the
-// content here is to be inserted into that file at a defined insertion
-// point.  This feature allows a code generator to extend the output
-// produced by another code generator.  The original generator may provide
-// insertion points by placing special annotations in the file that look
-// like:
-//   @@protoc_insertion_point(NAME)
-// The annotation can have arbitrary text before and after it on the line,
-// which allows it to be placed in a comment.  NAME should be replaced with
-// an identifier naming the point -- this is what other generators will use
-// as the insertion_point.  Code inserted at this point will be placed
-// immediately above the line containing the insertion point (thus multiple
-// insertions to the same point will come out in the order they were added).
-// The double-@ is intended to make it unlikely that the generated code
-// could contain things that look like insertion points by accident.
-//
-// For example, the C++ code generator places the following line in the
-// .pb.h files that it generates:
-//   // @@protoc_insertion_point(namespace_scope)
-// This line appears within the scope of the file's package namespace, but
-// outside of any particular class.  Another plugin can then specify the
-// insertion_point "namespace_scope" to generate additional classes or
-// other declarations that should be placed in this scope.
-//
-// Note that if the line containing the insertion point begins with
-// whitespace, the same whitespace will be added to every line of the
-// inserted text.  This is useful for languages like Python, where
-// indentation matters.  In these languages, the insertion point comment
-// should be indented the same amount as any inserted code will need to be
-// in order to work correctly in that context.
-//
-// The code generator that generates the initial file and the one which
-// inserts into it must both run as part of a single invocation of protoc.
-// Code generators are executed in the order in which they appear on the
-// command line.
-//
-// If |insertion_point| is present, |name| must also be present.
-optional string insertion_point = 2;
-
-// The file contents.
-optional string content = 15;
-
-// Information describing the file content being inserted. If an insertion
-// point is used, this information will be appropriately offset and inserted
-// into the code generation metadata for the generated files.
-optional GeneratedCodeInfo generated_code_info = 16;
-
-  }
-  repeated File file = 15;
-}
-

Classes in this file

File Members

These definitions are not part of any class.
const ::protobuf::internal::DescriptorTable
descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto
PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_OPEN protobuf::compiler::CodeGeneratorRequest *
Arena::CreateMaybeMessage< protobuf::compiler::CodeGeneratorRequest >(Arena * )
protobuf::compiler::CodeGeneratorResponse *
Arena::CreateMaybeMessage< protobuf::compiler::CodeGeneratorResponse >(Arena * )
protobuf::compiler::CodeGeneratorResponse_File *
Arena::CreateMaybeMessage< protobuf::compiler::CodeGeneratorResponse_File >(Arena * )
protobuf::compiler::Version *
Arena::CreateMaybeMessage< protobuf::compiler::Version >(Arena * )
const EnumDescriptor *
GetEnumDescriptor< protobuf::compiler::CodeGeneratorResponse_Feature >()
diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.python_generator.md b/content/reference/cpp/api-docs/google.protobuf.compiler.python_generator.md deleted file mode 100644 index a87811668..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.python_generator.md +++ /dev/null @@ -1,12 +0,0 @@ -+++ -title = "python_generator.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/python/python_generator.h>
namespace google::protobuf::compiler::python

Generates Python code for a given .proto file.

Classes in this file

CodeGenerator implementation for generated Python protocol buffer classes.

class Generator: public CodeGenerator

#include <google/protobuf/compiler/python/python_generator.h>
namespace google::protobuf::compiler::python

CodeGenerator implementation for generated Python protocol buffer classes.

If you create your own protocol compiler binary and you want it to support Python output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.

- -

Members

Generator()
virtual
~Generator()
virtual bool
Generate(const FileDescriptor * file, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
CodeGenerator methods.
virtual uint64_t
GetSupportedFeatures() const
Implement this to indicate what features this code generator supports. more...

virtual uint64_t Generator::GetSupportedFeatures() const

Implement this to indicate what features this code generator supports.

This should be a bitwise OR of features from the Features enum in plugin.proto.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.compiler.ruby_generator.md b/content/reference/cpp/api-docs/google.protobuf.compiler.ruby_generator.md deleted file mode 100644 index ed974126d..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.compiler.ruby_generator.md +++ /dev/null @@ -1,13 +0,0 @@ - - -+++ -title = "ruby_generator.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/compiler/ruby/ruby_generator.h>
namespace google::protobuf::compiler::ruby

Generates Ruby code for a given .proto file.

Classes in this file

CodeGenerator implementation for generated Ruby protocol buffer classes.

class Generator: public CodeGenerator

#include <google/protobuf/compiler/ruby/ruby_generator.h>
namespace google::protobuf::compiler::ruby

CodeGenerator implementation for generated Ruby protocol buffer classes.

If you create your own protocol compiler binary and you want it to support Ruby output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.

- -

Members

diff --git a/content/reference/cpp/api-docs/google.protobuf.descriptor.md b/content/reference/cpp/api-docs/google.protobuf.descriptor.md deleted file mode 100644 index 5a7924fcf..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.descriptor.md +++ /dev/null @@ -1,182 +0,0 @@ -+++ -title = "descriptor.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/descriptor.h>
namespace google::protobuf

This file contains classes which describe a type of protocol message.

You can use a message's descriptor to learn at runtime what fields it contains and what the types of those fields are. The Message interface also allows you to dynamically access and modify individual fields by passing the FieldDescriptor of the field you are interested in.

- -

Most users will not care about descriptors, because they will write code specific to certain protocol types and will simply use the classes generated by the protocol compiler directly. Advanced users who want to operate on arbitrary types (not known at compile time) may want to read descriptors in order to learn about the contents of a message. A very small number of users will want to construct their own Descriptors, either because they are implementing Message manually or because they are writing something like the protocol compiler.

- -

For an example of how you might use descriptors, see the code example at the top of message.h.

- -

Classes in this file

NB, all indices are zero-based.
Options when generating machine-parsable output from a descriptor with DebugString().
Describes a type of protocol message, or a particular group within a message.
A range of field numbers which are designated for third-party extensions.
A range of reserved field numbers.
Describes a single field of a message.
Describes a oneof defined in a message type.
Describes an enum type defined in a .proto file.
A range of reserved field numbers.
Describes an individual enum constant of a particular type.
Describes an RPC service.
Describes an individual service method.
Describes a whole .proto file.
Used to construct descriptors.
When converting a FileDescriptorProto to a FileDescriptor, various errors might be detected in the input.

struct SourceLocation

#include <google/protobuf/descriptor.h>
namespace google::protobuf

NB, all indices are zero-based.

Members

int
start_line
int
end_line
int
start_column
int
end_column
std::string
leading_comments
Doc comments found at the source location. more...
std::string
trailing_comments
std::vector< std::string >
leading_detached_comments

std::string SourceLocation::leading_comments

Doc comments found at the source location.

See the comments in SourceCodeInfo.Location (descriptor.proto) for details.

-

struct DebugStringOptions

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Options when generating machine-parsable output from a descriptor with DebugString().

Members

bool
include_comments
include original user comments as recorded in SourceLocation entries. more...
bool
elide_group_body
If true, elide the braced body in the debug string.
bool
elide_oneof_body
DebugStringOptions()

bool DebugStringOptions::include_comments

include original user comments as recorded in SourceLocation entries.

N.B. that this must be |false| by default: several other pieces of code (for example, the C++ code generation for fields in the proto compiler) rely on DebugString() output being unobstructed by user comments.

-

class Descriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Describes a type of protocol message, or a particular group within a message.

To obtain the Descriptor for a given message object, call Message::GetDescriptor(). Generated message classes also have a static method called descriptor() which returns the type's descriptor. Use DescriptorPool to construct your own descriptors.

-

Members

enum
WellKnownType
typedef
DescriptorProto Proto
const std::string &
name() const
The name of the message type, not including its scope.
const std::string &
full_name() const
The fully-qualified name of the message type, scope delimited by periods. more...
int
index() const
Index of this descriptor within the file or containing type's message type array.
const FileDescriptor *
file() const
The .proto file in which this message type was defined. Never nullptr.
const Descriptor *
containing_type() const
If this Descriptor describes a nested type, this returns the type in which it is nested. more...
const MessageOptions &
options() const
Get options for this message type. more...
void
CopyTo(DescriptorProto * proto) const
Write the contents of this Descriptor into the given DescriptorProto. more...
std::string
DebugString() const
Write the contents of this descriptor in a human-readable form. more...
std::string
DebugStringWithOptions(const DebugStringOptions & options) const
Similar to DebugString(), but additionally takes options (e.g., include original user comments in output).
bool
is_placeholder() const
Returns true if this is a placeholder for an unknown type. more...
WellKnownType
well_known_type() const

Field stuff

int
field_count() const
The number of fields in this message type.
const FieldDescriptor *
field(int index) const
Gets a field by index, where 0 <= index < field_count(). more...
const FieldDescriptor *
FindFieldByNumber(int number) const
Looks up a field by declared tag number. more...
const FieldDescriptor *
FindFieldByName(ConstStringParam name) const
Looks up a field by name. Returns nullptr if no such field exists.
const FieldDescriptor *
FindFieldByLowercaseName(ConstStringParam lowercase_name) const
Looks up a field by lowercased name (as returned by lowercase_name()). more...
const FieldDescriptor *
FindFieldByCamelcaseName(ConstStringParam camelcase_name) const
Looks up a field by camel-case name (as returned by camelcase_name()). more...
int
oneof_decl_count() const
The number of oneofs in this message type.
int
real_oneof_decl_count() const
The number of oneofs in this message type, excluding synthetic oneofs. more...
const OneofDescriptor *
oneof_decl(int index) const
Get a oneof by index, where 0 <= index < oneof_decl_count(). more...
const OneofDescriptor *
FindOneofByName(ConstStringParam name) const
Looks up a oneof by name. Returns nullptr if no such oneof exists.

Nested type stuff

int
nested_type_count() const
The number of nested types in this message type.
const Descriptor *
nested_type(int index) const
Gets a nested type by index, where 0 <= index < nested_type_count(). more...
const Descriptor *
FindNestedTypeByName(ConstStringParam name) const
Looks up a nested type by name. more...

Enum stuff

int
enum_type_count() const
The number of enum types in this message type.
const EnumDescriptor *
enum_type(int index) const
Gets an enum type by index, where 0 <= index < enum_type_count(). more...
const EnumDescriptor *
FindEnumTypeByName(ConstStringParam name) const
Looks up an enum type by name. more...
const EnumValueDescriptor *
FindEnumValueByName(ConstStringParam name) const
Looks up an enum value by name, among all enum types in this message. more...

Extensions

int
extension_range_count() const
The number of extension ranges in this message type.
const ExtensionRange *
extension_range(int index) const
Gets an extension range by index, where 0 <= index < extension_range_count(). more...
bool
IsExtensionNumber(int number) const
Returns true if the number is in one of the extension ranges.
const ExtensionRange *
FindExtensionRangeContainingNumber(int number) const
Returns nullptr if no extension range contains the given number.
int
extension_count() const
The number of extensions defined nested within this message type's scope. more...
const FieldDescriptor *
extension(int index) const
Get an extension by index, where 0 <= index < extension_count(). more...
const FieldDescriptor *
FindExtensionByName(ConstStringParam name) const
Looks up a named extension (which extends some other message type) defined within this message type's scope.
const FieldDescriptor *
FindExtensionByLowercaseName(ConstStringParam name) const
Similar to FindFieldByLowercaseName(), but finds extensions defined within this message type's scope.
const FieldDescriptor *
FindExtensionByCamelcaseName(ConstStringParam name) const
Similar to FindFieldByCamelcaseName(), but finds extensions defined within this message type's scope.

Reserved fields

int
reserved_range_count() const
The number of reserved ranges in this message type.
const ReservedRange *
reserved_range(int index) const
Gets an reserved range by index, where 0 <= index < reserved_range_count(). more...
bool
IsReservedNumber(int number) const
Returns true if the number is in one of the reserved ranges.
const ReservedRange *
FindReservedRangeContainingNumber(int number) const
Returns nullptr if no reserved range contains the given number.
int
reserved_name_count() const
The number of reserved field names in this message type.
const std::string &
reserved_name(int index) const
Gets a reserved name by index, where 0 <= index < reserved_name_count(). more...
bool
IsReservedName(ConstStringParam name) const
Returns true if the field name is reserved.

Source Location

bool
GetSourceLocation(SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of this message declaration. more...

Maps

const FieldDescriptor *
map_key() const
Returns the FieldDescriptor for the "key" field. more...
const FieldDescriptor *
map_value() const
Returns the FieldDescriptor for the "value" field. more...

enum Descriptor::WellKnownType {
  WELLKNOWNTYPE_UNSPECIFIED,
  WELLKNOWNTYPE_DOUBLEVALUE,
  WELLKNOWNTYPE_FLOATVALUE,
  WELLKNOWNTYPE_INT64VALUE,
  WELLKNOWNTYPE_UINT64VALUE,
  WELLKNOWNTYPE_INT32VALUE,
  WELLKNOWNTYPE_UINT32VALUE,
  WELLKNOWNTYPE_STRINGVALUE,
  WELLKNOWNTYPE_BYTESVALUE,
  WELLKNOWNTYPE_BOOLVALUE,
  WELLKNOWNTYPE_ANY,
  WELLKNOWNTYPE_FIELDMASK,
  WELLKNOWNTYPE_DURATION,
  WELLKNOWNTYPE_TIMESTAMP,
  WELLKNOWNTYPE_VALUE,
  WELLKNOWNTYPE_LISTVALUE,
  WELLKNOWNTYPE_STRUCT,
  **WELLKNOWNTYPE**DO_NOT_USE__ADD_DEFAULT_INSTEAD__
}

WELLKNOWNTYPE_UNSPECIFIEDNot a well-known type.
WELLKNOWNTYPE_DOUBLEVALUE

Wrapper types.

google.protobuf.DoubleValue

WELLKNOWNTYPE_FLOATVALUEgoogle.protobuf.FloatValue
WELLKNOWNTYPE_INT64VALUEgoogle.protobuf.Int64Value
WELLKNOWNTYPE_UINT64VALUEgoogle.protobuf.UInt64Value
WELLKNOWNTYPE_INT32VALUEgoogle.protobuf.Int32Value
WELLKNOWNTYPE_UINT32VALUEgoogle.protobuf.UInt32Value
WELLKNOWNTYPE_STRINGVALUEgoogle.protobuf.StringValue
WELLKNOWNTYPE_BYTESVALUEgoogle.protobuf.BytesValue
WELLKNOWNTYPE_BOOLVALUEgoogle.protobuf.BoolValue
WELLKNOWNTYPE_ANY

Other well known types.

google.protobuf.Any

WELLKNOWNTYPE_FIELDMASKgoogle.protobuf.FieldMask
WELLKNOWNTYPE_DURATIONgoogle.protobuf.Duration
WELLKNOWNTYPE_TIMESTAMPgoogle.protobuf.Timestamp
WELLKNOWNTYPE_VALUEgoogle.protobuf.Value
WELLKNOWNTYPE_LISTVALUEgoogle.protobuf.ListValue
WELLKNOWNTYPE_STRUCTgoogle.protobuf.Struct
**WELLKNOWNTYPE**DO_NOT_USE__ADD_DEFAULT_INSTEAD__

New well-known types may be added in the future.

Please make sure any switch() statements have a 'default' case.

-

const std::string &
    Descriptor::full_name() const

The fully-qualified name of the message type, scope delimited by periods.

For example, message type "Foo" which is declared in package "bar" has full name "bar.Foo". If a type "Baz" is nested within Foo, Baz's full_name is "bar.Foo.Baz". To get only the part that comes after the last '.', use name().

-

const Descriptor *
    Descriptor::containing_type() const

If this Descriptor describes a nested type, this returns the type in which it is nested.

Otherwise, returns nullptr.

-

const MessageOptions &
    Descriptor::options() const

Get options for this message type.

These are specified in the .proto file by placing lines like "option foo = 1234;" in the message definition. Allowed options are defined by MessageOptions in descriptor.proto, and any available extensions of that message.

-

void Descriptor::CopyTo(
        DescriptorProto * proto) const

Write the contents of this Descriptor into the given DescriptorProto.

The target DescriptorProto must be clear before calling this; if it isn't, the result may be garbage.

-

std::string Descriptor::DebugString() const

Write the contents of this descriptor in a human-readable form.

Output will be suitable for re-parsing.

-

bool Descriptor::is_placeholder() const

Returns true if this is a placeholder for an unknown type.

This will only be the case if this descriptor comes from a DescriptorPool with AllowUnknownDependencies() set.

-

const FieldDescriptor *
    Descriptor::field(
        int index) const

Gets a field by index, where 0 <= index < field_count().

These are returned in the order they were defined in the .proto file.

-

const FieldDescriptor *
    Descriptor::FindFieldByNumber(
        int number) const

Looks up a field by declared tag number.

Returns nullptr if no such field exists.

-

const FieldDescriptor *
    Descriptor::FindFieldByLowercaseName(
        ConstStringParam lowercase_name) const

Looks up a field by lowercased name (as returned by lowercase_name()).

This lookup may be ambiguous if multiple field names differ only by case, in which case the field returned is chosen arbitrarily from the matches.

-

const FieldDescriptor *
    Descriptor::FindFieldByCamelcaseName(
        ConstStringParam camelcase_name) const

Looks up a field by camel-case name (as returned by camelcase_name()).

This lookup may be ambiguous if multiple field names differ in a way that leads them to have identical camel-case names, in which case the field returned is chosen arbitrarily from the matches.

-

int Descriptor::real_oneof_decl_count() const

The number of oneofs in this message type, excluding synthetic oneofs.

Real oneofs always come first, so iterating up to real_oneof_decl_cout() will yield all real oneofs.

-

const OneofDescriptor *
    Descriptor::oneof_decl(
        int index) const

Get a oneof by index, where 0 <= index < oneof_decl_count().

These are returned in the order they were defined in the .proto file.

-

const Descriptor *
    Descriptor::nested_type(
        int index) const

Gets a nested type by index, where 0 <= index < nested_type_count().

These are returned in the order they were defined in the .proto file.

-

const Descriptor *
    Descriptor::FindNestedTypeByName(
        ConstStringParam name) const

Looks up a nested type by name.

Returns nullptr if no such nested type exists.

-

const EnumDescriptor *
    Descriptor::enum_type(
        int index) const

Gets an enum type by index, where 0 <= index < enum_type_count().

These are returned in the order they were defined in the .proto file.

-

const EnumDescriptor *
    Descriptor::FindEnumTypeByName(
        ConstStringParam name) const

Looks up an enum type by name.

Returns nullptr if no such enum type exists.

-

const EnumValueDescriptor *
    Descriptor::FindEnumValueByName(
        ConstStringParam name) const

Looks up an enum value by name, among all enum types in this message.

Returns nullptr if no such value exists.

-

const ExtensionRange *
    Descriptor::extension_range(
        int index) const

Gets an extension range by index, where 0 <= index < extension_range_count().

These are returned in the order they were defined in the .proto file.

-

int Descriptor::extension_count() const


const FieldDescriptor *
    Descriptor::extension(
        int index) const

Get an extension by index, where 0 <= index < extension_count().

These are returned in the order they were defined in the .proto file.

-

const ReservedRange *
    Descriptor::reserved_range(
        int index) const

Gets an reserved range by index, where 0 <= index < reserved_range_count().

These are returned in the order they were defined in the .proto file.

-

const std::string &
    Descriptor::reserved_name(
        int index) const

Gets a reserved name by index, where 0 <= index < reserved_name_count().

Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because reserved_names_ is actually an array of pointers rather than the usual array of objects.

-

bool Descriptor::GetSourceLocation(
        SourceLocation * out_location) const

Updates |*out_location| to the source location of the complete extent of this message declaration.

Returns false and leaves |*out_location| unchanged iff location information was not available.

-

const FieldDescriptor *
    Descriptor::map_key() const

Returns the FieldDescriptor for the "key" field.

If this isn't a map entry field, returns nullptr.

-

const FieldDescriptor *
    Descriptor::map_value() const

Returns the FieldDescriptor for the "value" field.

If this isn't a map entry field, returns nullptr.

-

struct Descriptor::ExtensionRange

#include <google/protobuf/descriptor.h>
namespace google::protobuf

A range of field numbers which are designated for third-party extensions.

Members

typedef
DescriptorProto_ExtensionRange Proto
typedef
ExtensionRangeOptions OptionsType
int
start
inclusive
int
end
exclusive
const ExtensionRangeOptions *
options_
void
CopyTo(DescriptorProto_ExtensionRange * proto) const

struct Descriptor::ReservedRange

#include <google/protobuf/descriptor.h>
namespace google::protobuf

A range of reserved field numbers.

Members

int
start
inclusive
int
end
exclusive

class FieldDescriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Describes a single field of a message.

To get the descriptor for a given field, first get the Descriptor for the message in which it is defined, then call Descriptor::FindFieldByName(). To get a FieldDescriptor for an extension, do one of the following:

- -

Members

enum
Type
Identifies a field type. more...
enum
CppType
Specifies the C++ data type used to represent the field. more...
enum
Label
Identifies whether the field is optional, required, or repeated. more...
typedef
FieldDescriptorProto Proto
const int
kMaxNumber = = (1 << 29) - 1
Valid field numbers are positive integers up to kMaxNumber.
const int
kFirstReservedNumber = = 19000
First field number reserved for the protocol buffer library implementation. more...
const int
kLastReservedNumber = = 19999
Last field number reserved for the protocol buffer library implementation. more...
int32
default_value_int32_
int64
default_value_int64_
uint32
default_value_uint32_
uint64
default_value_uint64_
float
default_value_float_
double
default_value_double_
bool
default_value_bool_
const EnumValueDescriptor *
default_value_enum_
const std::string *
default_value_string_
std::atomic< const Message * >
default_generated_instance_
const std::string &
name() const
Name of this field within the message.
const std::string &
full_name() const
Fully-qualified name of the field.
const std::string &
json_name() const
JSON name of this field.
const FileDescriptor *
file() const
File in which this field was defined.
bool
is_extension() const
Is this an extension field?
int
number() const
Declared tag number.
const std::string &
lowercase_name() const
Same as name() except converted to lower-case. more...
const std::string &
camelcase_name() const
Same as name() except converted to camel-case. more...
Type
type() const
Declared type of this field.
const char *
type_name() const
Name of the declared type.
CppType
cpp_type() const
C++ type of this field.
const char *
cpp_type_name() const
Name of the C++ type.
Label
label() const
optional/required/repeated
bool
is_required() const
shorthand for label() == LABEL_REQUIRED
bool
is_optional() const
shorthand for label() == LABEL_OPTIONAL
bool
is_repeated() const
shorthand for label() == LABEL_REPEATED
bool
is_packable() const
shorthand for is_repeated() && IsTypePackable(type())
bool
is_packed() const
shorthand for is_packable() && options().packed()
bool
is_map() const
shorthand for type() == TYPE_MESSAGE && message_type()->options().map_entry()
bool
has_optional_keyword() const
Returns true if this field was syntactically written with "optional" in the .proto file. more...
bool
has_presence() const
Returns true if this field tracks presence, ie. more...
int
index() const
Index of this field within the message's field array, or the file or extension scope's extensions array.
bool
has_default_value() const
Does this field have an explicitly-declared default value?
bool
has_json_name() const
Whether the user has specified the json_name field option in the .proto file.
int32
default_value_int32() const
Get the field default value if cpp_type() == CPPTYPE_INT32. more...
int64
default_value_int64() const
Get the field default value if cpp_type() == CPPTYPE_INT64. more...
uint32
default_value_uint32() const
Get the field default value if cpp_type() == CPPTYPE_UINT32. more...
uint64
default_value_uint64() const
Get the field default value if cpp_type() == CPPTYPE_UINT64. more...
float
default_value_float() const
Get the field default value if cpp_type() == CPPTYPE_FLOAT. more...
double
default_value_double() const
Get the field default value if cpp_type() == CPPTYPE_DOUBLE. more...
bool
default_value_bool() const
Get the field default value if cpp_type() == CPPTYPE_BOOL. more...
const EnumValueDescriptor *
default_value_enum() const
Get the field default value if cpp_type() == CPPTYPE_ENUM. more...
const std::string &
default_value_string() const
Get the field default value if cpp_type() == CPPTYPE_STRING. more...
const Descriptor *
containing_type() const
The Descriptor for the message of which this is a field. more...
const OneofDescriptor *
containing_oneof() const
If the field is a member of a oneof, this is the one, otherwise this is nullptr.
const OneofDescriptor *
real_containing_oneof() const
If the field is a member of a non-synthetic oneof, returns the descriptor for the oneof, otherwise returns nullptr.
int
index_in_oneof() const
If the field is a member of a oneof, returns the index in that oneof.
const Descriptor *
extension_scope() const
An extension may be declared within the scope of another message. more...
const Descriptor *
message_type() const
If type is TYPE_MESSAGE or TYPE_GROUP, returns a descriptor for the message or the group type. more...
const EnumDescriptor *
enum_type() const
If type is TYPE_ENUM, returns a descriptor for the enum. more...
const FieldOptions &
options() const
Get the FieldOptions for this field. more...
void
CopyTo(FieldDescriptorProto * proto) const
std::string
DebugString() const
std::string
DebugStringWithOptions(const DebugStringOptions & options) const
const std::string &
PrintableNameForExtension() const
Returns full_name() except if the field is a MessageSet extension, in which case it returns the full_name() of the containing message type for backwards compatibility with proto1. more...
static CppType
TypeToCppType(Type type)
Helper method to get the CppType for a particular Type.
static const char *
TypeName(Type type)
Helper method to get the name of a Type.
static const char *
CppTypeName(CppType cpp_type)
Helper method to get the name of a CppType.
static bool
IsTypePackable(Type field_type)
Return true iff [[]packed = true] is valid for fields of this type.

Source Location

bool
GetSourceLocation(SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of this field declaration. more...

enum FieldDescriptor::Type {
  TYPE_DOUBLE = = 1,
  TYPE_FLOAT = = 2,
  TYPE_INT64 = = 3,
  TYPE_UINT64 = = 4,
  TYPE_INT32 = = 5,
  TYPE_FIXED64 = = 6,
  TYPE_FIXED32 = = 7,
  TYPE_BOOL = = 8,
  TYPE_STRING = = 9,
  TYPE_GROUP = = 10,
  TYPE_MESSAGE = = 11,
  TYPE_BYTES = = 12,
  TYPE_UINT32 = = 13,
  TYPE_ENUM = = 14,
  TYPE_SFIXED32 = = 15,
  TYPE_SFIXED64 = = 16,
  TYPE_SINT32 = = 17,
  TYPE_SINT64 = = 18,
  MAX_TYPE = = 18
}

Identifies a field type.

0 is reserved for errors. The order is weird for historical reasons. Types 12 and up are new in proto2.

-
TYPE_DOUBLEdouble, exactly eight bytes on the wire.
TYPE_FLOATfloat, exactly four bytes on the wire.
TYPE_INT64

int64, varint on the wire.

Negative numbers take 10 bytes. Use TYPE_SINT64 if negative values are likely.

-
TYPE_UINT64uint64, varint on the wire.
TYPE_INT32

int32, varint on the wire.

Negative numbers take 10 bytes. Use TYPE_SINT32 if negative values are likely.

-
TYPE_FIXED64uint64, exactly eight bytes on the wire.
TYPE_FIXED32uint32, exactly four bytes on the wire.
TYPE_BOOLbool, varint on the wire.
TYPE_STRINGUTF-8 text.
TYPE_GROUPTag-delimited message. Deprecated.
TYPE_MESSAGELength-delimited message.
TYPE_BYTESArbitrary byte array.
TYPE_UINT32uint32, varint on the wire
TYPE_ENUMEnum, varint on the wire.
TYPE_SFIXED32int32, exactly four bytes on the wire
TYPE_SFIXED64int64, exactly eight bytes on the wire
TYPE_SINT32int32, ZigZag-encoded varint on the wire
TYPE_SINT64int64, ZigZag-encoded varint on the wire
MAX_TYPEConstant useful for defining lookup tables indexed by Type.

enum FieldDescriptor::CppType {
  CPPTYPE_INT32 = = 1,
  CPPTYPE_INT64 = = 2,
  CPPTYPE_UINT32 = = 3,
  CPPTYPE_UINT64 = = 4,
  CPPTYPE_DOUBLE = = 5,
  CPPTYPE_FLOAT = = 6,
  CPPTYPE_BOOL = = 7,
  CPPTYPE_ENUM = = 8,
  CPPTYPE_STRING = = 9,
  CPPTYPE_MESSAGE = = 10,
  MAX_CPPTYPE = = 10
}

Specifies the C++ data type used to represent the field.

There is a fixed mapping from Type to CppType where each Type maps to exactly one CppType. 0 is reserved for errors.

-
CPPTYPE_INT32TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32.
CPPTYPE_INT64TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64.
CPPTYPE_UINT32TYPE_UINT32, TYPE_FIXED32.
CPPTYPE_UINT64TYPE_UINT64, TYPE_FIXED64.
CPPTYPE_DOUBLETYPE_DOUBLE.
CPPTYPE_FLOATTYPE_FLOAT.
CPPTYPE_BOOLTYPE_BOOL.
CPPTYPE_ENUMTYPE_ENUM.
CPPTYPE_STRINGTYPE_STRING, TYPE_BYTES.
CPPTYPE_MESSAGETYPE_MESSAGE, TYPE_GROUP.
MAX_CPPTYPEConstant useful for defining lookup tables indexed by CppType.

enum FieldDescriptor::Label {
  LABEL_OPTIONAL = = 1,
  LABEL_REQUIRED = = 2,
  LABEL_REPEATED = = 3,
  MAX_LABEL = = 3
}

Identifies whether the field is optional, required, or repeated.

0 is reserved for errors.

-
LABEL_OPTIONALoptional
LABEL_REQUIREDrequired
LABEL_REPEATEDrepeated
MAX_LABELConstant useful for defining lookup tables indexed by Label.

const int FieldDescriptor::kFirstReservedNumber = = 19000

First field number reserved for the protocol buffer library implementation.

Users may not declare fields that use reserved numbers.

-

const int FieldDescriptor::kLastReservedNumber = = 19999

Last field number reserved for the protocol buffer library implementation.

Users may not declare fields that use reserved numbers.

-

const std::string &
    FieldDescriptor::lowercase_name() const

Same as name() except converted to lower-case.

This (and especially the FindFieldByLowercaseName() method) can be useful when parsing formats which prefer to use lowercase naming style. (Although, technically field names should be lowercased anyway according to the protobuf style guide, so this only makes a difference when dealing with old .proto files which do not follow the guide.)

-

const std::string &
    FieldDescriptor::camelcase_name() const

Same as name() except converted to camel-case.

In this conversion, any time an underscore appears in the name, it is removed and the next letter is capitalized. Furthermore, the first letter of the name is lower-cased. Examples:

-
FooBar -> fooBar
-foo_bar -> fooBar
-fooBar -> fooBar
-

This (and especially the FindFieldByCamelcaseName() method) can be useful when parsing formats which prefer to use camel-case naming style.

-

bool FieldDescriptor::has_optional_keyword() const

Returns true if this field was syntactically written with "optional" in the .proto file.

Excludes singular proto3 fields that do not have a label.

-

bool FieldDescriptor::has_presence() const

Returns true if this field tracks presence, ie.

does the field distinguish between "unset" and "present with default value." This includes required, optional, and oneof fields. It excludes maps, repeated fields, and singular proto3 fields without "optional".

-

For fields where has_presence() == true, the return value of Reflection::HasField() is semantically meaningful.

-

int32 FieldDescriptor::default_value_int32() const

Get the field default value if cpp_type() == CPPTYPE_INT32.

If no explicit default was defined, the default is 0.

-

int64 FieldDescriptor::default_value_int64() const

Get the field default value if cpp_type() == CPPTYPE_INT64.

If no explicit default was defined, the default is 0.

-

uint32 FieldDescriptor::default_value_uint32() const

Get the field default value if cpp_type() == CPPTYPE_UINT32.

If no explicit default was defined, the default is 0.

-

uint64 FieldDescriptor::default_value_uint64() const

Get the field default value if cpp_type() == CPPTYPE_UINT64.

If no explicit default was defined, the default is 0.

-

float FieldDescriptor::default_value_float() const

Get the field default value if cpp_type() == CPPTYPE_FLOAT.

If no explicit default was defined, the default is 0.0.

-

double FieldDescriptor::default_value_double() const

Get the field default value if cpp_type() == CPPTYPE_DOUBLE.

If no explicit default was defined, the default is 0.0.

-

bool FieldDescriptor::default_value_bool() const

Get the field default value if cpp_type() == CPPTYPE_BOOL.

If no explicit default was defined, the default is false.

-

const EnumValueDescriptor *
    FieldDescriptor::default_value_enum() const

Get the field default value if cpp_type() == CPPTYPE_ENUM.

If no explicit default was defined, the default is the first value defined in the enum type (all enum types are required to have at least one value). This never returns nullptr.

-

const std::string &
    FieldDescriptor::default_value_string() const

Get the field default value if cpp_type() == CPPTYPE_STRING.

If no explicit default was defined, the default is the empty string.

-

const Descriptor *
    FieldDescriptor::containing_type() const

The Descriptor for the message of which this is a field.

For extensions, this is the extended type. Never nullptr.

-

const Descriptor *
    FieldDescriptor::extension_scope() const

An extension may be declared within the scope of another message.

If this field is an extension (is_extension() is true), then extension_scope() returns that message, or nullptr if the extension was declared at global scope. If this is not an extension, extension_scope() is undefined (may assert-fail).

-

const Descriptor *
    FieldDescriptor::message_type() const

If type is TYPE_MESSAGE or TYPE_GROUP, returns a descriptor for the message or the group type.

Otherwise, returns null.

-

const EnumDescriptor *
    FieldDescriptor::enum_type() const

If type is TYPE_ENUM, returns a descriptor for the enum.

Otherwise, returns null.

-

const FieldOptions &
    FieldDescriptor::options() const

Get the FieldOptions for this field.

This includes things listed in square brackets after the field definition. E.g., the field:

-
optional string text = 1 [[]ctype=CORD];
-

has the "ctype" option set. Allowed options are defined by FieldOptions in descriptor.proto, and any available extensions of that message.

-

const std::string &
    FieldDescriptor::PrintableNameForExtension() const

Returns full_name() except if the field is a MessageSet extension, in which case it returns the full_name() of the containing message type for backwards compatibility with proto1.

A MessageSet extension is defined as an optional message extension whose containing type has the message_set_wire_format option set. This should be true of extensions of google.protobuf.bridge.MessageSet; by convention, such extensions are named "message_set_extension".

-

The opposite operation (looking up an extension's FieldDescriptor given its printable name) can be accomplished with

-
message->file()->pool()->FindExtensionByPrintableName(message, name)
-

where the extension extends "message".

-

bool FieldDescriptor::GetSourceLocation(
        SourceLocation * out_location) const

Updates |*out_location| to the source location of the complete extent of this field declaration.

Returns false and leaves |*out_location| unchanged iff location information was not available.

-

class OneofDescriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Describes a oneof defined in a message type.

Members

typedef
OneofDescriptorProto Proto
const std::string &
name() const
Name of this oneof.
const std::string &
full_name() const
Fully-qualified name of the oneof.
int
index() const
Index of this oneof within the message's oneof array.
bool
is_synthetic() const
Returns whether this oneof was inserted by the compiler to wrap a proto3 optional field. more...
const FileDescriptor *
file() const
The .proto file in which this oneof was defined. Never nullptr.
const Descriptor *
containing_type() const
The Descriptor for the message containing this oneof.
int
field_count() const
The number of (non-extension) fields which are members of this oneof.
const FieldDescriptor *
field(int index) const
Get a member of this oneof, in the order in which they were declared in the .proto file. more...
const OneofOptions &
options() const
void
CopyTo(OneofDescriptorProto * proto) const
std::string
DebugString() const
std::string
DebugStringWithOptions(const DebugStringOptions & options) const

Source Location

bool
GetSourceLocation(SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of this oneof declaration. more...

bool OneofDescriptor::is_synthetic() const

Returns whether this oneof was inserted by the compiler to wrap a proto3 optional field.

If this returns true, code generators should not emit it.

-

const FieldDescriptor *
    OneofDescriptor::field(
        int index) const

Get a member of this oneof, in the order in which they were declared in the .proto file.

Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because fields_ is actually an array of pointers rather than the usual array of objects.

-

Does not include extensions.

-

bool OneofDescriptor::GetSourceLocation(
        SourceLocation * out_location) const

Updates |*out_location| to the source location of the complete extent of this oneof declaration.

Returns false and leaves |*out_location| unchanged iff location information was not available.

-

class EnumDescriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Describes an enum type defined in a .proto file.

To get the EnumDescriptor for a generated enum type, call TypeName_descriptor(). Use DescriptorPool to construct your own descriptors.

-

Members

typedef
EnumDescriptorProto Proto
const std::string &
name() const
The name of this enum type in the containing scope.
const std::string &
full_name() const
The fully-qualified name of the enum type, scope delimited by periods.
int
index() const
Index of this enum within the file or containing message's enum array.
const FileDescriptor *
file() const
The .proto file in which this enum type was defined. Never nullptr.
int
value_count() const
The number of values for this EnumDescriptor. more...
const EnumValueDescriptor *
value(int index) const
Gets a value by index, where 0 <= index < value_count(). more...
const EnumValueDescriptor *
FindValueByName(ConstStringParam name) const
Looks up a value by name. Returns nullptr if no such value exists.
const EnumValueDescriptor *
FindValueByNumber(int number) const
Looks up a value by number. more...
const Descriptor *
containing_type() const
If this enum type is nested in a message type, this is that message type. more...
const EnumOptions &
options() const
Get options for this enum type. more...
void
CopyTo(EnumDescriptorProto * proto) const
std::string
DebugString() const
std::string
DebugStringWithOptions(const DebugStringOptions & options) const
bool
is_placeholder() const
Returns true if this is a placeholder for an unknown enum. more...

Reserved fields

int
reserved_range_count() const
The number of reserved ranges in this message type.
const EnumDescriptor::ReservedRange *
reserved_range(int index) const
Gets an reserved range by index, where 0 <= index < reserved_range_count(). more...
bool
IsReservedNumber(int number) const
Returns true if the number is in one of the reserved ranges.
const EnumDescriptor::ReservedRange *
FindReservedRangeContainingNumber(int number) const
Returns nullptr if no reserved range contains the given number.
int
reserved_name_count() const
The number of reserved field names in this message type.
const std::string &
reserved_name(int index) const
Gets a reserved name by index, where 0 <= index < reserved_name_count(). more...
bool
IsReservedName(ConstStringParam name) const
Returns true if the field name is reserved.

Source Location

bool
GetSourceLocation(SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of this enum declaration. more...

int EnumDescriptor::value_count() const

The number of values for this EnumDescriptor.

Guaranteed to be greater than zero.

-

const EnumValueDescriptor *
    EnumDescriptor::value(
        int index) const

Gets a value by index, where 0 <= index < value_count().

These are returned in the order they were defined in the .proto file.

-

const EnumValueDescriptor *
    EnumDescriptor::FindValueByNumber(
        int number) const

Looks up a value by number.

Returns nullptr if no such value exists. If multiple values have this number, the first one defined is returned.

-

const Descriptor *
    EnumDescriptor::containing_type() const

If this enum type is nested in a message type, this is that message type.

Otherwise, nullptr.

-

const EnumOptions &
    EnumDescriptor::options() const

Get options for this enum type.

These are specified in the .proto file by placing lines like "option foo = 1234;" in the enum definition. Allowed options are defined by EnumOptions in descriptor.proto, and any available extensions of that message.

-

bool EnumDescriptor::is_placeholder() const

Returns true if this is a placeholder for an unknown enum.

This will only be the case if this descriptor comes from a DescriptorPool with AllowUnknownDependencies() set.

-

const EnumDescriptor::ReservedRange *
    EnumDescriptor::reserved_range(
        int index) const

Gets an reserved range by index, where 0 <= index < reserved_range_count().

These are returned in the order they were defined in the .proto file.

-

const std::string &
    EnumDescriptor::reserved_name(
        int index) const

Gets a reserved name by index, where 0 <= index < reserved_name_count().

Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because reserved_names_ is actually an array of pointers rather than the usual array of objects.

-

bool EnumDescriptor::GetSourceLocation(
        SourceLocation * out_location) const

Updates |*out_location| to the source location of the complete extent of this enum declaration.

Returns false and leaves |*out_location| unchanged iff location information was not available.

-

struct EnumDescriptor::ReservedRange

#include <google/protobuf/descriptor.h>
namespace google::protobuf

A range of reserved field numbers.

Members

int
start
inclusive
int
end
inclusive

class EnumValueDescriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Describes an individual enum constant of a particular type.

To get the EnumValueDescriptor for a given enum value, first get the EnumDescriptor for its type, then use EnumDescriptor::FindValueByName() or EnumDescriptor::FindValueByNumber(). Use DescriptorPool to construct your own descriptors.

-

Members

typedef
EnumValueDescriptorProto Proto
const std::string &
name() const
Name of this enum constant.
int
index() const
Index within the enums's Descriptor.
int
number() const
Numeric value of this enum constant.
const std::string &
full_name() const
The full_name of an enum value is a sibling symbol of the enum type. more...
const FileDescriptor *
file() const
The .proto file in which this value was defined. Never nullptr.
const EnumDescriptor *
type() const
The type of this value. Never nullptr.
const EnumValueOptions &
options() const
Get options for this enum value. more...
void
CopyTo(EnumValueDescriptorProto * proto) const
std::string
DebugString() const
std::string
DebugStringWithOptions(const DebugStringOptions & options) const

Source Location

bool
GetSourceLocation(SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of this enum value declaration. more...

const std::string &
    EnumValueDescriptor::full_name() const

The full_name of an enum value is a sibling symbol of the enum type.

e.g. the full name of FieldDescriptorProto::TYPE_INT32 is actually "google.protobuf.FieldDescriptorProto.TYPE_INT32", NOT "google.protobuf.FieldDescriptorProto.Type.TYPE_INT32". This is to conform with C++ scoping rules for enums.

-

const EnumValueOptions &
    EnumValueDescriptor::options() const

Get options for this enum value.

These are specified in the .proto file by adding text like "[[]foo = 1234]" after an enum value definition. Allowed options are defined by EnumValueOptions in descriptor.proto, and any available extensions of that message.

-

bool EnumValueDescriptor::GetSourceLocation(
        SourceLocation * out_location) const

Updates |*out_location| to the source location of the complete extent of this enum value declaration.

Returns false and leaves |*out_location| unchanged iff location information was not available.

-

class ServiceDescriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Describes an RPC service.

Use DescriptorPool to construct your own descriptors.

-

Members

typedef
ServiceDescriptorProto Proto
const std::string &
name() const
The name of the service, not including its containing scope.
const std::string &
full_name() const
The fully-qualified name of the service, scope delimited by periods.
int
index() const
Index of this service within the file's services array.
const FileDescriptor *
file() const
The .proto file in which this service was defined. Never nullptr.
const ServiceOptions &
options() const
Get options for this service type. more...
int
method_count() const
The number of methods this service defines.
const MethodDescriptor *
method(int index) const
Gets a MethodDescriptor by index, where 0 <= index < method_count(). more...
const MethodDescriptor *
FindMethodByName(ConstStringParam name) const
Look up a MethodDescriptor by name.
void
CopyTo(ServiceDescriptorProto * proto) const
std::string
DebugString() const
std::string
DebugStringWithOptions(const DebugStringOptions & options) const

Source Location

bool
GetSourceLocation(SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of this service declaration. more...

const ServiceOptions &
    ServiceDescriptor::options() const

Get options for this service type.

These are specified in the .proto file by placing lines like "option foo = 1234;" in the service definition. Allowed options are defined by ServiceOptions in descriptor.proto, and any available extensions of that message.

-

const MethodDescriptor *
    ServiceDescriptor::method(
        int index) const

Gets a MethodDescriptor by index, where 0 <= index < method_count().

These are returned in the order they were defined in the .proto file.

-

bool ServiceDescriptor::GetSourceLocation(
        SourceLocation * out_location) const

Updates |*out_location| to the source location of the complete extent of this service declaration.

Returns false and leaves |*out_location| unchanged iff location information was not available.

-

class MethodDescriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Describes an individual service method.

To obtain a MethodDescriptor given a service, first get its ServiceDescriptor, then call ServiceDescriptor::FindMethodByName(). Use DescriptorPool to construct your own descriptors.

-

Members

typedef
MethodDescriptorProto Proto
const std::string &
name() const
Name of this method, not including containing scope.
const std::string &
full_name() const
The fully-qualified name of the method, scope delimited by periods.
int
index() const
Index within the service's Descriptor.
const FileDescriptor *
file() const
The .proto file in which this method was defined. Never nullptr.
const ServiceDescriptor *
service() const
Gets the service to which this method belongs. Never nullptr.
const Descriptor *
input_type() const
Gets the type of protocol message which this method accepts as input.
const Descriptor *
output_type() const
Gets the type of protocol message which this message produces as output.
bool
client_streaming() const
Gets whether the client streams multiple requests.
bool
server_streaming() const
Gets whether the server streams multiple responses.
const MethodOptions &
options() const
Get options for this method. more...
void
CopyTo(MethodDescriptorProto * proto) const
std::string
DebugString() const
std::string
DebugStringWithOptions(const DebugStringOptions & options) const

Source Location

bool
GetSourceLocation(SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of this method declaration. more...

const MethodOptions &
    MethodDescriptor::options() const

Get options for this method.

These are specified in the .proto file by placing lines like "option foo = 1234;" in curly-braces after a method declaration. Allowed options are defined by MethodOptions in descriptor.proto, and any available extensions of that message.

-

bool MethodDescriptor::GetSourceLocation(
        SourceLocation * out_location) const

Updates |*out_location| to the source location of the complete extent of this method declaration.

Returns false and leaves |*out_location| unchanged iff location information was not available.

-

class FileDescriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Describes a whole .proto file.

To get the FileDescriptor for a compiled-in file, get the descriptor for something defined in that file and call descriptor->file(). Use DescriptorPool to construct your own descriptors.

-

Members

enum
Syntax
Syntax of this file. more...
typedef
FileDescriptorProto Proto
const std::string &
name() const
The filename, relative to the source tree. more...
const std::string &
package() const
The package, e.g. "google.protobuf.compiler".
const DescriptorPool *
pool() const
The DescriptorPool in which this FileDescriptor and all its contents were allocated. more...
int
dependency_count() const
The number of files imported by this one.
const FileDescriptor *
dependency(int index) const
Gets an imported file by index, where 0 <= index < dependency_count(). more...
int
public_dependency_count() const
The number of files public imported by this one. more...
const FileDescriptor *
public_dependency(int index) const
Gets a public imported file by index, where 0 <= index < public_dependency_count(). more...
int
weak_dependency_count() const
The number of files that are imported for weak fields. more...
const FileDescriptor *
weak_dependency(int index) const
Gets a weak imported file by index, where 0 <= index < weak_dependency_count(). more...
int
message_type_count() const
Number of top-level message types defined in this file. more...
const Descriptor *
message_type(int index) const
Gets a top-level message type, where 0 <= index < message_type_count(). more...
int
enum_type_count() const
Number of top-level enum types defined in this file. more...
const EnumDescriptor *
enum_type(int index) const
Gets a top-level enum type, where 0 <= index < enum_type_count(). more...
int
service_count() const
Number of services defined in this file.
const ServiceDescriptor *
service(int index) const
Gets a service, where 0 <= index < service_count(). more...
int
extension_count() const
Number of extensions defined at file scope. more...
const FieldDescriptor *
extension(int index) const
Gets an extension's descriptor, where 0 <= index < extension_count(). more...
const FileOptions &
options() const
Get options for this file. more...
Syntax
syntax() const
const Descriptor *
FindMessageTypeByName(ConstStringParam name) const
Find a top-level message type by name (not full_name). more...
const EnumDescriptor *
FindEnumTypeByName(ConstStringParam name) const
Find a top-level enum type by name. Returns nullptr if not found.
const EnumValueDescriptor *
FindEnumValueByName(ConstStringParam name) const
Find an enum value defined in any top-level enum by name. more...
const ServiceDescriptor *
FindServiceByName(ConstStringParam name) const
Find a service definition by name. Returns nullptr if not found.
const FieldDescriptor *
FindExtensionByName(ConstStringParam name) const
Find a top-level extension definition by name. more...
const FieldDescriptor *
FindExtensionByLowercaseName(ConstStringParam name) const
Similar to FindExtensionByName(), but searches by lowercased-name. more...
const FieldDescriptor *
FindExtensionByCamelcaseName(ConstStringParam name) const
Similar to FindExtensionByName(), but searches by camelcased-name. more...
void
CopyTo(FileDescriptorProto * proto) const
void
CopySourceCodeInfoTo(FileDescriptorProto * proto) const
Write the source code information of this FileDescriptor into the given FileDescriptorProto. more...
void
CopyJsonNameTo(FileDescriptorProto * proto) const
Fill the json_name field of FieldDescriptorProto for all fields. more...
std::string
DebugString() const
std::string
DebugStringWithOptions(const DebugStringOptions & options) const
bool
is_placeholder() const
Returns true if this is a placeholder for an unknown file. more...
bool
GetSourceLocation(SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of this file declaration (namely, the empty path).
bool
GetSourceLocation(const std::vector< int > & path, SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of the declaration or declaration-part denoted by |path|. more...
static const char *
SyntaxName(Syntax syntax)

enum FileDescriptor::Syntax {
  SYNTAX_UNKNOWN = = 0,
  SYNTAX_PROTO2 = = 2,
  SYNTAX_PROTO3 = = 3
}

Syntax of this file.

SYNTAX_UNKNOWN
SYNTAX_PROTO2
SYNTAX_PROTO3

const std::string &
    FileDescriptor::name() const

The filename, relative to the source tree.

e.g. "foo/bar/baz.proto"

-

const DescriptorPool *
    FileDescriptor::pool() const

The DescriptorPool in which this FileDescriptor and all its contents were allocated.

Never nullptr.

-

const FileDescriptor *
    FileDescriptor::dependency(
        int index) const

Gets an imported file by index, where 0 <= index < dependency_count().

These are returned in the order they were defined in the .proto file.

-

int FileDescriptor::public_dependency_count() const

The number of files public imported by this one.

The public dependency list is a subset of the dependency list.

-

const FileDescriptor *
    FileDescriptor::public_dependency(
        int index) const

Gets a public imported file by index, where 0 <= index < public_dependency_count().

These are returned in the order they were defined in the .proto file.

-

int FileDescriptor::weak_dependency_count() const

The number of files that are imported for weak fields.

The weak dependency list is a subset of the dependency list.

-

const FileDescriptor *
    FileDescriptor::weak_dependency(
        int index) const

Gets a weak imported file by index, where 0 <= index < weak_dependency_count().

These are returned in the order they were defined in the .proto file.

-

int FileDescriptor::message_type_count() const

Number of top-level message types defined in this file.

(This does not include nested types.)

-

const Descriptor *
    FileDescriptor::message_type(
        int index) const

Gets a top-level message type, where 0 <= index < message_type_count().

These are returned in the order they were defined in the .proto file.

-

int FileDescriptor::enum_type_count() const

Number of top-level enum types defined in this file.

(This does not include nested types.)

-

const EnumDescriptor *
    FileDescriptor::enum_type(
        int index) const

Gets a top-level enum type, where 0 <= index < enum_type_count().

These are returned in the order they were defined in the .proto file.

-

const ServiceDescriptor *
    FileDescriptor::service(
        int index) const

Gets a service, where 0 <= index < service_count().

These are returned in the order they were defined in the .proto file.

-

int FileDescriptor::extension_count() const

Number of extensions defined at file scope.

(This does not include extensions nested within message types.)

-

const FieldDescriptor *
    FileDescriptor::extension(
        int index) const

Gets an extension's descriptor, where 0 <= index < extension_count().

These are returned in the order they were defined in the .proto file.

-

const FileOptions &
    FileDescriptor::options() const

Get options for this file.

These are specified in the .proto file by placing lines like "option foo = 1234;" at the top level, outside of any other definitions. Allowed options are defined by FileOptions in descriptor.proto, and any available extensions of that message.

-

const Descriptor *
    FileDescriptor::FindMessageTypeByName(
        ConstStringParam name) const

Find a top-level message type by name (not full_name).

Returns nullptr if not found.

-

const EnumValueDescriptor *
    FileDescriptor::FindEnumValueByName(
        ConstStringParam name) const

Find an enum value defined in any top-level enum by name.

Returns nullptr if not found.

-

const FieldDescriptor *
    FileDescriptor::FindExtensionByName(
        ConstStringParam name) const

Find a top-level extension definition by name.

Returns nullptr if not found.

-

const FieldDescriptor *
    FileDescriptor::FindExtensionByLowercaseName(
        ConstStringParam name) const

Similar to FindExtensionByName(), but searches by lowercased-name.

See Descriptor::FindFieldByLowercaseName().

-

const FieldDescriptor *
    FileDescriptor::FindExtensionByCamelcaseName(
        ConstStringParam name) const

Similar to FindExtensionByName(), but searches by camelcased-name.

See Descriptor::FindFieldByCamelcaseName().

-

void FileDescriptor::CopyTo(
        FileDescriptorProto * proto) const

See Descriptor::CopyTo().

Notes:

-
    -
  • This method does NOT copy source code information since it is relatively large and rarely needed. See CopySourceCodeInfoTo() below.
  • -
-

void FileDescriptor::CopySourceCodeInfoTo(
        FileDescriptorProto * proto) const

Write the source code information of this FileDescriptor into the given FileDescriptorProto.

See CopyTo() above.

-

void FileDescriptor::CopyJsonNameTo(
        FileDescriptorProto * proto) const

Fill the json_name field of FieldDescriptorProto for all fields.

Can only be called after CopyTo().

-

bool FileDescriptor::is_placeholder() const

Returns true if this is a placeholder for an unknown file.

This will only be the case if this descriptor comes from a DescriptorPool with AllowUnknownDependencies() set.

-

bool FileDescriptor::GetSourceLocation(
        const std::vector< int > & path,
        SourceLocation * out_location) const

Updates |*out_location| to the source location of the complete extent of the declaration or declaration-part denoted by |path|.

Returns false and leaves |*out_location| unchanged iff location information was not available. (See SourceCodeInfo for description of path encoding.)

-

class DescriptorPool

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Used to construct descriptors.

Normally you won't want to build your own descriptors. Message classes constructed by the protocol compiler will provide them for you. However, if you are implementing Message on your own, or if you are writing a program which can operate on totally arbitrary types and needs to load them from some sort of database, you might need to.

-

Since Descriptors are composed of a whole lot of cross-linked bits of data that would be a pain to put together manually, the DescriptorPool class is provided to make the process easier. It can take a FileDescriptorProto (defined in descriptor.proto), validate it, and convert it to a set of nicely cross-linked Descriptors.

-

DescriptorPool also helps with memory management. Descriptors are composed of many objects containing static data and pointers to each other. In all likelihood, when it comes time to delete this data, you'll want to delete it all at once. In fact, it is not uncommon to have a whole pool of descriptors all cross-linked with each other which you wish to delete all at once. This class represents such a pool, and handles the memory management for you.

-

You can also search for descriptors within a DescriptorPool by name, and extensions by number.

-

Members

DescriptorPool()
Create a normal, empty DescriptorPool.
explicit
DescriptorPool(DescriptorDatabase * fallback_database, ErrorCollector * error_collector = nullptr)
~DescriptorPool()
const FileDescriptor *
FindFileByName(ConstStringParam name) const
Find a FileDescriptor in the pool by file name. more...
const FileDescriptor *
FindFileContainingSymbol(ConstStringParam symbol_name) const
Find the FileDescriptor in the pool which defines the given symbol. more...
static const DescriptorPool *
generated_pool()
Get a pointer to the generated pool. more...

Looking up descriptors

These find descriptors by fully-qualified name. These will find both top-level descriptors and nested descriptors. They return nullptr if not found.
const Descriptor *
FindMessageTypeByName(ConstStringParam name) const
const FieldDescriptor *
FindFieldByName(ConstStringParam name) const
const FieldDescriptor *
FindExtensionByName(ConstStringParam name) const
const OneofDescriptor *
FindOneofByName(ConstStringParam name) const
const EnumDescriptor *
FindEnumTypeByName(ConstStringParam name) const
const EnumValueDescriptor *
FindEnumValueByName(ConstStringParam name) const
const ServiceDescriptor *
FindServiceByName(ConstStringParam name) const
const MethodDescriptor *
FindMethodByName(ConstStringParam name) const
const FieldDescriptor *
FindExtensionByNumber(const Descriptor * extendee, int number) const
Finds an extension of the given type by number. more...
const FieldDescriptor *
FindExtensionByPrintableName(const Descriptor * extendee, ConstStringParam printable_name) const
Finds an extension of the given type by its printable name. more...
void
FindAllExtensions(const Descriptor * extendee, std::vector< const FieldDescriptor * > * out) const
Finds extensions of extendee. more...

Building descriptors

const FileDescriptor *
BuildFile(const FileDescriptorProto & proto)
Convert the FileDescriptorProto to real descriptors and place them in this DescriptorPool. more...
const FileDescriptor *
BuildFileCollectingErrors(const FileDescriptorProto & proto, ErrorCollector * error_collector)
Same as BuildFile() except errors are sent to the given ErrorCollector.
void
AllowUnknownDependencies()
By default, it is an error if a FileDescriptorProto contains references to types or other files that are not found in the DescriptorPool (or its backing DescriptorDatabase, if any). more...
void
EnforceWeakDependencies(bool enforce)
By default, weak imports are allowed to be missing, in which case we will use a placeholder for the dependency and convert the field to be an Empty message field. more...

Internal stuff

-

These methods MUST NOT be called from outside the proto2 library.

-

These methods may contain hidden pitfalls and may be removed in a future library version.

-
explicit
DescriptorPool(const DescriptorPool * underlay)
Create a DescriptorPool which is overlaid on top of some other pool. more...
void
DisallowEnforceUtf8()
Disallow [[]enforce_utf8 = false] in .proto files.
void
InternalDontEnforceDependencies()
For internal use only: Changes the behavior of BuildFile() such that it allows the file to make reference to message types declared in other files which it did not officially declare as dependencies.
void
InternalSetLazilyBuildDependencies()
For internal use only: Enables lazy building of dependencies of a file. more...
void
internal_set_underlay(const DescriptorPool * underlay)
For internal use only.
bool
InternalIsFileLoaded(ConstStringParam filename) const
For internal (unit test) use only: Returns true if a FileDescriptor has been constructed for the given file, false otherwise. more...
void
AddUnusedImportTrackFile(ConstStringParam file_name, bool is_error = false)
Add a file to unused_import_track_files_. more...
void
ClearUnusedImportTrackFiles()
static void
InternalAddGeneratedFile(const void * encoded_file_descriptor, int size)
Called by generated classes at init time to add their descriptors to generated_pool. more...
static DescriptorPool *
internal_generated_pool()
For internal use only: Gets a non-const pointer to the generated pool. more...
static DescriptorDatabase *
internal_generated_database()
For internal use only: Gets a non-const pointer to the generated descriptor database. more...

const FileDescriptor *
    DescriptorPool::FindFileByName(
        ConstStringParam name) const

Find a FileDescriptor in the pool by file name.

Returns nullptr if not found.

-

const FileDescriptor *
    DescriptorPool::FindFileContainingSymbol(
        ConstStringParam symbol_name) const

Find the FileDescriptor in the pool which defines the given symbol.

If any of the Find*ByName() methods below would succeed, then this is equivalent to calling that method and calling the result's file() method. Otherwise this returns nullptr.

-

static const DescriptorPool *
    DescriptorPool::generated_pool()

Get a pointer to the generated pool.

Generated protocol message classes which are compiled into the binary will allocate their descriptors in this pool. Do not add your own descriptors to this pool.

-

const FieldDescriptor *
    DescriptorPool::FindExtensionByNumber(
        const Descriptor * extendee,
        int number) const

Finds an extension of the given type by number.

The extendee must be a member of this DescriptorPool or one of its underlays.

-

const FieldDescriptor *
    DescriptorPool::FindExtensionByPrintableName(
        const Descriptor * extendee,
        ConstStringParam printable_name) const

Finds an extension of the given type by its printable name.

See comments above PrintableNameForExtension() for the definition of "printable name". The extendee must be a member of this DescriptorPool or one of its underlays. Returns nullptr if there is no known message extension with the given printable name.

-

void DescriptorPool::FindAllExtensions(
        const Descriptor * extendee,
        std::vector< const FieldDescriptor * > * out) const

Finds extensions of extendee.

The extensions will be appended to out in an undefined order. Only extensions defined directly in this DescriptorPool or one of its underlays are guaranteed to be found: extensions defined in the fallback database might not be found depending on the database implementation.

-

const FileDescriptor *
    DescriptorPool::BuildFile(
        const FileDescriptorProto & proto)

Convert the FileDescriptorProto to real descriptors and place them in this DescriptorPool.

All dependencies of the file must already be in the pool. Returns the resulting FileDescriptor, or nullptr if there were problems with the input (e.g. the message was invalid, or dependencies were missing). Details about the errors are written to GOOGLE_LOG(ERROR).

-

void DescriptorPool::AllowUnknownDependencies()

By default, it is an error if a FileDescriptorProto contains references to types or other files that are not found in the DescriptorPool (or its backing DescriptorDatabase, if any).

If you call AllowUnknownDependencies(), however, then unknown types and files will be replaced by placeholder descriptors (which can be identified by the is_placeholder() method). This can allow you to perform some useful operations with a .proto file even if you do not have access to other .proto files on which it depends. However, some heuristics must be used to fill in the gaps in information, and these can lead to descriptors which are inaccurate. For example, the DescriptorPool may be forced to guess whether an unknown type is a message or an enum, as well as what package it resides in. Furthermore, placeholder types will not be discoverable via FindMessageTypeByName() and similar methods, which could confuse some descriptor-based algorithms. Generally, the results of this option should be handled with extreme care.

-

void DescriptorPool::EnforceWeakDependencies(
        bool enforce)

By default, weak imports are allowed to be missing, in which case we will use a placeholder for the dependency and convert the field to be an Empty message field.

If you call EnforceWeakDependencies(true), however, the DescriptorPool will report a import not found error.

-

explicit DescriptorPool::DescriptorPool(
        const DescriptorPool * underlay)

Create a DescriptorPool which is overlaid on top of some other pool.

If you search for a descriptor in the overlay and it is not found, the underlay will be searched as a backup. If the underlay has its own underlay, that will be searched next, and so on. This also means that files built in the overlay will be cross-linked with the underlay's descriptors if necessary. The underlay remains property of the caller; it must remain valid for the lifetime of the newly-constructed pool.

-

Example: Say you want to parse a .proto file at runtime in order to use its type with a DynamicMessage. Say this .proto file has dependencies, but you know that all the dependencies will be things that are already compiled into the binary. For ease of use, you'd like to load the types right out of generated_pool() rather than have to parse redundant copies of all these .protos and runtime. But, you don't want to add the parsed types directly into generated_pool(): this is not allowed, and would be bad design anyway. So, instead, you could use generated_pool() as an underlay for a new DescriptorPool in which you add only the new file.

-

WARNING: Use of underlays can lead to many subtle gotchas. Instead, try to formulate what you want to do in terms of DescriptorDatabases.

-

void DescriptorPool::InternalSetLazilyBuildDependencies()

For internal use only: Enables lazy building of dependencies of a file.

Delay the building of dependencies of a file descriptor until absolutely necessary, like when message_type() is called on a field that is defined in that dependency's file. This will cause functional issues if a proto or one of its dependencies has errors. Should only be enabled for the generated_pool_ (because no descriptor build errors are guaranteed by the compilation generation process), testing, or if a lack of descriptor build errors can be guaranteed for a pool.

-

bool DescriptorPool::InternalIsFileLoaded(
        ConstStringParam filename) const

For internal (unit test) use only: Returns true if a FileDescriptor has been constructed for the given file, false otherwise.

Useful for testing lazy descriptor initialization behavior.

-

void DescriptorPool::AddUnusedImportTrackFile(
        ConstStringParam file_name,
        bool is_error = false)

Add a file to unused_import_track_files_.

DescriptorBuilder will log warnings or errors for those files if there is any unused import.

-

static void DescriptorPool::InternalAddGeneratedFile(
        const void * encoded_file_descriptor,
        int size)

Called by generated classes at init time to add their descriptors to generated_pool.

Do NOT call this in your own code! filename must be a permanent string (e.g. a string literal).

-

static DescriptorPool * DescriptorPool::internal_generated_pool()

For internal use only: Gets a non-const pointer to the generated pool.

This is called at static-initialization time only, so thread-safety is not a concern. If both an underlay and a fallback database are present, the underlay takes precedence.

-

static DescriptorDatabase *
    DescriptorPool::internal_generated_database()

For internal use only: Gets a non-const pointer to the generated descriptor database.

Only used for testing.

-

class DescriptorPool::ErrorCollector

#include <google/protobuf/descriptor.h>
namespace google::protobuf

When converting a FileDescriptorProto to a FileDescriptor, various errors might be detected in the input.

The caller may handle these programmatically by implementing an ErrorCollector.

-

Members

enum
ErrorLocation
These constants specify what exact part of the construct is broken. more...
ErrorCollector()
virtual
~ErrorCollector()
virtual void
AddError(const std::string & filename, const std::string & element_name, const Message * descriptor, ErrorLocation location, const std::string & message) = 0
Reports an error in the FileDescriptorProto. more...
virtual void
AddWarning(const std::string & , const std::string & , const Message * , ErrorLocation , const std::string & )
Reports a warning in the FileDescriptorProto. more...

enum ErrorCollector::ErrorLocation {
  NAME,
  NUMBER,
  TYPE,
  EXTENDEE,
  DEFAULT_VALUE,
  INPUT_TYPE,
  OUTPUT_TYPE,
  OPTION_NAME,
  OPTION_VALUE,
  IMPORT,
  OTHER
}

These constants specify what exact part of the construct is broken.

This is useful e.g. for mapping the error back to an exact location in a .proto file.

-
NAMEthe symbol name, or the package name for files
NUMBERfield or extension range number
TYPEfield type
EXTENDEEfield extendee
DEFAULT_VALUEfield default value
INPUT_TYPEmethod input type
OUTPUT_TYPEmethod output type
OPTION_NAMEname in assignment
OPTION_VALUEvalue in option assignment
IMPORTimport error
OTHERsome other problem

virtual void ErrorCollector::AddError(
        const std::string & filename,
        const std::string & element_name,
        const Message * descriptor,
        ErrorLocation location,
        const std::string & message) = 0

Reports an error in the FileDescriptorProto.

Use this function if the problem occurred should interrupt building the FileDescriptorProto.

-

virtual void ErrorCollector::AddWarning(
        const std::string & ,
        const std::string & ,
        const Message * ,
        ErrorLocation ,
        const std::string & )

Reports a warning in the FileDescriptorProto.

Use this function if the problem occurred should NOT interrupt building the FileDescriptorProto.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.descriptor.pb.md b/content/reference/cpp/api-docs/google.protobuf.descriptor.pb.md deleted file mode 100644 index b0dfacd6c..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.descriptor.pb.md +++ /dev/null @@ -1,915 +0,0 @@ -+++ -title = "descriptor.pb.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/descriptor.pb.h>
namespace google::protobuf

Protocol buffer representations of descriptors.

This file defines a set of protocol message classes which represent the same information represented by the classes defined in descriptor.h. You can convert a FileDescriptorProto to a FileDescriptor using the DescriptorPool class. Thus, the classes in this file allow protocol type definitions to be communicated efficiently between processes.

- -

The protocol compiler currently doesn't support auto-generated documentation, hence this page contains no descriptions. This file was generated by the protocol compiler from descriptor.proto, whose contents are as follows:

- -
// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: kenton@google.com (Kenton Varda)
-//  Based on original Protocol Buffers design by
-//  Sanjay Ghemawat, Jeff Dean, and others.
-//
-// The messages in this file describe the definitions found in .proto files.
-// A valid .proto file can be translated directly to a FileDescriptorProto
-// without any other information (e.g. without reading its imports).
-
-syntax = "proto2";
-
-package google.protobuf;
-
-option go_package = "google.golang.org/protobuf/types/descriptorpb";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "DescriptorProtos";
-option csharp_namespace = "Google.Protobuf.Reflection";
-option objc_class_prefix = "GPB";
-option cc_enable_arenas = true;
-
-// descriptor.proto must be optimized for speed because reflection-based
-// algorithms don't work during bootstrapping.
-option optimize_for = SPEED;
-
-// The protocol compiler can output a FileDescriptorSet containing the .proto
-// files it parses.
-message FileDescriptorSet {
-  repeated FileDescriptorProto file = 1;
-}
-
-// Describes a complete .proto file.
-message FileDescriptorProto {
-  optional string name = 1;     // file name, relative to root of source tree
-  optional string package = 2;  // e.g. "foo", "foo.bar", etc.
-
-  // Names of files imported by this file.
-  repeated string dependency = 3;
-  // Indexes of the public imported files in the dependency list above.
-  repeated int32 public_dependency = 10;
-  // Indexes of the weak imported files in the dependency list.
-  // For Google-internal migration only. Do not use.
-  repeated int32 weak_dependency = 11;
-
-  // All top-level definitions in this file.
-  repeated DescriptorProto message_type = 4;
-  repeated EnumDescriptorProto enum_type = 5;
-  repeated ServiceDescriptorProto service = 6;
-  repeated FieldDescriptorProto extension = 7;
-
-  optional FileOptions options = 8;
-
-  // This field contains optional information about the original source code.
-  // You may safely remove this entire field without harming runtime
-  // functionality of the descriptors -- the information is needed only by
-  // development tools.
-  optional SourceCodeInfo source_code_info = 9;
-
-  // The syntax of the proto file.
-  // The supported values are "proto2" and "proto3".
-  optional string syntax = 12;
-}
-
-// Describes a message type.
-message DescriptorProto {
-  optional string name = 1;
-
-  repeated FieldDescriptorProto field = 2;
-  repeated FieldDescriptorProto extension = 6;
-
-  repeated DescriptorProto nested_type = 3;
-  repeated EnumDescriptorProto enum_type = 4;
-
-  message ExtensionRange {
-    optional int32 start = 1;  // Inclusive.
-    optional int32 end = 2;    // Exclusive.
-
-optional ExtensionRangeOptions options = 3;
-
-  }
-  repeated ExtensionRange extension_range = 5;
-
-  repeated OneofDescriptorProto oneof_decl = 8;
-
-  optional MessageOptions options = 7;
-
-  // Range of reserved tag numbers. Reserved tag numbers may not be used by
-  // fields or extension ranges in the same message. Reserved ranges may
-  // not overlap.
-  message ReservedRange {
-    optional int32 start = 1;  // Inclusive.
-    optional int32 end = 2;    // Exclusive.
-  }
-  repeated ReservedRange reserved_range = 9;
-  // Reserved field names, which may not be used by fields in the same message.
-  // A given name may only be reserved once.
-  repeated string reserved_name = 10;
-}
-
-message ExtensionRangeOptions {
-  // The parser stores options it doesn't recognize here. See above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message. See above.
-  extensions 1000 to max;
-}
-
-// Describes a field within a message.
-message FieldDescriptorProto {
-  enum Type {
-    // 0 is reserved for errors.
-    // Order is weird for historical reasons.
-    TYPE_DOUBLE = 1;
-    TYPE_FLOAT = 2;
-    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT64 if
-    // negative values are likely.
-    TYPE_INT64 = 3;
-    TYPE_UINT64 = 4;
-    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT32 if
-    // negative values are likely.
-    TYPE_INT32 = 5;
-    TYPE_FIXED64 = 6;
-    TYPE_FIXED32 = 7;
-    TYPE_BOOL = 8;
-    TYPE_STRING = 9;
-    // Tag-delimited aggregate.
-    // Group type is deprecated and not supported in proto3. However, Proto3
-    // implementations should still be able to parse the group wire format and
-    // treat group fields as unknown fields.
-    TYPE_GROUP = 10;
-    TYPE_MESSAGE = 11;  // Length-delimited aggregate.
-
-// New in version 2.
-TYPE_BYTES = 12;
-TYPE_UINT32 = 13;
-TYPE_ENUM = 14;
-TYPE_SFIXED32 = 15;
-TYPE_SFIXED64 = 16;
-TYPE_SINT32 = 17;  // Uses ZigZag encoding.
-TYPE_SINT64 = 18;  // Uses ZigZag encoding.
-
-  }
-
-  enum Label {
-    // 0 is reserved for errors
-    LABEL_OPTIONAL = 1;
-    LABEL_REQUIRED = 2;
-    LABEL_REPEATED = 3;
-  }
-
-  optional string name = 1;
-  optional int32 number = 3;
-  optional Label label = 4;
-
-  // If type_name is set, this need not be set.  If both this and type_name
-  // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
-  optional Type type = 5;
-
-  // For message and enum types, this is the name of the type.  If the name
-  // starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping
-  // rules are used to find the type (i.e. first the nested types within this
-  // message are searched, then within the parent, on up to the root
-  // namespace).
-  optional string type_name = 6;
-
-  // For extensions, this is the name of the type being extended.  It is
-  // resolved in the same manner as type_name.
-  optional string extendee = 2;
-
-  // For numeric types, contains the original text representation of the value.
-  // For booleans, "true" or "false".
-  // For strings, contains the default text contents (not escaped in any way).
-  // For bytes, contains the C escaped value.  All bytes >= 128 are escaped.
-  optional string default_value = 7;
-
-  // If set, gives the index of a oneof in the containing type's oneof_decl
-  // list.  This field is a member of that oneof.
-  optional int32 oneof_index = 9;
-
-  // JSON name of this field. The value is set by protocol compiler. If the
-  // user has set a "json_name" option on this field, that option's value
-  // will be used. Otherwise, it's deduced from the field's name by converting
-  // it to camelCase.
-  optional string json_name = 10;
-
-  optional FieldOptions options = 8;
-
-  // If true, this is a proto3 "optional". When a proto3 field is optional, it
-  // tracks presence regardless of field type.
-  //
-  // When proto3_optional is true, this field must be belong to a oneof to
-  // signal to old proto3 clients that presence is tracked for this field. This
-  // oneof is known as a "synthetic" oneof, and this field must be its sole
-  // member (each proto3 optional field gets its own synthetic oneof). Synthetic
-  // oneofs exist in the descriptor only, and do not generate any API. Synthetic
-  // oneofs must be ordered after all "real" oneofs.
-  //
-  // For message fields, proto3_optional doesn't create any semantic change,
-  // since non-repeated message fields always track presence. However it still
-  // indicates the semantic detail of whether the user wrote "optional" or not.
-  // This can be useful for round-tripping the .proto file. For consistency we
-  // give message fields a synthetic oneof also, even though it is not required
-  // to track presence. This is especially important because the parser can't
-  // tell if a field is a message or an enum, so it must always create a
-  // synthetic oneof.
-  //
-  // Proto2 optional fields do not set this flag, because they already indicate
-  // optional with `LABEL_OPTIONAL`.
-  optional bool proto3_optional = 17;
-}
-
-// Describes a oneof.
-message OneofDescriptorProto {
-  optional string name = 1;
-  optional OneofOptions options = 2;
-}
-
-// Describes an enum type.
-message EnumDescriptorProto {
-  optional string name = 1;
-
-  repeated EnumValueDescriptorProto value = 2;
-
-  optional EnumOptions options = 3;
-
-  // Range of reserved numeric values. Reserved values may not be used by
-  // entries in the same enum. Reserved ranges may not overlap.
-  //
-  // Note that this is distinct from DescriptorProto.ReservedRange in that it
-  // is inclusive such that it can appropriately represent the entire int32
-  // domain.
-  message EnumReservedRange {
-    optional int32 start = 1;  // Inclusive.
-    optional int32 end = 2;    // Inclusive.
-  }
-
-  // Range of reserved numeric values. Reserved numeric values may not be used
-  // by enum values in the same enum declaration. Reserved ranges may not
-  // overlap.
-  repeated EnumReservedRange reserved_range = 4;
-
-  // Reserved enum value names, which may not be reused. A given name may only
-  // be reserved once.
-  repeated string reserved_name = 5;
-}
-
-// Describes a value within an enum.
-message EnumValueDescriptorProto {
-  optional string name = 1;
-  optional int32 number = 2;
-
-  optional EnumValueOptions options = 3;
-}
-
-// Describes a service.
-message ServiceDescriptorProto {
-  optional string name = 1;
-  repeated MethodDescriptorProto method = 2;
-
-  optional ServiceOptions options = 3;
-}
-
-// Describes a method of a service.
-message MethodDescriptorProto {
-  optional string name = 1;
-
-  // Input and output type names.  These are resolved in the same way as
-  // FieldDescriptorProto.type_name, but must refer to a message type.
-  optional string input_type = 2;
-  optional string output_type = 3;
-
-  optional MethodOptions options = 4;
-
-  // Identifies if client streams multiple client messages
-  optional bool client_streaming = 5 [default = false];
-  // Identifies if server streams multiple server messages
-  optional bool server_streaming = 6 [default = false];
-}
-
-// ===================================================================
-// Options
-
-// Each of the definitions above may have "options" attached.  These are
-// just annotations which may cause code to be generated slightly differently
-// or may contain hints for code that manipulates protocol messages.
-//
-// Clients may define custom options as extensions of the *Options messages.
-// These extensions may not yet be known at parsing time, so the parser cannot
-// store the values in them.  Instead it stores them in a field in the *Options
-// message called uninterpreted_option. This field must have the same name
-// across all *Options messages. We then use this field to populate the
-// extensions when we build a descriptor, at which point all protos have been
-// parsed and so all extensions are known.
-//
-// Extension numbers for custom options may be chosen as follows:
-// * For options which will only be used within a single application or
-//   organization, or for experimental options, use field numbers 50000
-//   through 99999.  It is up to you to ensure that you do not use the
-//   same number for multiple options.
-// * For options which will be published and used publicly by multiple
-//   independent entities, e-mail protobuf-global-extension-registry@google.com
-//   to reserve extension numbers. Simply provide your project name (e.g.
-//   Objective-C plugin) and your project website (if available) -- there's no
-//   need to explain how you intend to use them. Usually you only need one
-//   extension number. You can declare multiple options with only one extension
-//   number by putting them in a sub-message. See the Custom Options section of
-//   the docs for examples:
-//   /programming-guides/proto#options
-//   If this turns out to be popular, a web service will be set up
-//   to automatically assign option numbers.
-
-message FileOptions {
-
-  // Sets the Java package where classes generated from this .proto will be
-  // placed.  By default, the proto package is used, but this is often
-  // inappropriate because proto packages do not normally start with backwards
-  // domain names.
-  optional string java_package = 1;
-
-  // Controls the name of the wrapper Java class generated for the .proto file.
-  // That class will always contain the .proto file's getDescriptor() method as
-  // well as any top-level extensions defined in the .proto file.
-  // If java_multiple_files is disabled, then all the other classes from the
-  // .proto file will be nested inside the single wrapper outer class.
-  optional string java_outer_classname = 8;
-
-  // If enabled, then the Java code generator will generate a separate .java
-  // file for each top-level message, enum, and service defined in the .proto
-  // file.  Thus, these types will *not* be nested inside the wrapper class
-  // named by java_outer_classname.  However, the wrapper class will still be
-  // generated to contain the file's getDescriptor() method as well as any
-  // top-level extensions defined in the file.
-  optional bool java_multiple_files = 10 [default = false];
-
-  // This option does nothing.
-  optional bool java_generate_equals_and_hash = 20 [deprecated=true];
-
-  // If set true, then the Java2 code generator will generate code that
-  // throws an exception whenever an attempt is made to assign a non-UTF-8
-  // byte sequence to a string field.
-  // Message reflection will do the same.
-  // However, an extension field still accepts non-UTF-8 byte sequences.
-  // This option has no effect on when used with the lite runtime.
-  optional bool java_string_check_utf8 = 27 [default = false];
-
-  // Generated classes can be optimized for speed or code size.
-  enum OptimizeMode {
-    SPEED = 1;         // Generate complete code for parsing, serialization,
-                       // etc.
-    CODE_SIZE = 2;     // Use ReflectionOps to implement these methods.
-    LITE_RUNTIME = 3;  // Generate code using MessageLite and the lite runtime.
-  }
-  optional OptimizeMode optimize_for = 9 [default = SPEED];
-
-  // Sets the Go package where structs generated from this .proto will be
-  // placed. If omitted, the Go package will be derived from the following:
-  //   - The basename of the package import path, if provided.
-  //   - Otherwise, the package statement in the .proto file, if present.
-  //   - Otherwise, the basename of the .proto file, without extension.
-  optional string go_package = 11;
-
-  // Should generic services be generated in each language?  "Generic" services
-  // are not specific to any particular RPC system.  They are generated by the
-  // main code generators in each language (without additional plugins).
-  // Generic services were the only kind of service generation supported by
-  // early versions of google.protobuf.
-  //
-  // Generic services are now considered deprecated in favor of using plugins
-  // that generate code specific to your particular RPC system.  Therefore,
-  // these default to false.  Old code which depends on generic services should
-  // explicitly set them to true.
-  optional bool cc_generic_services = 16 [default = false];
-  optional bool java_generic_services = 17 [default = false];
-  optional bool py_generic_services = 18 [default = false];
-  optional bool php_generic_services = 42 [default = false];
-
-  // Is this file deprecated?
-  // Depending on the target platform, this can emit Deprecated annotations
-  // for everything in the file, or it will be completely ignored; in the very
-  // least, this is a formalization for deprecating files.
-  optional bool deprecated = 23 [default = false];
-
-  // Enables the use of arenas for the proto messages in this file. This applies
-  // only to generated classes for C++.
-  optional bool cc_enable_arenas = 31 [default = true];
-
-  // Sets the objective c class prefix which is prepended to all objective c
-  // generated classes from this .proto. There is no default.
-  optional string objc_class_prefix = 36;
-
-  // Namespace for generated classes; defaults to the package.
-  optional string csharp_namespace = 37;
-
-  // By default Swift generators will take the proto package and CamelCase it
-  // replacing '.' with underscore and use that to prefix the types/symbols
-  // defined. When this options is provided, they will use this value instead
-  // to prefix the types/symbols defined.
-  optional string swift_prefix = 39;
-
-  // Sets the php class prefix which is prepended to all php generated classes
-  // from this .proto. Default is empty.
-  optional string php_class_prefix = 40;
-
-  // Use this option to change the namespace of php generated classes. Default
-  // is empty. When this option is empty, the package name will be used for
-  // determining the namespace.
-  optional string php_namespace = 41;
-
-  // Use this option to change the namespace of php generated metadata classes.
-  // Default is empty. When this option is empty, the proto file name will be
-  // used for determining the namespace.
-  optional string php_metadata_namespace = 44;
-
-  // Use this option to change the package of ruby generated classes. Default
-  // is empty. When this option is not set, the package name will be used for
-  // determining the ruby package.
-  optional string ruby_package = 45;
-
-  // The parser stores options it doesn't recognize here.
-  // See the documentation for the "Options" section above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message.
-  // See the documentation for the "Options" section above.
-  extensions 1000 to max;
-
-  reserved 38;
-}
-
-message MessageOptions {
-  // Set true to use the old proto1 MessageSet wire format for extensions.
-  // This is provided for backwards-compatibility with the MessageSet wire
-  // format.  You should not use this for any other reason:  It's less
-  // efficient, has fewer features, and is more complicated.
-  //
-  // The message must be defined exactly as follows:
-  //   message Foo {
-  //     option message_set_wire_format = true;
-  //     extensions 4 to max;
-  //   }
-  // Note that the message cannot have any defined fields; MessageSets only
-  // have extensions.
-  //
-  // All extensions of your type must be singular messages; e.g. they cannot
-  // be int32s, enums, or repeated messages.
-  //
-  // Because this is an option, the above two restrictions are not enforced by
-  // the protocol compiler.
-  optional bool message_set_wire_format = 1 [default = false];
-
-  // Disables the generation of the standard "descriptor()" accessor, which can
-  // conflict with a field of the same name.  This is meant to make migration
-  // from proto1 easier; new code should avoid fields named "descriptor".
-  optional bool no_standard_descriptor_accessor = 2 [default = false];
-
-  // Is this message deprecated?
-  // Depending on the target platform, this can emit Deprecated annotations
-  // for the message, or it will be completely ignored; in the very least,
-  // this is a formalization for deprecating messages.
-  optional bool deprecated = 3 [default = false];
-
-  reserved 4, 5, 6;
-
-  // Whether the message is an automatically generated map entry type for the
-  // maps field.
-  //
-  // For maps fields:
-  //     map<KeyType, ValueType> map_field = 1;
-  // The parsed descriptor looks like:
-  //     message MapFieldEntry {
-  //         option map_entry = true;
-  //         optional KeyType key = 1;
-  //         optional ValueType value = 2;
-  //     }
-  //     repeated MapFieldEntry map_field = 1;
-  //
-  // Implementations may choose not to generate the map_entry=true message, but
-  // use a native map in the target language to hold the keys and values.
-  // The reflection APIs in such implementations still need to work as
-  // if the field is a repeated message field.
-  //
-  // NOTE: Do not set the option in .proto files. Always use the maps syntax
-  // instead. The option should only be implicitly set by the proto compiler
-  // parser.
-  optional bool map_entry = 7;
-
-  reserved 8;  // javalite_serializable
-  reserved 9;  // javanano_as_lite
-
-  // The parser stores options it doesn't recognize here. See above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message. See above.
-  extensions 1000 to max;
-}
-
-message FieldOptions {
-  // The ctype option instructs the C++ code generator to use a different
-  // representation of the field than it normally would.  See the specific
-  // options below.  This option is not yet implemented in the open source
-  // release -- sorry, we'll try to include it in a future version!
-  optional CType ctype = 1 [default = STRING];
-  enum CType {
-    // Default mode.
-    STRING = 0;
-
-CORD = 1;
-
-STRING_PIECE = 2;
-
-  }
-  // The packed option can be enabled for repeated primitive fields to enable
-  // a more efficient representation on the wire. Rather than repeatedly
-  // writing the tag and type for each element, the entire array is encoded as
-  // a single length-delimited blob. In proto3, only explicit setting it to
-  // false will avoid using packed encoding.
-  optional bool packed = 2;
-
-  // The jstype option determines the JavaScript type used for values of the
-  // field.  The option is permitted only for 64 bit integral and fixed types
-  // (int64, uint64, sint64, fixed64, sfixed64).  A field with jstype JS_STRING
-  // is represented as JavaScript string, which avoids loss of precision that
-  // can happen when a large value is converted to a floating point JavaScript.
-  // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
-  // use the JavaScript "number" type.  The behavior of the default option
-  // JS_NORMAL is implementation dependent.
-  //
-  // This option is an enum to permit additional types to be added, e.g.
-  // goog.math.Integer.
-  optional JSType jstype = 6 [default = JS_NORMAL];
-  enum JSType {
-    // Use the default type.
-    JS_NORMAL = 0;
-
-// Use JavaScript strings.
-JS_STRING = 1;
-
-// Use JavaScript numbers.
-JS_NUMBER = 2;
-
-  }
-
-  // Should this field be parsed lazily?  Lazy applies only to message-type
-  // fields.  It means that when the outer message is initially parsed, the
-  // inner message's contents will not be parsed but instead stored in encoded
-  // form.  The inner message will actually be parsed when it is first accessed.
-  //
-  // This is only a hint.  Implementations are free to choose whether to use
-  // eager or lazy parsing regardless of the value of this option.  However,
-  // setting this option true suggests that the protocol author believes that
-  // using lazy parsing on this field is worth the additional bookkeeping
-  // overhead typically needed to implement it.
-  //
-  // This option does not affect the public interface of any generated code;
-  // all method signatures remain the same.  Furthermore, thread-safety of the
-  // interface is not affected by this option; const methods remain safe to
-  // call from multiple threads concurrently, while non-const methods continue
-  // to require exclusive access.
-  //
-  //
-  // Note that implementations may choose not to check required fields within
-  // a lazy sub-message.  That is, calling IsInitialized() on the outer message
-  // may return true even if the inner message has missing required fields.
-  // This is necessary because otherwise the inner message would have to be
-  // parsed in order to perform the check, defeating the purpose of lazy
-  // parsing.  An implementation which chooses not to check required fields
-  // must be consistent about it.  That is, for any particular sub-message, the
-  // implementation must either *always* check its required fields, or *never*
-  // check its required fields, regardless of whether or not the message has
-  // been parsed.
-  optional bool lazy = 5 [default = false];
-
-  // Is this field deprecated?
-  // Depending on the target platform, this can emit Deprecated annotations
-  // for accessors, or it will be completely ignored; in the very least, this
-  // is a formalization for deprecating fields.
-  optional bool deprecated = 3 [default = false];
-
-  // For Google-internal migration only. Do not use.
-  optional bool weak = 10 [default = false];
-
-  // The parser stores options it doesn't recognize here. See above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message. See above.
-  extensions 1000 to max;
-
-  reserved 4;  // removed jtype
-}
-
-message OneofOptions {
-  // The parser stores options it doesn't recognize here. See above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message. See above.
-  extensions 1000 to max;
-}
-
-message EnumOptions {
-
-  // Set this option to true to allow mapping different tag names to the same
-  // value.
-  optional bool allow_alias = 2;
-
-  // Is this enum deprecated?
-  // Depending on the target platform, this can emit Deprecated annotations
-  // for the enum, or it will be completely ignored; in the very least, this
-  // is a formalization for deprecating enums.
-  optional bool deprecated = 3 [default = false];
-
-  reserved 5;  // javanano_as_lite
-
-  // The parser stores options it doesn't recognize here. See above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message. See above.
-  extensions 1000 to max;
-}
-
-message EnumValueOptions {
-  // Is this enum value deprecated?
-  // Depending on the target platform, this can emit Deprecated annotations
-  // for the enum value, or it will be completely ignored; in the very least,
-  // this is a formalization for deprecating enum values.
-  optional bool deprecated = 1 [default = false];
-
-  // The parser stores options it doesn't recognize here. See above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message. See above.
-  extensions 1000 to max;
-}
-
-message ServiceOptions {
-
-  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC
-  //   framework.  We apologize for hoarding these numbers to ourselves, but
-  //   we were already using them long before we decided to release Protocol
-  //   Buffers.
-
-  // Is this service deprecated?
-  // Depending on the target platform, this can emit Deprecated annotations
-  // for the service, or it will be completely ignored; in the very least,
-  // this is a formalization for deprecating services.
-  optional bool deprecated = 33 [default = false];
-
-  // The parser stores options it doesn't recognize here. See above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message. See above.
-  extensions 1000 to max;
-}
-
-message MethodOptions {
-
-  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC
-  //   framework.  We apologize for hoarding these numbers to ourselves, but
-  //   we were already using them long before we decided to release Protocol
-  //   Buffers.
-
-  // Is this method deprecated?
-  // Depending on the target platform, this can emit Deprecated annotations
-  // for the method, or it will be completely ignored; in the very least,
-  // this is a formalization for deprecating methods.
-  optional bool deprecated = 33 [default = false];
-
-  // Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
-  // or neither? HTTP based RPC implementation may choose GET verb for safe
-  // methods, and PUT verb for idempotent methods instead of the default POST.
-  enum IdempotencyLevel {
-    IDEMPOTENCY_UNKNOWN = 0;
-    NO_SIDE_EFFECTS = 1;  // implies idempotent
-    IDEMPOTENT = 2;       // idempotent, but may have side effects
-  }
-  optional IdempotencyLevel idempotency_level = 34
-      [default = IDEMPOTENCY_UNKNOWN];
-
-  // The parser stores options it doesn't recognize here. See above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message. See above.
-  extensions 1000 to max;
-}
-
-// A message representing a option the parser does not recognize. This only
-// appears in options protos created by the compiler::Parser class.
-// DescriptorPool resolves these when building Descriptor objects. Therefore,
-// options protos in descriptor objects (e.g. returned by Descriptor::options(),
-// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
-// in them.
-message UninterpretedOption {
-  // The name of the uninterpreted option.  Each string represents a segment in
-  // a dot-separated name.  is_extension is true iff a segment represents an
-  // extension (denoted with parentheses in options specs in .proto files).
-  // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
-  // "foo.(bar.baz).qux".
-  message NamePart {
-    required string name_part = 1;
-    required bool is_extension = 2;
-  }
-  repeated NamePart name = 2;
-
-  // The value of the uninterpreted option, in whatever type the tokenizer
-  // identified it as during parsing. Exactly one of these should be set.
-  optional string identifier_value = 3;
-  optional uint64 positive_int_value = 4;
-  optional int64 negative_int_value = 5;
-  optional double double_value = 6;
-  optional bytes string_value = 7;
-  optional string aggregate_value = 8;
-}
-
-// ===================================================================
-// Optional source code info
-
-// Encapsulates information about the original source file from which a
-// FileDescriptorProto was generated.
-message SourceCodeInfo {
-  // A Location identifies a piece of source code in a .proto file which
-  // corresponds to a particular definition.  This information is intended
-  // to be useful to IDEs, code indexers, documentation generators, and similar
-  // tools.
-  //
-  // For example, say we have a file like:
-  //   message Foo {
-  //     optional string foo = 1;
-  //   }
-  // Let's look at just the field definition:
-  //   optional string foo = 1;
-  //   ^       ^^     ^^  ^  ^^^
-  //   a       bc     de  f  ghi
-  // We have the following locations:
-  //   span   path               represents
-  //   [a,i)  [ 4, 0, 2, 0 ]     The whole field definition.
-  //   [a,b)  [ 4, 0, 2, 0, 4 ]  The label (optional).
-  //   [c,d)  [ 4, 0, 2, 0, 5 ]  The type (string).
-  //   [e,f)  [ 4, 0, 2, 0, 1 ]  The name (foo).
-  //   [g,h)  [ 4, 0, 2, 0, 3 ]  The number (1).
-  //
-  // Notes:
-  // - A location may refer to a repeated field itself (i.e. not to any
-  //   particular index within it).  This is used whenever a set of elements are
-  //   logically enclosed in a single code segment.  For example, an entire
-  //   extend block (possibly containing multiple extension definitions) will
-  //   have an outer location whose path refers to the "extensions" repeated
-  //   field without an index.
-  // - Multiple locations may have the same path.  This happens when a single
-  //   logical declaration is spread out across multiple places.  The most
-  //   obvious example is the "extend" block again -- there may be multiple
-  //   extend blocks in the same scope, each of which will have the same path.
-  // - A location's span is not always a subset of its parent's span.  For
-  //   example, the "extendee" of an extension declaration appears at the
-  //   beginning of the "extend" block and is shared by all extensions within
-  //   the block.
-  // - Just because a location's span is a subset of some other location's span
-  //   does not mean that it is a descendant.  For example, a "group" defines
-  //   both a type and a field in a single declaration.  Thus, the locations
-  //   corresponding to the type and field and their components will overlap.
-  // - Code which tries to interpret locations should probably be designed to
-  //   ignore those that it doesn't understand, as more types of locations could
-  //   be recorded in the future.
-  repeated Location location = 1;
-  message Location {
-    // Identifies which part of the FileDescriptorProto was defined at this
-    // location.
-    //
-    // Each element is a field number or an index.  They form a path from
-    // the root FileDescriptorProto to the place where the definition.  For
-    // example, this path:
-    //   [ 4, 3, 2, 7, 1 ]
-    // refers to:
-    //   file.message_type(3)  // 4, 3
-    //       .field(7)         // 2, 7
-    //       .name()           // 1
-    // This is because FileDescriptorProto.message_type has field number 4:
-    //   repeated DescriptorProto message_type = 4;
-    // and DescriptorProto.field has field number 2:
-    //   repeated FieldDescriptorProto field = 2;
-    // and FieldDescriptorProto.name has field number 1:
-    //   optional string name = 1;
-    //
-    // Thus, the above path gives the location of a field name.  If we removed
-    // the last element:
-    //   [ 4, 3, 2, 7 ]
-    // this path refers to the whole field declaration (from the beginning
-    // of the label to the terminating semicolon).
-    repeated int32 path = 1 [packed = true];
-
-// Always has exactly three or four elements: start line, start column,
-// end line (optional, otherwise assumed same as start line), end column.
-// These are packed into a single field for efficiency.  Note that line
-// and column numbers are zero-based -- typically you will want to add
-// 1 to each before displaying to a user.
-repeated int32 span = 2 [packed = true];
-
-// If this SourceCodeInfo represents a complete declaration, these are any
-// comments appearing before and after the declaration which appear to be
-// attached to the declaration.
-//
-// A series of line comments appearing on consecutive lines, with no other
-// tokens appearing on those lines, will be treated as a single comment.
-//
-// leading_detached_comments will keep paragraphs of comments that appear
-// before (but not connected to) the current element. Each paragraph,
-// separated by empty lines, will be one comment element in the repeated
-// field.
-//
-// Only the comment content is provided; comment markers (e.g. //) are
-// stripped out.  For block comments, leading whitespace and an asterisk
-// will be stripped from the beginning of each line other than the first.
-// Newlines are included in the output.
-//
-// Examples:
-//
-//   optional int32 foo = 1;  // Comment attached to foo.
-//   // Comment attached to bar.
-//   optional int32 bar = 2;
-//
-//   optional string baz = 3;
-//   // Comment attached to baz.
-//   // Another line attached to baz.
-//
-//   // Comment attached to qux.
-//   //
-//   // Another line attached to qux.
-//   optional double qux = 4;
-//
-//   // Detached comment for corge. This is not leading or trailing comments
-//   // to qux or corge because there are blank lines separating it from
-//   // both.
-//
-//   // Detached comment for corge paragraph 2.
-//
-//   optional string corge = 5;
-//   /* Block comment attached
-//    * to corge.  Leading asterisks
-//    * will be removed. */ // /* Block comment attached to
-//    * grault. */
-//   optional int32 grault = 6;
-//
-//   // ignored detached comments.
-optional string leading_comments = 3;
-optional string trailing_comments = 4;
-repeated string leading_detached_comments = 6;
-
-  }
-}
-
-// Describes the relationship between generated code and its original source
-// file. A GeneratedCodeInfo message is associated with only one generated
-// source file, but may contain references to different source .proto files.
-message GeneratedCodeInfo {
-  // An Annotation connects some span of text in generated code to an element
-  // of its generating .proto file.
-  repeated Annotation annotation = 1;
-  message Annotation {
-    // Identifies the element in the original source .proto file. This field
-    // is formatted the same as SourceCodeInfo.Location.path.
-    repeated int32 path = 1 [packed = true];
-
-// Identifies the filesystem path to the original source .proto.
-optional string source_file = 2;
-
-// Identifies the starting offset in bytes in the generated code
-// that relates to the identified object.
-optional int32 begin = 3;
-
-// Identifies the ending offset in bytes in the generated code that
-// relates to the identified offset. The end offset should be one past
-// the last relevant byte (so the length of the text = end - begin).
-optional int32 end = 4;
-
-  }
-}
-

Classes in this file

File Members

These definitions are not part of any class.
enum
FieldDescriptorProto_Type
enum
FieldDescriptorProto_Label
enum
FileOptions_OptimizeMode
enum
FieldOptions_CType
enum
FieldOptions_JSType
enum
MethodOptions_IdempotencyLevel
const ::protobuf::internal::DescriptorTable
descriptor_table_google_2fprotobuf_2fdescriptor_2eproto
DescriptorProtoDefaultTypeInternal
_DescriptorProto_default_instance_
DescriptorProto_ExtensionRangeDefaultTypeInternal
_DescriptorProto_ExtensionRange_default_instance_
DescriptorProto_ReservedRangeDefaultTypeInternal
_DescriptorProto_ReservedRange_default_instance_
EnumDescriptorProtoDefaultTypeInternal
_EnumDescriptorProto_default_instance_
EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal
_EnumDescriptorProto_EnumReservedRange_default_instance_
EnumOptionsDefaultTypeInternal
_EnumOptions_default_instance_
EnumValueDescriptorProtoDefaultTypeInternal
_EnumValueDescriptorProto_default_instance_
EnumValueOptionsDefaultTypeInternal
_EnumValueOptions_default_instance_
ExtensionRangeOptionsDefaultTypeInternal
_ExtensionRangeOptions_default_instance_
FieldDescriptorProtoDefaultTypeInternal
_FieldDescriptorProto_default_instance_
FieldOptionsDefaultTypeInternal
_FieldOptions_default_instance_
FileDescriptorProtoDefaultTypeInternal
_FileDescriptorProto_default_instance_
FileDescriptorSetDefaultTypeInternal
_FileDescriptorSet_default_instance_
FileOptionsDefaultTypeInternal
_FileOptions_default_instance_
GeneratedCodeInfoDefaultTypeInternal
_GeneratedCodeInfo_default_instance_
GeneratedCodeInfo_AnnotationDefaultTypeInternal
_GeneratedCodeInfo_Annotation_default_instance_
MessageOptionsDefaultTypeInternal
_MessageOptions_default_instance_
MethodDescriptorProtoDefaultTypeInternal
_MethodDescriptorProto_default_instance_
MethodOptionsDefaultTypeInternal
_MethodOptions_default_instance_
OneofDescriptorProtoDefaultTypeInternal
_OneofDescriptorProto_default_instance_
OneofOptionsDefaultTypeInternal
_OneofOptions_default_instance_
ServiceDescriptorProtoDefaultTypeInternal
_ServiceDescriptorProto_default_instance_
ServiceOptionsDefaultTypeInternal
_ServiceOptions_default_instance_
SourceCodeInfoDefaultTypeInternal
_SourceCodeInfo_default_instance_
SourceCodeInfo_LocationDefaultTypeInternal
_SourceCodeInfo_Location_default_instance_
UninterpretedOptionDefaultTypeInternal
_UninterpretedOption_default_instance_
UninterpretedOption_NamePartDefaultTypeInternal
_UninterpretedOption_NamePart_default_instance_
constexpr FieldDescriptorProto_Type
FieldDescriptorProto_Type_Type_MIN = = FieldDescriptorProto_Type_TYPE_DOUBLE
constexpr FieldDescriptorProto_Type
FieldDescriptorProto_Type_Type_MAX = = FieldDescriptorProto_Type_TYPE_SINT64
constexpr int
FieldDescriptorProto_Type_Type_ARRAYSIZE = = FieldDescriptorProto_Type_Type_MAX + 1
constexpr FieldDescriptorProto_Label
FieldDescriptorProto_Label_Label_MIN = = FieldDescriptorProto_Label_LABEL_OPTIONAL
constexpr FieldDescriptorProto_Label
FieldDescriptorProto_Label_Label_MAX = = FieldDescriptorProto_Label_LABEL_REPEATED
constexpr int
FieldDescriptorProto_Label_Label_ARRAYSIZE = = FieldDescriptorProto_Label_Label_MAX + 1
constexpr FileOptions_OptimizeMode
FileOptions_OptimizeMode_OptimizeMode_MIN = = FileOptions_OptimizeMode_SPEED
constexpr FileOptions_OptimizeMode
FileOptions_OptimizeMode_OptimizeMode_MAX = = FileOptions_OptimizeMode_LITE_RUNTIME
constexpr int
FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE = = FileOptions_OptimizeMode_OptimizeMode_MAX + 1
constexpr FieldOptions_CType
FieldOptions_CType_CType_MIN = = FieldOptions_CType_STRING
constexpr FieldOptions_CType
FieldOptions_CType_CType_MAX = = FieldOptions_CType_STRING_PIECE
constexpr int
FieldOptions_CType_CType_ARRAYSIZE = = FieldOptions_CType_CType_MAX + 1
constexpr FieldOptions_JSType
FieldOptions_JSType_JSType_MIN = = FieldOptions_JSType_JS_NORMAL
constexpr FieldOptions_JSType
FieldOptions_JSType_JSType_MAX = = FieldOptions_JSType_JS_NUMBER
constexpr int
FieldOptions_JSType_JSType_ARRAYSIZE = = FieldOptions_JSType_JSType_MAX + 1
constexpr MethodOptions_IdempotencyLevel
MethodOptions_IdempotencyLevel_IdempotencyLevel_MIN = = MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN
constexpr MethodOptions_IdempotencyLevel
MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX = = MethodOptions_IdempotencyLevel_IDEMPOTENT
constexpr int
MethodOptions_IdempotencyLevel_IdempotencyLevel_ARRAYSIZE = = MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX + 1
PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_OPEN protobuf::DescriptorProto *
Arena::CreateMaybeMessage< protobuf::DescriptorProto >(Arena * )
protobuf::DescriptorProto_ExtensionRange *
Arena::CreateMaybeMessage< protobuf::DescriptorProto_ExtensionRange >(Arena * )
protobuf::DescriptorProto_ReservedRange *
Arena::CreateMaybeMessage< protobuf::DescriptorProto_ReservedRange >(Arena * )
protobuf::EnumDescriptorProto *
Arena::CreateMaybeMessage< protobuf::EnumDescriptorProto >(Arena * )
protobuf::EnumDescriptorProto_EnumReservedRange *
Arena::CreateMaybeMessage< protobuf::EnumDescriptorProto_EnumReservedRange >(Arena * )
protobuf::EnumOptions *
Arena::CreateMaybeMessage< protobuf::EnumOptions >(Arena * )
protobuf::EnumValueDescriptorProto *
Arena::CreateMaybeMessage< protobuf::EnumValueDescriptorProto >(Arena * )
protobuf::EnumValueOptions *
Arena::CreateMaybeMessage< protobuf::EnumValueOptions >(Arena * )
protobuf::ExtensionRangeOptions *
Arena::CreateMaybeMessage< protobuf::ExtensionRangeOptions >(Arena * )
protobuf::FieldDescriptorProto *
Arena::CreateMaybeMessage< protobuf::FieldDescriptorProto >(Arena * )
protobuf::FieldOptions *
Arena::CreateMaybeMessage< protobuf::FieldOptions >(Arena * )
protobuf::FileDescriptorProto *
Arena::CreateMaybeMessage< protobuf::FileDescriptorProto >(Arena * )
protobuf::FileDescriptorSet *
Arena::CreateMaybeMessage< protobuf::FileDescriptorSet >(Arena * )
protobuf::FileOptions *
Arena::CreateMaybeMessage< protobuf::FileOptions >(Arena * )
protobuf::GeneratedCodeInfo *
Arena::CreateMaybeMessage< protobuf::GeneratedCodeInfo >(Arena * )
protobuf::GeneratedCodeInfo_Annotation *
Arena::CreateMaybeMessage< protobuf::GeneratedCodeInfo_Annotation >(Arena * )
protobuf::MessageOptions *
Arena::CreateMaybeMessage< protobuf::MessageOptions >(Arena * )
protobuf::MethodDescriptorProto *
Arena::CreateMaybeMessage< protobuf::MethodDescriptorProto >(Arena * )
protobuf::MethodOptions *
Arena::CreateMaybeMessage< protobuf::MethodOptions >(Arena * )
protobuf::OneofDescriptorProto *
Arena::CreateMaybeMessage< protobuf::OneofDescriptorProto >(Arena * )
protobuf::OneofOptions *
Arena::CreateMaybeMessage< protobuf::OneofOptions >(Arena * )
protobuf::ServiceDescriptorProto *
Arena::CreateMaybeMessage< protobuf::ServiceDescriptorProto >(Arena * )
protobuf::ServiceOptions *
Arena::CreateMaybeMessage< protobuf::ServiceOptions >(Arena * )
protobuf::SourceCodeInfo *
Arena::CreateMaybeMessage< protobuf::SourceCodeInfo >(Arena * )
protobuf::SourceCodeInfo_Location *
Arena::CreateMaybeMessage< protobuf::SourceCodeInfo_Location >(Arena * )
protobuf::UninterpretedOption *
Arena::CreateMaybeMessage< protobuf::UninterpretedOption >(Arena * )
protobuf::UninterpretedOption_NamePart *
Arena::CreateMaybeMessage< protobuf::UninterpretedOption_NamePart >(Arena * )
bool
FieldDescriptorProto_Type_IsValid(int value)
const ::protobuf::EnumDescriptor *
FieldDescriptorProto_Type_descriptor()
template const std::string &
FieldDescriptorProto_Type_Name(T enum_t_value)
bool
FieldDescriptorProto_Type_Parse(::protobuf::ConstStringParam name, FieldDescriptorProto_Type * value)
bool
FieldDescriptorProto_Label_IsValid(int value)
const ::protobuf::EnumDescriptor *
FieldDescriptorProto_Label_descriptor()
template const std::string &
FieldDescriptorProto_Label_Name(T enum_t_value)
bool
FieldDescriptorProto_Label_Parse(::protobuf::ConstStringParam name, FieldDescriptorProto_Label * value)
bool
FileOptions_OptimizeMode_IsValid(int value)
const ::protobuf::EnumDescriptor *
FileOptions_OptimizeMode_descriptor()
template const std::string &
FileOptions_OptimizeMode_Name(T enum_t_value)
bool
FileOptions_OptimizeMode_Parse(::protobuf::ConstStringParam name, FileOptions_OptimizeMode * value)
bool
FieldOptions_CType_IsValid(int value)
const ::protobuf::EnumDescriptor *
FieldOptions_CType_descriptor()
template const std::string &
FieldOptions_CType_Name(T enum_t_value)
bool
FieldOptions_CType_Parse(::protobuf::ConstStringParam name, FieldOptions_CType * value)
bool
FieldOptions_JSType_IsValid(int value)
const ::protobuf::EnumDescriptor *
FieldOptions_JSType_descriptor()
template const std::string &
FieldOptions_JSType_Name(T enum_t_value)
bool
FieldOptions_JSType_Parse(::protobuf::ConstStringParam name, FieldOptions_JSType * value)
bool
MethodOptions_IdempotencyLevel_IsValid(int value)
const ::protobuf::EnumDescriptor *
MethodOptions_IdempotencyLevel_descriptor()
template const std::string &
MethodOptions_IdempotencyLevel_Name(T enum_t_value)
bool
MethodOptions_IdempotencyLevel_Parse(::protobuf::ConstStringParam name, MethodOptions_IdempotencyLevel * value)
const EnumDescriptor *
GetEnumDescriptor< protobuf::FieldDescriptorProto_Type >()
const EnumDescriptor *
GetEnumDescriptor< protobuf::FieldDescriptorProto_Label >()
const EnumDescriptor *
GetEnumDescriptor< protobuf::FileOptions_OptimizeMode >()
const EnumDescriptor *
GetEnumDescriptor< protobuf::FieldOptions_CType >()
const EnumDescriptor *
GetEnumDescriptor< protobuf::FieldOptions_JSType >()
const EnumDescriptor *
GetEnumDescriptor< protobuf::MethodOptions_IdempotencyLevel >()

enum protobuf::FieldDescriptorProto_Type {
  FieldDescriptorProto_Type_TYPE_DOUBLE = = 1,
  FieldDescriptorProto_Type_TYPE_FLOAT = = 2,
  FieldDescriptorProto_Type_TYPE_INT64 = = 3,
  FieldDescriptorProto_Type_TYPE_UINT64 = = 4,
  FieldDescriptorProto_Type_TYPE_INT32 = = 5,
  FieldDescriptorProto_Type_TYPE_FIXED64 = = 6,
  FieldDescriptorProto_Type_TYPE_FIXED32 = = 7,
  FieldDescriptorProto_Type_TYPE_BOOL = = 8,
  FieldDescriptorProto_Type_TYPE_STRING = = 9,
  FieldDescriptorProto_Type_TYPE_GROUP = = 10,
  FieldDescriptorProto_Type_TYPE_MESSAGE = = 11,
  FieldDescriptorProto_Type_TYPE_BYTES = = 12,
  FieldDescriptorProto_Type_TYPE_UINT32 = = 13,
  FieldDescriptorProto_Type_TYPE_ENUM = = 14,
  FieldDescriptorProto_Type_TYPE_SFIXED32 = = 15,
  FieldDescriptorProto_Type_TYPE_SFIXED64 = = 16,
  FieldDescriptorProto_Type_TYPE_SINT32 = = 17,
  FieldDescriptorProto_Type_TYPE_SINT64 = = 18
}

FieldDescriptorProto_Type_TYPE_DOUBLE
FieldDescriptorProto_Type_TYPE_FLOAT
FieldDescriptorProto_Type_TYPE_INT64
FieldDescriptorProto_Type_TYPE_UINT64
FieldDescriptorProto_Type_TYPE_INT32
FieldDescriptorProto_Type_TYPE_FIXED64
FieldDescriptorProto_Type_TYPE_FIXED32
FieldDescriptorProto_Type_TYPE_BOOL
FieldDescriptorProto_Type_TYPE_STRING
FieldDescriptorProto_Type_TYPE_GROUP
FieldDescriptorProto_Type_TYPE_MESSAGE
FieldDescriptorProto_Type_TYPE_BYTES
FieldDescriptorProto_Type_TYPE_UINT32
FieldDescriptorProto_Type_TYPE_ENUM
FieldDescriptorProto_Type_TYPE_SFIXED32
FieldDescriptorProto_Type_TYPE_SFIXED64
FieldDescriptorProto_Type_TYPE_SINT32
FieldDescriptorProto_Type_TYPE_SINT64

enum protobuf::FieldDescriptorProto_Label {
  FieldDescriptorProto_Label_LABEL_OPTIONAL = = 1,
  FieldDescriptorProto_Label_LABEL_REQUIRED = = 2,
  FieldDescriptorProto_Label_LABEL_REPEATED = = 3
}

FieldDescriptorProto_Label_LABEL_OPTIONAL
FieldDescriptorProto_Label_LABEL_REQUIRED
FieldDescriptorProto_Label_LABEL_REPEATED

enum protobuf::FileOptions_OptimizeMode {
  FileOptions_OptimizeMode_SPEED = = 1,
  FileOptions_OptimizeMode_CODE_SIZE = = 2,
  FileOptions_OptimizeMode_LITE_RUNTIME = = 3
}

FileOptions_OptimizeMode_SPEED
FileOptions_OptimizeMode_CODE_SIZE
FileOptions_OptimizeMode_LITE_RUNTIME

enum protobuf::FieldOptions_CType {
  FieldOptions_CType_STRING = = 0,
  FieldOptions_CType_CORD = = 1,
  FieldOptions_CType_STRING_PIECE = = 2
}

FieldOptions_CType_STRING
FieldOptions_CType_CORD
FieldOptions_CType_STRING_PIECE

enum protobuf::FieldOptions_JSType {
  FieldOptions_JSType_JS_NORMAL = = 0,
  FieldOptions_JSType_JS_STRING = = 1,
  FieldOptions_JSType_JS_NUMBER = = 2
}

FieldOptions_JSType_JS_NORMAL
FieldOptions_JSType_JS_STRING
FieldOptions_JSType_JS_NUMBER

enum protobuf::MethodOptions_IdempotencyLevel {
  MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN = = 0,
  MethodOptions_IdempotencyLevel_NO_SIDE_EFFECTS = = 1,
  MethodOptions_IdempotencyLevel_IDEMPOTENT = = 2
}

MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN
MethodOptions_IdempotencyLevel_NO_SIDE_EFFECTS
MethodOptions_IdempotencyLevel_IDEMPOTENT
diff --git a/content/reference/cpp/api-docs/google.protobuf.descriptor_database.md b/content/reference/cpp/api-docs/google.protobuf.descriptor_database.md deleted file mode 100644 index c2f28e434..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.descriptor_database.md +++ /dev/null @@ -1,54 +0,0 @@ -+++ -title = "descriptor_database.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/descriptor_database.h>
namespace google::protobuf

Interface for manipulating databases of descriptors.

Classes in this file

Abstract interface for a database of descriptors.
A DescriptorDatabase into which you can insert files manually.
Very similar to SimpleDescriptorDatabase, but stores all the descriptors as raw bytes and generally tries to use as little memory as possible.
A DescriptorDatabase that fetches files from a given pool.
A DescriptorDatabase that wraps two or more others.

class DescriptorDatabase

#include <google/protobuf/descriptor_database.h>
namespace google::protobuf

Abstract interface for a database of descriptors.

This is useful if you want to create a DescriptorPool which loads descriptors on-demand from some sort of large database. If the database is large, it may be inefficient to enumerate every .proto file inside it calling DescriptorPool::BuildFile() for each one. Instead, a DescriptorPool can be created which wraps a DescriptorDatabase and only builds particular descriptors when they are needed.

- -

Known subclasses:

Members

DescriptorDatabase()
virtual
~DescriptorDatabase()
virtual bool
FindFileByName(const std::string & filename, FileDescriptorProto * output) = 0
Find a file by file name. more...
virtual bool
FindFileContainingSymbol(const std::string & symbol_name, FileDescriptorProto * output) = 0
Find the file that declares the given fully-qualified symbol name. more...
virtual bool
FindFileContainingExtension(const std::string & containing_type, int field_number, FileDescriptorProto * output) = 0
Find the file which defines an extension extending the given message type with the given field number. more...
virtual bool
FindAllExtensionNumbers(const std::string & , std::vector< int > * )
Finds the tag numbers used by all known extensions of extendee_type, and appends them to output in an undefined order. more...
virtual bool
FindAllFileNames(std::vector< std::string > * )
Finds the file names and appends them to the output in an undefined order. more...
bool
FindAllPackageNames(std::vector< std::string > * output)
Finds the package names and appends them to the output in an undefined order. more...
bool
FindAllMessageNames(std::vector< std::string > * output)
Finds the message names and appends them to the output in an undefined order. more...

virtual bool DescriptorDatabase::FindFileByName(
        const std::string & filename,
        FileDescriptorProto * output) = 0

Find a file by file name.

Fills in in *output and returns true if found. Otherwise, returns false, leaving the contents of *output undefined.

-

virtual bool DescriptorDatabase::FindFileContainingSymbol(
        const std::string & symbol_name,
        FileDescriptorProto * output) = 0

Find the file that declares the given fully-qualified symbol name.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined.

-

virtual bool DescriptorDatabase::FindFileContainingExtension(
        const std::string & containing_type,
        int field_number,
        FileDescriptorProto * output) = 0

Find the file which defines an extension extending the given message type with the given field number.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined. containing_type must be a fully-qualified type name.

-

virtual bool DescriptorDatabase::FindAllExtensionNumbers(
        const std::string & ,
        std::vector< int > * )

Finds the tag numbers used by all known extensions of extendee_type, and appends them to output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all extensions, and it's not guaranteed that FindFileContainingExtension will return true on all of the found numbers. Returns true if the search was successful, otherwise returns false and leaves output unchanged.

- -

This method has a default implementation that always returns false.

-

virtual bool DescriptorDatabase::FindAllFileNames(
        std::vector< std::string > * )

Finds the file names and appends them to the output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all files. Returns true if the database supports searching all file names, otherwise returns false and leaves output unchanged.

- -

This method has a default implementation that always returns false.

-

bool DescriptorDatabase::FindAllPackageNames(
        std::vector< std::string > * output)

Finds the package names and appends them to the output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all packages. Returns true if the database supports searching all package names, otherwise returns false and leaves output unchanged.

-

bool DescriptorDatabase::FindAllMessageNames(
        std::vector< std::string > * output)

Finds the message names and appends them to the output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all messages. Returns true if the database supports searching all message names, otherwise returns false and leaves output unchanged.

-

class SimpleDescriptorDatabase: public DescriptorDatabase

#include <google/protobuf/descriptor_database.h>
namespace google::protobuf

A DescriptorDatabase into which you can insert files manually.

FindFileContainingSymbol() is fully-implemented. When you add a file, its symbols will be indexed for this purpose. Note that the implementation may return false positives, but only if it isn't possible for the symbol to be defined in any other file. In particular, if a file defines a symbol "Foo", then searching for "Foo.[anything]" will match that file. This way, the database does not need to aggressively index all children of a symbol.

- -

FindFileContainingExtension() is mostly-implemented. It works if and only if the original FieldDescriptorProto defining the extension has a fully-qualified type name in its "extendee" field (i.e. starts with a '.'). If the extendee is a relative name, SimpleDescriptorDatabase will not attempt to resolve the type, so it will not know what type the extension is extending. Therefore, calling FindFileContainingExtension() with the extension's containing type will never actually find that extension. Note that this is an unlikely problem, as all FileDescriptorProtos created by the protocol compiler (as well as ones created by calling FileDescriptor::CopyTo()) will always use fully-qualified names for all types. You only need to worry if you are constructing FileDescriptorProtos yourself, or are calling compiler::Parser directly.

- -

Members

SimpleDescriptorDatabase()
~SimpleDescriptorDatabase()
bool
Add(const FileDescriptorProto & file)
Adds the FileDescriptorProto to the database, making a copy. more...
bool
AddAndOwn(const FileDescriptorProto * file)
Adds the FileDescriptorProto to the database and takes ownership of it.

implements DescriptorDatabase

virtual bool
FindFileByName(const std::string & filename, FileDescriptorProto * output)
Find a file by file name. more...
virtual bool
FindFileContainingSymbol(const std::string & symbol_name, FileDescriptorProto * output)
Find the file that declares the given fully-qualified symbol name. more...
virtual bool
FindFileContainingExtension(const std::string & containing_type, int field_number, FileDescriptorProto * output)
Find the file which defines an extension extending the given message type with the given field number. more...
virtual bool
FindAllExtensionNumbers(const std::string & , std::vector< int > * )
Finds the tag numbers used by all known extensions of extendee_type, and appends them to output in an undefined order. more...
virtual bool
FindAllFileNames(std::vector< std::string > * )
Finds the file names and appends them to the output in an undefined order. more...

bool SimpleDescriptorDatabase::Add(
        const FileDescriptorProto & file)

Adds the FileDescriptorProto to the database, making a copy.

The object can be deleted after Add() returns. Returns false if the file conflicted with a file already in the database, in which case an error will have been written to GOOGLE_LOG(ERROR).

-

virtual bool SimpleDescriptorDatabase::FindFileByName(
        const std::string & filename,
        FileDescriptorProto * output)

Find a file by file name.

Fills in in *output and returns true if found. Otherwise, returns false, leaving the contents of *output undefined.

-

virtual bool SimpleDescriptorDatabase::FindFileContainingSymbol(
        const std::string & symbol_name,
        FileDescriptorProto * output)

Find the file that declares the given fully-qualified symbol name.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined.

-

virtual bool SimpleDescriptorDatabase::FindFileContainingExtension(
        const std::string & containing_type,
        int field_number,
        FileDescriptorProto * output)

Find the file which defines an extension extending the given message type with the given field number.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined. containing_type must be a fully-qualified type name.

-

virtual bool SimpleDescriptorDatabase::FindAllExtensionNumbers(
        const std::string & ,
        std::vector< int > * )

Finds the tag numbers used by all known extensions of extendee_type, and appends them to output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all extensions, and it's not guaranteed that FindFileContainingExtension will return true on all of the found numbers. Returns true if the search was successful, otherwise returns false and leaves output unchanged.

-

This method has a default implementation that always returns false.

-

virtual bool SimpleDescriptorDatabase::FindAllFileNames(
        std::vector< std::string > * )

Finds the file names and appends them to the output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all files. Returns true if the database supports searching all file names, otherwise returns false and leaves output unchanged.

-

This method has a default implementation that always returns false.

-

class EncodedDescriptorDatabase: public DescriptorDatabase

#include <google/protobuf/descriptor_database.h>
namespace google::protobuf

Very similar to SimpleDescriptorDatabase, but stores all the descriptors as raw bytes and generally tries to use as little memory as possible.

The same caveats regarding FindFileContainingExtension() apply as with SimpleDescriptorDatabase.

-

Members

EncodedDescriptorDatabase()
~EncodedDescriptorDatabase()
bool
Add(const void * encoded_file_descriptor, int size)
Adds the FileDescriptorProto to the database. more...
bool
AddCopy(const void * encoded_file_descriptor, int size)
Like Add(), but makes a copy of the data, so that the caller does not need to keep it around.
bool
FindNameOfFileContainingSymbol(const std::string & symbol_name, std::string * output)
Like FindFileContainingSymbol but returns only the name of the file.

implements DescriptorDatabase

virtual bool
FindFileByName(const std::string & filename, FileDescriptorProto * output)
Find a file by file name. more...
virtual bool
FindFileContainingSymbol(const std::string & symbol_name, FileDescriptorProto * output)
Find the file that declares the given fully-qualified symbol name. more...
virtual bool
FindFileContainingExtension(const std::string & containing_type, int field_number, FileDescriptorProto * output)
Find the file which defines an extension extending the given message type with the given field number. more...
virtual bool
FindAllExtensionNumbers(const std::string & , std::vector< int > * )
Finds the tag numbers used by all known extensions of extendee_type, and appends them to output in an undefined order. more...
virtual bool
FindAllFileNames(std::vector< std::string > * )
Finds the file names and appends them to the output in an undefined order. more...

bool EncodedDescriptorDatabase::Add(
        const void * encoded_file_descriptor,
        int size)

Adds the FileDescriptorProto to the database.

The descriptor is provided in encoded form. The database does not make a copy of the bytes, nor does it take ownership; it's up to the caller to make sure the bytes remain valid for the life of the database. Returns false and logs an error if the bytes are not a valid FileDescriptorProto or if the file conflicted with a file already in the database.

-

virtual bool EncodedDescriptorDatabase::FindFileByName(
        const std::string & filename,
        FileDescriptorProto * output)

Find a file by file name.

Fills in in *output and returns true if found. Otherwise, returns false, leaving the contents of *output undefined.

-

virtual bool EncodedDescriptorDatabase::FindFileContainingSymbol(
        const std::string & symbol_name,
        FileDescriptorProto * output)

Find the file that declares the given fully-qualified symbol name.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined.

-

virtual bool EncodedDescriptorDatabase::FindFileContainingExtension(
        const std::string & containing_type,
        int field_number,
        FileDescriptorProto * output)

Find the file which defines an extension extending the given message type with the given field number.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined. containing_type must be a fully-qualified type name.

-

virtual bool EncodedDescriptorDatabase::FindAllExtensionNumbers(
        const std::string & ,
        std::vector< int > * )

Finds the tag numbers used by all known extensions of extendee_type, and appends them to output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all extensions, and it's not guaranteed that FindFileContainingExtension will return true on all of the found numbers. Returns true if the search was successful, otherwise returns false and leaves output unchanged.

-

This method has a default implementation that always returns false.

-

virtual bool EncodedDescriptorDatabase::FindAllFileNames(
        std::vector< std::string > * )

Finds the file names and appends them to the output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all files. Returns true if the database supports searching all file names, otherwise returns false and leaves output unchanged.

-

This method has a default implementation that always returns false.

-

class DescriptorPoolDatabase: public DescriptorDatabase

#include <google/protobuf/descriptor_database.h>
namespace google::protobuf

A DescriptorDatabase that fetches files from a given pool.

Members

explicit
DescriptorPoolDatabase(const DescriptorPool & pool)
~DescriptorPoolDatabase()

implements DescriptorDatabase

virtual bool
FindFileByName(const std::string & filename, FileDescriptorProto * output)
Find a file by file name. more...
virtual bool
FindFileContainingSymbol(const std::string & symbol_name, FileDescriptorProto * output)
Find the file that declares the given fully-qualified symbol name. more...
virtual bool
FindFileContainingExtension(const std::string & containing_type, int field_number, FileDescriptorProto * output)
Find the file which defines an extension extending the given message type with the given field number. more...
virtual bool
FindAllExtensionNumbers(const std::string & , std::vector< int > * )
Finds the tag numbers used by all known extensions of extendee_type, and appends them to output in an undefined order. more...

virtual bool DescriptorPoolDatabase::FindFileByName(
        const std::string & filename,
        FileDescriptorProto * output)

Find a file by file name.

Fills in in *output and returns true if found. Otherwise, returns false, leaving the contents of *output undefined.

-

virtual bool DescriptorPoolDatabase::FindFileContainingSymbol(
        const std::string & symbol_name,
        FileDescriptorProto * output)

Find the file that declares the given fully-qualified symbol name.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined.

-

virtual bool DescriptorPoolDatabase::FindFileContainingExtension(
        const std::string & containing_type,
        int field_number,
        FileDescriptorProto * output)

Find the file which defines an extension extending the given message type with the given field number.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined. containing_type must be a fully-qualified type name.

-

virtual bool DescriptorPoolDatabase::FindAllExtensionNumbers(
        const std::string & ,
        std::vector< int > * )

Finds the tag numbers used by all known extensions of extendee_type, and appends them to output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all extensions, and it's not guaranteed that FindFileContainingExtension will return true on all of the found numbers. Returns true if the search was successful, otherwise returns false and leaves output unchanged.

-

This method has a default implementation that always returns false.

-

class MergedDescriptorDatabase: public DescriptorDatabase

#include <google/protobuf/descriptor_database.h>
namespace google::protobuf

A DescriptorDatabase that wraps two or more others.

It first searches the first database and, if that fails, tries the second, and so on.

-

Members

MergedDescriptorDatabase(DescriptorDatabase * source1, DescriptorDatabase * source2)
Merge just two databases. The sources remain property of the caller.
explicit
MergedDescriptorDatabase(const std::vector< DescriptorDatabase * > & sources)
Merge more than two databases. more...
~MergedDescriptorDatabase()

implements DescriptorDatabase

virtual bool
FindFileByName(const std::string & filename, FileDescriptorProto * output)
Find a file by file name. more...
virtual bool
FindFileContainingSymbol(const std::string & symbol_name, FileDescriptorProto * output)
Find the file that declares the given fully-qualified symbol name. more...
virtual bool
FindFileContainingExtension(const std::string & containing_type, int field_number, FileDescriptorProto * output)
Find the file which defines an extension extending the given message type with the given field number. more...
virtual bool
FindAllExtensionNumbers(const std::string & extendee_type, std::vector< int > * output)
Merges the results of calling all databases. more...

explicit MergedDescriptorDatabase::MergedDescriptorDatabase(
        const std::vector< DescriptorDatabase * > & sources)

Merge more than two databases.

The sources remain property of the caller. The vector may be deleted after the constructor returns but the DescriptorDatabases need to stick around.

-

virtual bool MergedDescriptorDatabase::FindFileByName(
        const std::string & filename,
        FileDescriptorProto * output)

Find a file by file name.

Fills in in *output and returns true if found. Otherwise, returns false, leaving the contents of *output undefined.

-

virtual bool MergedDescriptorDatabase::FindFileContainingSymbol(
        const std::string & symbol_name,
        FileDescriptorProto * output)

Find the file that declares the given fully-qualified symbol name.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined.

-

virtual bool MergedDescriptorDatabase::FindFileContainingExtension(
        const std::string & containing_type,
        int field_number,
        FileDescriptorProto * output)

Find the file which defines an extension extending the given message type with the given field number.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined. containing_type must be a fully-qualified type name.

-

virtual bool MergedDescriptorDatabase::FindAllExtensionNumbers(
        const std::string & extendee_type,
        std::vector< int > * output)

Merges the results of calling all databases.

Returns true iff any of the databases returned true.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.dynamic_message.md b/content/reference/cpp/api-docs/google.protobuf.dynamic_message.md deleted file mode 100644 index 17d432754..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.dynamic_message.md +++ /dev/null @@ -1,22 +0,0 @@ - - -+++ -title = "dynamic_message.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/dynamic_message.h>
namespace google::protobuf

Defines an implementation of Message which can emulate types which are not known at compile-time.

Classes in this file

Constructs implementations of Message which can emulate types which are not known at compile-time.
Helper for computing a sorted list of map entries via reflection.

class DynamicMessageFactory: public MessageFactory

#include <google/protobuf/dynamic_message.h>
namespace google::protobuf

Constructs implementations of Message which can emulate types which are not known at compile-time.

Sometimes you want to be able to manipulate protocol types that you don't know about at compile time. It would be nice to be able to construct a Message object which implements the message type given by any arbitrary Descriptor. DynamicMessage provides this.

- -

As it turns out, a DynamicMessage needs to construct extra information about its type in order to operate. Most of this information can be shared between all DynamicMessages of the same type. But, caching this information in some sort of global map would be a bad idea, since the cached information for a particular descriptor could outlive the descriptor itself. To avoid this problem, DynamicMessageFactory encapsulates this "cache". All DynamicMessages of the same type created from the same factory will share the same support data. Any Descriptors used with a particular factory must outlive the factory.

- -

Members

DynamicMessageFactory()
Construct a DynamicMessageFactory that will search for extensions in the DescriptorPool in which the extendee is defined.
DynamicMessageFactory(const DescriptorPool * pool)
Construct a DynamicMessageFactory that will search for extensions in the given DescriptorPool. more...
~DynamicMessageFactory()
void
SetDelegateToGeneratedFactory(bool enable)
Call this to tell the DynamicMessageFactory that if it is given a Descriptor d for which: more...

implements MessageFactory

virtual const Message *
GetPrototype(const Descriptor * type)
Given a Descriptor, constructs the default (prototype) Message of that type. more...

DynamicMessageFactory::DynamicMessageFactory(
        const DescriptorPool * pool)

Construct a DynamicMessageFactory that will search for extensions in the given DescriptorPool.

DEPRECATED: Use CodedInputStream::SetExtensionRegistry() to tell the parser to look for extensions in an alternate pool. However, note that this is almost never what you want to do. Almost all users should use the zero-arg constructor.

-

void DynamicMessageFactory::SetDelegateToGeneratedFactory(
        bool enable)

Call this to tell the DynamicMessageFactory that if it is given a Descriptor d for which:

d->file()->pool() == DescriptorPool::generated_pool(),
-

then it should delegate to MessageFactory::generated_factory() instead of constructing a dynamic implementation of the message. In theory there is no down side to doing this, so it may become the default in the future.

-

virtual const Message * DynamicMessageFactory::GetPrototype(
        const Descriptor * type)

Given a Descriptor, constructs the default (prototype) Message of that type.

You can then call that message's New() method to construct a mutable message of that type.

-

Calling this method twice with the same Descriptor returns the same object. The returned object remains property of the factory and will be destroyed when the factory is destroyed. Also, any objects created by calling the prototype's New() method share some data with the prototype, so these must be destroyed before the DynamicMessageFactory is destroyed.

-

The given descriptor must outlive the returned message, and hence must outlive the DynamicMessageFactory.

-

The method is thread-safe.

-

class DynamicMapSorter

#include <google/protobuf/dynamic_message.h>
namespace google::protobuf

Helper for computing a sorted list of map entries via reflection.

Members

static std::vector< const Message * >
Sort(const Message & message, int map_size, const Reflection * reflection, const FieldDescriptor * field)
diff --git a/content/reference/cpp/api-docs/google.protobuf.io.coded_stream.md b/content/reference/cpp/api-docs/google.protobuf.io.coded_stream.md deleted file mode 100644 index 04db2bc81..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.io.coded_stream.md +++ /dev/null @@ -1,187 +0,0 @@ -+++ -title = "coded_stream.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/io/coded_stream.h>
namespace google::protobuf::io

This file contains the CodedInputStream and CodedOutputStream classes, which wrap a ZeroCopyInputStream or ZeroCopyOutputStream, respectively, and allow you to read or write individual pieces of data in various formats.

In particular, these implement the varint encoding for integers, a simple variable-length encoding in which smaller numbers take fewer bytes.

- -

Typically these classes will only be used internally by the protocol buffer library in order to encode and decode protocol buffers. Clients of the library only need to know about this class if they wish to write custom message parsing or serialization procedures.

- -

CodedOutputStream example:

- -
// Write some data to "myfile".  First we write a 4-byte "magic number"
-// to identify the file type, then write a length-delimited string.  The
-// string is composed of a varint giving the length followed by the raw
-// bytes.
-int fd = open("myfile", O_CREAT | O_WRONLY);
-ZeroCopyOutputStream* raw_output = new FileOutputStream(fd);
-CodedOutputStream* coded_output = new CodedOutputStream(raw_output);
-
-int magic_number = 1234;
-char text[] = "Hello world!";
-coded_output->WriteLittleEndian32(magic_number);
-coded_output->WriteVarint32(strlen(text));
-coded_output->WriteRaw(text, strlen(text));
-
-delete coded_output;
-delete raw_output;
-close(fd);
- -

CodedInputStream example:

- -
// Read a file created by the above code.
-int fd = open("myfile", O_RDONLY);
-ZeroCopyInputStream* raw_input = new FileInputStream(fd);
-CodedInputStream* coded_input = new CodedInputStream(raw_input);
-
-coded_input->ReadLittleEndian32(&magic_number);
-if (magic_number != 1234) {
-  cerr << "File not in expected format." << endl;
-  return;
-}
-
-uint32 size;
-coded_input->ReadVarint32(&size);
-
-char* text = new char[size + 1];
-coded_input->ReadRaw(buffer, size);
-text[size] = '\0';
-
-delete coded_input;
-delete raw_input;
-close(fd);
-
-cout << "Text is: " << text << endl;
-delete [] text;
- -

For those who are interested, varint encoding is defined as follows:

- -

The encoding operates on unsigned integers of up to 64 bits in length. Each byte of the encoded value has the format:

- -
    -
  • bits 0-6: Seven bits of the number being encoded.
  • -
  • bit 7: Zero if this is the last byte in the encoding (in which case all remaining bits of the number are zero) or 1 if more bytes follow. The first byte contains the least-significant 7 bits of the number, the second byte (if present) contains the next-least-significant 7 bits, and so on. So, the binary number 1011000101011 would be encoded in two bytes as "10101011 00101100".
  • -
- -

In theory, varint could be used to encode integers of any length. However, for practicality we set a limit at 64 bits. The maximum encoded length of a number is thus 10 bytes.

- -

Classes in this file

Class which reads and decodes binary data which is composed of varint- encoded integers and fixed-width pieces.
EpsCopyOutputStream wraps a ZeroCopyOutputStream and exposes a new stream, which has the property you can write kSlopBytes (16 bytes) from the current position without bounds checks.
Class which encodes and writes binary data which is composed of varint- encoded integers and fixed-width pieces.
Compile-time equivalent of VarintSize32().

class CodedInputStream

#include <google/protobuf/io/coded_stream.h>
namespace google::protobuf::io

Class which reads and decodes binary data which is composed of varint- encoded integers and fixed-width pieces.

Wraps a ZeroCopyInputStream. Most users will not need to deal with CodedInputStream.

-

Most methods of CodedInputStream that return a bool return false if an underlying I/O error occurs or if the data is malformed. Once such a failure occurs, the CodedInputStream is broken and is no longer useful. After a failure, callers also should assume writes to "out" args may have occurred, though nothing useful can be determined from those writes.

-

Members

explicit
CodedInputStream(ZeroCopyInputStream * input)
Create a CodedInputStream that reads from the given ZeroCopyInputStream.
explicit
CodedInputStream(const uint8 * buffer, int size)
Create a CodedInputStream that reads from the given flat array. more...
~CodedInputStream()
Destroy the CodedInputStream and position the underlying ZeroCopyInputStream at the first unread byte. more...
bool
IsFlat() const
Return true if this CodedInputStream reads from a flat array instead of a ZeroCopyInputStream.
bool
Skip(int count)
Skips a number of bytes. more...
bool
GetDirectBufferPointer(const void ** data, int * size)
Sets *data to point directly at the unread part of the CodedInputStream's underlying buffer, and *size to the size of that buffer, but does not advance the stream's current position. more...
void
GetDirectBufferPointerInline(const void ** data, int * size)
Like GetDirectBufferPointer, but this method is inlined, and does not attempt to Refresh() if the buffer is currently empty.
bool
ReadRaw(void * buffer, int size)
Read raw bytes, copying them into the given buffer.
bool
ReadString(std::string * buffer, int size)
Like ReadRaw, but reads into a string.
bool
ReadLittleEndian32(uint32 * value)
Read a 32-bit little-endian integer.
bool
ReadLittleEndian64(uint64 * value)
Read a 64-bit little-endian integer.
bool
ReadVarint32(uint32 * value)
Read an unsigned integer with Varint encoding, truncating to 32 bits. more...
bool
ReadVarint64(uint64 * value)
Read an unsigned integer with Varint encoding.
bool
ReadVarintSizeAsInt(int * value)
Reads a varint off the wire into an "int". more...
uint32
ReadTag()
Read a tag. more...
uint32
ReadTagNoLastTag()
std::pair< uint32, bool >
ReadTagWithCutoff(uint32 cutoff)
This usually a faster alternative to ReadTag() when cutoff is a manifest constant. more...
std::pair< uint32, bool >
ReadTagWithCutoffNoLastTag(uint32 cutoff)
bool
ExpectTag(uint32 expected)
Usually returns true if calling ReadVarint32() now would produce the given value. more...
bool
ExpectAtEnd()
Usually returns true if no more bytes can be read. more...
bool
LastTagWas(uint32 expected)
If the last call to ReadTag() or ReadTagWithCutoff() returned the given value, returns true. more...
void
SetLastTag(uint32 tag)
bool
ConsumedEntireMessage()
When parsing message (but NOT a group), this method must be called immediately after MergeFromCodedStream() returns (if it returns true) to further verify that the message ended in a legitimate way. more...
void
SetConsumed()
static const uint8 *
ReadLittleEndian32FromArray(const uint8 * buffer, uint32 * value)
These methods read from an externally provided buffer. more...
static const uint8 *
ReadLittleEndian64FromArray(const uint8 * buffer, uint64 * value)
Read a 64-bit little-endian integer. more...
static const uint8 *
ExpectTagFromArray(const uint8 * buffer, uint32 expected)
Like above, except this reads from the specified buffer. more...

Limits

Limits are used when parsing length-delimited embedded messages. After the message's length is read, PushLimit() is used to prevent the CodedInputStream from reading beyond that length. Once the embedded message has been parsed, PopLimit() is called to undo the limit.
typedef
int Limit
Opaque type used with PushLimit() and PopLimit(). more...
Limit
PushLimit(int byte_limit)
Places a limit on the number of bytes that the stream may read, starting from the current position. more...
void
PopLimit(Limit limit)
Pops the last limit pushed by PushLimit(). more...
int
BytesUntilLimit() const
Returns the number of bytes left until the nearest limit on the stack is hit, or -1 if no limits are in place.
int
CurrentPosition() const
Returns current position relative to the beginning of the input stream.

Total Bytes Limit

To prevent malicious users from sending excessively large messages and causing memory exhaustion, CodedInputStream imposes a hard limit on the total number of bytes it will read.
int = { - SetTotalBytesLimit(total_bytes_limit)
void
SetTotalBytesLimit(int total_bytes_limit)
Sets the maximum number of bytes that this CodedInputStream will read before refusing to continue. more...
PROTOBUF_DEPRECATED_MSG("Please use the single parameter version of SetTotalBytesLimit(). The " "second parameter is ignored." )
int
BytesUntilTotalBytesLimit() const
The Total Bytes Limit minus the Current Position, or -1 if the total bytes limit is INT_MAX.

Recursion Limit

-

To prevent corrupt or malicious messages from causing stack overflows, we must keep track of the depth of recursion when parsing embedded messages and groups.

-

CodedInputStream keeps track of this because it is the only object that is passed down the stack during parsing.

-
void
SetRecursionLimit(int limit)
Sets the maximum recursion depth. The default is 100.
int
RecursionBudget()
bool
IncrementRecursionDepth()
Increments the current recursion depth. more...
void
DecrementRecursionDepth()
Decrements the recursion depth if possible.
void
UnsafeDecrementRecursionDepth()
Decrements the recursion depth blindly. more...
std::pair< CodedInputStream::Limit, int >
IncrementRecursionDepthAndPushLimit(int byte_limit)
Shorthand for make_pair(PushLimit(byte_limit), –recursion_budget_). more...
Limit
ReadLengthAndPushLimit()
Shorthand for PushLimit(ReadVarint32(&length) ? length : 0).
bool
DecrementRecursionDepthAndPopLimit(Limit limit)
Helper that is equivalent to: { bool result = ConsumedEntireMessage(); PopLimit(limit); UnsafeDecrementRecursionDepth(); return result; } Using this can reduce code size and complexity in some cases. more...
bool
CheckEntireMessageConsumedAndPopLimit(Limit limit)
Helper that is equivalent to: { bool result = ConsumedEntireMessage(); PopLimit(limit); return result; } Using this can reduce code size and complexity in some cases.
static int
GetDefaultRecursionLimit()

Extension Registry

-

ADVANCED USAGE: 99.9% of people can ignore this section.

-

By default, when parsing extensions, the parser looks for extension definitions in the pool which owns the outer message's Descriptor. However, you may call SetExtensionRegistry() to provide an alternative pool instead. This makes it possible, for example, to parse a message using a generated class, but represent some extensions using DynamicMessage.

-
void
SetExtensionRegistry(const DescriptorPool * pool, MessageFactory * factory)
Set the pool used to look up extensions. more...
const DescriptorPool *
GetExtensionPool()
Get the DescriptorPool set via SetExtensionRegistry(), or NULL if no pool has been provided.
MessageFactory *
GetExtensionFactory()
Get the MessageFactory set via SetExtensionRegistry(), or NULL if no factory has been provided.

explicit CodedInputStream::CodedInputStream(
        const uint8 * buffer,
        int size)

Create a CodedInputStream that reads from the given flat array.

This is faster than using an ArrayInputStream. PushLimit(size) is implied by this constructor.

-

CodedInputStream::~CodedInputStream()

Destroy the CodedInputStream and position the underlying ZeroCopyInputStream at the first unread byte.

If an error occurred while reading (causing a method to return false), then the exact position of the input stream may be anywhere between the last value that was read successfully and the stream's byte limit.

-

bool CodedInputStream::Skip(
        int count)

Skips a number of bytes.

Returns false if an underlying read error occurs.

-

bool CodedInputStream::GetDirectBufferPointer(
        const void ** data,
        int * size)

Sets *data to point directly at the unread part of the CodedInputStream's underlying buffer, and *size to the size of that buffer, but does not advance the stream's current position.

This will always either produce a non-empty buffer or return false. If the caller consumes any of this data, it should then call Skip() to skip over the consumed bytes. This may be useful for implementing external fast parsing routines for types of data not covered by the CodedInputStream interface.

-

bool CodedInputStream::ReadVarint32(
        uint32 * value)

Read an unsigned integer with Varint encoding, truncating to 32 bits.

Reading a 32-bit value is equivalent to reading a 64-bit one and casting it to uint32, but may be more efficient.

-

bool CodedInputStream::ReadVarintSizeAsInt(
        int * value)

Reads a varint off the wire into an "int".

This should be used for reading sizes off the wire (sizes of strings, submessages, bytes fields, etc).

-

The value from the wire is interpreted as unsigned. If its value exceeds the representable value of an integer on this platform, instead of truncating we return false. Truncating (as performed by ReadVarint32() above) is an acceptable approach for fields representing an integer, but when we are parsing a size from the wire, truncating the value would result in us misparsing the payload.

-

uint32 CodedInputStream::ReadTag()

Read a tag.

This calls ReadVarint32() and returns the result, or returns zero (which is not a valid tag) if ReadVarint32() fails. Also, ReadTag (but not ReadTagNoLastTag) updates the last tag value, which can be checked with LastTagWas().

-

Always inline because this is only called in one place per parse loop but it is called for every iteration of said loop, so it should be fast. GCC doesn't want to inline this by default.

-

std::pair< uint32, bool >
    CodedInputStream::ReadTagWithCutoff(
        uint32 cutoff)

This usually a faster alternative to ReadTag() when cutoff is a manifest constant.

It does particularly well for cutoff >= 127. The first part of the return value is the tag that was read, though it can also be 0 in the cases where ReadTag() would return 0. If the second part is true then the tag is known to be in [0, cutoff]. If not, the tag either is above cutoff or is 0. (There's intentional wiggle room when tag is 0, because that can arise in several ways, and for best performance we want to avoid an extra "is tag == 0?" check here.)

-

bool CodedInputStream::ExpectTag(
        uint32 expected)

Usually returns true if calling ReadVarint32() now would produce the given value.

Will always return false if ReadVarint32() would not return the given value. If ExpectTag() returns true, it also advances past the varint. For best performance, use a compile-time constant as the parameter. Always inline because this collapses to a small number of instructions when given a constant parameter, but GCC doesn't want to inline by default.

-

bool CodedInputStream::ExpectAtEnd()

Usually returns true if no more bytes can be read.

Always returns false if more bytes can be read. If ExpectAtEnd() returns true, a subsequent call to LastTagWas() will act as if ReadTag() had been called and returned zero, and ConsumedEntireMessage() will return true.

-

bool CodedInputStream::LastTagWas(
        uint32 expected)

If the last call to ReadTag() or ReadTagWithCutoff() returned the given value, returns true.

Otherwise, returns false. ReadTagNoLastTag/ReadTagWithCutoffNoLastTag do not preserve the last returned value.

-

This is needed because parsers for some types of embedded messages (with field type TYPE_GROUP) don't actually know that they've reached the end of a message until they see an ENDGROUP tag, which was actually part of the enclosing message. The enclosing message would like to check that tag to make sure it had the right number, so it calls LastTagWas() on return from the embedded parser to check.

-

bool CodedInputStream::ConsumedEntireMessage()

When parsing message (but NOT a group), this method must be called immediately after MergeFromCodedStream() returns (if it returns true) to further verify that the message ended in a legitimate way.

For example, this verifies that parsing did not end on an end-group tag. It also checks for some cases where, due to optimizations, MergeFromCodedStream() can incorrectly return true.

-

static const uint8 * CodedInputStream::ReadLittleEndian32FromArray(
        const uint8 * buffer,
        uint32 * value)

These methods read from an externally provided buffer.

static

-

The caller is responsible for ensuring that the buffer has sufficient space. Read a 32-bit little-endian integer.

-

static const uint8 * CodedInputStream::ReadLittleEndian64FromArray(
        const uint8 * buffer,
        uint64 * value)

Read a 64-bit little-endian integer.

static

-

static const uint8 * CodedInputStream::ExpectTagFromArray(
        const uint8 * buffer,
        uint32 expected)

Like above, except this reads from the specified buffer.

The caller is responsible for ensuring that the buffer is large enough to read a varint of the expected size. For best performance, use a compile-time constant as the expected tag parameter.

-

Returns a pointer beyond the expected tag if it was found, or NULL if it was not.

-

typedef CodedInputStream::Limit

Opaque type used with PushLimit() and PopLimit().

Do not modify values of this type yourself. The only reason that this isn't a struct with private internals is for efficiency.

-

Limit CodedInputStream::PushLimit(
        int byte_limit)

Places a limit on the number of bytes that the stream may read, starting from the current position.

Once the stream hits this limit, it will act like the end of the input has been reached until PopLimit() is called.

-

As the names imply, the stream conceptually has a stack of limits. The shortest limit on the stack is always enforced, even if it is not the top limit.

-

The value returned by PushLimit() is opaque to the caller, and must be passed unchanged to the corresponding call to PopLimit().

-

void CodedInputStream::PopLimit(
        Limit limit)

Pops the last limit pushed by PushLimit().

The input must be the value returned by that call to PushLimit().

-

void CodedInputStream::SetTotalBytesLimit(
        int total_bytes_limit)

Sets the maximum number of bytes that this CodedInputStream will read before refusing to continue.

To prevent servers from allocating enormous amounts of memory to hold parsed messages, the maximum message length should be limited to the shortest length that will not harm usability. The default limit is INT_MAX (~2GB) and apps should set shorter limits if possible. An error will always be printed to stderr if the limit is reached.

-

Note: setting a limit less than the current read position is interpreted as a limit on the current position.

-

This is unrelated to PushLimit()/PopLimit().

-

bool CodedInputStream::IncrementRecursionDepth()

Increments the current recursion depth.

Returns true if the depth is under the limit, false if it has gone over.

-

void CodedInputStream::UnsafeDecrementRecursionDepth()

Decrements the recursion depth blindly.

This is faster than DecrementRecursionDepth(). It should be used only if all previous increments to recursion depth were successful.

-

std::pair< CodedInputStream::Limit, int >
    CodedInputStream::IncrementRecursionDepthAndPushLimit(
        int byte_limit)

Shorthand for make_pair(PushLimit(byte_limit), –recursion_budget_).

Using this can reduce code size and complexity in some cases. The caller is expected to check that the second part of the result is non-negative (to bail out if the depth of recursion is too high) and, if all is well, to later pass the first part of the result to PopLimit() or similar.

-

bool CodedInputStream::DecrementRecursionDepthAndPopLimit(
        Limit limit)

Helper that is equivalent to: { bool result = ConsumedEntireMessage(); PopLimit(limit); UnsafeDecrementRecursionDepth(); return result; } Using this can reduce code size and complexity in some cases.

Do not use unless the current recursion depth is greater than zero.

-

void CodedInputStream::SetExtensionRegistry(
        const DescriptorPool * pool,
        MessageFactory * factory)

Set the pool used to look up extensions.

Most users do not need to call this as the correct pool will be chosen automatically.

-

WARNING: It is very easy to misuse this. Carefully read the requirements below. Do not use this unless you are sure you need it. Almost no one does.

-

Let's say you are parsing a message into message object m, and you want to take advantage of SetExtensionRegistry(). You must follow these requirements:

-

The given DescriptorPool must contain m->GetDescriptor(). It is not sufficient for it to simply contain a descriptor that has the same name and content – it must be the exact object. In other words:

-
assert(pool->FindMessageTypeByName(m->GetDescriptor()->full_name()) ==
-       m->GetDescriptor());
-

There are two ways to satisfy this requirement: 1) Use m->GetDescriptor()->pool() as the pool. This is generally useless

-
because this is the pool that would be used anyway if you didn't call
-SetExtensionRegistry() at all.
-

2) Use a DescriptorPool which has m->GetDescriptor()->pool() as an

-
"underlay".  Read the documentation for DescriptorPool for more
-information about underlays.
-

You must also provide a MessageFactory. This factory will be used to construct Message objects representing extensions. The factory's GetPrototype() MUST return non-NULL for any Descriptor which can be found through the provided pool.

-

If the provided factory might return instances of protocol-compiler- generated (i.e. compiled-in) types, or if the outer message object m is a generated type, then the given factory MUST have this property: If GetPrototype() is given a Descriptor which resides in DescriptorPool::generated_pool(), the factory MUST return the same prototype which MessageFactory::generated_factory() would return. That is, given a descriptor for a generated type, the factory must return an instance of the generated class (NOT DynamicMessage). However, when given a descriptor for a type that is NOT in generated_pool, the factory is free to return any implementation.

-

The reason for this requirement is that generated sub-objects may be accessed via the standard (non-reflection) extension accessor methods, and these methods will down-cast the object to the generated class type. If the object is not actually of that type, the results would be undefined. On the other hand, if an extension is not compiled in, then there is no way the code could end up accessing it via the standard accessors – the only way to access the extension is via reflection. When using reflection, DynamicMessage and generated messages are indistinguishable, so it's fine if these objects are represented using DynamicMessage.

-

Using DynamicMessageFactory on which you have called SetDelegateToGeneratedFactory(true) should be sufficient to satisfy the above requirement.

-

If either pool or factory is NULL, both must be NULL.

-

Note that this feature is ignored when parsing "lite" messages as they do not have descriptors.

-

class EpsCopyOutputStream

#include <google/protobuf/io/coded_stream.h>
namespace google::protobuf::io

EpsCopyOutputStream wraps a ZeroCopyOutputStream and exposes a new stream, which has the property you can write kSlopBytes (16 bytes) from the current position without bounds checks.

The cursor into the stream is managed by the user of the class and is an explicit parameter in the methods. Careful use of this class, ie. keep ptr a local variable, eliminates the need to for the compiler to sync the ptr value between register and memory.

-

Members

enum
@33
EpsCopyOutputStream(ZeroCopyOutputStream * stream, bool deterministic, uint8 ** pp)
Initialize from a stream.
EpsCopyOutputStream(void * data, int size, bool deterministic)
Only for array serialization. more...
EpsCopyOutputStream(void * data, int size, ZeroCopyOutputStream * stream, bool deterministic, uint8 ** pp)
Initialize from stream but with the first buffer already given (eager).
uint8 *
Trim(uint8 * ptr)
Flush everything that's written into the underlying ZeroCopyOutputStream and trims the underlying stream to the location of ptr.
PROTOBUF_MUST_USE_RESULT uint8 *
EnsureSpace(uint8 * ptr)
After this it's guaranteed you can safely write kSlopBytes to ptr. more...
uint8 *
WriteRaw(const void * data, int size, uint8 * ptr)
uint8 *
WriteRawMaybeAliased(const void * data, int size, uint8 * ptr)
Writes the buffer specified by data, size to the stream. more...
uint8 *
WriteStringMaybeAliased(uint32 num, const std::string & s, uint8 * ptr)
uint8 *
WriteBytesMaybeAliased(uint32 num, const std::string & s, uint8 * ptr)
template uint8 *
WriteString(uint32 num, const T & s, uint8 * ptr)
template uint8 *
WriteBytes(uint32 num, const T & s, uint8 * ptr)
template uint8 *
WriteInt32Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteUInt32Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteSInt32Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteInt64Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteUInt64Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteSInt64Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteEnumPacked(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteFixedPacked(int num, const T & r, uint8 * ptr)
bool
HadError() const
Returns true if there was an underlying I/O error since this object was created.
void
EnableAliasing(bool enabled)
Instructs the EpsCopyOutputStream to allow the underlying ZeroCopyOutputStream to hold pointers to the original structure instead of copying, if it supports it (i.e. more...
void
SetSerializationDeterministic(bool value)
bool
IsSerializationDeterministic() const
int64
ByteCount(uint8 * ptr) const
The number of bytes written to the stream at position ptr, relative to the stream's overall position.
uint8 *
SetInitialBuffer(void * data, int size)
These methods are for CodedOutputStream. more...

enum EpsCopyOutputStream::@33 {
  kSlopBytes = = 16
}

kSlopBytes

EpsCopyOutputStream::EpsCopyOutputStream(
        void * data,
        int size,
        bool deterministic)

Only for array serialization.

No overflow protection, end_ will be the pointed to the end of the array. When using this the total size is already known, so no need to maintain the slop region.

-

PROTOBUF_MUST_USE_RESULT uint8 *
    EpsCopyOutputStream::EnsureSpace(
        uint8 * ptr)

After this it's guaranteed you can safely write kSlopBytes to ptr.

This will never fail! The underlying stream can produce an error. Use HadError to check for errors.

-

uint8 * EpsCopyOutputStream::WriteRawMaybeAliased(
        const void * data,
        int size,
        uint8 * ptr)

Writes the buffer specified by data, size to the stream.

Possibly by aliasing the buffer (ie. not copying the data). The caller is responsible to make sure the buffer is alive for the duration of the ZeroCopyOutputStream.

-

void EpsCopyOutputStream::EnableAliasing(
        bool enabled)

Instructs the EpsCopyOutputStream to allow the underlying ZeroCopyOutputStream to hold pointers to the original structure instead of copying, if it supports it (i.e.

output->AllowsAliasing() is true). If the underlying stream does not support aliasing, then enabling it has no affect. For now, this only affects the behavior of WriteRawMaybeAliased().

-

NOTE: It is caller's responsibility to ensure that the chunk of memory remains live until all of the data has been consumed from the stream.

-

uint8 * EpsCopyOutputStream::SetInitialBuffer(
        void * data,
        int size)

These methods are for CodedOutputStream.

Ideally they should be private but to match current behavior of CodedOutputStream as close as possible we allow it some functionality.

-

class CodedOutputStream

#include <google/protobuf/io/coded_stream.h>
namespace google::protobuf::io

Class which encodes and writes binary data which is composed of varint- encoded integers and fixed-width pieces.

Wraps a ZeroCopyOutputStream. Most users will not need to deal with CodedOutputStream.

-

Most methods of CodedOutputStream which return a bool return false if an underlying I/O error occurs. Once such a failure occurs, the CodedOutputStream is broken and is no longer useful. The Write* methods do not return the stream status, but will invalidate the stream if an error occurs. The client can probe HadError() to determine the status.

-

Note that every method of CodedOutputStream which writes some data has a corresponding static "ToArray" version. These versions write directly to the provided buffer, returning a pointer past the last written byte. They require that the buffer has sufficient capacity for the encoded data. This allows an optimization where we check if an output stream has enough space for an entire message before we start writing and, if there is, we call only the ToArray methods to avoid doing bound checks for each individual value. i.e., in the example above:

-
CodedOutputStream* coded_output = new CodedOutputStream(raw_output);
-int magic_number = 1234;
-char text[] = "Hello world!";
-
-int coded_size = sizeof(magic_number) +
-                 CodedOutputStream::VarintSize32(strlen(text)) +
-                 strlen(text);
-
-uint8* buffer =
-    coded_output->GetDirectBufferForNBytesAndAdvance(coded_size);
-if (buffer != nullptr) {
-  // The output stream has enough space in the buffer: write directly to
-  // the array.
-  buffer = CodedOutputStream::WriteLittleEndian32ToArray(magic_number,
-                                                         buffer);
-  buffer = CodedOutputStream::WriteVarint32ToArray(strlen(text), buffer);
-  buffer = CodedOutputStream::WriteRawToArray(text, strlen(text), buffer);
-} else {
-  // Make bound-checked writes, which will ask the underlying stream for
-  // more space as needed.
-  coded_output->WriteLittleEndian32(magic_number);
-  coded_output->WriteVarint32(strlen(text));
-  coded_output->WriteRaw(text, strlen(text));
-}
-
-delete coded_output;
-

Members

explicit
CodedOutputStream(ZeroCopyOutputStream * stream)
Create an CodedOutputStream that writes to the given ZeroCopyOutputStream.
CodedOutputStream(ZeroCopyOutputStream * stream, bool do_eager_refresh)
~CodedOutputStream()
Destroy the CodedOutputStream and position the underlying ZeroCopyOutputStream immediately after the last byte written.
bool
HadError()
Returns true if there was an underlying I/O error since this object was created. more...
void
Trim()
Trims any unused space in the underlying buffer so that its size matches the number of bytes written by this stream. more...
bool
Skip(int count)
Skips a number of bytes, leaving the bytes unmodified in the underlying buffer. more...
bool
GetDirectBufferPointer(void ** data, int * size)
Sets *data to point directly at the unwritten part of the CodedOutputStream's underlying buffer, and *size to the size of that buffer, but does not advance the stream's current position. more...
uint8 *
GetDirectBufferForNBytesAndAdvance(int size)
If there are at least "size" bytes available in the current buffer, returns a pointer directly into the buffer and advances over these bytes. more...
void
WriteRaw(const void * buffer, int size)
Write raw bytes, copying them from the given buffer.
void
WriteRawMaybeAliased(const void * data, int size)
Like WriteRaw() but will try to write aliased data if aliasing is turned on.
void
WriteString(const std::string & str)
Equivalent to WriteRaw(str.data(), str.size()).
void
WriteLittleEndian32(uint32 value)
Write a 32-bit little-endian integer.
void
WriteLittleEndian64(uint64 value)
Write a 64-bit little-endian integer.
void
WriteVarint32(uint32 value)
Write an unsigned integer with Varint encoding. more...
void
WriteVarint64(uint64 value)
Write an unsigned integer with Varint encoding.
void
WriteVarint32SignExtended(int32 value)
Equivalent to WriteVarint32() except when the value is negative, in which case it must be sign-extended to a full 10 bytes.
void
WriteTag(uint32 value)
This is identical to WriteVarint32(), but optimized for writing tags. more...
int
ByteCount() const
Returns the total number of bytes written since this object was created.
void
EnableAliasing(bool enabled)
Instructs the CodedOutputStream to allow the underlying ZeroCopyOutputStream to hold pointers to the original structure instead of copying, if it supports it (i.e. more...
void
SetSerializationDeterministic(bool value)
Indicate to the serializer whether the user wants derministic serialization. more...
bool
IsSerializationDeterministic() const
Return whether the user wants deterministic serialization. See above.
template void
Serialize(const Func & func)
uint8 *
Cur() const
void
SetCur(uint8 * ptr)
EpsCopyOutputStream *
EpsCopy()
static uint8 *
WriteRawToArray(const void * buffer, int size, uint8 * target)
Like WriteRaw() but writing directly to the target array. more...
static uint8 *
WriteStringToArray(const std::string & str, uint8 * target)
Like WriteString() but writing directly to the target array.
static uint8 *
WriteStringWithSizeToArray(const std::string & str, uint8 * target)
Write the varint-encoded size of str followed by str.
static uint8 *
WriteLittleEndian32ToArray(uint32 value, uint8 * target)
Like WriteLittleEndian32() but writing directly to the target array.
static uint8 *
WriteLittleEndian64ToArray(uint64 value, uint8 * target)
Like WriteLittleEndian64() but writing directly to the target array.
static uint8 *
WriteVarint32ToArray(uint32 value, uint8 * target)
Like WriteVarint32() but writing directly to the target array.
static uint8 *
WriteVarint32ToArrayOutOfLine(uint32 value, uint8 * target)
Like WriteVarint32() but writing directly to the target array, and with the less common-case paths being out of line rather than inlined.
static uint8 *
WriteVarint64ToArray(uint64 value, uint8 * target)
Like WriteVarint64() but writing directly to the target array.
static uint8 *
WriteVarint32SignExtendedToArray(int32 value, uint8 * target)
Like WriteVarint32SignExtended() but writing directly to the target array.
static uint8 *
WriteTagToArray(uint32 value, uint8 * target)
Like WriteTag() but writing directly to the target array.
static size_t
VarintSize32(uint32 value)
Returns the number of bytes needed to encode the given value as a varint.
static size_t
VarintSize64(uint64 value)
Returns the number of bytes needed to encode the given value as a varint.
static size_t
VarintSize32SignExtended(int32 value)
If negative, 10 bytes. Otherwise, same as VarintSize32().
static bool
IsDefaultSerializationDeterministic()

bool CodedOutputStream::HadError()

Returns true if there was an underlying I/O error since this object was created.

On should call Trim before this function in order to catch all errors.

-

void CodedOutputStream::Trim()

Trims any unused space in the underlying buffer so that its size matches the number of bytes written by this stream.

The underlying buffer will automatically be trimmed when this stream is destroyed; this call is only necessary if the underlying buffer is accessed before the stream is destroyed.

-

bool CodedOutputStream::Skip(
        int count)

Skips a number of bytes, leaving the bytes unmodified in the underlying buffer.

Returns false if an underlying write error occurs. This is mainly useful with GetDirectBufferPointer(). Note of caution, the skipped bytes may contain uninitialized data. The caller must make sure that the skipped bytes are properly initialized, otherwise you might leak bytes from your heap.

-

bool CodedOutputStream::GetDirectBufferPointer(
        void ** data,
        int * size)

Sets *data to point directly at the unwritten part of the CodedOutputStream's underlying buffer, and *size to the size of that buffer, but does not advance the stream's current position.

This will always either produce a non-empty buffer or return false. If the caller writes any data to this buffer, it should then call Skip() to skip over the consumed bytes. This may be useful for implementing external fast serialization routines for types of data not covered by the CodedOutputStream interface.

-

uint8 * CodedOutputStream::GetDirectBufferForNBytesAndAdvance(
        int size)

If there are at least "size" bytes available in the current buffer, returns a pointer directly into the buffer and advances over these bytes.

The caller may then write directly into this buffer (e.g. using the *ToArray static methods) rather than go through CodedOutputStream. If there are not enough bytes available, returns NULL. The return pointer is invalidated as soon as any other non-const method of CodedOutputStream is called.

-

void CodedOutputStream::WriteVarint32(
        uint32 value)

Write an unsigned integer with Varint encoding.

Writing a 32-bit value is equivalent to casting it to uint64 and writing it as a 64-bit value, but may be more efficient.

-

void CodedOutputStream::WriteTag(
        uint32 value)

This is identical to WriteVarint32(), but optimized for writing tags.

In particular, if the input is a compile-time constant, this method compiles down to a couple instructions. Always inline because otherwise the aforementioned optimization can't work, but GCC by default doesn't want to inline this.

-

void CodedOutputStream::EnableAliasing(
        bool enabled)

Instructs the CodedOutputStream to allow the underlying ZeroCopyOutputStream to hold pointers to the original structure instead of copying, if it supports it (i.e.

output->AllowsAliasing() is true). If the underlying stream does not support aliasing, then enabling it has no affect. For now, this only affects the behavior of WriteRawMaybeAliased().

-

NOTE: It is caller's responsibility to ensure that the chunk of memory remains live until all of the data has been consumed from the stream.

-

void CodedOutputStream::SetSerializationDeterministic(
        bool value)

Indicate to the serializer whether the user wants derministic serialization.

The default when this is not called comes from the global default, controlled by SetDefaultSerializationDeterministic.

-

What deterministic serialization means is entirely up to the driver of the serialization process (i.e. the caller of methods like WriteVarint32). In the case of serializing a proto buffer message using one of the methods of MessageLite, this means that for a given binary equal messages will always be serialized to the same bytes. This implies:

-
Repeated serialization of a message will return the same bytes.
-
-Different processes running the same binary (including on different
-machines) will serialize equal messages to the same bytes.
-

Note that this is not canonical across languages. It is also unstable across different builds with intervening message definition changes, due to unknown fields. Users who need canonical serialization (e.g. persistent storage in a canonical form, fingerprinting) should define their own canonicalization specification and implement the serializer using reflection APIs rather than relying on this API.

-

static uint8 * CodedOutputStream::WriteRawToArray(
        const void * buffer,
        int size,
        uint8 * target)

Like WriteRaw() but writing directly to the target array.

This is not inlined, as the compiler often optimizes memcpy into inline copy loops. Since this gets called by every field with string or bytes type, inlining may lead to a significant amount of code bloat, with only a minor performance gain.

-

template struct CodedOutputStream::StaticVarintSize32

#include <google/protobuf/io/coded_stream.h>
namespace google::protobuf::io

template <typename Value>

Compile-time equivalent of VarintSize32().

Members

const size_t
value = = (Value < (1 << 7)) ? 1 - : (Value < (1 << 14)) ? 2 - : (Value < (1 << 21)) ? 3 - : (Value < (1 << 28)) ? 4 - : 5
diff --git a/content/reference/cpp/api-docs/google.protobuf.io.gzip_stream.md b/content/reference/cpp/api-docs/google.protobuf.io.gzip_stream.md deleted file mode 100644 index dabc10c3b..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.io.gzip_stream.md +++ /dev/null @@ -1,65 +0,0 @@ -+++ -title = "gzip_stream.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/io/gzip_stream.h>
namespace google::protobuf::io

This file contains the definition for classes GzipInputStream and GzipOutputStream.

GzipInputStream decompresses data from an underlying ZeroCopyInputStream and provides the decompressed data as a ZeroCopyInputStream.

- -

GzipOutputStream is an ZeroCopyOutputStream that compresses data to an underlying ZeroCopyOutputStream.

- -

Classes in this file

A ZeroCopyInputStream that reads compressed data through zlib.

class GzipInputStream: public ZeroCopyInputStream

#include <google/protobuf/io/gzip_stream.h>
namespace google::protobuf::io

A ZeroCopyInputStream that reads compressed data through zlib.

Members

enum
Format
Format key for constructor. more...
explicit
GzipInputStream(ZeroCopyInputStream * sub_stream, Format format = AUTO, int buffer_size = -1)
buffer_size and format may be -1 for default of 64kB and GZIP format
virtual
~GzipInputStream()
const char *
ZlibErrorMessage() const
Return last error message or NULL if no error.
int
ZlibErrorCode() const

implements ZeroCopyInputStream

virtual bool
Next(const void ** data, int * size)
Obtains a chunk of data from the stream. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next(). more...
virtual bool
Skip(int count)
Skips a number of bytes. more...
virtual int64
ByteCount() const
Returns the total number of bytes read since this object was created.

enum GzipInputStream::Format {
  AUTO = = 0,
  GZIP = = 1,
  ZLIB = = 2
}

Format key for constructor.

AUTOzlib will autodetect gzip header or deflate stream
GZIPGZIP streams have some extra header data for file attributes.
ZLIBSimpler zlib stream format.

virtual bool GzipInputStream::Next(
        const void ** data,
        int * size)

Obtains a chunk of data from the stream.

Preconditions:

-
    -
  • "size" and "data" are not NULL.
  • -
-

Postconditions:

-
    -
  • If the returned value is false, there is no more data to return or an error occurred. All errors are permanent.
  • -
  • Otherwise, "size" points to the actual number of bytes read and "data" points to a pointer to a buffer containing these bytes.
  • -
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • -
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.
  • -
-

virtual void GzipInputStream::BackUp(
        int count)

Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next().

This is useful when writing procedures that are only supposed to read up to a certain point in the input, then return. If Next() returns a buffer that goes beyond what you wanted to read, you can use BackUp() to return to the point where you intended to finish.

-

Preconditions:

-
    -
  • The last method called must have been Next().
  • -
  • count must be less than or equal to the size of the last buffer returned by Next().
  • -
-

Postconditions:

-
    -
  • The last "count" bytes of the last buffer returned by Next() will be pushed back into the stream. Subsequent calls to Next() will return the same data again before producing new data.
  • -
-

virtual bool GzipInputStream::Skip(
        int count)

Skips a number of bytes.

Returns false if the end of the stream is reached or some input error occurred. In the end-of-stream case, the stream is advanced to the end of the stream (so ByteCount() will return the total size of the stream).

-

class GzipOutputStream: public ZeroCopyOutputStream

#include <google/protobuf/io/gzip_stream.h>
namespace google::protobuf::io

Members

enum
Format
Format key for constructor. more...
explicit
GzipOutputStream(ZeroCopyOutputStream * sub_stream)
Create a GzipOutputStream with default options.
GzipOutputStream(ZeroCopyOutputStream * sub_stream, const Options & options)
Create a GzipOutputStream with the given options.
virtual
~GzipOutputStream()
const char *
ZlibErrorMessage() const
Return last error message or NULL if no error.
int
ZlibErrorCode() const
bool
Flush()
Flushes data written so far to zipped data in the underlying stream. more...
bool
Close()
Writes out all data and closes the gzip stream. more...

implements ZeroCopyOutputStream

virtual bool
Next(void ** data, int * size)
Obtains a buffer into which data can be written. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written. more...
virtual int64
ByteCount() const
Returns the total number of bytes written since this object was created.

enum GzipOutputStream::Format {
  GZIP = = 1,
  ZLIB = = 2
}

Format key for constructor.

GZIPGZIP streams have some extra header data for file attributes.
ZLIBSimpler zlib stream format.

bool GzipOutputStream::Flush()

Flushes data written so far to zipped data in the underlying stream.

It is the caller's responsibility to flush the underlying stream if necessary. Compression may be less efficient stopping and starting around flushes. Returns true if no error.

-

Please ensure that block size is > 6. Here is an excerpt from the zlib doc that explains why:

-

In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out is greater than six to avoid repeated flush markers due to avail_out == 0 on return.

-

bool GzipOutputStream::Close()

Writes out all data and closes the gzip stream.

It is the caller's responsibility to close the underlying stream if necessary. Returns true if no error.

-

virtual bool GzipOutputStream::Next(
        void ** data,
        int * size)

Obtains a buffer into which data can be written.

Any data written into this buffer will eventually (maybe instantly, maybe later on) be written to the output.

-

Preconditions:

-
    -
  • "size" and "data" are not NULL.
  • -
-

Postconditions:

-
    -
  • If the returned value is false, an error occurred. All errors are permanent.
  • -
  • Otherwise, "size" points to the actual number of bytes in the buffer and "data" points to the buffer.
  • -
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • -
  • Any data which the caller stores in this buffer will eventually be written to the output (unless BackUp() is called).
  • -
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.
  • -
-

virtual void GzipOutputStream::BackUp(
        int count)

Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written.

This is needed when you finish writing all the data you want to write, but the last buffer was bigger than you needed. You don't want to write a bunch of garbage after the end of your data, so you use BackUp() to back up.

-

Preconditions:

-
    -
  • The last method called must have been Next().
  • -
  • count must be less than or equal to the size of the last buffer returned by Next().
  • -
  • The caller must not have written anything to the last "count" bytes of that buffer.
  • -
-

Postconditions:

-
    -
  • The last "count" bytes of the last buffer returned by Next() will be ignored.
  • -
-

struct GzipOutputStream::Options

#include <google/protobuf/io/gzip_stream.h>
namespace google::protobuf::io

Members

Format
format
Defaults to GZIP.
int
buffer_size
What size buffer to use internally. Defaults to 64kB.
int
compression_level
A number between 0 and 9, where 0 is no compression and 9 is best compression. more...
int
compression_strategy
Defaults to Z_DEFAULT_STRATEGY. more...
Options()
Initializes with default values.

intOptions::compression_level

A number between 0 and 9, where 0 is no compression and 9 is best compression.

Defaults to Z_DEFAULT_COMPRESSION (see zlib.h).

-

intOptions::compression_strategy

Defaults to Z_DEFAULT_STRATEGY.

Can also be set to Z_FILTERED, Z_HUFFMAN_ONLY, or Z_RLE. See the documentation for deflateInit2 in zlib.h for definitions of these constants.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.io.printer.md b/content/reference/cpp/api-docs/google.protobuf.io.printer.md deleted file mode 100644 index f1048c50d..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.io.printer.md +++ /dev/null @@ -1,24 +0,0 @@ -+++ -title = "printer.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/io/printer.h>
namespace google::protobuf::io

Utility class for writing text to a ZeroCopyOutputStream.

Classes in this file

Records annotations about a Printer's output.
Records annotations about a Printer's output to the given protocol buffer, assuming that the buffer has an ::Annotation message exposing path, source_file, begin and end fields.

class AnnotationCollector

#include <google/protobuf/io/printer.h>
namespace google::protobuf::io

Records annotations about a Printer's output.

Known subclasses:

Members

typedef
std::pair< std::pair< size_t, size_t >, std::string > Annotation
Annotation is a offset range and a payload pair.
virtual void
AddAnnotation(size_t begin_offset, size_t end_offset, const std::string & file_path, const std::vector< int > & path) = 0
Records that the bytes in file_path beginning with begin_offset and ending before end_offset are associated with the SourceCodeInfo-style path.
virtual void
AddAnnotationNew(Annotation & )
virtual
~AnnotationCollector()

virtual void AnnotationCollector::AddAnnotationNew(
        Annotation & )

Just a vector of range, payload pairs stored in a context should suffice.

- -

template class AnnotationProtoCollector: public AnnotationCollector

#include <google/protobuf/io/printer.h>
namespace google::protobuf::io

template <typename >

Records annotations about a Printer's output to the given protocol buffer, assuming that the buffer has an ::Annotation message exposing path, source_file, begin and end fields.

Members

explicit
AnnotationProtoCollector(AnnotationProto * annotation_proto)
annotation_proto is the protocol buffer to which new Annotations should be added. more...
virtual void
AddAnnotation(size_t begin_offset, size_t end_offset, const std::string & file_path, const std::vector< int > & path)
virtual void
AddAnnotationNew(Annotation & a)

explicit AnnotationProtoCollector::AnnotationProtoCollector(
        AnnotationProto * annotation_proto)

annotation_proto is the protocol buffer to which new Annotations should be added.

It is not owned by the AnnotationProtoCollector.

-

class Printer

#include <google/protobuf/io/printer.h>
namespace google::protobuf::io

Members

Printer(ZeroCopyOutputStream * output, char variable_delimiter)
Create a printer that writes text to the given output stream. more...
Printer(ZeroCopyOutputStream * output, char variable_delimiter, AnnotationCollector * annotation_collector)
Create a printer that writes text to the given output stream. more...
~Printer()
template void
Annotate(const char * varname, const SomeDescriptor * descriptor)
Link a substitution variable emitted by the last call to Print to the object described by descriptor.
template void
Annotate(const char * begin_varname, const char * end_varname, const SomeDescriptor * descriptor)
Link the output range defined by the substitution variables as emitted by the last call to Print to the object described by descriptor. more...
void
Annotate(const char * varname, const std::string & file_name)
Link a substitution variable emitted by the last call to Print to the file with path file_name.
void
Annotate(const char * begin_varname, const char * end_varname, const std::string & file_name)
Link the output range defined by the substitution variables as emitted by the last call to Print to the file with path file_name. more...
void
Print(const std::map< std::string, std::string > & variables, const char * text)
Print some text after applying variable substitutions. more...
template void
Print(const char * text, const Args &... args)
Like the first Print(), except the substitutions are given as parameters.
void
Indent()
Indent text by two spaces. more...
void
Outdent()
Reduces the current indent level by two spaces, or crashes if the indent level is zero.
void
PrintRaw(const std::string & data)
Write a string to the output buffer. more...
void
PrintRaw(const char * data)
Write a zero-delimited string to output buffer. more...
void
WriteRaw(const char * data, int size)
Write some bytes to the output buffer. more...
void
FormatInternal(const std::vector< std::string > & args, const std::map< std::string, std::string > & vars, const char * format)
FormatInternal is a helper function not meant to use directly, use compiler::cpp::Formatter instead. more...
bool
failed() const
True if any write to the underlying stream failed. more...

Printer::Printer(
        ZeroCopyOutputStream * output,
        char variable_delimiter)

Create a printer that writes text to the given output stream.

Use the given character as the delimiter for variables.

-

Printer::Printer(
        ZeroCopyOutputStream * output,
        char variable_delimiter,
        AnnotationCollector * annotation_collector)

Create a printer that writes text to the given output stream.

Use the given character as the delimiter for variables. If annotation_collector is not null, Printer will provide it with annotations about code written to the stream. annotation_collector is not owned by Printer.

-

template void Printer::Annotate(
        const char * begin_varname,
        const char * end_varname,
        const SomeDescriptor * descriptor)

Link the output range defined by the substitution variables as emitted by the last call to Print to the object described by descriptor.

The range begins at begin_varname's value and ends after the last character of the value substituted for end_varname.

-

void Printer::Annotate(
        const char * begin_varname,
        const char * end_varname,
        const std::string & file_name)

Link the output range defined by the substitution variables as emitted by the last call to Print to the file with path file_name.

The range begins at begin_varname's value and ends after the last character of the value substituted for end_varname.

-

void Printer::Print(
        const std::map< std::string, std::string > & variables,
        const char * text)

Print some text after applying variable substitutions.

If a particular variable in the text is not defined, this will crash. Variables to be substituted are identified by their names surrounded by delimiter characters (as given to the constructor). The variable bindings are defined by the given map.

-

void Printer::Indent()

Indent text by two spaces.

After calling Indent(), two spaces will be inserted at the beginning of each line of text. Indent() may be called multiple times to produce deeper indents.

-

void Printer::PrintRaw(
        const std::string & data)

Write a string to the output buffer.

This method does not look for newlines to add indentation.

-

void Printer::PrintRaw(
        const char * data)

Write a zero-delimited string to output buffer.

This method does not look for newlines to add indentation.

-

void Printer::WriteRaw(
        const char * data,
        int size)

Write some bytes to the output buffer.

This method does not look for newlines to add indentation.

-

void Printer::FormatInternal(
        const std::vector< std::string > & args,
        const std::map< std::string, std::string > & vars,
        const char * format)

FormatInternal is a helper function not meant to use directly, use compiler::cpp::Formatter instead.

This function is meant to support formatting text using named variables (eq. "$foo$) from a lookup map (vars) -and variables directly supplied by arguments (eq "$1$" meaning first argument which is the zero index element of args).

-

bool Printer::failed() const

True if any write to the underlying stream failed.

(We don't just crash in this case because this is an I/O failure, not a programming error.)

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.io.tokenizer.md b/content/reference/cpp/api-docs/google.protobuf.io.tokenizer.md deleted file mode 100644 index 0b05302c3..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.io.tokenizer.md +++ /dev/null @@ -1,60 +0,0 @@ -+++ -title = "tokenizer.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/io/tokenizer.h>
namespace google::protobuf::io

Class for parsing tokenized text from a ZeroCopyInputStream.

Classes in this file

Abstract interface for an object which collects the errors that occur during parsing.
This class converts a stream of raw text into a stream of tokens for the protocol definition parser to parse.
Structure representing a token read from the token stream.

File Members

These definitions are not part of any class.
typedef
int ColumnNumber
By "column number", the proto compiler refers to a count of the number of bytes before a given byte, except that a tab character advances to the next multiple of 8 bytes. more...

typedef io::ColumnNumber

By "column number", the proto compiler refers to a count of the number of bytes before a given byte, except that a tab character advances to the next multiple of 8 bytes.

Note in particular that column numbers are zero-based, while many user interfaces use one-based column numbers.

-

class ErrorCollector

#include <google/protobuf/io/tokenizer.h>
namespace google::protobuf::io

Abstract interface for an object which collects the errors that occur during parsing.

A typical implementation might simply print the errors to stdout.

- -

Members

ErrorCollector()
virtual
~ErrorCollector()
virtual void
AddError(int line, ColumnNumber column, const std::string & message) = 0
Indicates that there was an error in the input at the given line and column numbers. more...
virtual void
AddWarning(int , ColumnNumber , const std::string & )
Indicates that there was a warning in the input at the given line and column numbers. more...

virtual void ErrorCollector::AddError(
        int line,
        ColumnNumber column,
        const std::string & message) = 0

Indicates that there was an error in the input at the given line and column numbers.

The numbers are zero-based, so you may want to add 1 to each before printing them.

-

virtual void ErrorCollector::AddWarning(
        int ,
        ColumnNumber ,
        const std::string & )

Indicates that there was a warning in the input at the given line and column numbers.

The numbers are zero-based, so you may want to add 1 to each before printing them.

-

class Tokenizer

#include <google/protobuf/io/tokenizer.h>
namespace google::protobuf::io

This class converts a stream of raw text into a stream of tokens for the protocol definition parser to parse.

The tokens recognized are similar to those that make up the C language; see the TokenType enum for precise descriptions. Whitespace and comments are skipped. By default, C- and C++-style comments are recognized, but other styles can be used by calling set_comment_style().

-

Members

enum
TokenType
Tokenizer(ZeroCopyInputStream * input, ErrorCollector * error_collector)
Construct a Tokenizer that reads and tokenizes text from the given input stream and writes errors to the given error_collector. more...
~Tokenizer()
const Token &
current()
Get the current token. more...
const Token &
previous()
Return the previous token – i.e. more...
bool
Next()
Advance to the next token. more...
bool
NextWithComments(std::string * prev_trailing_comments, std::vector< std::string > * detached_comments, std::string * next_leading_comments)
Like Next(), but also collects comments which appear between the previous and next tokens. more...

Options

enum
CommentStyle
Valid values for set_comment_style(). more...
void
set_allow_f_after_float(bool value)
Set true to allow floats to be suffixed with the letter 'f'. more...
void
set_comment_style(CommentStyle style)
Sets the comment style.
void
set_require_space_after_number(bool require)
Whether to require whitespace between a number and a field name. more...
void
set_allow_multiline_strings(bool allow)
Whether to allow string literals to span multiple lines. more...
static bool
IsIdentifier(const std::string & text)
External helper: validate an identifier.

Parse helpers

static double
ParseFloat(const std::string & text)
Parses a TYPE_FLOAT token. more...
static void
ParseString(const std::string & text, std::string * output)
Parses a TYPE_STRING token. more...
static void
ParseStringAppend(const std::string & text, std::string * output)
Identical to ParseString, but appends to output.
static bool
ParseInteger(const std::string & text, uint64 max_value, uint64 * output)
Parses a TYPE_INTEGER token. more...

enum Tokenizer::TokenType {
  TYPE_START,
  TYPE_END,
  TYPE_IDENTIFIER,
  TYPE_INTEGER,
  TYPE_FLOAT,
  TYPE_STRING,
  TYPE_SYMBOL
}

TYPE_STARTNext() has not yet been called.
TYPE_ENDEnd of input reached. "text" is empty.
TYPE_IDENTIFIER

A sequence of letters, digits, and underscores, not starting with a digit.

It is an error for a number to be followed by an identifier with no space in between.

-
TYPE_INTEGER

A sequence of digits representing an integer.

Normally the digits are decimal, but a prefix of "0x" indicates a hex number and a leading zero indicates octal, just like with C numeric literals. A leading negative sign is NOT included in the token; it's up to the parser to interpret the unary minus operator on its own.

-
TYPE_FLOAT

A floating point literal, with a fractional part and/or an exponent.

Always in decimal. Again, never negative.

-
TYPE_STRING

A quoted sequence of escaped characters.

Either single or double quotes can be used, but they must match. A string literal cannot cross a line break.

-
TYPE_SYMBOL

Any other printable character, like '!' or '+'.

Symbols are always a single character, so "!+$%" is four tokens.

-

Tokenizer::Tokenizer(
        ZeroCopyInputStream * input,
        ErrorCollector * error_collector)

Construct a Tokenizer that reads and tokenizes text from the given input stream and writes errors to the given error_collector.

The caller keeps ownership of input and error_collector.

-

const Token & Tokenizer::current()

Get the current token.

This is updated when Next() is called. Before the first call to Next(), current() has type TYPE_START and no contents.

-

const Token & Tokenizer::previous()

Return the previous token – i.e.

what current() returned before the previous call to Next().

-

bool Tokenizer::Next()

Advance to the next token.

Returns false if the end of the input is reached.

-

bool Tokenizer::NextWithComments(
        std::string * prev_trailing_comments,
        std::vector< std::string > * detached_comments,
        std::string * next_leading_comments)

Like Next(), but also collects comments which appear between the previous and next tokens.

Comments which appear to be attached to the previous token are stored in *prev_tailing_comments. Comments which appear to be attached to the next token are stored in *next_leading_comments. Comments appearing in between which do not appear to be attached to either will be added to detached_comments. Any of these parameters can be NULL to simply discard the comments.

-

A series of line comments appearing on consecutive lines, with no other tokens appearing on those lines, will be treated as a single comment.

-

Only the comment content is returned; comment markers (e.g. //) are stripped out. For block comments, leading whitespace and an asterisk will be stripped from the beginning of each line other than the first. Newlines are included in the output.

-

Examples:

-
optional int32 foo = 1;  // Comment attached to foo.
-// Comment attached to bar.
-optional int32 bar = 2;
-
-optional string baz = 3;
-// Comment attached to baz.
-// Another line attached to baz.
-
-// Comment attached to qux.
-//
-// Another line attached to qux.
-optional double qux = 4;
-
-// Detached comment.  This is not attached to qux or corge
-// because there are blank lines separating it from both.
-
-optional string corge = 5;
-/* Block comment attached
- * to corge.  Leading asterisks
- * will be removed. * /
-/* Block comment attached to
- * grault. * /
-optional int32 grault = 6;
-   *  
-

enum Tokenizer::CommentStyle {
  CPP_COMMENT_STYLE,
  SH_COMMENT_STYLE
}

Valid values for set_comment_style().

CPP_COMMENT_STYLELine comments begin with "//", block comments are delimited by "/*" and "* /".
SH_COMMENT_STYLELine comments begin with "#". No way to write block comments.

void Tokenizer::set_allow_f_after_float(
        bool value)

Set true to allow floats to be suffixed with the letter 'f'.

Tokens which would otherwise be integers but which have the 'f' suffix will be forced to be interpreted as floats. For all other purposes, the 'f' is ignored.

-

void Tokenizer::set_require_space_after_number(
        bool require)

Whether to require whitespace between a number and a field name.

Default is true. Do not use this; for Google-internal cleanup only.

-

void Tokenizer::set_allow_multiline_strings(
        bool allow)

Whether to allow string literals to span multiple lines.

Default is false. Do not use this; for Google-internal cleanup only.

-

static double Tokenizer::ParseFloat(
        const std::string & text)

Parses a TYPE_FLOAT token.

This never fails, so long as the text actually comes from a TYPE_FLOAT token parsed by Tokenizer. If it doesn't, the result is undefined (possibly an assert failure).

-

static void Tokenizer::ParseString(
        const std::string & text,
        std::string * output)

Parses a TYPE_STRING token.

This never fails, so long as the text actually comes from a TYPE_STRING token parsed by Tokenizer. If it doesn't, the result is undefined (possibly an assert failure).

-

static bool Tokenizer::ParseInteger(
        const std::string & text,
        uint64 max_value,
        uint64 * output)

Parses a TYPE_INTEGER token.

Returns false if the result would be greater than max_value. Otherwise, returns true and sets *output to the result. If the text is not from a Token of type TYPE_INTEGER originally parsed by a Tokenizer, the result is undefined (possibly an assert failure).

-

struct Tokenizer::Token

#include <google/protobuf/io/tokenizer.h>
namespace google::protobuf::io

Structure representing a token read from the token stream.

Members

TokenType
type
std::string
text
The exact text of the token as it appeared in the input. more...
int
line
"line" and "column" specify the position of the first character of the token within the input stream. more...
ColumnNumber
column
ColumnNumber
end_column

std::string Token::text

The exact text of the token as it appeared in the input.

e.g. tokens of TYPE_STRING will still be escaped and in quotes.

-

int Token::line

"line" and "column" specify the position of the first character of the token within the input stream.

They are zero-based.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream.md b/content/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream.md deleted file mode 100644 index 9ccbcda3c..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream.md +++ /dev/null @@ -1,116 +0,0 @@ -+++ -title = "zero_copy_stream.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/io/zero_copy_stream.h>
namespace google::protobuf::io

This file contains the ZeroCopyInputStream and ZeroCopyOutputStream interfaces, which represent abstract I/O streams to and from which protocol buffers can be read and written.

For a few simple implementations of these interfaces, see zero_copy_stream_impl.h.

- -

These interfaces are different from classic I/O streams in that they try to minimize the amount of data copying that needs to be done. To accomplish this, responsibility for allocating buffers is moved to the stream object, rather than being the responsibility of the caller. So, the stream can return a buffer which actually points directly into the final data structure where the bytes are to be stored, and the caller can interact directly with that buffer, eliminating an intermediate copy operation.

- -

As an example, consider the common case in which you are reading bytes from an array that is already in memory (or perhaps an mmap()ed file). With classic I/O streams, you would do something like:

- -
char buffer[BUFFER_SIZE];
-input->Read(buffer, BUFFER_SIZE);
-DoSomething(buffer, BUFFER_SIZE);
- -

Then, the stream basically just calls memcpy() to copy the data from the array into your buffer. With a ZeroCopyInputStream, you would do this instead:

- -
const void* buffer;
-int size;
-input->Next(&buffer, &size);
-DoSomething(buffer, size);
- -

Here, no copy is performed. The input stream returns a pointer directly into the backing array, and the caller ends up reading directly from it.

- -

If you want to be able to read the old-fashion way, you can create a CodedInputStream or CodedOutputStream wrapping these objects and use their ReadRaw()/WriteRaw() methods. These will, of course, add a copy step, but Coded*Stream will handle buffering so at least it will be reasonably efficient.

- -

ZeroCopyInputStream example:

- -
// Read in a file and print its contents to stdout.
-int fd = open("myfile", O_RDONLY);
-ZeroCopyInputStream* input = new FileInputStream(fd);
-
-const void* buffer;
-int size;
-while (input->Next(&buffer, &size)) {
-  cout.write(buffer, size);
-}
-
-delete input;
-close(fd);
- -

ZeroCopyOutputStream example:

- -
// Copy the contents of "infile" to "outfile", using plain read() for
-// "infile" but a ZeroCopyOutputStream for "outfile".
-int infd = open("infile", O_RDONLY);
-int outfd = open("outfile", O_WRONLY);
-ZeroCopyOutputStream* output = new FileOutputStream(outfd);
-
-void* buffer;
-int size;
-while (output->Next(&buffer, &size)) {
-  int bytes = read(infd, buffer, size);
-  if (bytes < size) {
-    // Reached EOF.
-    output->BackUp(size - bytes);
-    break;
-  }
-}
-
-delete output;
-close(infd);
-close(outfd);
- -

Classes in this file

Abstract interface similar to an input stream but designed to minimize copying.
Abstract interface similar to an output stream but designed to minimize copying.

class ZeroCopyInputStream

#include <google/protobuf/io/zero_copy_stream.h>
namespace google::protobuf::io

Abstract interface similar to an input stream but designed to minimize copying.

Known subclasses:

Members

ZeroCopyInputStream()
virtual
~ZeroCopyInputStream()
virtual bool
Next(const void ** data, int * size) = 0
Obtains a chunk of data from the stream. more...
virtual void
BackUp(int count) = 0
Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next(). more...
virtual bool
Skip(int count) = 0
Skips a number of bytes. more...
virtual int64_t
ByteCount() const = 0
Returns the total number of bytes read since this object was created.

virtual bool ZeroCopyInputStream::Next(
        const void ** data,
        int * size) = 0

Obtains a chunk of data from the stream.

Preconditions:

-
    -
  • "size" and "data" are not NULL.
  • -
-

Postconditions:

-
    -
  • If the returned value is false, there is no more data to return or an error occurred. All errors are permanent.
  • -
  • Otherwise, "size" points to the actual number of bytes read and "data" points to a pointer to a buffer containing these bytes.
  • -
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • -
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.
  • -
-

virtual void ZeroCopyInputStream::BackUp(
        int count) = 0

Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next().

This is useful when writing procedures that are only supposed to read up to a certain point in the input, then return. If Next() returns a buffer that goes beyond what you wanted to read, you can use BackUp() to return to the point where you intended to finish.

-

Preconditions:

-
    -
  • The last method called must have been Next().
  • -
  • count must be less than or equal to the size of the last buffer returned by Next().
  • -
-

Postconditions:

-
    -
  • The last "count" bytes of the last buffer returned by Next() will be pushed back into the stream. Subsequent calls to Next() will return the same data again before producing new data.
  • -
-

virtual bool ZeroCopyInputStream::Skip(
        int count) = 0

Skips a number of bytes.

Returns false if the end of the stream is reached or some input error occurred. In the end-of-stream case, the stream is advanced to the end of the stream (so ByteCount() will return the total size of the stream).

-

class ZeroCopyOutputStream

#include <google/protobuf/io/zero_copy_stream.h>
namespace google::protobuf::io

Abstract interface similar to an output stream but designed to minimize copying.

Known subclasses:

Members

ZeroCopyOutputStream()
virtual
~ZeroCopyOutputStream()
virtual bool
Next(void ** data, int * size) = 0
Obtains a buffer into which data can be written. more...
virtual void
BackUp(int count) = 0
Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written. more...
virtual int64_t
ByteCount() const = 0
Returns the total number of bytes written since this object was created.
virtual bool
WriteAliasedRaw(const void * data, int size)
Write a given chunk of data to the output. more...
virtual bool
AllowsAliasing() const

virtual bool ZeroCopyOutputStream::Next(
        void ** data,
        int * size) = 0

Obtains a buffer into which data can be written.

Any data written into this buffer will eventually (maybe instantly, maybe later on) be written to the output.

-

Preconditions:

-
    -
  • "size" and "data" are not NULL.
  • -
-

Postconditions:

-
    -
  • If the returned value is false, an error occurred. All errors are permanent.
  • -
  • Otherwise, "size" points to the actual number of bytes in the buffer and "data" points to the buffer.
  • -
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • -
  • Any data which the caller stores in this buffer will eventually be written to the output (unless BackUp() is called).
  • -
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.
  • -
-

virtual void ZeroCopyOutputStream::BackUp(
        int count) = 0

Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written.

This is needed when you finish writing all the data you want to write, but the last buffer was bigger than you needed. You don't want to write a bunch of garbage after the end of your data, so you use BackUp() to back up.

-

Preconditions:

-
    -
  • The last method called must have been Next().
  • -
  • count must be less than or equal to the size of the last buffer returned by Next().
  • -
  • The caller must not have written anything to the last "count" bytes of that buffer.
  • -
-

Postconditions:

-
    -
  • The last "count" bytes of the last buffer returned by Next() will be ignored.
  • -
-

virtual bool ZeroCopyOutputStream::WriteAliasedRaw(
        const void * data,
        int size)

Write a given chunk of data to the output.

Some output streams may implement this in a way that avoids copying. Check AllowsAliasing() before calling WriteAliasedRaw(). It will GOOGLE_CHECK fail if WriteAliasedRaw() is called on a stream that does not allow aliasing.

-

NOTE: It is caller's responsibility to ensure that the chunk of memory remains live until all of the data has been consumed from the stream.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl.md b/content/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl.md deleted file mode 100644 index e9a433053..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl.md +++ /dev/null @@ -1,116 +0,0 @@ -+++ -title = "zero_copy_stream_impl.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/io/zero_copy_stream_impl.h>
namespace google::protobuf::io

This file contains common implementations of the interfaces defined in zero_copy_stream.h which are only included in the full (non-lite) protobuf library.

These implementations include Unix file descriptors and C++ iostreams. See also: zero_copy_stream_impl_lite.h

- -

Classes in this file

A ZeroCopyInputStream which reads from a file descriptor.
A ZeroCopyOutputStream which writes to a file descriptor.
A ZeroCopyInputStream which reads from a C++ istream.
A ZeroCopyOutputStream which writes to a C++ ostream.
A ZeroCopyInputStream which reads from several other streams in sequence.

class FileInputStream: public ZeroCopyInputStream

#include <google/protobuf/io/zero_copy_stream_impl.h>
namespace google::protobuf::io

A ZeroCopyInputStream which reads from a file descriptor.

FileInputStream is preferred over using an ifstream with IstreamInputStream. The latter will introduce an extra layer of buffering, harming performance. Also, it's conceivable that FileInputStream could someday be enhanced to use zero-copy file descriptors on OSs which support them.

-

Members

explicit
FileInputStream(int file_descriptor, int block_size = -1)
Creates a stream that reads from the given Unix file descriptor. more...
bool
Close()
Flushes any buffers and closes the underlying file. more...
void
SetCloseOnDelete(bool value)
By default, the file descriptor is not closed when the stream is destroyed. more...
int
GetErrno() const
If an I/O error has occurred on this file descriptor, this is the errno from that error. more...

implements ZeroCopyInputStream

virtual bool
Next(const void ** data, int * size)
Obtains a chunk of data from the stream. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next(). more...
virtual bool
Skip(int count)
Skips a number of bytes. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes read since this object was created.

explicit FileInputStream::FileInputStream(
        int file_descriptor,
        int block_size = -1)

Creates a stream that reads from the given Unix file descriptor.

If a block_size is given, it specifies the number of bytes that should be read and returned with each call to Next(). Otherwise, a reasonable default is used.

-

bool FileInputStream::Close()

Flushes any buffers and closes the underlying file.

Returns false if an error occurs during the process; use GetErrno() to examine the error. Even if an error occurs, the file descriptor is closed when this returns.

-

void FileInputStream::SetCloseOnDelete(
        bool value)

By default, the file descriptor is not closed when the stream is destroyed.

Call SetCloseOnDelete(true) to change that. WARNING: This leaves no way for the caller to detect if close() fails. If detecting close() errors is important to you, you should arrange to close the descriptor yourself.

-

int FileInputStream::GetErrno() const

If an I/O error has occurred on this file descriptor, this is the errno from that error.

Otherwise, this is zero. Once an error occurs, the stream is broken and all subsequent operations will fail.

-

virtual bool FileInputStream::Next(
        const void ** data,
        int * size)

Obtains a chunk of data from the stream.

Preconditions:

-
    -
  • "size" and "data" are not NULL.
  • -
-

Postconditions:

-
    -
  • If the returned value is false, there is no more data to return or an error occurred. All errors are permanent.
  • -
  • Otherwise, "size" points to the actual number of bytes read and "data" points to a pointer to a buffer containing these bytes.
  • -
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • -
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.
  • -
-

virtual void FileInputStream::BackUp(
        int count)

Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next().

This is useful when writing procedures that are only supposed to read up to a certain point in the input, then return. If Next() returns a buffer that goes beyond what you wanted to read, you can use BackUp() to return to the point where you intended to finish.

-

Preconditions:

-
    -
  • The last method called must have been Next().
  • -
  • count must be less than or equal to the size of the last buffer returned by Next().
  • -
-

Postconditions:

-
    -
  • The last "count" bytes of the last buffer returned by Next() will be pushed back into the stream. Subsequent calls to Next() will return the same data again before producing new data.
  • -
-

virtual bool FileInputStream::Skip(
        int count)

Skips a number of bytes.

Returns false if the end of the stream is reached or some input error occurred. In the end-of-stream case, the stream is advanced to the end of the stream (so ByteCount() will return the total size of the stream).

-

class FileOutputStream: public CopyingOutputStreamAdaptor

#include <google/protobuf/io/zero_copy_stream_impl.h>
namespace google::protobuf::io

A ZeroCopyOutputStream which writes to a file descriptor.

FileOutputStream is preferred over using an ofstream with OstreamOutputStream. The latter will introduce an extra layer of buffering, harming performance. Also, it's conceivable that FileOutputStream could someday be enhanced to use zero-copy file descriptors on OSs which support them.

-

Members

explicit
FileOutputStream(int file_descriptor, int block_size = -1)
Creates a stream that writes to the given Unix file descriptor. more...
~FileOutputStream()
bool
Close()
Flushes any buffers and closes the underlying file. more...
void
SetCloseOnDelete(bool value)
By default, the file descriptor is not closed when the stream is destroyed. more...
int
GetErrno() const
If an I/O error has occurred on this file descriptor, this is the errno from that error. more...

explicit FileOutputStream::FileOutputStream(
        int file_descriptor,
        int block_size = -1)

Creates a stream that writes to the given Unix file descriptor.

If a block_size is given, it specifies the size of the buffers that should be returned by Next(). Otherwise, a reasonable default is used.

-

bool FileOutputStream::Close()

Flushes any buffers and closes the underlying file.

Returns false if an error occurs during the process; use GetErrno() to examine the error. Even if an error occurs, the file descriptor is closed when this returns.

-

void FileOutputStream::SetCloseOnDelete(
        bool value)

By default, the file descriptor is not closed when the stream is destroyed.

Call SetCloseOnDelete(true) to change that. WARNING: This leaves no way for the caller to detect if close() fails. If detecting close() errors is important to you, you should arrange to close the descriptor yourself.

-

int FileOutputStream::GetErrno() const

If an I/O error has occurred on this file descriptor, this is the errno from that error.

Otherwise, this is zero. Once an error occurs, the stream is broken and all subsequent operations will fail.

-

class IstreamInputStream: public ZeroCopyInputStream

#include <google/protobuf/io/zero_copy_stream_impl.h>
namespace google::protobuf::io

A ZeroCopyInputStream which reads from a C++ istream.

Note that for reading files (or anything represented by a file descriptor), FileInputStream is more efficient.

-

Members

explicit
IstreamInputStream(std::istream * stream, int block_size = -1)
Creates a stream that reads from the given C++ istream. more...

implements ZeroCopyInputStream

virtual bool
Next(const void ** data, int * size)
Obtains a chunk of data from the stream. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next(). more...
virtual bool
Skip(int count)
Skips a number of bytes. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes read since this object was created.

explicit IstreamInputStream::IstreamInputStream(
        std::istream * stream,
        int block_size = -1)

Creates a stream that reads from the given C++ istream.

If a block_size is given, it specifies the number of bytes that should be read and returned with each call to Next(). Otherwise, a reasonable default is used.

-

virtual bool IstreamInputStream::Next(
        const void ** data,
        int * size)

Obtains a chunk of data from the stream.

Preconditions:

-
    -
  • "size" and "data" are not NULL.
  • -
-

Postconditions:

-
    -
  • If the returned value is false, there is no more data to return or an error occurred. All errors are permanent.
  • -
  • Otherwise, "size" points to the actual number of bytes read and "data" points to a pointer to a buffer containing these bytes.
  • -
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • -
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.
  • -
-

virtual void IstreamInputStream::BackUp(
        int count)

Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next().

This is useful when writing procedures that are only supposed to read up to a certain point in the input, then return. If Next() returns a buffer that goes beyond what you wanted to read, you can use BackUp() to return to the point where you intended to finish.

-

Preconditions:

-
    -
  • The last method called must have been Next().
  • -
  • count must be less than or equal to the size of the last buffer returned by Next().
  • -
-

Postconditions:

-
    -
  • The last "count" bytes of the last buffer returned by Next() will be pushed back into the stream. Subsequent calls to Next() will return the same data again before producing new data.
  • -
-

virtual bool IstreamInputStream::Skip(
        int count)

Skips a number of bytes.

Returns false if the end of the stream is reached or some input error occurred. In the end-of-stream case, the stream is advanced to the end of the stream (so ByteCount() will return the total size of the stream).

-

class OstreamOutputStream: public ZeroCopyOutputStream

#include <google/protobuf/io/zero_copy_stream_impl.h>
namespace google::protobuf::io

A ZeroCopyOutputStream which writes to a C++ ostream.

Note that for writing files (or anything represented by a file descriptor), FileOutputStream is more efficient.

-

Members

explicit
OstreamOutputStream(std::ostream * stream, int block_size = -1)
Creates a stream that writes to the given C++ ostream. more...
~OstreamOutputStream()

implements ZeroCopyOutputStream

virtual bool
Next(void ** data, int * size)
Obtains a buffer into which data can be written. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes written since this object was created.

explicit OstreamOutputStream::OstreamOutputStream(
        std::ostream * stream,
        int block_size = -1)

Creates a stream that writes to the given C++ ostream.

If a block_size is given, it specifies the size of the buffers that should be returned by Next(). Otherwise, a reasonable default is used.

-

virtual bool OstreamOutputStream::Next(
        void ** data,
        int * size)

Obtains a buffer into which data can be written.

Any data written into this buffer will eventually (maybe instantly, maybe later on) be written to the output.

-

Preconditions:

-
    -
  • "size" and "data" are not NULL.
  • -
-

Postconditions:

-
    -
  • If the returned value is false, an error occurred. All errors are permanent.
  • -
  • Otherwise, "size" points to the actual number of bytes in the buffer and "data" points to the buffer.
  • -
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • -
  • Any data which the caller stores in this buffer will eventually be written to the output (unless BackUp() is called).
  • -
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.
  • -
-

virtual void OstreamOutputStream::BackUp(
        int count)

Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written.

This is needed when you finish writing all the data you want to write, but the last buffer was bigger than you needed. You don't want to write a bunch of garbage after the end of your data, so you use BackUp() to back up.

-

Preconditions:

-
    -
  • The last method called must have been Next().
  • -
  • count must be less than or equal to the size of the last buffer returned by Next().
  • -
  • The caller must not have written anything to the last "count" bytes of that buffer.
  • -
-

Postconditions:

-
    -
  • The last "count" bytes of the last buffer returned by Next() will be ignored.
  • -
-

class ConcatenatingInputStream: public ZeroCopyInputStream

#include <google/protobuf/io/zero_copy_stream_impl.h>
namespace google::protobuf::io

A ZeroCopyInputStream which reads from several other streams in sequence.

ConcatenatingInputStream is unable to distinguish between end-of-stream and read errors in the underlying streams, so it assumes any errors mean end-of-stream. So, if the underlying streams fail for any other reason, ConcatenatingInputStream may do odd things. It is suggested that you do not use ConcatenatingInputStream on streams that might produce read errors other than end-of-stream.

-

Members

ConcatenatingInputStream(ZeroCopyInputStream *const streams, int count)
All streams passed in as well as the array itself must remain valid until the ConcatenatingInputStream is destroyed.
~ConcatenatingInputStream()

implements ZeroCopyInputStream

virtual bool
Next(const void ** data, int * size)
Obtains a chunk of data from the stream. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next(). more...
virtual bool
Skip(int count)
Skips a number of bytes. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes read since this object was created.

virtual bool ConcatenatingInputStream::Next(
        const void ** data,
        int * size)

Obtains a chunk of data from the stream.

Preconditions:

-
    -
  • "size" and "data" are not NULL.
  • -
-

Postconditions:

-
    -
  • If the returned value is false, there is no more data to return or an error occurred. All errors are permanent.
  • -
  • Otherwise, "size" points to the actual number of bytes read and "data" points to a pointer to a buffer containing these bytes.
  • -
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • -
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.
  • -
-

virtual void ConcatenatingInputStream::BackUp(
        int count)

Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next().

This is useful when writing procedures that are only supposed to read up to a certain point in the input, then return. If Next() returns a buffer that goes beyond what you wanted to read, you can use BackUp() to return to the point where you intended to finish.

-

Preconditions:

-
    -
  • The last method called must have been Next().
  • -
  • count must be less than or equal to the size of the last buffer returned by Next().
  • -
-

Postconditions:

-
    -
  • The last "count" bytes of the last buffer returned by Next() will be pushed back into the stream. Subsequent calls to Next() will return the same data again before producing new data.
  • -
-

virtual bool ConcatenatingInputStream::Skip(
        int count)

Skips a number of bytes.

Returns false if the end of the stream is reached or some input error occurred. In the end-of-stream case, the stream is advanced to the end of the stream (so ByteCount() will return the total size of the stream).

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl_lite.md b/content/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl_lite.md deleted file mode 100644 index a04133874..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl_lite.md +++ /dev/null @@ -1,171 +0,0 @@ -+++ -title = "zero_copy_stream_iml_lite.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

This file contains common implementations of the interfaces defined in zero_copy_stream.h which are included in the "lite" protobuf library.

These implementations cover I/O on raw arrays and strings, as well as adaptors which make it easy to implement streams based on traditional streams. Of course, many users will probably want to write their own implementations of these interfaces specific to the particular I/O abstractions they prefer to use, but these should cover the most common cases.

- -

Classes in this file

A ZeroCopyInputStream backed by an in-memory array of bytes.
A ZeroCopyOutputStream backed by an in-memory array of bytes.
A ZeroCopyOutputStream which appends bytes to a string.
A generic traditional input stream interface.
A generic traditional output stream interface.
A ZeroCopyInputStream which wraps some other stream and limits it to a particular byte count.

File Members

These definitions are not part of any class.
char *
mutable_string_data(std::string * s)
Return a pointer to mutable characters underlying the given string. more...
std::pair< char *, bool >
as_string_data(std::string * s)
as_string_data(s) is equivalent to ({ char* p = mutable_string_data(s); make_pair(p, p != NULL); }) Sometimes it's faster: in some scenarios p cannot be NULL, and then the code can avoid that check.

char * io::mutable_string_data(
        std::string * s)

Return a pointer to mutable characters underlying the given string.

The return value is valid until the next time the string is resized. We trust the caller to treat the return value as an array of length s->size().

-

class ArrayInputStream: public ZeroCopyInputStream

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

A ZeroCopyInputStream backed by an in-memory array of bytes.

Members

ArrayInputStream(const void * data, int size, int block_size = -1)
Create an InputStream that returns the bytes pointed to by "data". more...
~ArrayInputStream()

implements ZeroCopyInputStream

virtual bool
Next(const void ** data, int * size)
Obtains a chunk of data from the stream. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next(). more...
virtual bool
Skip(int count)
Skips a number of bytes. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes read since this object was created.

ArrayInputStream::ArrayInputStream(
        const void * data,
        int size,
        int block_size = -1)

Create an InputStream that returns the bytes pointed to by "data".

"data" remains the property of the caller but must remain valid until the stream is destroyed. If a block_size is given, calls to Next() will return data blocks no larger than the given size. Otherwise, the first call to Next() returns the entire array. block_size is mainly useful for testing; in production you would probably never want to set it.

-

virtual bool ArrayInputStream::Next(
        const void ** data,
        int * size)

Obtains a chunk of data from the stream.

Preconditions:

-
    -
  • "size" and "data" are not NULL.
  • -
-

Postconditions:

-
    -
  • If the returned value is false, there is no more data to return or an error occurred. All errors are permanent.
  • -
  • Otherwise, "size" points to the actual number of bytes read and "data" points to a pointer to a buffer containing these bytes.
  • -
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • -
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.
  • -
-

virtual void ArrayInputStream::BackUp(
        int count)

Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next().

This is useful when writing procedures that are only supposed to read up to a certain point in the input, then return. If Next() returns a buffer that goes beyond what you wanted to read, you can use BackUp() to return to the point where you intended to finish.

-

Preconditions:

-
    -
  • The last method called must have been Next().
  • -
  • count must be less than or equal to the size of the last buffer returned by Next().
  • -
-

Postconditions:

-
    -
  • The last "count" bytes of the last buffer returned by Next() will be pushed back into the stream. Subsequent calls to Next() will return the same data again before producing new data.
  • -
-

virtual bool ArrayInputStream::Skip(
        int count)

Skips a number of bytes.

Returns false if the end of the stream is reached or some input error occurred. In the end-of-stream case, the stream is advanced to the end of the stream (so ByteCount() will return the total size of the stream).

-

class ArrayOutputStream: public ZeroCopyOutputStream

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

A ZeroCopyOutputStream backed by an in-memory array of bytes.

Members

ArrayOutputStream(void * data, int size, int block_size = -1)
Create an OutputStream that writes to the bytes pointed to by "data". more...
~ArrayOutputStream()

implements ZeroCopyOutputStream

virtual bool
Next(void ** data, int * size)
Obtains a buffer into which data can be written. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes written since this object was created.

ArrayOutputStream::ArrayOutputStream(
        void * data,
        int size,
        int block_size = -1)

Create an OutputStream that writes to the bytes pointed to by "data".

"data" remains the property of the caller but must remain valid until the stream is destroyed. If a block_size is given, calls to Next() will return data blocks no larger than the given size. Otherwise, the first call to Next() returns the entire array. block_size is mainly useful for testing; in production you would probably never want to set it.

-

virtual bool ArrayOutputStream::Next(
        void ** data,
        int * size)

Obtains a buffer into which data can be written.

Any data written into this buffer will eventually (maybe instantly, maybe later on) be written to the output.

-

Preconditions:

-
    -
  • "size" and "data" are not NULL.
  • -
-

Postconditions:

-
    -
  • If the returned value is false, an error occurred. All errors are permanent.
  • -
  • Otherwise, "size" points to the actual number of bytes in the buffer and "data" points to the buffer.
  • -
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • -
  • Any data which the caller stores in this buffer will eventually be written to the output (unless BackUp() is called).
  • -
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.
  • -
-

virtual void ArrayOutputStream::BackUp(
        int count)

Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written.

This is needed when you finish writing all the data you want to write, but the last buffer was bigger than you needed. You don't want to write a bunch of garbage after the end of your data, so you use BackUp() to back up.

-

Preconditions:

-
    -
  • The last method called must have been Next().
  • -
  • count must be less than or equal to the size of the last buffer returned by Next().
  • -
  • The caller must not have written anything to the last "count" bytes of that buffer.
  • -
-

Postconditions:

-
    -
  • The last "count" bytes of the last buffer returned by Next() will be ignored.
  • -
-

class StringOutputStream: public ZeroCopyOutputStream

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

A ZeroCopyOutputStream which appends bytes to a string.

Members

explicit
StringOutputStream(std::string * target)
Create a StringOutputStream which appends bytes to the given string. more...
~StringOutputStream()

implements ZeroCopyOutputStream

virtual bool
Next(void ** data, int * size)
Obtains a buffer into which data can be written. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes written since this object was created.

explicit StringOutputStream::StringOutputStream(
        std::string * target)

Create a StringOutputStream which appends bytes to the given string.

The string remains property of the caller, but it is mutated in arbitrary ways and MUST NOT be accessed in any way until you're done with the stream. Either be sure there's no further usage, or (safest) destroy the stream before using the contents.

-

Hint: If you call target->reserve(n) before creating the stream, the first call to Next() will return at least n bytes of buffer space.

-

virtual bool StringOutputStream::Next(
        void ** data,
        int * size)

Obtains a buffer into which data can be written.

Any data written into this buffer will eventually (maybe instantly, maybe later on) be written to the output.

-

Preconditions:

-
    -
  • "size" and "data" are not NULL.
  • -
-

Postconditions:

-
    -
  • If the returned value is false, an error occurred. All errors are permanent.
  • -
  • Otherwise, "size" points to the actual number of bytes in the buffer and "data" points to the buffer.
  • -
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • -
  • Any data which the caller stores in this buffer will eventually be written to the output (unless BackUp() is called).
  • -
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.
  • -
-

virtual void StringOutputStream::BackUp(
        int count)

Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written.

This is needed when you finish writing all the data you want to write, but the last buffer was bigger than you needed. You don't want to write a bunch of garbage after the end of your data, so you use BackUp() to back up.

-

Preconditions:

-
    -
  • The last method called must have been Next().
  • -
  • count must be less than or equal to the size of the last buffer returned by Next().
  • -
  • The caller must not have written anything to the last "count" bytes of that buffer.
  • -
-

Postconditions:

-
    -
  • The last "count" bytes of the last buffer returned by Next() will be ignored.
  • -
-

class CopyingInputStream

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

A generic traditional input stream interface.

Lots of traditional input streams (e.g. file descriptors, C stdio streams, and C++ iostreams) expose an interface where every read involves copying bytes into a buffer. If you want to take such an interface and make a ZeroCopyInputStream based on it, simply implement CopyingInputStream and then use CopyingInputStreamAdaptor.

-

CopyingInputStream implementations should avoid buffering if possible. CopyingInputStreamAdaptor does its own buffering and will read data in large blocks.

-

Members

virtual
~CopyingInputStream()
virtual int
Read(void * buffer, int size) = 0
Reads up to "size" bytes into the given buffer. more...
virtual int
Skip(int count)
Skips the next "count" bytes of input. more...

virtual int CopyingInputStream::Read(
        void * buffer,
        int size) = 0

Reads up to "size" bytes into the given buffer.

Returns the number of bytes read. Read() waits until at least one byte is available, or returns zero if no bytes will ever become available (EOF), or -1 if a permanent read error occurred.

-

virtual int CopyingInputStream::Skip(
        int count)

Skips the next "count" bytes of input.

Returns the number of bytes actually skipped. This will always be exactly equal to "count" unless EOF was reached or a permanent read error occurred.

-

The default implementation just repeatedly calls Read() into a scratch buffer.

-

class CopyingInputStreamAdaptor: public ZeroCopyInputStream

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

A ZeroCopyInputStream which reads from a CopyingInputStream.

This is useful for implementing ZeroCopyInputStreams that read from traditional streams. Note that this class is not really zero-copy.

-

If you want to read from file descriptors or C++ istreams, this is already implemented for you: use FileInputStream or IstreamInputStream respectively.

-

Members

explicit
CopyingInputStreamAdaptor(CopyingInputStream * copying_stream, int block_size = -1)
Creates a stream that reads from the given CopyingInputStream. more...
~CopyingInputStreamAdaptor()
void
SetOwnsCopyingStream(bool value)
Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to delete the underlying CopyingInputStream when it is destroyed.

implements ZeroCopyInputStream

virtual bool
Next(const void ** data, int * size)
Obtains a chunk of data from the stream. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next(). more...
virtual bool
Skip(int count)
Skips a number of bytes. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes read since this object was created.

explicit CopyingInputStreamAdaptor::CopyingInputStreamAdaptor(
        CopyingInputStream * copying_stream,
        int block_size = -1)

Creates a stream that reads from the given CopyingInputStream.

If a block_size is given, it specifies the number of bytes that should be read and returned with each call to Next(). Otherwise, a reasonable default is used. The caller retains ownership of copying_stream unless SetOwnsCopyingStream(true) is called.

-

virtual bool CopyingInputStreamAdaptor::Next(
        const void ** data,
        int * size)

Obtains a chunk of data from the stream.

Preconditions:

-
    -
  • "size" and "data" are not NULL.
  • -
-

Postconditions:

-
    -
  • If the returned value is false, there is no more data to return or an error occurred. All errors are permanent.
  • -
  • Otherwise, "size" points to the actual number of bytes read and "data" points to a pointer to a buffer containing these bytes.
  • -
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • -
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.
  • -
-

virtual void CopyingInputStreamAdaptor::BackUp(
        int count)

Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next().

This is useful when writing procedures that are only supposed to read up to a certain point in the input, then return. If Next() returns a buffer that goes beyond what you wanted to read, you can use BackUp() to return to the point where you intended to finish.

-

Preconditions:

-
    -
  • The last method called must have been Next().
  • -
  • count must be less than or equal to the size of the last buffer returned by Next().
  • -
-

Postconditions:

-
    -
  • The last "count" bytes of the last buffer returned by Next() will be pushed back into the stream. Subsequent calls to Next() will return the same data again before producing new data.
  • -
-

virtual bool CopyingInputStreamAdaptor::Skip(
        int count)

Skips a number of bytes.

Returns false if the end of the stream is reached or some input error occurred. In the end-of-stream case, the stream is advanced to the end of the stream (so ByteCount() will return the total size of the stream).

-

class CopyingOutputStream

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

A generic traditional output stream interface.

Lots of traditional output streams (e.g. file descriptors, C stdio streams, and C++ iostreams) expose an interface where every write involves copying bytes from a buffer. If you want to take such an interface and make a ZeroCopyOutputStream based on it, simply implement CopyingOutputStream and then use CopyingOutputStreamAdaptor.

-

CopyingOutputStream implementations should avoid buffering if possible. CopyingOutputStreamAdaptor does its own buffering and will write data in large blocks.

-

Members

virtual
~CopyingOutputStream()
virtual bool
Write(const void * buffer, int size) = 0
Writes "size" bytes from the given buffer to the output. more...

virtual bool CopyingOutputStream::Write(
        const void * buffer,
        int size) = 0

Writes "size" bytes from the given buffer to the output.

Returns true if successful, false on a write error.

-

class CopyingOutputStreamAdaptor: public ZeroCopyOutputStream

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

A ZeroCopyOutputStream which writes to a CopyingOutputStream.

This is useful for implementing ZeroCopyOutputStreams that write to traditional streams. Note that this class is not really zero-copy.

-

If you want to write to file descriptors or C++ ostreams, this is already implemented for you: use FileOutputStream or OstreamOutputStream respectively.

-

Known subclasses:

Members

explicit
CopyingOutputStreamAdaptor(CopyingOutputStream * copying_stream, int block_size = -1)
Creates a stream that writes to the given Unix file descriptor. more...
~CopyingOutputStreamAdaptor()
bool
Flush()
Writes all pending data to the underlying stream. more...
void
SetOwnsCopyingStream(bool value)
Call SetOwnsCopyingStream(true) to tell the CopyingOutputStreamAdaptor to delete the underlying CopyingOutputStream when it is destroyed.

implements ZeroCopyOutputStream

virtual bool
Next(void ** data, int * size)
Obtains a buffer into which data can be written. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes written since this object was created.
virtual bool
WriteAliasedRaw(const void * data, int size)
Write a given chunk of data to the output. more...
virtual bool
AllowsAliasing() const

explicit CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor(
        CopyingOutputStream * copying_stream,
        int block_size = -1)

Creates a stream that writes to the given Unix file descriptor.

If a block_size is given, it specifies the size of the buffers that should be returned by Next(). Otherwise, a reasonable default is used.

-

bool CopyingOutputStreamAdaptor::Flush()

Writes all pending data to the underlying stream.

Returns false if a write error occurred on the underlying stream. (The underlying stream itself is not necessarily flushed.)

-

virtual bool CopyingOutputStreamAdaptor::Next(
        void ** data,
        int * size)

Obtains a buffer into which data can be written.

Any data written into this buffer will eventually (maybe instantly, maybe later on) be written to the output.

-

Preconditions:

-
    -
  • "size" and "data" are not NULL.
  • -
-

Postconditions:

-
    -
  • If the returned value is false, an error occurred. All errors are permanent.
  • -
  • Otherwise, "size" points to the actual number of bytes in the buffer and "data" points to the buffer.
  • -
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • -
  • Any data which the caller stores in this buffer will eventually be written to the output (unless BackUp() is called).
  • -
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.
  • -
-

virtual void CopyingOutputStreamAdaptor::BackUp(
        int count)

Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written.

This is needed when you finish writing all the data you want to write, but the last buffer was bigger than you needed. You don't want to write a bunch of garbage after the end of your data, so you use BackUp() to back up.

-

Preconditions:

-
    -
  • The last method called must have been Next().
  • -
  • count must be less than or equal to the size of the last buffer returned by Next().
  • -
  • The caller must not have written anything to the last "count" bytes of that buffer.
  • -
-

Postconditions:

-
    -
  • The last "count" bytes of the last buffer returned by Next() will be ignored.
  • -
-

virtual bool CopyingOutputStreamAdaptor::WriteAliasedRaw(
        const void * data,
        int size)

Write a given chunk of data to the output.

Some output streams may implement this in a way that avoids copying. Check AllowsAliasing() before calling WriteAliasedRaw(). It will GOOGLE_CHECK fail if WriteAliasedRaw() is called on a stream that does not allow aliasing.

-

NOTE: It is caller's responsibility to ensure that the chunk of memory remains live until all of the data has been consumed from the stream.

-

class LimitingInputStream: public ZeroCopyInputStream

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

A ZeroCopyInputStream which wraps some other stream and limits it to a particular byte count.

Members

LimitingInputStream(ZeroCopyInputStream * input, int64 limit)
~LimitingInputStream()

implements ZeroCopyInputStream

virtual bool
Next(const void ** data, int * size)
Obtains a chunk of data from the stream. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next(). more...
virtual bool
Skip(int count)
Skips a number of bytes. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes read since this object was created.

virtual bool LimitingInputStream::Next(
        const void ** data,
        int * size)

Obtains a chunk of data from the stream.

Preconditions:

-
    -
  • "size" and "data" are not NULL.
  • -
-

Postconditions:

-
    -
  • If the returned value is false, there is no more data to return or an error occurred. All errors are permanent.
  • -
  • Otherwise, "size" points to the actual number of bytes read and "data" points to a pointer to a buffer containing these bytes.
  • -
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • -
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.
  • -
-

virtual void LimitingInputStream::BackUp(
        int count)

Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next().

This is useful when writing procedures that are only supposed to read up to a certain point in the input, then return. If Next() returns a buffer that goes beyond what you wanted to read, you can use BackUp() to return to the point where you intended to finish.

-

Preconditions:

-
    -
  • The last method called must have been Next().
  • -
  • count must be less than or equal to the size of the last buffer returned by Next().
  • -
-

Postconditions:

-
    -
  • The last "count" bytes of the last buffer returned by Next() will be pushed back into the stream. Subsequent calls to Next() will return the same data again before producing new data.
  • -
-

virtual bool LimitingInputStream::Skip(
        int count)

Skips a number of bytes.

Returns false if the end of the stream is reached or some input error occurred. In the end-of-stream case, the stream is advanced to the end of the stream (so ByteCount() will return the total size of the stream).

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.map.md b/content/reference/cpp/api-docs/google.protobuf.map.md deleted file mode 100644 index f0022eb39..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.map.md +++ /dev/null @@ -1,17 +0,0 @@ - - -+++ -title = "map.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/map.h>
namespace google::protobuf

This file defines the map container and its helpers to support protobuf maps.

The Map and MapIterator types are provided by this header file. Please avoid using other types defined here, unless they are public types within Map or MapIterator, such as Map::value_type.

- -

Classes in this file

This is the class for Map's internal value_type.
Map is an associative container type used to store protobuf map fields.
Iterators.

template alias MapPair

#include <google/protobuf/map.h>
namespace google::protobuf

template <typename , typename >

This is the class for Map's internal value_type, which is just an alias to std::pair.

-

template class Map

#include <google/protobuf/map.h>
namespace google::protobuf

template <typename , typename >

Map is an associative container type used to store protobuf map fields.

Each Map instance may or may not use a different hash function, a different iteration order, and so on. E.g., please don't examine implementation details to decide if the following would work: Map<int, int> m0, m1; m0[0] = m1[0] = m0[1] = m1[1] = 0; assert(m0.begin()->first == m1.begin()->first); // Bug!

-

Map's interface is similar to std::unordered_map, except that Map is not designed to play well with exceptions.

-

Members

typedef
Key key_type
typedef
T mapped_type
typedef
MapPair< Key, T > value_type
typedef
value_type * pointer
typedef
const value_type * const_pointer
typedef
value_type & reference
typedef
const value_type & const_reference
typedef
size_t size_type
typedef
typename internal::TransparentSupport< Key >::hash hasher
constexpr
Map()
explicit
Map(Arena * arena)
Map(const Map & other)
Map(Map && other)
Map &
operator=(Map && other)
template
Map(const InputIt & first, const InputIt & last)
~Map()
iterator
begin()
iterator
end()
const_iterator
begin() const
const_iterator
end() const
const_iterator
cbegin() const
const_iterator
cend() const
size_type
size() const
Capacity.
bool
empty() const
template T &
operator[](const key_arg< K > & key)
Element access.
template T &
operator[](key_arg< K > && key)
template const T &
at(const key_arg< K > & key) const
template T &
at(const key_arg< K > & key)
template size_type
count(const key_arg< K > & key) const
Lookup.
template const_iterator
find(const key_arg< K > & key) const
template iterator
find(const key_arg< K > & key)
template bool
contains(const key_arg< K > & key) const
template std::pair< const_iterator, const_iterator >
equal_range(const key_arg< K > & key) const
template std::pair< iterator, iterator >
equal_range(const key_arg< K > & key)
std::pair< iterator, bool >
insert(const value_type & value)
insert
template void
insert(InputIt first, InputIt last)
void
insert(std::initializer_list< value_type > values)
template size_type
erase(const key_arg< K > & key)
Erase and clear.
iterator
erase(iterator pos)
void
erase(iterator first, iterator last)
void
clear()
Map &
operator=(const Map & other)
Assign.
void
swap(Map & other)
void
InternalSwap(Map & other)
hasher
hash_function() const
Access to hasher. more...
size_t
SpaceUsedExcludingSelfLong() const

hasher Map::hash_function() const

Access to hasher.

Currently this returns a copy, but it may be modified to return a const reference in the future.

-

class Map::const_iterator

#include <google/protobuf/map.h>
namespace google::protobuf

Iterators.

Members

typedef
std::forward_iterator_tag iterator_category
typedef
typename Map::value_type value_type
typedef
ptrdiff_t difference_type
typedef
const value_type * pointer
typedef
const value_type & reference
const_iterator()
explicit
const_iterator(const InnerIt & it)
const_reference
operator*() const
const_pointer
operator->() const
const_iterator &
operator++()
const_iterator
operator++(int )

class Map::iterator

#include <google/protobuf/map.h>
namespace google::protobuf

Members

typedef
std::forward_iterator_tag iterator_category
typedef
typename Map::value_type value_type
typedef
ptrdiff_t difference_type
typedef
value_type * pointer
typedef
value_type & reference
iterator()
explicit
iterator(const InnerIt & it)
reference
operator*() const
pointer
operator->() const
iterator &
operator++()
iterator
operator++(int )
operator const_iterator() const
Allow implicit conversion to const_iterator.
diff --git a/content/reference/cpp/api-docs/google.protobuf.message.md b/content/reference/cpp/api-docs/google.protobuf.message.md deleted file mode 100644 index 2ff71173f..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.message.md +++ /dev/null @@ -1,205 +0,0 @@ -+++ -title = "message.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/message.h>
namespace google::protobuf

Defines Message, the abstract interface implemented by non-lite protocol message objects.

Although it's possible to implement this interface manually, most users will use the protocol compiler to generate implementations.

- -

Example usage:

- -

Say you have a message defined as:

- -
message Foo {
-  optional string text = 1;
-  repeated int32 numbers = 2;
-}
- -

Then, if you used the protocol compiler to generate a class from the above definition, you could use it like so:

- -
std::string data;  // Will store a serialized version of the message.
-
-{
-  // Create a message and serialize it.
-  Foo foo;
-  foo.set_text("Hello World!");
-  foo.add_numbers(1);
-  foo.add_numbers(5);
-  foo.add_numbers(42);
-
-  foo.SerializeToString(&data);
-}
-
-{
-  // Parse the serialized message and check that it contains the
-  // correct data.
-  Foo foo;
-  foo.ParseFromString(data);
-
-  assert(foo.text() == "Hello World!");
-  assert(foo.numbers_size() == 3);
-  assert(foo.numbers(0) == 1);
-  assert(foo.numbers(1) == 5);
-  assert(foo.numbers(2) == 42);
-}
-
-{
-  // Same as the last block, but do it dynamically via the Message
-  // reflection interface.
-  Message* foo = new Foo;
-  const Descriptor* descriptor = foo->GetDescriptor();
-
-  // Get the descriptors for the fields we're interested in and verify
-  // their types.
-  const FieldDescriptor* text_field = descriptor->FindFieldByName("text");
-  assert(text_field != nullptr);
-  assert(text_field->type() == FieldDescriptor::TYPE_STRING);
-  assert(text_field->label() == FieldDescriptor::LABEL_OPTIONAL);
-  const FieldDescriptor* numbers_field = descriptor->
-                                         FindFieldByName("numbers");
-  assert(numbers_field != nullptr);
-  assert(numbers_field->type() == FieldDescriptor::TYPE_INT32);
-  assert(numbers_field->label() == FieldDescriptor::LABEL_REPEATED);
-
-  // Parse the message.
-  foo->ParseFromString(data);
-
-  // Use the reflection interface to examine the contents.
-  const Reflection* reflection = foo->GetReflection();
-  assert(reflection->GetString(*foo, text_field) == "Hello World!");
-  assert(reflection->FieldSize(*foo, numbers_field) == 3);
-  assert(reflection->GetRepeatedInt32(*foo, numbers_field, 0) == 1);
-  assert(reflection->GetRepeatedInt32(*foo, numbers_field, 1) == 5);
-  assert(reflection->GetRepeatedInt32(*foo, numbers_field, 2) == 42);
-
-  delete foo;
-}
- -

Classes in this file

A container to hold message metadata.
Abstract interface for protocol messages.
This interface contains methods that can be used to dynamically access and modify the fields of a protocol message.
Abstract interface for a factory for message objects.

File Members

These definitions are not part of any class.
template const T *
DynamicCastToGenerated(const Message * from)
Tries to downcast this message to a generated message type. more...
template T *
DynamicCastToGenerated(Message * from)
template void
LinkMessageReflection()
Call this function to ensure that this message's reflection is linked into the binary: more...
const RepeatedPtrField< std::string > &
Reflection::GetRepeatedPtrFieldInternal< std::string >(const Message & message, const FieldDescriptor * field) const
RepeatedPtrField< std::string > *
Reflection::MutableRepeatedPtrFieldInternal< std::string >(Message * message, const FieldDescriptor * field) const

template const T * protobuf::DynamicCastToGenerated(
        const Message * from)

Tries to downcast this message to a generated message type.

Returns nullptr if this class is not an instance of T. This works even if RTTI is disabled.

-

This also has the effect of creating a strong reference to T that will prevent the linker from stripping it out at link time. This can be important if you are using a DynamicMessageFactory that delegates to the generated factory.

-

template void protobuf::LinkMessageReflection()

Call this function to ensure that this message's reflection is linked into the binary:

google::protobuf::LinkMessageReflection<FooMessage>();
-

This will ensure that the following lookup will succeed:

-
DescriptorPool::generated_pool()->FindMessageTypeByName("FooMessage");
-

As a side-effect, it will also guarantee that anything else from the same .proto file will also be available for lookup in the generated pool.

-

This function does not actually register the message, so it does not need to be called before the lookup. However it does need to occur in a function that cannot be stripped from the binary (ie. it must be reachable from main).

-

Best practice is to call this function as close as possible to where the reflection is actually needed. This function is very cheap to call, so you should not need to worry about its runtime overhead except in the tightest of loops (on x86-64 it compiles into two "mov" instructions).

-

struct Metadata

#include <google/protobuf/message.h>
namespace google::protobuf

A container to hold message metadata.

Members

const Descriptor *
descriptor
const Reflection *
reflection

class Message: public MessageLite

#include <google/protobuf/message.h>
namespace google::protobuf

Abstract interface for protocol messages.

See also MessageLite, which contains most every-day operations. Message adds descriptors and reflection on top of that.

-

The methods of this class that are virtual but not pure-virtual have default implementations based on reflection. Message classes which are optimized for speed will want to override these with faster implementations, but classes optimized for code size may be happy with keeping them. See the optimize_for option in descriptor.proto.

-

Users must not derive from this class. Only the protocol compiler and the internal library are allowed to create subclasses.

-

Members

constexpr
Message()
protected virtual Metadata
GetMetadata() const = 0
Get a struct containing the metadata for the Message, which is used in turn to implement GetDescriptor() and GetReflection() above.
protected explicit
Message(Arena * arena)
protected static uint64
GetInvariantPerBuild(uint64 salt)

Basic Operations

virtual Message *
New() const = 0
Construct a new instance of the same type. more...
virtual Message *
New(Arena * arena) const
Construct a new instance on the arena. more...
virtual void
CopyFrom(const Message & from)
Make this message into a copy of the given message. more...
virtual void
MergeFrom(const Message & from)
Merge the fields from the given message into this message. more...
void
CheckInitialized() const
Verifies that IsInitialized() returns true. more...
void
FindInitializationErrors(std::vector< std::string > * errors) const
Slowly build a list of all required fields that are not set. more...
virtual std::string
InitializationErrorString() const
Like FindInitializationErrors, but joins all the strings, delimited by commas, and returns them.
virtual void
DiscardUnknownFields()
Clears all unknown fields from this message and all embedded messages. more...
virtual size_t
SpaceUsedLong() const
Computes (an estimate of) the total number of bytes currently used for storing the message in memory. more...
int
SpaceUsed() const

Debugging & Testing

std::string
DebugString() const
Generates a human readable form of this message, useful for debugging and other purposes.
std::string
ShortDebugString() const
Like DebugString(), but with less whitespace.
std::string
Utf8DebugString() const
Like DebugString(), but do not escape UTF-8 byte sequences.
void
PrintDebugString() const
Convenience function useful in GDB. Prints DebugString() to stdout.

Reflection-based methods

These methods are pure-virtual in MessageLite, but Message provides reflection-based default implementations.
virtual std::string
GetTypeName() const
Get the name of this message type, e.g. "foo.bar.BazProto".
virtual void
Clear()
Clear all fields of the message and set them to their default values. more...
virtual bool
IsInitialized() const
Returns whether all required fields have been set. more...
virtual void
CheckTypeAndMergeFrom(const MessageLite & other)
If |other| is the exact same class as this, calls MergeFrom(). more...
virtual const char *
_InternalParse(const char * ptr, internal::ParseContext * ctx)
Reflective parser.
virtual size_t
ByteSizeLong() const
Computes the serialized size of the message. more...
virtual uint8 *
_InternalSerialize(uint8 * ptr, io::EpsCopyOutputStream * stream) const
Fast path when conditions match (ie. more...

Introspection

const Descriptor *
GetDescriptor() const
Get a non-owning pointer to a Descriptor for this message's type. more...
const Reflection *
GetReflection() const
Get a non-owning pointer to the Reflection interface for this Message, which can be used to read and modify the fields of the Message dynamically (in other words, without knowing the message type at compile time). more...

virtual Message * Message::New() const = 0

Construct a new instance of the same type.

Ownership is passed to the caller. (This is also defined in MessageLite, but is defined again here for return-type covariance.)

-

virtual Message * Message::New(
        Arena * arena) const

Construct a new instance on the arena.

Ownership is passed to the caller if arena is a nullptr. Default implementation allows for API compatibility during the Arena transition.

-

virtual void Message::CopyFrom(
        const Message & from)

Make this message into a copy of the given message.

The given message must have the same descriptor, but need not necessarily be the same class. By default this is just implemented as "Clear(); MergeFrom(from);".

-

virtual void Message::MergeFrom(
        const Message & from)

Merge the fields from the given message into this message.

Singular fields will be overwritten, if specified in from, except for embedded messages which will be merged. Repeated fields will be concatenated. The given message must be of the same type as this message (i.e. the exact same class).

-

void Message::CheckInitialized() const

Verifies that IsInitialized() returns true.

GOOGLE_CHECK-fails otherwise, with a nice error message.

-

void Message::FindInitializationErrors(
        std::vector< std::string > * errors) const

Slowly build a list of all required fields that are not set.

This is much, much slower than IsInitialized() as it is implemented purely via reflection. Generally, you should not call this unless you have already determined that an error exists by calling IsInitialized().

-

virtual void Message::DiscardUnknownFields()

Clears all unknown fields from this message and all embedded messages.

Normally, if unknown tag numbers are encountered when parsing a message, the tag and value are stored in the message's UnknownFieldSet and then written back out when the message is serialized. This allows servers which simply route messages to other servers to pass through messages that have new field definitions which they don't yet know about. However, this behavior can have security implications. To avoid it, call this method after parsing.

-

See Reflection::GetUnknownFields() for more on unknown fields.

-

virtual size_t Message::SpaceUsedLong() const

Computes (an estimate of) the total number of bytes currently used for storing the message in memory.

The default implementation calls the Reflection object's SpaceUsed() method.

-

SpaceUsed() is noticeably slower than ByteSize(), as it is implemented using reflection (rather than the generated code implementation for ByteSize()). Like ByteSize(), its CPU time is linear in the number of fields defined for the proto.

-

virtual void Message::Clear()

Clear all fields of the message and set them to their default values.

Clear() avoids freeing memory, assuming that any memory allocated to hold parts of the message will be needed again to hold the next message. If you actually want to free the memory used by a Message, you must delete it.

-

virtual bool Message::IsInitialized() const

Returns whether all required fields have been set.

Note that required fields no longer exist starting in proto3.

-

virtual void Message::CheckTypeAndMergeFrom(
        const MessageLite & other)

If |other| is the exact same class as this, calls MergeFrom().

Otherwise, results are undefined (probably crash).

-

virtual size_t Message::ByteSizeLong() const

Computes the serialized size of the message.

This recursively calls ByteSizeLong() on all embedded messages.

-

ByteSizeLong() is generally linear in the number of fields defined for the proto.

-

virtual uint8 * Message::_InternalSerialize(
        uint8 * ptr,
        io::EpsCopyOutputStream * stream) const

Fast path when conditions match (ie.

non-deterministic) uint8* _InternalSerialize(uint8* ptr) const;

-

const Descriptor *
    Message::GetDescriptor() const

Get a non-owning pointer to a Descriptor for this message's type.

This describes what fields the message contains, the types of those fields, etc. This object remains property of the Message.

-

const Reflection *
    Message::GetReflection() const

Get a non-owning pointer to the Reflection interface for this Message, which can be used to read and modify the fields of the Message dynamically (in other words, without knowing the message type at compile time).

This object remains property of the Message.

-

class Reflection

#include <google/protobuf/message.h>
namespace google::protobuf

This interface contains methods that can be used to dynamically access and modify the fields of a protocol message.

Their semantics are similar to the accessors the protocol compiler generates.

-

To get the Reflection for a given Message, call Message::GetReflection().

-

This interface is separate from Message only for efficiency reasons; the vast majority of implementations of Message will share the same implementation of Reflection (GeneratedMessageReflection, defined in generated_message.h), and all Messages of a particular class should share the same Reflection object (though you should not rely on the latter fact).

-

There are several ways that these methods can be used incorrectly. For example, any of the following conditions will lead to undefined results (probably assertion failures):

-
    -
  • The FieldDescriptor is not a field of this message type.
  • -
  • The method called is not appropriate for the field's type. For each field type in FieldDescriptor::TYPE_*, there is only one Get*() method, one Set*() method, and one Add*() method that is valid for that type. It should be obvious which (except maybe for TYPE_BYTES, which are represented using strings in C++).
  • -
  • A Get*() or Set*() method for singular fields is called on a repeated field.
  • -
  • GetRepeated*(), SetRepeated*(), or Add*() is called on a non-repeated field.
  • -
  • The Message object passed to any method is not of the right type for this Reflection object (i.e. message.GetReflection() != reflection).
  • -
-

You might wonder why there is not any abstract representation for a field of arbitrary type. E.g., why isn't there just a "GetField()" method that returns "const Field&", where "Field" is some class with accessors like "GetInt32Value()". The problem is that someone would have to deal with allocating these Field objects. For generated message classes, having to allocate space for an additional object to wrap every field would at least double the message's memory footprint, probably worse. Allocating the objects on-demand, on the other hand, would be expensive and prone to memory leaks. So, instead we ended up with this flat interface.

-

Members

const UnknownFieldSet &
GetUnknownFields(const Message & message) const
Get the UnknownFieldSet for the message. more...
UnknownFieldSet *
MutableUnknownFields(Message * message) const
Get a mutable pointer to the UnknownFieldSet for the message. more...
size_t
SpaceUsedLong(const Message & message) const
Estimate the amount of memory used by the message object.
int
SpaceUsed(const Message & message) const
bool
HasField(const Message & message, const FieldDescriptor * field) const
Check if the given non-repeated field is set.
int
FieldSize(const Message & message, const FieldDescriptor * field) const
Get the number of elements of a repeated field.
void
ClearField(Message * message, const FieldDescriptor * field) const
Clear the value of a field, so that HasField() returns false or FieldSize() returns zero.
bool
HasOneof(const Message & message, const OneofDescriptor * oneof_descriptor) const
Check if the oneof is set. more...
void
ClearOneof(Message * message, const OneofDescriptor * oneof_descriptor) const
const FieldDescriptor *
GetOneofFieldDescriptor(const Message & message, const OneofDescriptor * oneof_descriptor) const
Returns the field descriptor if the oneof is set. nullptr otherwise.
void
RemoveLast(Message * message, const FieldDescriptor * field) const
Removes the last element of a repeated field. more...
PROTOBUF_FUTURE_MUST_USE_RESULT Message *
ReleaseLast(Message * message, const FieldDescriptor * field) const
Removes the last element of a repeated message field, and returns the pointer to the caller. more...
void
Swap(Message * message1, Message * message2) const
Swap the complete contents of two messages.
void
SwapFields(Message * message1, Message * message2, const std::vector< const FieldDescriptor * > & fields) const
Swap fields listed in fields vector of two messages.
void
SwapElements(Message * message, const FieldDescriptor * field, int index1, int index2) const
Swap two elements of a repeated field.
void
ListFields(const Message & message, std::vector< const FieldDescriptor * > * output) const
List all fields of the message which are currently set, except for unknown fields, but including extension known to the parser (i.e. more...
const RepeatedPtrField< Message > &
GetRepeatedPtrFieldInternal(const Message & message, const FieldDescriptor * field) const
RepeatedPtrField< Message > *
MutableRepeatedPtrFieldInternal(Message * message, const FieldDescriptor * field) const

Singular field getters

These get the value of a non-repeated field. They return the default value for fields that aren't set.
int32
GetInt32(const Message & message, const FieldDescriptor * field) const
int64
GetInt64(const Message & message, const FieldDescriptor * field) const
uint32
GetUInt32(const Message & message, const FieldDescriptor * field) const
uint64
GetUInt64(const Message & message, const FieldDescriptor * field) const
float
GetFloat(const Message & message, const FieldDescriptor * field) const
double
GetDouble(const Message & message, const FieldDescriptor * field) const
bool
GetBool(const Message & message, const FieldDescriptor * field) const
std::string
GetString(const Message & message, const FieldDescriptor * field) const
const EnumValueDescriptor *
GetEnum(const Message & message, const FieldDescriptor * field) const
int
GetEnumValue(const Message & message, const FieldDescriptor * field) const
GetEnumValue() returns an enum field's value as an integer rather than an EnumValueDescriptor*. more...
const Message &
GetMessage(const Message & message, const FieldDescriptor * field, MessageFactory * factory = nullptr) const
See MutableMessage() for the meaning of the "factory" parameter.
const std::string &
GetStringReference(const Message & message, const FieldDescriptor * field, std::string * scratch) const
Get a string value without copying, if possible. more...

Singular field mutators

These mutate the value of a non-repeated field.
void
SetInt32(Message * message, const FieldDescriptor * field, int32 value) const
void
SetInt64(Message * message, const FieldDescriptor * field, int64 value) const
void
SetUInt32(Message * message, const FieldDescriptor * field, uint32 value) const
void
SetUInt64(Message * message, const FieldDescriptor * field, uint64 value) const
void
SetFloat(Message * message, const FieldDescriptor * field, float value) const
void
SetDouble(Message * message, const FieldDescriptor * field, double value) const
void
SetBool(Message * message, const FieldDescriptor * field, bool value) const
void
SetString(Message * message, const FieldDescriptor * field, std::string value) const
void
SetEnum(Message * message, const FieldDescriptor * field, const EnumValueDescriptor * value) const
void
SetEnumValue(Message * message, const FieldDescriptor * field, int value) const
Set an enum field's value with an integer rather than EnumValueDescriptor. more...
Message *
MutableMessage(Message * message, const FieldDescriptor * field, MessageFactory * factory = nullptr) const
Get a mutable pointer to a field with a message type. more...
void
SetAllocatedMessage(Message * message, Message * sub_message, const FieldDescriptor * field) const
Replaces the message specified by 'field' with the already-allocated object sub_message, passing ownership to the message. more...
void
UnsafeArenaSetAllocatedMessage(Message * message, Message * sub_message, const FieldDescriptor * field) const
Similar to SetAllocatedMessage, but omits all internal safety and ownership checks. more...
PROTOBUF_FUTURE_MUST_USE_RESULT Message *
ReleaseMessage(Message * message, const FieldDescriptor * field, MessageFactory * factory = nullptr) const
Releases the message specified by 'field' and returns the pointer, ReleaseMessage() will return the message the message object if it exists. more...
Message *
UnsafeArenaReleaseMessage(Message * message, const FieldDescriptor * field, MessageFactory * factory = nullptr) const
Similar to ReleaseMessage, but omits all internal safety and ownership checks. more...

Repeated field getters

These get the value of one element of a repeated field.
int32
GetRepeatedInt32(const Message & message, const FieldDescriptor * field, int index) const
int64
GetRepeatedInt64(const Message & message, const FieldDescriptor * field, int index) const
uint32
GetRepeatedUInt32(const Message & message, const FieldDescriptor * field, int index) const
uint64
GetRepeatedUInt64(const Message & message, const FieldDescriptor * field, int index) const
float
GetRepeatedFloat(const Message & message, const FieldDescriptor * field, int index) const
double
GetRepeatedDouble(const Message & message, const FieldDescriptor * field, int index) const
bool
GetRepeatedBool(const Message & message, const FieldDescriptor * field, int index) const
std::string
GetRepeatedString(const Message & message, const FieldDescriptor * field, int index) const
const EnumValueDescriptor *
GetRepeatedEnum(const Message & message, const FieldDescriptor * field, int index) const
int
GetRepeatedEnumValue(const Message & message, const FieldDescriptor * field, int index) const
GetRepeatedEnumValue() returns an enum field's value as an integer rather than an EnumValueDescriptor*. more...
const Message &
GetRepeatedMessage(const Message & message, const FieldDescriptor * field, int index) const
const std::string &
GetRepeatedStringReference(const Message & message, const FieldDescriptor * field, int index, std::string * scratch) const

Repeated field mutators

These mutate the value of one element of a repeated field.
void
SetRepeatedInt32(Message * message, const FieldDescriptor * field, int index, int32 value) const
void
SetRepeatedInt64(Message * message, const FieldDescriptor * field, int index, int64 value) const
void
SetRepeatedUInt32(Message * message, const FieldDescriptor * field, int index, uint32 value) const
void
SetRepeatedUInt64(Message * message, const FieldDescriptor * field, int index, uint64 value) const
void
SetRepeatedFloat(Message * message, const FieldDescriptor * field, int index, float value) const
void
SetRepeatedDouble(Message * message, const FieldDescriptor * field, int index, double value) const
void
SetRepeatedBool(Message * message, const FieldDescriptor * field, int index, bool value) const
void
SetRepeatedString(Message * message, const FieldDescriptor * field, int index, std::string value) const
void
SetRepeatedEnum(Message * message, const FieldDescriptor * field, int index, const EnumValueDescriptor * value) const
void
SetRepeatedEnumValue(Message * message, const FieldDescriptor * field, int index, int value) const
Set an enum field's value with an integer rather than EnumValueDescriptor. more...
Message *
MutableRepeatedMessage(Message * message, const FieldDescriptor * field, int index) const
Get a mutable pointer to an element of a repeated field with a message type.

Repeated field adders

These add an element to a repeated field.
void
AddInt32(Message * message, const FieldDescriptor * field, int32 value) const
void
AddInt64(Message * message, const FieldDescriptor * field, int64 value) const
void
AddUInt32(Message * message, const FieldDescriptor * field, uint32 value) const
void
AddUInt64(Message * message, const FieldDescriptor * field, uint64 value) const
void
AddFloat(Message * message, const FieldDescriptor * field, float value) const
void
AddDouble(Message * message, const FieldDescriptor * field, double value) const
void
AddBool(Message * message, const FieldDescriptor * field, bool value) const
void
AddString(Message * message, const FieldDescriptor * field, std::string value) const
void
AddEnum(Message * message, const FieldDescriptor * field, const EnumValueDescriptor * value) const
void
AddEnumValue(Message * message, const FieldDescriptor * field, int value) const
Add an integer value to a repeated enum field rather than EnumValueDescriptor. more...
Message *
AddMessage(Message * message, const FieldDescriptor * field, MessageFactory * factory = nullptr) const
See MutableMessage() for comments on the "factory" parameter.
void
AddAllocatedMessage(Message * message, const FieldDescriptor * field, Message * new_entry) const
Appends an already-allocated object 'new_entry' to the repeated field specified by 'field' passing ownership to the message.
template RepeatedFieldRef< T >
GetRepeatedFieldRef(const Message & message, const FieldDescriptor * field) const
Get a RepeatedFieldRef object that can be used to read the underlying repeated field. more...
template MutableRepeatedFieldRef< T >
GetMutableRepeatedFieldRef(Message * message, const FieldDescriptor * field) const
Like GetRepeatedFieldRef() but return an object that can also be used manipulate the underlying repeated field.
template const RepeatedField< T > &
GetRepeatedField(const Message & msg, const FieldDescriptor * d) const
DEPRECATED. more...
template RepeatedField< T > *
MutableRepeatedField(Message * msg, const FieldDescriptor * d) const
DEPRECATED. more...
template const RepeatedPtrField< T > &
GetRepeatedPtrField(const Message & msg, const FieldDescriptor * d) const
DEPRECATED. more...
template RepeatedPtrField< T > *
MutableRepeatedPtrField(Message * msg, const FieldDescriptor * d) const
DEPRECATED. more...

Extensions

const FieldDescriptor *
FindKnownExtensionByName(const std::string & name) const
Try to find an extension of this message type by fully-qualified field name. more...
const FieldDescriptor *
FindKnownExtensionByNumber(int number) const
Try to find an extension of this message type by field number. more...

Feature Flags

bool
SupportsUnknownEnumValues() const
Does this message support storing arbitrary integer values in enum fields? If |true|, GetEnumValue/SetEnumValue and associated repeated-field versions take arbitrary integer values, and the legacy GetEnum() getter will dynamically create an EnumValueDescriptor for any integer value without one. more...
MessageFactory *
GetMessageFactory() const
Returns the MessageFactory associated with this message. more...

const UnknownFieldSet &
    Reflection::GetUnknownFields(
        const Message & message) const

Get the UnknownFieldSet for the message.

This contains fields which were seen when the Message was parsed but were not recognized according to the Message's definition.

-

UnknownFieldSet *
    Reflection::MutableUnknownFields(
        Message * message) const

Get a mutable pointer to the UnknownFieldSet for the message.

This contains fields which were seen when the Message was parsed but were not recognized according to the Message's definition.

-

bool Reflection::HasOneof(
        const Message & message,
        const OneofDescriptor * oneof_descriptor) const

Check if the oneof is set.

Returns true if any field in oneof is set, false otherwise.

-

void Reflection::RemoveLast(
        Message * message,
        const FieldDescriptor * field) const

Removes the last element of a repeated field.

We don't provide a way to remove any element other than the last because it invites inefficient use, such as O(n^2) filtering loops that should have been O(n). If you want to remove an element other than the last, the best way to do it is to re-arrange the elements (using Swap()) so that the one you want removed is at the end, then call RemoveLast().

-

PROTOBUF_FUTURE_MUST_USE_RESULT Message *
    Reflection::ReleaseLast(
        Message * message,
        const FieldDescriptor * field) const

Removes the last element of a repeated message field, and returns the pointer to the caller.

Caller takes ownership of the returned pointer.

-

void Reflection::ListFields(
        const Message & message,
        std::vector< const FieldDescriptor * > * output) const

List all fields of the message which are currently set, except for unknown fields, but including extension known to the parser (i.e.

compiled in). Singular fields will only be listed if HasField(field) would return true and repeated fields will only be listed if FieldSize(field) would return non-zero. Fields (both normal fields and extension fields) will be listed ordered by field number. Use Reflection::GetUnknownFields() or message.unknown_fields() to also get access to fields/extensions unknown to the parser.

-

int Reflection::GetEnumValue(
        const Message & message,
        const FieldDescriptor * field) const

GetEnumValue() returns an enum field's value as an integer rather than an EnumValueDescriptor*.

If the integer value does not correspond to a known value descriptor, a new value descriptor is created. (Such a value will only be present when the new unknown-enum-value semantics are enabled for a message.)

-

const std::string &
    Reflection::GetStringReference(
        const Message & message,
        const FieldDescriptor * field,
        std::string * scratch) const

Get a string value without copying, if possible.

GetString() necessarily returns a copy of the string. This can be inefficient when the std::string is already stored in a std::string object in the underlying message. GetStringReference() will return a reference to the underlying std::string in this case. Otherwise, it will copy the string into *scratch and return that.

-

Note: It is perfectly reasonable and useful to write code like:

-
str = reflection->GetStringReference(message, field, &str);
-

This line would ensure that only one copy of the string is made regardless of the field's underlying representation. When initializing a newly-constructed string, though, it's just as fast and more readable to use code like:

-
std::string str = reflection->GetString(message, field);
-

void Reflection::SetEnumValue(
        Message * message,
        const FieldDescriptor * field,
        int value) const

Set an enum field's value with an integer rather than EnumValueDescriptor.

For proto3 this is just setting the enum field to the value specified, for proto2 it's more complicated. If value is a known enum value the field is set as usual. If the value is unknown then it is added to the unknown field set. Note this matches the behavior of parsing unknown enum values. If multiple calls with unknown values happen than they are all added to the unknown field set in order of the calls.

-

Message * Reflection::MutableMessage(
        Message * message,
        const FieldDescriptor * field,
        MessageFactory * factory = nullptr) const

Get a mutable pointer to a field with a message type.

If a MessageFactory is provided, it will be used to construct instances of the sub-message; otherwise, the default factory is used. If the field is an extension that does not live in the same pool as the containing message's descriptor (e.g. it lives in an overlay pool), then a MessageFactory must be provided. If you have no idea what that meant, then you probably don't need to worry about it (don't provide a MessageFactory). WARNING: If the FieldDescriptor is for a compiled-in extension, then factory->GetPrototype(field->message_type()) MUST return an instance of the compiled-in class for this type, NOT DynamicMessage.

-

void Reflection::SetAllocatedMessage(
        Message * message,
        Message * sub_message,
        const FieldDescriptor * field) const

Replaces the message specified by 'field' with the already-allocated object sub_message, passing ownership to the message.

If the field contained a message, that message is deleted. If sub_message is nullptr, the field is cleared.

-

void Reflection::UnsafeArenaSetAllocatedMessage(
        Message * message,
        Message * sub_message,
        const FieldDescriptor * field) const

Similar to SetAllocatedMessage, but omits all internal safety and ownership checks.

This method should only be used when the objects are on the same arena or paired with a call to UnsafeArenaReleaseMessage.

-

PROTOBUF_FUTURE_MUST_USE_RESULT Message *
    Reflection::ReleaseMessage(
        Message * message,
        const FieldDescriptor * field,
        MessageFactory * factory = nullptr) const

Releases the message specified by 'field' and returns the pointer, ReleaseMessage() will return the message the message object if it exists.

Otherwise, it may or may not return nullptr. In any case, if the return value is non-null, the caller takes ownership of the pointer. If the field existed (HasField() is true), then the returned pointer will be the same as the pointer returned by MutableMessage(). This function has the same effect as ClearField().

-

Message * Reflection::UnsafeArenaReleaseMessage(
        Message * message,
        const FieldDescriptor * field,
        MessageFactory * factory = nullptr) const

Similar to ReleaseMessage, but omits all internal safety and ownership checks.

This method should only be used when the objects are on the same arena or paired with a call to UnsafeArenaSetAllocatedMessage.

-

int Reflection::GetRepeatedEnumValue(
        const Message & message,
        const FieldDescriptor * field,
        int index) const

GetRepeatedEnumValue() returns an enum field's value as an integer rather than an EnumValueDescriptor*.

If the integer value does not correspond to a known value descriptor, a new value descriptor is created. (Such a value will only be present when the new unknown-enum-value semantics are enabled for a message.)

-

void Reflection::SetRepeatedEnumValue(
        Message * message,
        const FieldDescriptor * field,
        int index,
        int value) const

Set an enum field's value with an integer rather than EnumValueDescriptor.

For proto3 this is just setting the enum field to the value specified, for proto2 it's more complicated. If value is a known enum value the field is set as usual. If the value is unknown then it is added to the unknown field set. Note this matches the behavior of parsing unknown enum values. If multiple calls with unknown values happen than they are all added to the unknown field set in order of the calls.

-

void Reflection::AddEnumValue(
        Message * message,
        const FieldDescriptor * field,
        int value) const

Add an integer value to a repeated enum field rather than EnumValueDescriptor.

For proto3 this is just setting the enum field to the value specified, for proto2 it's more complicated. If value is a known enum value the field is set as usual. If the value is unknown then it is added to the unknown field set. Note this matches the behavior of parsing unknown enum values. If multiple calls with unknown values happen than they are all added to the unknown field set in order of the calls.

-

template RepeatedFieldRef< T >
    Reflection::GetRepeatedFieldRef(
        const Message & message,
        const FieldDescriptor * field) const

Get a RepeatedFieldRef object that can be used to read the underlying repeated field.

The type parameter T must be set according to the field's cpp type. The following table shows the mapping from cpp type to acceptable T.

-
field->cpp_type()      T
-CPPTYPE_INT32        int32
-CPPTYPE_UINT32       uint32
-CPPTYPE_INT64        int64
-CPPTYPE_UINT64       uint64
-CPPTYPE_DOUBLE       double
-CPPTYPE_FLOAT        float
-CPPTYPE_BOOL         bool
-CPPTYPE_ENUM         generated enum type or int32
-CPPTYPE_STRING       std::string
-CPPTYPE_MESSAGE      generated message type or google::protobuf::Message
-

A RepeatedFieldRef object can be copied and the resulted object will point to the same repeated field in the same message. The object can be used as long as the message is not destroyed.

-

Note that to use this method users need to include the header file "reflection.h" (which defines the RepeatedFieldRef class templates).

-

template const RepeatedField< T > &
    Reflection::GetRepeatedField(
        const Message & msg,
        const FieldDescriptor * d) const

DEPRECATED.

Please use GetRepeatedFieldRef().

-

for T = Cord and all protobuf scalar types except enums.

-

template RepeatedField< T > *
    Reflection::MutableRepeatedField(
        Message * msg,
        const FieldDescriptor * d) const

DEPRECATED.

Please use GetMutableRepeatedFieldRef().

-

for T = Cord and all protobuf scalar types except enums.

-

template const RepeatedPtrField< T > &
    Reflection::GetRepeatedPtrField(
        const Message & msg,
        const FieldDescriptor * d) const

DEPRECATED.

Please use GetRepeatedFieldRef().

-

for T = std::string, google::protobuf::internal::StringPieceField

-
google::protobuf::Message & descendants.
-

template RepeatedPtrField< T > *
    Reflection::MutableRepeatedPtrField(
        Message * msg,
        const FieldDescriptor * d) const

DEPRECATED.

Please use GetMutableRepeatedFieldRef().

-

for T = std::string, google::protobuf::internal::StringPieceField

-
google::protobuf::Message & descendants.
-

const FieldDescriptor *
    Reflection::FindKnownExtensionByName(
        const std::string & name) const

Try to find an extension of this message type by fully-qualified field name.

Returns nullptr if no extension is known for this name or number.

-

const FieldDescriptor *
    Reflection::FindKnownExtensionByNumber(
        int number) const

Try to find an extension of this message type by field number.

Returns nullptr if no extension is known for this name or number.

-

bool Reflection::SupportsUnknownEnumValues() const

Does this message support storing arbitrary integer values in enum fields? If |true|, GetEnumValue/SetEnumValue and associated repeated-field versions take arbitrary integer values, and the legacy GetEnum() getter will dynamically create an EnumValueDescriptor for any integer value without one.

If |false|, setting an unknown enum value via the integer-based setters results in undefined behavior (in practice, GOOGLE_DCHECK-fails).

-

Generic code that uses reflection to handle messages with enum fields should check this flag before using the integer-based setter, and either downgrade to a compatible value or use the UnknownFieldSet if not. For example:

-
int new_value = GetValueFromApplicationLogic();
-if (reflection->SupportsUnknownEnumValues()) {
-  reflection->SetEnumValue(message, field, new_value);
-} else {
-  if (field_descriptor->enum_type()->
-          FindValueByNumber(new_value) != nullptr) {
-    reflection->SetEnumValue(message, field, new_value);
-  } else if (emit_unknown_enum_values) {
-    reflection->MutableUnknownFields(message)->AddVarint(
-        field->number(), new_value);
-  } else {
-    // convert value to a compatible/default value.
-    new_value = CompatibleDowngrade(new_value);
-    reflection->SetEnumValue(message, field, new_value);
-  }
-}
-

MessageFactory * Reflection::GetMessageFactory() const

Returns the MessageFactory associated with this message.

This can be useful for determining if a message is a generated message or not, for example:

-
if (message->GetReflection()->GetMessageFactory() ==
-    google::protobuf::MessageFactory::generated_factory()) {
-  // This is a generated message.
-}
-

It can also be used to create more messages of this type, though Message::New() is an easier way to accomplish this.

-

class MessageFactory

#include <google/protobuf/message.h>
namespace google::protobuf

Abstract interface for a factory for message objects.

Known subclasses:

Members

MessageFactory()
virtual
~MessageFactory()
virtual const Message *
GetPrototype(const Descriptor * type) = 0
Given a Descriptor, gets or constructs the default (prototype) Message of that type. more...
static MessageFactory *
generated_factory()
Gets a MessageFactory which supports all generated, compiled-in messages. more...
static void
InternalRegisterGeneratedFile(const google::protobuf::internal::DescriptorTable * table)
For internal use only: Registers a .proto file at static initialization time, to be placed in generated_factory. more...
static void
InternalRegisterGeneratedMessage(const Descriptor * descriptor, const Message * prototype)
For internal use only: Registers a message type. more...

virtual const Message * MessageFactory::GetPrototype(
        const Descriptor * type) = 0

Given a Descriptor, gets or constructs the default (prototype) Message of that type.

You can then call that message's New() method to construct a mutable message of that type.

-

Calling this method twice with the same Descriptor returns the same object. The returned object remains property of the factory. Also, any objects created by calling the prototype's New() method share some data with the prototype, so these must be destroyed before the MessageFactory is destroyed.

-

The given descriptor must outlive the returned message, and hence must outlive the MessageFactory.

-

Some implementations do not support all types. GetPrototype() will return nullptr if the descriptor passed in is not supported.

-

This method may or may not be thread-safe depending on the implementation. Each implementation should document its own degree thread-safety.

-

static MessageFactory * MessageFactory::generated_factory()

Gets a MessageFactory which supports all generated, compiled-in messages.

In other words, for any compiled-in type FooMessage, the following is true:

-
MessageFactory::generated_factory()->GetPrototype(
-  FooMessage::descriptor()) == FooMessage::default_instance()
-

This factory supports all types which are found in DescriptorPool::generated_pool(). If given a descriptor from any other pool, GetPrototype() will return nullptr. (You can also check if a descriptor is for a generated message by checking if descriptor->file()->pool() == DescriptorPool::generated_pool().)

-

This factory is 100% thread-safe; calling GetPrototype() does not modify any shared data.

-

This factory is a singleton. The caller must not delete the object.

-

static void MessageFactory::InternalRegisterGeneratedFile(
        const google::protobuf::internal::DescriptorTable * table)

For internal use only: Registers a .proto file at static initialization time, to be placed in generated_factory.

The first time GetPrototype() is called with a descriptor from this file, |register_messages| will be called, with the file name as the parameter. It must call InternalRegisterGeneratedMessage() (below) to register each message type in the file. This strange mechanism is necessary because descriptors are built lazily, so we can't register types by their descriptor until we know that the descriptor exists. |filename| must be a permanent string.

-

static void MessageFactory::InternalRegisterGeneratedMessage(
        const Descriptor * descriptor,
        const Message * prototype)

For internal use only: Registers a message type.

Called only by the functions which are registered with InternalRegisterGeneratedFile(), above.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.message_lite.md b/content/reference/cpp/api-docs/google.protobuf.message_lite.md deleted file mode 100644 index d6fa41333..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.message_lite.md +++ /dev/null @@ -1,80 +0,0 @@ - - -+++ -title = "message_lite.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/message_lite.h>
namespace google::protobuf

Defines MessageLite, the abstract interface implemented by all (lite and non-lite) protocol message objects.

Classes in this file

Interface to light weight protocol messages.

File Members

These definitions are not part of any class.
void
ShutdownProtobufLibrary()
Shut down the entire protocol buffers library, deleting all static-duration objects allocated by the library or by generated .pb.cc files. more...

void protobuf::ShutdownProtobufLibrary()

Shut down the entire protocol buffers library, deleting all static-duration objects allocated by the library or by generated .pb.cc files.

There are two reasons you might want to call this:

- -
    -
  • You use a draconian definition of "memory leak" in which you expect every single malloc() to have a corresponding free(), even for objects which live until program exit.
  • -
  • You are writing a dynamically-loaded library which needs to clean up after itself when the library is unloaded.
  • -
- -

It is safe to call this multiple times. However, it is not safe to use any other part of the protocol buffers library after ShutdownProtobufLibrary() has been called. Furthermore this call is not thread safe, user needs to synchronize multiple calls.

-

class MessageLite

#include <google/protobuf/message_lite.h>
namespace google::protobuf

Interface to light weight protocol messages.

This interface is implemented by all protocol message objects. Non-lite messages additionally implement the Message interface, which is a subclass of MessageLite. Use MessageLite instead when you only need the subset of features which it supports – namely, nothing that uses descriptors or reflection. You can instruct the protocol compiler to generate classes which implement only MessageLite, not the full Message interface, by adding the following line to the .proto file:

- -
option optimize_for = LITE_RUNTIME;
- -

This is particularly useful on resource-constrained systems where the full protocol buffers runtime library is too big.

- -

Note that on non-constrained systems (e.g. servers) when you need to link in lots of protocol definitions, a better way to reduce total code footprint is to use optimize_for = CODE_SIZE. This will make the generated code smaller while still supporting all the same features (at the expense of speed). optimize_for = LITE_RUNTIME is best when you only have a small number of message types linked into your binary, in which case the size of the protocol buffers runtime itself is the biggest problem.

- -

Users must not derive from this class. Only the protocol compiler and the internal library are allowed to create subclasses.

- -

Known subclasses:

Members

enum
ParseFlags
protected internal::InternalMetadata
_internal_metadata_
constexpr
MessageLite()
virtual
~MessageLite()
template bool
ParseFrom(const T & input)
virtual uint8 *
_InternalSerialize(uint8 * ptr, io::EpsCopyOutputStream * stream) const = 0
Fast path when conditions match (ie. more...
bool
IsInitializedWithErrors() const
Identical to IsInitialized() except that it logs an error message.
protected template static T *
CreateMaybeMessage(Arena * arena)
protected explicit
MessageLite(Arena * arena)
protected Arena *
GetOwningArena() const
Returns the arena, if any, that directly owns this message and its internal memory (Arena::Own is different in that the arena doesn't directly own the internal memory). more...
protected Arena *
GetArenaForAllocation() const
Returns the arena, used for allocating internal objects(e.g., child messages, etc), or owning incoming objects (e.g., set allocated).

Basic Operations

virtual std::string
GetTypeName() const = 0
Get the name of this message type, e.g. "foo.bar.BazProto".
virtual MessageLite *
New() const = 0
Construct a new instance of the same type. more...
virtual MessageLite *
New(Arena * arena) const
Construct a new instance on the arena. more...
Arena *
GetArena() const
Same as GetOwningArena.
void *
GetMaybeArenaPointer() const
Get a pointer that may be equal to this message's arena, or may not be. more...
virtual void
Clear() = 0
Clear all fields of the message and set them to their default values. more...
virtual bool
IsInitialized() const = 0
Quickly check if all required fields have values set.
virtual std::string
InitializationErrorString() const
This is not implemented for Lite messages – it just returns "(cannot -determine missing fields for lite message)". more...
virtual void
CheckTypeAndMergeFrom(const MessageLite & other) = 0
If |other| is the exact same class as this, calls MergeFrom(). more...
std::string
DebugString() const
These methods return a human-readable summary of the message. more...
std::string
ShortDebugString() const
std::string
Utf8DebugString() const
MessageLite::DebugString is already Utf8 Safe. more...

Parsing

-

Methods for parsing in protocol buffer format.

- -

Most of these are just simple wrappers around MergeFromCodedStream(). Clear() will be called before merging the input.

-
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParseFromCodedStream(io::CodedInputStream * input)
Fill the message with a protocol buffer parsed from the given input stream. more...
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParsePartialFromCodedStream(io::CodedInputStream * input)
Like ParseFromCodedStream(), but accepts messages that are missing required fields.
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParseFromZeroCopyStream(io::ZeroCopyInputStream * input)
Read a protocol buffer from the given zero-copy input stream. more...
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream * input)
Like ParseFromZeroCopyStream(), but accepts messages that are missing required fields.
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParseFromFileDescriptor(int file_descriptor)
Parse a protocol buffer from a file descriptor. more...
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParsePartialFromFileDescriptor(int file_descriptor)
Like ParseFromFileDescriptor(), but accepts messages that are missing required fields.
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParseFromIstream(std::istream * input)
Parse a protocol buffer from a C++ istream. more...
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParsePartialFromIstream(std::istream * input)
Like ParseFromIstream(), but accepts messages that are missing required fields.
bool
MergePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream * input, int size)
Read a protocol buffer from the given zero-copy input stream, expecting the message to be exactly "size" bytes long. more...
bool
MergeFromBoundedZeroCopyStream(io::ZeroCopyInputStream * input, int size)
Like ParseFromBoundedZeroCopyStream(), but accepts messages that are missing required fields.
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream * input, int size)
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream * input, int size)
Like ParseFromBoundedZeroCopyStream(), but accepts messages that are missing required fields.
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParseFromString(ConstStringParam data)
Parses a protocol buffer contained in a string. more...
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParsePartialFromString(ConstStringParam data)
Like ParseFromString(), but accepts messages that are missing required fields.
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParseFromArray(const void * data, int size)
Parse a protocol buffer contained in an array of bytes.
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParsePartialFromArray(const void * data, int size)
Like ParseFromArray(), but accepts messages that are missing required fields.
bool
MergeFromCodedStream(io::CodedInputStream * input)
Reads a protocol buffer from the stream and merges it into this Message. more...
bool
MergePartialFromCodedStream(io::CodedInputStream * input)
Like MergeFromCodedStream(), but succeeds even if required fields are missing in the input. more...
bool
MergeFromString(ConstStringParam data)
Merge a protocol buffer contained in a string.

Serialization

-

Methods for serializing in protocol buffer format.

- -

Most of these are just simple wrappers around ByteSize() and SerializeWithCachedSizes().

-
bool
SerializeToCodedStream(io::CodedOutputStream * output) const
Write a protocol buffer of this message to the given output. more...
bool
SerializePartialToCodedStream(io::CodedOutputStream * output) const
Like SerializeToCodedStream(), but allows missing required fields.
bool
SerializeToZeroCopyStream(io::ZeroCopyOutputStream * output) const
Write the message to the given zero-copy output stream. more...
bool
SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream * output) const
Like SerializeToZeroCopyStream(), but allows missing required fields.
bool
SerializeToString(std::string * output) const
Serialize the message and store it in the given string. more...
bool
SerializePartialToString(std::string * output) const
Like SerializeToString(), but allows missing required fields.
bool
SerializeToArray(void * data, int size) const
Serialize the message and store it in the given byte array. more...
bool
SerializePartialToArray(void * data, int size) const
Like SerializeToArray(), but allows missing required fields.
std::string
SerializeAsString() const
Make a string encoding the message. more...
std::string
SerializePartialAsString() const
Like SerializeAsString(), but allows missing required fields.
bool
SerializeToFileDescriptor(int file_descriptor) const
Serialize the message and write it to the given file descriptor. more...
bool
SerializePartialToFileDescriptor(int file_descriptor) const
Like SerializeToFileDescriptor(), but allows missing required fields.
bool
SerializeToOstream(std::ostream * output) const
Serialize the message and write it to the given C++ ostream. more...
bool
SerializePartialToOstream(std::ostream * output) const
Like SerializeToOstream(), but allows missing required fields.
bool
AppendToString(std::string * output) const
Like SerializeToString(), but appends to the data to the string's existing contents. more...
bool
AppendPartialToString(std::string * output) const
Like AppendToString(), but allows missing required fields.
virtual size_t
ByteSizeLong() const = 0
Computes the serialized size of the message. more...
int
ByteSize() const
Legacy ByteSize() API.
void
SerializeWithCachedSizes(io::CodedOutputStream * output) const
Serializes the message without recomputing the size. more...
uint8 *
SerializeWithCachedSizesToArray(uint8 * target) const
Like SerializeWithCachedSizes, but writes directly to *target, returning a pointer to the byte immediately after the last byte written. more...
virtual int
GetCachedSize() const = 0
Returns the result of the last call to ByteSize(). more...
virtual const char *
_InternalParse(const char * , internal::ParseContext * )

enum MessageLite::ParseFlags {
  kMerge = = 0,
  kParse = = 1,
  kMergePartial = = 2,
  kParsePartial = = 3,
  kMergeWithAliasing = = 4,
  kParseWithAliasing = = 5,
  kMergePartialWithAliasing = = 6,
  kParsePartialWithAliasing = = 7
}

kMerge
kParse
kMergePartial
kParsePartial
kMergeWithAliasing
kParseWithAliasing
kMergePartialWithAliasing
kParsePartialWithAliasing

virtual uint8 * MessageLite::_InternalSerialize(
        uint8 * ptr,
        io::EpsCopyOutputStream * stream) const = 0

Fast path when conditions match (ie.

non-deterministic) uint8* _InternalSerialize(uint8* ptr) const;

-

protected Arena * MessageLite::GetOwningArena() const

Returns the arena, if any, that directly owns this message and its internal memory (Arena::Own is different in that the arena doesn't directly own the internal memory).

This method is used in proto's implementation for swapping, moving and setting allocated, for deciding whether the ownership of this message or its internal memory could be changed.

-

virtual MessageLite * MessageLite::New() const = 0

Construct a new instance of the same type.

Ownership is passed to the caller.

-

virtual MessageLite * MessageLite::New(
        Arena * arena) const

Construct a new instance on the arena.

Ownership is passed to the caller if arena is a NULL. Default implementation for backwards compatibility.

-

void * MessageLite::GetMaybeArenaPointer() const

Get a pointer that may be equal to this message's arena, or may not be.

If the value returned by this method is equal to some arena pointer, then this message is on that arena; however, if this message is on some arena, this method may or may not return that arena's pointer. As a tradeoff, this method may be more efficient than GetArena(). The intent is to allow underlying representations that use e.g. tagged pointers to sometimes store the arena pointer directly, and sometimes in a more indirect way, and allow a fastpath comparison against the arena pointer when it's easy to obtain.

-

virtual void MessageLite::Clear() = 0

Clear all fields of the message and set them to their default values.

Clear() avoids freeing memory, assuming that any memory allocated to hold parts of the message will be needed again to hold the next message. If you actually want to free the memory used by a Message, you must delete it.

-

virtual std::string MessageLite::InitializationErrorString() const

This is not implemented for Lite messages – it just returns "(cannot -determine missing fields for lite message)".

However, it is implemented for full messages. See message.h.

-

virtual void MessageLite::CheckTypeAndMergeFrom(
        const MessageLite & other) = 0

If |other| is the exact same class as this, calls MergeFrom().

Otherwise, results are undefined (probably crash).

-

std::string MessageLite::DebugString() const

These methods return a human-readable summary of the message.

Note that since the MessageLite interface does not support reflection, there is very little information that these methods can provide. They are shadowed by methods of the same name on the Message interface which provide much more information. The methods here are intended primarily to facilitate code reuse for logic that needs to interoperate with both full and lite protos.

- -

The format of the returned string is subject to change, so please do not assume it will remain stable over time.

-

std::string MessageLite::Utf8DebugString() const

MessageLite::DebugString is already Utf8 Safe.

This is to add compatibility with Message.

-

PROTOBUF_ATTRIBUTE_REINITIALIZES bool
    MessageLite::ParseFromCodedStream(
        io::CodedInputStream * input)

Fill the message with a protocol buffer parsed from the given input stream.

Returns false on a read error or if the input is in the wrong format. A successful return does not indicate the entire input is consumed, ensure you call ConsumedEntireMessage() to check that if applicable.

-

PROTOBUF_ATTRIBUTE_REINITIALIZES bool
    MessageLite::ParseFromZeroCopyStream(
        io::ZeroCopyInputStream * input)

Read a protocol buffer from the given zero-copy input stream.

If successful, the entire input will be consumed.

-

PROTOBUF_ATTRIBUTE_REINITIALIZES bool
    MessageLite::ParseFromFileDescriptor(
        int file_descriptor)

Parse a protocol buffer from a file descriptor.

If successful, the entire input will be consumed.

-

PROTOBUF_ATTRIBUTE_REINITIALIZES bool
    MessageLite::ParseFromIstream(
        std::istream * input)

Parse a protocol buffer from a C++ istream.

If successful, the entire input will be consumed.

-

bool MessageLite::MergePartialFromBoundedZeroCopyStream(
        io::ZeroCopyInputStream * input,
        int size)

Read a protocol buffer from the given zero-copy input stream, expecting the message to be exactly "size" bytes long.

If successful, exactly this many bytes will have been consumed from the input.

-

PROTOBUF_ATTRIBUTE_REINITIALIZES bool
    MessageLite::ParseFromString(
        ConstStringParam data)

Parses a protocol buffer contained in a string.

Returns true on success. This function takes a string in the (non-human-readable) binary wire format, matching the encoding output by MessageLite::SerializeToString(). If you'd like to convert a human-readable string into a protocol buffer object, see google::protobuf::TextFormat::ParseFromString().

-

bool MessageLite::MergeFromCodedStream(
        io::CodedInputStream * input)

Reads a protocol buffer from the stream and merges it into this Message.

Singular fields read from the what is already in the Message and repeated fields are appended to those already present.

- -

It is the responsibility of the caller to call input->LastTagWas() (for groups) or input->ConsumedEntireMessage() (for non-groups) after this returns to verify that the message's end was delimited correctly.

- -

ParseFromCodedStream() is implemented as Clear() followed by MergeFromCodedStream().

-

bool MessageLite::MergePartialFromCodedStream(
        io::CodedInputStream * input)

Like MergeFromCodedStream(), but succeeds even if required fields are missing in the input.

MergeFromCodedStream() is just implemented as MergePartialFromCodedStream() followed by IsInitialized().

-

bool MessageLite::SerializeToCodedStream(
        io::CodedOutputStream * output) const

Write a protocol buffer of this message to the given output.

Returns false on a write error. If the message is missing required fields, this may GOOGLE_CHECK-fail.

-

bool MessageLite::SerializeToZeroCopyStream(
        io::ZeroCopyOutputStream * output) const

Write the message to the given zero-copy output stream.

All required fields must be set.

-

bool MessageLite::SerializeToString(
        std::string * output) const

Serialize the message and store it in the given string.

All required fields must be set.

-

bool MessageLite::SerializeToArray(
        void * data,
        int size) const

Serialize the message and store it in the given byte array.

All required fields must be set.

-

std::string MessageLite::SerializeAsString() const

Make a string encoding the message.

Is equivalent to calling SerializeToString() on a string and using that. Returns the empty string if SerializeToString() would have returned an error. Note: If you intend to generate many such strings, you may reduce heap fragmentation by instead re-using the same string object with calls to SerializeToString().

-

bool MessageLite::SerializeToFileDescriptor(
        int file_descriptor) const

Serialize the message and write it to the given file descriptor.

All required fields must be set.

-

bool MessageLite::SerializeToOstream(
        std::ostream * output) const

Serialize the message and write it to the given C++ ostream.

All required fields must be set.

-

bool MessageLite::AppendToString(
        std::string * output) const

Like SerializeToString(), but appends to the data to the string's existing contents.

All required fields must be set.

-

virtual size_t MessageLite::ByteSizeLong() const = 0

Computes the serialized size of the message.

This recursively calls ByteSizeLong() on all embedded messages.

- -

ByteSizeLong() is generally linear in the number of fields defined for the proto.

-

void MessageLite::SerializeWithCachedSizes(
        io::CodedOutputStream * output) const

Serializes the message without recomputing the size.

The message must not have changed since the last call to ByteSize(), and the value returned by ByteSize must be non-negative. Otherwise the results are undefined.

-

uint8 * MessageLite::SerializeWithCachedSizesToArray(
        uint8 * target) const

Like SerializeWithCachedSizes, but writes directly to *target, returning a pointer to the byte immediately after the last byte written.

"target" must point at a byte array of at least ByteSize() bytes. Whether to use deterministic serialization, e.g., maps in sorted order, is determined by CodedOutputStream::IsDefaultSerializationDeterministic().

-

virtual int MessageLite::GetCachedSize() const = 0

Returns the result of the last call to ByteSize().

An embedded message's size is needed both to serialize it (because embedded messages are length-delimited) and to compute the outer message's size. Caching the size avoids computing it multiple times.

- -

ByteSize() does not automatically use the cached size when available because this would require invalidating it every time the message was modified, which would be too hard and expensive. (E.g. if a deeply-nested sub-message is changed, all of its parents' cached sizes would need to be invalidated, which is too much work for an otherwise inlined setter method.)

- -
diff --git a/content/reference/cpp/api-docs/google.protobuf.repeated_field.md b/content/reference/cpp/api-docs/google.protobuf.repeated_field.md deleted file mode 100644 index 7dafc1aac..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.repeated_field.md +++ /dev/null @@ -1,68 +0,0 @@ -+++ -title = "repeated_field.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/repeated_field.h>
namespace google::protobuf

RepeatedField and RepeatedPtrField are used by generated protocol message classes to manipulate repeated fields.

These classes are very similar to STL's vector, but include a number of optimizations found to be useful specifically in the case of Protocol Buffers. RepeatedPtrField is particularly different from STL vector as it manages ownership of the pointers that it contains.

- -

Typically, clients should not need to access RepeatedField objects directly, but should instead use the accessor functions generated automatically by the protocol compiler.

- -

Classes in this file

RepeatedField is used to represent repeated fields of a primitive type (in other words, everything except strings and nested Messages).
RepeatedPtrField is like RepeatedField, but used for repeated strings or Messages.

File Members

These definitions are not part of any class.
template internal::RepeatedFieldBackInsertIterator< T >
RepeatedFieldBackInserter(RepeatedField< T > *const mutable_field)
Provides a back insert iterator for RepeatedField instances, similar to std::back_inserter().
template internal::RepeatedPtrFieldBackInsertIterator< T >
RepeatedPtrFieldBackInserter(RepeatedPtrField< T > *const mutable_field)
Provides a back insert iterator for RepeatedPtrField instances, similar to std::back_inserter().
template internal::RepeatedPtrFieldBackInsertIterator< T >
RepeatedFieldBackInserter(RepeatedPtrField< T > *const mutable_field)
Special back insert iterator for RepeatedPtrField instances, just in case someone wants to write generic template code that can access both RepeatedFields and RepeatedPtrFields using a common name.
template internal::AllocatedRepeatedPtrFieldBackInsertIterator< T >
AllocatedRepeatedPtrFieldBackInserter(RepeatedPtrField< T > *const mutable_field)
Provides a back insert iterator for RepeatedPtrField instances similar to std::back_inserter() which transfers the ownership while copying elements.
template internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator< T >
UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(RepeatedPtrField< T > *const mutable_field)
Similar to AllocatedRepeatedPtrFieldBackInserter, using UnsafeArenaAddAllocated instead of AddAllocated. more...

template internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator< T >
    protobuf::UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
        RepeatedPtrField< T > *const mutable_field)

Similar to AllocatedRepeatedPtrFieldBackInserter, using UnsafeArenaAddAllocated instead of AddAllocated.

This is slightly faster if that matters. It is also useful in legacy code that uses temporary ownership to avoid copies. Example:

-
RepeatedPtrField<T> temp_field;
-temp_field.AddAllocated(new T);
-... // Do something with temp_field
-temp_field.ExtractSubrange(0, temp_field.size(), nullptr);
-

If you put temp_field on the arena this fails, because the ownership transfers to the arena at the "AddAllocated" call and is not released anymore causing a double delete. Using UnsafeArenaAddAllocated prevents this.

-

template class RepeatedField

#include <google/protobuf/repeated_field.h>
namespace google::protobuf

template <typename >

RepeatedField is used to represent repeated fields of a primitive type (in other words, everything except strings and nested Messages).

Most users will not ever use a RepeatedField directly; they will use the get-by-index, set-by-index, and add accessors that are generated for all repeated fields.

-

Members

typedef
Element * iterator
STL-like iterator support.
typedef
const Element * const_iterator
typedef
Element value_type
typedef
value_type & reference
typedef
const value_type & const_reference
typedef
value_type * pointer
typedef
const value_type * const_pointer
typedef
int size_type
typedef
ptrdiff_t difference_type
typedef
std::reverse_iterator< const_iterator > const_reverse_iterator
Reverse iterator support.
typedef
std::reverse_iterator< iterator > reverse_iterator
constexpr
RepeatedField()
explicit
RepeatedField(Arena * arena)
RepeatedField(const RepeatedField & other)
template
RepeatedField(Iter begin, Iter end)
~RepeatedField()
RepeatedField &
operator=(const RepeatedField & other)
RepeatedField(RepeatedField && other)
RepeatedField &
operator=(RepeatedField && other)
bool
empty() const
int
size() const
const Element &
Get(int index) const
Element *
Mutable(int index)
const Element &
operator[](int index) const
Element &
operator[](int index)
const Element &
at(int index) const
Element &
at(int index)
void
Set(int index, const Element & value)
void
Add(const Element & value)
Element *
Add()
Appends a new element and return a pointer to it. more...
template void
Add(Iter begin, Iter end)
Append elements in the range [begin, end) after reserving the appropriate number of elements.
void
RemoveLast()
Remove the last element in the array.
void
ExtractSubrange(int start, int num, Element * elements)
Extract elements with indices in "[start .. start+num-1]". more...
void
Clear()
void
MergeFrom(const RepeatedField & other)
void
CopyFrom(const RepeatedField & other)
template void
Assign(Iter begin, Iter end)
Replaces the contents with RepeatedField(begin, end).
void
Reserve(int new_size)
Reserve space to expand the field to at least the given size. more...
void
Truncate(int new_size)
Resize the RepeatedField to a new, smaller size. This is O(1).
void
AddAlreadyReserved(const Element & value)
Element *
AddAlreadyReserved()
Appends a new element and return a pointer to it. more...
Element *
AddNAlreadyReserved(int elements)
int
Capacity() const
void
Resize(int new_size, const Element & value)
Like STL resize. more...
Element *
mutable_data()
Gets the underlying array. more...
const Element *
data() const
void
Swap(RepeatedField * other)
Swap entire contents with "other". more...
void
UnsafeArenaSwap(RepeatedField * other)
Swap entire contents with "other". more...
void
SwapElements(int index1, int index2)
Swap two elements.
iterator
begin()
const_iterator
begin() const
const_iterator
cbegin() const
iterator
end()
const_iterator
end() const
const_iterator
cend() const
reverse_iterator
rbegin()
const_reverse_iterator
rbegin() const
reverse_iterator
rend()
const_reverse_iterator
rend() const
size_t
SpaceUsedExcludingSelfLong() const
Returns the number of bytes used by the repeated field, excluding sizeof(*this)
int
SpaceUsedExcludingSelf() const
iterator
erase(const_iterator position)
Removes the element referenced by position. more...
iterator
erase(const_iterator first, const_iterator last)
Removes the elements in the range [first, last). more...
Arena *
GetArena() const
Get the Arena on which this RepeatedField stores its elements.
void
InternalSwap(RepeatedField * other)
For internal use only. more...
template
RepeatedField(Iter begin, Iter end)

Element * RepeatedField::Add()

Appends a new element and return a pointer to it.

The new element is uninitialized if |Element| is a POD type.

-

void RepeatedField::ExtractSubrange(
        int start,
        int num,
        Element * elements)

Extract elements with indices in "[start .. start+num-1]".

Copy them into "elements[0 .. num-1]" if "elements" is not NULL. Caution: implementation also moves elements with indices [start+num ..]. Calling this routine inside a loop can cause quadratic behavior.

-

void RepeatedField::Reserve(
        int new_size)

Reserve space to expand the field to at least the given size.

Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant amount of code bloat.

-

If the array is grown, it will always be at least doubled in size.

-

Element * RepeatedField::AddAlreadyReserved()

Appends a new element and return a pointer to it.

The new element is uninitialized if |Element| is a POD type. Should be called only if Capacity() > Size().

-

void RepeatedField::Resize(
        int new_size,
        const Element & value)

Like STL resize.

Uses value to fill appended elements. Like Truncate() if new_size <= size(), otherwise this is O(new_size - size()).

-

Element * RepeatedField::mutable_data()

Gets the underlying array.

This pointer is possibly invalidated by any add or remove operation.

-

void RepeatedField::Swap(
        RepeatedField * other)

Swap entire contents with "other".

If they are separate arenas then, copies data between each other.

-

void RepeatedField::UnsafeArenaSwap(
        RepeatedField * other)

Swap entire contents with "other".

Should be called only if the caller can guarantee that both repeated fields are on the same arena or are on the heap. Swapping between different arenas is disallowed and caught by a GOOGLE_DCHECK (see API docs for details).

-

iterator RepeatedField::erase(
        const_iterator position)

Removes the element referenced by position.

Returns an iterator to the element immediately following the removed element.

-

Invalidates all iterators at or after the removed element, including end().

-

iterator RepeatedField::erase(
        const_iterator first,
        const_iterator last)

Removes the elements in the range [first, last).

Returns an iterator to the element immediately following the removed range.

-

Invalidates all iterators at or after the removed range, including end().

-

void RepeatedField::InternalSwap(
        RepeatedField * other)

For internal use only.

This is public due to it being called by generated code.

-

template class RepeatedPtrField

#include <google/protobuf/repeated_field.h>
namespace google::protobuf

template <typename >

RepeatedPtrField is like RepeatedField, but used for repeated strings or Messages.

Members

typedef
internal::RepeatedPtrIterator< Element > iterator
STL-like iterator support.
typedef
internal::RepeatedPtrIterator< const Element > const_iterator
typedef
Element value_type
typedef
value_type & reference
typedef
const value_type & const_reference
typedef
value_type * pointer
typedef
const value_type * const_pointer
typedef
int size_type
typedef
ptrdiff_t difference_type
typedef
std::reverse_iterator< const_iterator > const_reverse_iterator
Reverse iterator support.
typedef
std::reverse_iterator< iterator > reverse_iterator
typedef
internal::RepeatedPtrOverPtrsIterator< Element *, void * > pointer_iterator
Custom STL-like iterator that iterates over and returns the underlying pointers to Element rather than Element itself.
typedef
internal::RepeatedPtrOverPtrsIterator< const Element *const, const void *const > const_pointer_iterator
constexpr
RepeatedPtrField()
explicit
RepeatedPtrField(Arena * arena)
RepeatedPtrField(const RepeatedPtrField & other)
template
RepeatedPtrField(Iter begin, Iter end)
~RepeatedPtrField()
RepeatedPtrField &
operator=(const RepeatedPtrField & other)
RepeatedPtrField(RepeatedPtrField && other)
RepeatedPtrField &
operator=(RepeatedPtrField && other)
bool
empty() const
int
size() const
const Element &
Get(int index) const
Element *
Mutable(int index)
Element *
Add()
void
Add(Element && value)
template void
Add(Iter begin, Iter end)
Append elements in the range [begin, end) after reserving the appropriate number of elements.
const Element &
operator[](int index) const
Element &
operator[](int index)
const Element &
at(int index) const
Element &
at(int index)
void
RemoveLast()
Remove the last element in the array. more...
void
DeleteSubrange(int start, int num)
Delete elements with indices in the range [start . more...
void
Clear()
void
MergeFrom(const RepeatedPtrField & other)
void
CopyFrom(const RepeatedPtrField & other)
template void
Assign(Iter begin, Iter end)
Replaces the contents with RepeatedPtrField(begin, end).
void
Reserve(int new_size)
Reserve space to expand the field to at least the given size. more...
int
Capacity() const
Element **
mutable_data()
Gets the underlying array. more...
const Element *const *
data() const
void
Swap(RepeatedPtrField * other)
Swap entire contents with "other". more...
void
UnsafeArenaSwap(RepeatedPtrField * other)
Swap entire contents with "other". more...
void
SwapElements(int index1, int index2)
Swap two elements.
iterator
begin()
const_iterator
begin() const
const_iterator
cbegin() const
iterator
end()
const_iterator
end() const
const_iterator
cend() const
reverse_iterator
rbegin()
const_reverse_iterator
rbegin() const
reverse_iterator
rend()
const_reverse_iterator
rend() const
pointer_iterator
pointer_begin()
const_pointer_iterator
pointer_begin() const
pointer_iterator
pointer_end()
const_pointer_iterator
pointer_end() const
size_t
SpaceUsedExcludingSelfLong() const
Returns (an estimate of) the number of bytes used by the repeated field, excluding sizeof(*this).
int
SpaceUsedExcludingSelf() const
template
RepeatedPtrField(Iter begin, Iter end)

Advanced memory management

When hardcore memory management becomes necessary – as it sometimes does here at Google – the following methods may be useful.
void
AddAllocated(Element * value)
Add an already-allocated object, passing ownership to the RepeatedPtrField. more...
PROTOBUF_FUTURE_MUST_USE_RESULT Element *
ReleaseLast()
Remove the last element and return it, passing ownership to the caller. more...
void
UnsafeArenaAddAllocated(Element * value)
Add an already-allocated object, skipping arena-ownership checks. more...
Element *
UnsafeArenaReleaseLast()
Remove the last element and return it. more...
void
ExtractSubrange(int start, int num, Element ** elements)
Extract elements with indices in the range "[start .. start+num-1]". more...
void
UnsafeArenaExtractSubrange(int start, int num, Element ** elements)
Identical to ExtractSubrange() described above, except that when this repeated field is on an arena, no object copies are performed. more...
int
ClearedCount() const
Get the number of cleared objects that are currently being kept around for reuse.
void
AddCleared(Element * value)
Add an element to the pool of cleared objects, passing ownership to the RepeatedPtrField. more...
PROTOBUF_FUTURE_MUST_USE_RESULT Element *
ReleaseCleared()
Remove a single element from the cleared pool and return it, passing ownership to the caller. more...
iterator
erase(const_iterator position)
Removes the element referenced by position. more...
iterator
erase(const_iterator first, const_iterator last)
Removes the elements in the range [first, last). more...
Arena *
GetArena() const
Gets the arena on which this RepeatedPtrField stores its elements.
void
InternalSwap(RepeatedPtrField * other)
For internal use only. more...

void RepeatedPtrField::RemoveLast()

Remove the last element in the array.

Ownership of the element is retained by the array.

-

void RepeatedPtrField::DeleteSubrange(
        int start,
        int num)

Delete elements with indices in the range [start .

. start+num-1]. Caution: implementation moves all elements with indices [start+num .. ]. Calling this routine inside a loop can cause quadratic behavior.

-

void RepeatedPtrField::Reserve(
        int new_size)

Reserve space to expand the field to at least the given size.

This only resizes the pointer array; it doesn't allocate any objects. If the array is grown, it will always be at least doubled in size.

-

Element ** RepeatedPtrField::mutable_data()

Gets the underlying array.

This pointer is possibly invalidated by any add or remove operation.

-

void RepeatedPtrField::Swap(
        RepeatedPtrField * other)

Swap entire contents with "other".

If they are on separate arenas, then copies data.

-

void RepeatedPtrField::UnsafeArenaSwap(
        RepeatedPtrField * other)

Swap entire contents with "other".

Caller should guarantee that either both fields are on the same arena or both are on the heap. Swapping between different arenas with this function is disallowed and is caught via GOOGLE_DCHECK.

-

void RepeatedPtrField::AddAllocated(
        Element * value)

Add an already-allocated object, passing ownership to the RepeatedPtrField.

Note that some special behavior occurs with respect to arenas:

-
(i) if this field holds submessages, the new submessage will be copied if
-the original is in an arena and this RepeatedPtrField is either in a
-different arena, or on the heap.
-(ii) if this field holds strings, the passed-in string *must* be
-heap-allocated, not arena-allocated. There is no way to dynamically check
-this at runtime, so User Beware.
-

PROTOBUF_FUTURE_MUST_USE_RESULT Element *
    RepeatedPtrField::ReleaseLast()

Remove the last element and return it, passing ownership to the caller.

Requires: size() > 0

-

If this RepeatedPtrField is on an arena, an object copy is required to pass ownership back to the user (for compatible semantics). Use UnsafeArenaReleaseLast() if this behavior is undesired.

-

void RepeatedPtrField::UnsafeArenaAddAllocated(
        Element * value)

Add an already-allocated object, skipping arena-ownership checks.

The user must guarantee that the given object is in the same arena as this RepeatedPtrField. It is also useful in legacy code that uses temporary ownership to avoid copies. Example:

-
RepeatedPtrField<T> temp_field;
-temp_field.AddAllocated(new T);
-... // Do something with temp_field
-temp_field.ExtractSubrange(0, temp_field.size(), nullptr);
-

If you put temp_field on the arena this fails, because the ownership transfers to the arena at the "AddAllocated" call and is not released anymore causing a double delete. UnsafeArenaAddAllocated prevents this.

-

Element * RepeatedPtrField::UnsafeArenaReleaseLast()

Remove the last element and return it.

Works only when operating on an arena. The returned pointer is to the original object in the arena, hence has the arena's lifetime. Requires: current_size_ > 0

-

void RepeatedPtrField::ExtractSubrange(
        int start,
        int num,
        Element ** elements)

Extract elements with indices in the range "[start .. start+num-1]".

The caller assumes ownership of the extracted elements and is responsible for deleting them when they are no longer needed. If "elements" is non-NULL, then pointers to the extracted elements are stored in "elements[0 .. num-1]" for the convenience of the caller. If "elements" is NULL, then the caller must use some other mechanism to perform any further operations (like deletion) on these elements. Caution: implementation also moves elements with indices [start+num ..]. Calling this routine inside a loop can cause quadratic behavior.

-

Memory copying behavior is identical to ReleaseLast(), described above: if this RepeatedPtrField is on an arena, an object copy is performed for each returned element, so that all returned element pointers are to heap-allocated copies. If this copy is not desired, the user should call UnsafeArenaExtractSubrange().

-

void RepeatedPtrField::UnsafeArenaExtractSubrange(
        int start,
        int num,
        Element ** elements)

Identical to ExtractSubrange() described above, except that when this repeated field is on an arena, no object copies are performed.

Instead, the raw object pointers are returned. Thus, if on an arena, the returned objects must not be freed, because they will not be heap-allocated objects.

-

void RepeatedPtrField::AddCleared(
        Element * value)

Add an element to the pool of cleared objects, passing ownership to the RepeatedPtrField.

The element must be cleared prior to calling this method.

-

This method cannot be called when the repeated field is on an arena or when |value| is; both cases will trigger a GOOGLE_DCHECK-failure.

-

PROTOBUF_FUTURE_MUST_USE_RESULT Element *
    RepeatedPtrField::ReleaseCleared()

Remove a single element from the cleared pool and return it, passing ownership to the caller.

The element is guaranteed to be cleared. Requires: ClearedCount() > 0

-

This method cannot be called when the repeated field is on an arena; doing so will trigger a GOOGLE_DCHECK-failure.

-

iterator RepeatedPtrField::erase(
        const_iterator position)

Removes the element referenced by position.

Returns an iterator to the element immediately following the removed element.

-

Invalidates all iterators at or after the removed element, including end().

-

iterator RepeatedPtrField::erase(
        const_iterator first,
        const_iterator last)

Removes the elements in the range [first, last).

Returns an iterator to the element immediately following the removed range.

-

Invalidates all iterators at or after the removed range, including end().

-

void RepeatedPtrField::InternalSwap(
        RepeatedPtrField * other)

For internal use only.

This is public due to it being called by generated code.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.service.md b/content/reference/cpp/api-docs/google.protobuf.service.md deleted file mode 100644 index dd36735e7..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.service.md +++ /dev/null @@ -1,95 +0,0 @@ -+++ -title = "service.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/service.h>
namespace google::protobuf

DEPRECATED: This module declares the abstract interfaces underlying proto2 RPC services.

These are intended to be independent of any particular RPC implementation, so that proto2 services can be used on top of a variety of implementations. Starting with version 2.3.0, RPC implementations should not try to build on these, but should instead provide code generator plugins which generate code specific to the particular RPC implementation. This way the generated code can be more appropriate for the implementation in use and can avoid unnecessary layers of indirection.

- -

When you use the protocol compiler to compile a service definition, it generates two classes: An abstract interface for the service (with methods matching the service definition) and a "stub" implementation. A stub is just a type-safe wrapper around an RpcChannel which emulates a local implementation of the service.

- -

For example, the service definition:

- -
service MyService {
-  rpc Foo(MyRequest) returns(MyResponse);
-}
- -

will generate abstract interface "MyService" and class "MyService::Stub". You could implement a MyService as follows:

- -
class MyServiceImpl : public MyService {
- public:
-  MyServiceImpl() {}
-  ~MyServiceImpl() {}
-
-  // implements MyService ---------------------------------------
-
-  void Foo(google::protobuf::RpcController* controller,
-           const MyRequest* request,
-           MyResponse* response,
-           Closure* done) {
-    // ... read request and fill in response ...
-    done->Run();
-  }
-};
- -

You would then register an instance of MyServiceImpl with your RPC server implementation. (How to do that depends on the implementation.)

- -

To call a remote MyServiceImpl, first you need an RpcChannel connected to it. How to construct a channel depends, again, on your RPC implementation. Here we use a hypothetical "MyRpcChannel" as an example:

- -
MyRpcChannel channel("rpc:hostname:1234/myservice");
-MyRpcController controller;
-MyServiceImpl::Stub stub(&channel);
-FooRequest request;
-FooResponse response;
-
-// ... fill in request ...
-
-stub.Foo(&controller, request, &response, NewCallback(HandleResponse));
- -

On Thread-Safety:

- -

Different RPC implementations may make different guarantees about what threads they may run callbacks on, and what threads the application is allowed to use to call the RPC system. Portable software should be ready for callbacks to be called on any thread, but should not try to call the RPC system from any thread except for the ones on which it received the callbacks. Realistically, though, simple software will probably want to use a single-threaded RPC system while high-end software will want to use multiple threads. RPC implementations should provide multiple choices.

- -

Classes in this file

Abstract base interface for protocol-buffer-based RPC services.
An RpcController mediates a single method call.
Abstract interface for an RPC channel.

class Service

#include <google/protobuf/service.h>
namespace google::protobuf

Abstract base interface for protocol-buffer-based RPC services.

Services themselves are abstract interfaces (implemented either by servers or as stubs), but they subclass this base interface. The methods of this interface can be used to call the methods of the Service without knowing its exact type at compile time (analogous to Reflection).

-

Members

enum
ChannelOwnership
When constructing a stub, you may pass STUB_OWNS_CHANNEL as the second parameter to the constructor to tell it to delete its RpcChannel when destroyed. more...
Service()
virtual
~Service()
virtual const ServiceDescriptor *
GetDescriptor() = 0
Get the ServiceDescriptor describing this service and its methods.
virtual void
CallMethod(const MethodDescriptor * method, RpcController * controller, const Message * request, Message * response, Closure * done) = 0
Call a method of the service specified by MethodDescriptor. more...
virtual const Message &
GetRequestPrototype(const MethodDescriptor * method) const = 0
CallMethod() requires that the request and response passed in are of a particular subclass of Message. more...
virtual const Message &
GetResponsePrototype(const MethodDescriptor * method) const = 0

enum Service::ChannelOwnership {
  STUB_OWNS_CHANNEL,
  STUB_DOESNT_OWN_CHANNEL
}

When constructing a stub, you may pass STUB_OWNS_CHANNEL as the second parameter to the constructor to tell it to delete its RpcChannel when destroyed.

STUB_OWNS_CHANNEL
STUB_DOESNT_OWN_CHANNEL

virtual void Service::CallMethod(
        const MethodDescriptor * method,
        RpcController * controller,
        const Message * request,
        Message * response,
        Closure * done) = 0

Call a method of the service specified by MethodDescriptor.

This is normally implemented as a simple switch() that calls the standard definitions of the service's methods.

-

Preconditions:

-
    -
  • method->service() == GetDescriptor()
  • -
  • request and response are of the exact same classes as the objects returned by GetRequestPrototype(method) and GetResponsePrototype(method).
  • -
  • After the call has started, the request must not be modified and the response must not be accessed at all until "done" is called.
  • -
  • "controller" is of the correct type for the RPC implementation being used by this Service. For stubs, the "correct type" depends on the RpcChannel which the stub is using. Server-side Service implementations are expected to accept whatever type of RpcController the server-side RPC implementation uses.
  • -
-

Postconditions:

-
    -
  • "done" will be called when the method is complete. This may be before CallMethod() returns or it may be at some point in the future.
  • -
  • If the RPC succeeded, "response" contains the response returned by the server.
  • -
  • If the RPC failed, "response"'s contents are undefined. The RpcController can be queried to determine if an error occurred and possibly to get more information about the error.
  • -
-

virtual const Message & Service::GetRequestPrototype(
        const MethodDescriptor * method) const = 0

CallMethod() requires that the request and response passed in are of a particular subclass of Message.

GetRequestPrototype() and GetResponsePrototype() get the default instances of these required types. You can then call Message::New() on these instances to construct mutable objects which you can then pass to CallMethod().

-

Example:

-
const MethodDescriptor* method =
-  service->GetDescriptor()->FindMethodByName("Foo");
-Message* request  = stub->GetRequestPrototype (method)->New();
-Message* response = stub->GetResponsePrototype(method)->New();
-request->ParseFromString(input);
-service->CallMethod(method, *request, response, callback);
-

class RpcController

#include <google/protobuf/service.h>
namespace google::protobuf

An RpcController mediates a single method call.

The primary purpose of the controller is to provide a way to manipulate settings specific to the RPC implementation and to find out about RPC-level errors.

-

The methods provided by the RpcController interface are intended to be a "least common denominator" set of features which we expect all implementations to support. Specific implementations may provide more advanced features (e.g. deadline propagation).

-

Members

RpcController()
virtual
~RpcController()

Client-side methods

These calls may be made from the client side only. Their results are undefined on the server side (may crash).
virtual void
Reset() = 0
Resets the RpcController to its initial state so that it may be reused in a new call. more...
virtual bool
Failed() const = 0
After a call has finished, returns true if the call failed. more...
virtual std::string
ErrorText() const = 0
If Failed() is true, returns a human-readable description of the error.
virtual void
StartCancel() = 0
Advises the RPC system that the caller desires that the RPC call be canceled. more...

Server-side methods

-

These calls may be made from the server side only.

-

Their results are undefined on the client side (may crash).

-
virtual void
SetFailed(const std::string & reason) = 0
Causes Failed() to return true on the client side. more...
virtual bool
IsCanceled() const = 0
If true, indicates that the client canceled the RPC, so the server may as well give up on replying to it. more...
virtual void
NotifyOnCancel(Closure * callback) = 0
Asks that the given callback be called when the RPC is canceled. more...

virtual void RpcController::Reset() = 0

Resets the RpcController to its initial state so that it may be reused in a new call.

Must not be called while an RPC is in progress.

-

virtual bool RpcController::Failed() const = 0

After a call has finished, returns true if the call failed.

The possible reasons for failure depend on the RPC implementation. Failed() must not be called before a call has finished. If Failed() returns true, the contents of the response message are undefined.

-

virtual void RpcController::StartCancel() = 0

Advises the RPC system that the caller desires that the RPC call be canceled.

The RPC system may cancel it immediately, may wait awhile and then cancel it, or may not even cancel the call at all. If the call is canceled, the "done" callback will still be called and the RpcController will indicate that the call failed at that time.

-

virtual void RpcController::SetFailed(
        const std::string & reason) = 0

Causes Failed() to return true on the client side.

"reason" will be incorporated into the message returned by ErrorText(). If you find you need to return machine-readable information about failures, you should incorporate it into your response protocol buffer and should NOT call SetFailed().

-

virtual bool RpcController::IsCanceled() const = 0

If true, indicates that the client canceled the RPC, so the server may as well give up on replying to it.

The server should still call the final "done" callback.

-

virtual void RpcController::NotifyOnCancel(
        Closure * callback) = 0

Asks that the given callback be called when the RPC is canceled.

The callback will always be called exactly once. If the RPC completes without being canceled, the callback will be called after completion. If the RPC has already been canceled when NotifyOnCancel() is called, the callback will be called immediately.

-

NotifyOnCancel() must be called no more than once per request.

-

class RpcChannel

#include <google/protobuf/service.h>
namespace google::protobuf

Abstract interface for an RPC channel.

An RpcChannel represents a communication line to a Service which can be used to call that Service's methods. The Service may be running on another machine. Normally, you should not call an RpcChannel directly, but instead construct a stub Service wrapping it. Example:

-
RpcChannel* channel = new MyRpcChannel("remotehost.example.com:1234");
-MyService* service = new MyService::Stub(channel);
-service->MyMethod(request, &response, callback);
-

Members

RpcChannel()
virtual
~RpcChannel()
virtual void
CallMethod(const MethodDescriptor * method, RpcController * controller, const Message * request, Message * response, Closure * done) = 0
Call the given method of the remote service. more...

virtual void RpcChannel::CallMethod(
        const MethodDescriptor * method,
        RpcController * controller,
        const Message * request,
        Message * response,
        Closure * done) = 0

Call the given method of the remote service.

The signature of this procedure looks the same as Service::CallMethod(), but the requirements are less strict in one important way: the request and response objects need not be of any specific class as long as their descriptors are method->input_type() and method->output_type().

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.text_format.md b/content/reference/cpp/api-docs/google.protobuf.text_format.md deleted file mode 100644 index 26ae8cebb..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.text_format.md +++ /dev/null @@ -1,53 +0,0 @@ -+++ -title = "text_format.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/text_format.h>
namespace google::protobuf

Utilities for printing and parsing protocol messages in a human-readable, text-based format.

Classes in this file

This class implements protocol buffer text format, colloquially known as text proto.
The default printer that converts scalar values from fields into their string representation.
Deprecated: please use FastFieldValuePrinter instead.
Interface that Printers or Parsers can use to find extensions, or types referenced in Any messages.
Data structure which is populated with the locations of each field value parsed from the text.
A location in the parsed text.
For more control over parsing, use this class.
Class for those users which require more fine-grained control over how a protobuffer message is printed out.

class TextFormat

#include <google/protobuf/text_format.h>
namespace google::protobuf

This class implements protocol buffer text format, colloquially known as text proto.

Printing and parsing protocol messages in text format is useful for debugging and human editing of messages.

- -

This class is really a namespace that contains only static methods.

- -

Members

static bool
Print(const Message & message, io::ZeroCopyOutputStream * output)
Outputs a textual representation of the given message to the given output stream. more...
static bool
PrintUnknownFields(const UnknownFieldSet & unknown_fields, io::ZeroCopyOutputStream * output)
Print the fields in an UnknownFieldSet. more...
static bool
PrintToString(const Message & message, std::string * output)
Like Print(), but outputs directly to a string. more...
static bool
PrintUnknownFieldsToString(const UnknownFieldSet & unknown_fields, std::string * output)
Like PrintUnknownFields(), but outputs directly to a string. more...
static void
PrintFieldValueToString(const Message & message, const FieldDescriptor * field, int index, std::string * output)
Outputs a textual representation of the value of the field supplied on the message supplied. more...
static bool
Parse(io::ZeroCopyInputStream * input, Message * output)
Parses a text-format protocol message from the given input stream to the given message object. more...
static bool
ParseFromString(ConstStringParam input, Message * output)
Like Parse(), but reads directly from a string.
static bool
Merge(io::ZeroCopyInputStream * input, Message * output)
Like Parse(), but the data is merged into the given message, as if using Message::MergeFrom().
static bool
MergeFromString(ConstStringParam input, Message * output)
Like Merge(), but reads directly from a string.
static bool
ParseFieldValueFromString(const std::string & input, const FieldDescriptor * field, Message * message)
Parse the given text as a single field value and store it into the given field of the given message. more...

static bool TextFormat::Print(
        const Message & message,
        io::ZeroCopyOutputStream * output)

Outputs a textual representation of the given message to the given output stream.

Returns false if printing fails.

-

static bool TextFormat::PrintUnknownFields(
        const UnknownFieldSet & unknown_fields,
        io::ZeroCopyOutputStream * output)

Print the fields in an UnknownFieldSet.

They are printed by tag number only. Embedded messages are heuristically identified by attempting to parse them. Returns false if printing fails.

-

static bool TextFormat::PrintToString(
        const Message & message,
        std::string * output)

Like Print(), but outputs directly to a string.

Note: output will be cleared prior to printing, and will be left empty even if printing fails. Returns false if printing fails.

-

static bool TextFormat::PrintUnknownFieldsToString(
        const UnknownFieldSet & unknown_fields,
        std::string * output)

Like PrintUnknownFields(), but outputs directly to a string.

Returns false if printing fails.

-

static void TextFormat::PrintFieldValueToString(
        const Message & message,
        const FieldDescriptor * field,
        int index,
        std::string * output)

Outputs a textual representation of the value of the field supplied on the message supplied.

For non-repeated fields, an index of -1 must be supplied. Note that this method will print the default value for a field if it is not set.

-

static bool TextFormat::Parse(
        io::ZeroCopyInputStream * input,
        Message * output)

Parses a text-format protocol message from the given input stream to the given message object.

This function parses the human-readable format written by Print(). Returns true on success. The message is cleared first, even if the function fails – See Merge() to avoid this behavior.

-

Example input: "user {\n id: 123 extra { gender: MALE language: 'en' }\n}"

-

One use for this function is parsing handwritten strings in test code. Another use is to parse the output from google::protobuf::Message::DebugString() (or ShortDebugString()), because these functions output using google::protobuf::TextFormat::Print().

-

If you would like to read a protocol buffer serialized in the (non-human-readable) binary wire format, see google::protobuf::MessageLite::ParseFromString().

-

static bool TextFormat::ParseFieldValueFromString(
        const std::string & input,
        const FieldDescriptor * field,
        Message * message)

Parse the given text as a single field value and store it into the given field of the given message.

If the field is a repeated field, the new value will be added to the end

-

class TextFormat::BaseTextGenerator

#include <google/protobuf/text_format.h>
namespace google::protobuf

Members

virtual
~BaseTextGenerator()
virtual void
Indent()
virtual void
Outdent()
virtual size_t
GetCurrentIndentationSize() const
Returns the current indentation size in characters.
virtual void
Print(const char * text, size_t size) = 0
Print text to the output stream.
void
PrintString(const std::string & str)
template void
PrintLiteral(const char(&) text)

class TextFormat::FastFieldValuePrinter

#include <google/protobuf/text_format.h>
namespace google::protobuf

The default printer that converts scalar values from fields into their string representation.

You can derive from this FastFieldValuePrinter if you want to have fields to be printed in a different way and register it at the Printer.

-

Members

FastFieldValuePrinter()
virtual
~FastFieldValuePrinter()
virtual void
PrintBool(bool val, BaseTextGenerator * generator) const
virtual void
PrintInt32(int32 val, BaseTextGenerator * generator) const
virtual void
PrintUInt32(uint32 val, BaseTextGenerator * generator) const
virtual void
PrintInt64(int64 val, BaseTextGenerator * generator) const
virtual void
PrintUInt64(uint64 val, BaseTextGenerator * generator) const
virtual void
PrintFloat(float val, BaseTextGenerator * generator) const
virtual void
PrintDouble(double val, BaseTextGenerator * generator) const
virtual void
PrintString(const std::string & val, BaseTextGenerator * generator) const
virtual void
PrintBytes(const std::string & val, BaseTextGenerator * generator) const
virtual void
PrintEnum(int32 val, const std::string & name, BaseTextGenerator * generator) const
virtual void
PrintFieldName(const Message & message, int field_index, int field_count, const Reflection * reflection, const FieldDescriptor * field, BaseTextGenerator * generator) const
virtual void
PrintFieldName(const Message & message, const Reflection * reflection, const FieldDescriptor * field, BaseTextGenerator * generator) const
virtual void
PrintMessageStart(const Message & message, int field_index, int field_count, bool single_line_mode, BaseTextGenerator * generator) const
virtual bool
PrintMessageContent(const Message & message, int field_index, int field_count, bool single_line_mode, BaseTextGenerator * generator) const
Allows to override the logic on how to print the content of a message. more...
virtual void
PrintMessageEnd(const Message & message, int field_index, int field_count, bool single_line_mode, BaseTextGenerator * generator) const

virtual bool FastFieldValuePrinter::PrintMessageContent(
        const Message & message,
        int field_index,
        int field_count,
        bool single_line_mode,
        BaseTextGenerator * generator) const

Allows to override the logic on how to print the content of a message.

Return false to use the default printing logic. Note that it is legal for this function to print something and then return false to use the default content printing (although at that point it would behave similarly to PrintMessageStart).

-

class TextFormat::FieldValuePrinter

#include <google/protobuf/text_format.h>
namespace google::protobuf

Deprecated: please use FastFieldValuePrinter instead.

Members

FieldValuePrinter()
virtual
~FieldValuePrinter()
virtual std::string
PrintBool(bool val) const
virtual std::string
PrintInt32(int32 val) const
virtual std::string
PrintUInt32(uint32 val) const
virtual std::string
PrintInt64(int64 val) const
virtual std::string
PrintUInt64(uint64 val) const
virtual std::string
PrintFloat(float val) const
virtual std::string
PrintDouble(double val) const
virtual std::string
PrintString(const std::string & val) const
virtual std::string
PrintBytes(const std::string & val) const
virtual std::string
PrintEnum(int32 val, const std::string & name) const
virtual std::string
PrintFieldName(const Message & message, const Reflection * reflection, const FieldDescriptor * field) const
virtual std::string
PrintMessageStart(const Message & message, int field_index, int field_count, bool single_line_mode) const
virtual std::string
PrintMessageEnd(const Message & message, int field_index, int field_count, bool single_line_mode) const

class TextFormat::Finder

#include <google/protobuf/text_format.h>
namespace google::protobuf

Interface that Printers or Parsers can use to find extensions, or types referenced in Any messages.

Members

virtual
~Finder()
virtual const FieldDescriptor *
FindExtension(Message * message, const std::string & name) const
Try to find an extension of *message by fully-qualified field name. more...
virtual const FieldDescriptor *
FindExtensionByNumber(const Descriptor * descriptor, int number) const
Similar to FindExtension, but uses a Descriptor and the extension number instead of using a Message and the name when doing the look up.
virtual const Descriptor *
FindAnyType(const Message & message, const std::string & prefix, const std::string & name) const
Find the message type for an Any proto. more...
virtual MessageFactory *
FindExtensionFactory(const FieldDescriptor * field) const
Find the message factory for the given extension field. more...

virtual const FieldDescriptor *
    Finder::FindExtension(
        Message * message,
        const std::string & name) const

Try to find an extension of *message by fully-qualified field name.

Returns NULL if no extension is known for this name or number. The base implementation uses the extensions already known by the message.

-

virtual const Descriptor *
    Finder::FindAnyType(
        const Message & message,
        const std::string & prefix,
        const std::string & name) const

Find the message type for an Any proto.

Returns NULL if no message is known for this name. The base implementation only accepts prefixes of type.googleprod.com/ or type.googleapis.com/, and searches the DescriptorPool of the parent message.

-

virtual MessageFactory * Finder::FindExtensionFactory(
        const FieldDescriptor * field) const

Find the message factory for the given extension field.

This can be used to generalize the Parser to add extension fields to a message in the same way as the "input" message for the Parser.

-

class TextFormat::MessagePrinter

#include <google/protobuf/text_format.h>
namespace google::protobuf

Members

MessagePrinter()
virtual
~MessagePrinter()
virtual void
Print(const Message & message, bool single_line_mode, BaseTextGenerator * generator) const = 0

class TextFormat::ParseInfoTree

#include <google/protobuf/text_format.h>
namespace google::protobuf

Data structure which is populated with the locations of each field value parsed from the text.

Members

ParseInfoTree()
ParseInfoTree(const ParseInfoTree & )
ParseInfoTree &
operator=(const ParseInfoTree & )
ParseLocation
GetLocation(const FieldDescriptor * field, int index) const
Returns the parse location for index-th value of the field in the parsed text. more...
ParseInfoTree *
GetTreeForNested(const FieldDescriptor * field, int index) const
Returns the parse info tree for the given field, which must be a message type. more...

ParseLocation ParseInfoTree::GetLocation(
        const FieldDescriptor * field,
        int index) const

Returns the parse location for index-th value of the field in the parsed text.

If none exists, returns a location with line = -1. Index should be -1 for not-repeated fields.

-

ParseInfoTree * ParseInfoTree::GetTreeForNested(
        const FieldDescriptor * field,
        int index) const

Returns the parse info tree for the given field, which must be a message type.

The nested information tree is owned by the root tree and will be deleted when it is deleted.

-

struct TextFormat::ParseLocation

#include <google/protobuf/text_format.h>
namespace google::protobuf

A location in the parsed text.

Members

int
line
int
column
ParseLocation()
ParseLocation(int line_param, int column_param)

class TextFormat::Parser

#include <google/protobuf/text_format.h>
namespace google::protobuf

For more control over parsing, use this class.

Members

Parser()
~Parser()
bool
Parse(io::ZeroCopyInputStream * input, Message * output)
bool
ParseFromString(ConstStringParam input, Message * output)
bool
Merge(io::ZeroCopyInputStream * input, Message * output)
bool
MergeFromString(ConstStringParam input, Message * output)
void
RecordErrorsTo(io::ErrorCollector * error_collector)
Set where to report parse errors. more...
void
SetFinder(const Finder * finder)
Set how parser finds extensions. more...
void
WriteLocationsTo(ParseInfoTree * tree)
Sets where location information about the parse will be written. more...
void
AllowPartialMessage(bool allow)
Normally parsing fails if, after parsing, output->IsInitialized() returns false. more...
void
AllowCaseInsensitiveField(bool allow)
Allow field names to be matched case-insensitively. more...
bool
ParseFieldValueFromString(const std::string & input, const FieldDescriptor * field, Message * output)
void
AllowUnknownExtension(bool allow)
When an unknown extension is met, parsing will fail if this option is set to false (the default). more...
void
AllowUnknownField(bool allow)
When an unknown field is met, parsing will fail if this option is set to false (the default). more...
void
AllowFieldNumber(bool allow)
void
SetRecursionLimit(int limit)
Sets maximum recursion depth which parser can use. more...

void Parser::RecordErrorsTo(
        io::ErrorCollector * error_collector)

Set where to report parse errors.

If NULL (the default), errors will be printed to stderr.

-

void Parser::SetFinder(
        const Finder * finder)

Set how parser finds extensions.

If NULL (the default), the parser will use the standard Reflection object associated with the message being parsed.

-

void Parser::WriteLocationsTo(
        ParseInfoTree * tree)

Sets where location information about the parse will be written.

If NULL (the default), then no location will be written.

-

void Parser::AllowPartialMessage(
        bool allow)

Normally parsing fails if, after parsing, output->IsInitialized() returns false.

Call AllowPartialMessage(true) to skip this check.

-

void Parser::AllowCaseInsensitiveField(
        bool allow)

Allow field names to be matched case-insensitively.

This is not advisable if there are fields that only differ in case, or if you want to enforce writing in the canonical form. This is 'false' by default.

-

void Parser::AllowUnknownExtension(
        bool allow)

When an unknown extension is met, parsing will fail if this option is set to false (the default).

If true, unknown extensions will be ignored and a warning message will be generated. Beware! Setting this option true may hide some errors (e.g. spelling error on extension name). This allows data loss; unlike binary format, text format cannot preserve unknown extensions. Avoid using this option if possible.

-

void Parser::AllowUnknownField(
        bool allow)

When an unknown field is met, parsing will fail if this option is set to false (the default).

If true, unknown fields will be ignored and a warning message will be generated. Beware! Setting this option true may hide some errors (e.g. spelling error on field name). This allows data loss; unlike binary format, text format cannot preserve unknown fields. Avoid using this option if possible.

-

void Parser::SetRecursionLimit(
        int limit)

Sets maximum recursion depth which parser can use.

This is effectively the maximum allowed nesting of proto messages.

-

class TextFormat::Printer

#include <google/protobuf/text_format.h>
namespace google::protobuf

Class for those users which require more fine-grained control over how a protobuffer message is printed out.

Members

Printer()
bool
Print(const Message & message, io::ZeroCopyOutputStream * output) const
bool
PrintUnknownFields(const UnknownFieldSet & unknown_fields, io::ZeroCopyOutputStream * output) const
bool
PrintToString(const Message & message, std::string * output) const
bool
PrintUnknownFieldsToString(const UnknownFieldSet & unknown_fields, std::string * output) const
void
PrintFieldValueToString(const Message & message, const FieldDescriptor * field, int index, std::string * output) const
void
SetInitialIndentLevel(int indent_level)
Adjust the initial indent level of all output. more...
void
SetSingleLineMode(bool single_line_mode)
If printing in single line mode, then the entire message will be output on a single line with no line breaks.
bool
IsInSingleLineMode() const
void
SetUseFieldNumber(bool use_field_number)
If use_field_number is true, uses field number instead of field name.
void
SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives)
Set true to print repeated primitives in a format like: more...
void
SetUseUtf8StringEscaping(bool as_utf8)
Set true to output UTF-8 instead of ASCII. more...
void
SetDefaultFieldValuePrinter(const FastFieldValuePrinter * printer)
Set the default FastFieldValuePrinter that is used for all fields that don't have a field-specific printer registered. more...
void
SetDefaultFieldValuePrinter(const FieldValuePrinter * printer)
void
SetHideUnknownFields(bool hide)
Sets whether we want to hide unknown fields or not. more...
void
SetPrintMessageFieldsInIndexOrder(bool print_message_fields_in_index_order)
If print_message_fields_in_index_order is true, fields of a proto message will be printed using the order defined in source code instead of the field number, extensions will be printed at the end of the message and their relative order is determined by the extension number. more...
void
SetExpandAny(bool expand)
If expand==true, expand google.protobuf.Any payloads. more...
void
SetFinder(const Finder * finder)
Set how parser finds message for Any payloads.
void
SetTruncateStringFieldLongerThan(const int64 truncate_string_field_longer_than)
If non-zero, we truncate all string fields that are longer than this threshold. more...
bool
RegisterFieldValuePrinter(const FieldDescriptor * field, const FastFieldValuePrinter * printer)
Register a custom field-specific FastFieldValuePrinter for fields with a particular FieldDescriptor. more...
bool
RegisterFieldValuePrinter(const FieldDescriptor * field, const FieldValuePrinter * printer)
bool
RegisterMessagePrinter(const Descriptor * descriptor, const MessagePrinter * printer)
Register a custom message-specific MessagePrinter for messages with a particular Descriptor. more...

void Printer::SetInitialIndentLevel(
        int indent_level)

Adjust the initial indent level of all output.

Each indent level is equal to two spaces.

-

void Printer::SetUseShortRepeatedPrimitives(
        bool use_short_repeated_primitives)

Set true to print repeated primitives in a format like:

field_name: [1, 2, 3, 4]
-

instead of printing each value on its own line. Short format applies only to primitive values – i.e. everything except strings and sub-messages/groups.

-

void Printer::SetUseUtf8StringEscaping(
        bool as_utf8)

Set true to output UTF-8 instead of ASCII.

The only difference is that bytes >= 0x80 in string fields will not be escaped, because they are assumed to be part of UTF-8 multi-byte sequences. This will change the default FastFieldValuePrinter.

-

void Printer::SetDefaultFieldValuePrinter(
        const FastFieldValuePrinter * printer)

Set the default FastFieldValuePrinter that is used for all fields that don't have a field-specific printer registered.

Takes ownership of the printer.

-

void Printer::SetHideUnknownFields(
        bool hide)

Sets whether we want to hide unknown fields or not.

Usually unknown fields are printed in a generic way that includes the tag number of the field instead of field name. However, sometimes it is useful to be able to print the message without unknown fields (e.g. for the python protobuf version to maintain consistency between its pure python and c++ implementations).

-

void Printer::SetPrintMessageFieldsInIndexOrder(
        bool print_message_fields_in_index_order)

If print_message_fields_in_index_order is true, fields of a proto message will be printed using the order defined in source code instead of the field number, extensions will be printed at the end of the message and their relative order is determined by the extension number.

By default, use the field number order.

-

void Printer::SetExpandAny(
        bool expand)

If expand==true, expand google.protobuf.Any payloads.

The output will be of form

-
[type_url] { <value_printed_in_text> }
-

If expand==false, print Any using the default printer. The output will look like

-
type_url: "<type_url>"  value: "serialized_content"
-

void Printer::SetTruncateStringFieldLongerThan(
        const int64 truncate_string_field_longer_than)

If non-zero, we truncate all string fields that are longer than this threshold.

This is useful when the proto message has very long strings, e.g., dump of encoded image file.

-

NOTE(hfgong): Setting a non-zero value breaks round-trip safe property of TextFormat::Printer. That is, from the printed message, we cannot fully recover the original string field any more.

-

bool Printer::RegisterFieldValuePrinter(
        const FieldDescriptor * field,
        const FastFieldValuePrinter * printer)

Register a custom field-specific FastFieldValuePrinter for fields with a particular FieldDescriptor.

Returns "true" if the registration succeeded, or "false", if there is already a printer for that FieldDescriptor. Takes ownership of the printer on successful registration.

-

bool Printer::RegisterMessagePrinter(
        const Descriptor * descriptor,
        const MessagePrinter * printer)

Register a custom message-specific MessagePrinter for messages with a particular Descriptor.

Returns "true" if the registration succeeded, or "false" if there is already a printer for that Descriptor.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.unknown_field_set.md b/content/reference/cpp/api-docs/google.protobuf.unknown_field_set.md deleted file mode 100644 index 8eb6e768f..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.unknown_field_set.md +++ /dev/null @@ -1,26 +0,0 @@ - - -+++ -title = "unknown_field_set.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/unknown_field_set.h>
namespace google::protobuf

Contains classes used to keep track of unrecognized fields seen while parsing a protocol message.

Classes in this file

An UnknownFieldSet contains fields that were encountered while parsing a message but were not defined by its type.
Represents one field in an UnknownFieldSet.

class UnknownFieldSet

#include <google/protobuf/unknown_field_set.h>
namespace google::protobuf

An UnknownFieldSet contains fields that were encountered while parsing a message but were not defined by its type.

Keeping track of these can be useful, especially in that they may be written if the message is serialized again without being cleared in between. This means that software which simply receives messages and forwards them to other servers does not need to be updated every time a new field is added to the message definition.

- -

To get the UnknownFieldSet attached to any message, call Reflection::GetUnknownFields().

- -

This class is necessarily tied to the protocol buffer wire format, unlike the Reflection interface which is independent of any serialization scheme.

- -

Members

UnknownFieldSet()
~UnknownFieldSet()
void
Clear()
Remove all fields.
void
ClearAndFreeMemory()
Remove all fields and deallocate internal data objects.
bool
empty() const
Is this set empty?
void
MergeFrom(const UnknownFieldSet & other)
Merge the contents of some other UnknownFieldSet with this one.
void
MergeFromAndDestroy(UnknownFieldSet * other)
Similar to above, but this function will destroy the contents of other.
void
Swap(UnknownFieldSet * x)
Swaps the contents of some other UnknownFieldSet with this one.
size_t
SpaceUsedExcludingSelfLong() const
Computes (an estimate of) the total number of bytes currently used for storing the unknown fields in memory. more...
int
SpaceUsedExcludingSelf() const
size_t
SpaceUsedLong() const
Version of SpaceUsed() including sizeof(*this).
int
SpaceUsed() const
int
field_count() const
Returns the number of fields present in the UnknownFieldSet.
const UnknownField &
field(int index) const
Get a field in the set, where 0 <= index < field_count(). more...
UnknownField *
mutable_field(int index)
Get a mutable pointer to a field in the set, where 0 <= index < field_count(). more...
static void
MergeToInternalMetadata(const UnknownFieldSet & other, internal::InternalMetadata * metadata)
Merge the contents an UnknownFieldSet with the UnknownFieldSet in *metadata, if there is one. more...

Adding fields

void
AddVarint(int number, uint64 value)
void
AddFixed32(int number, uint32 value)
void
AddFixed64(int number, uint64 value)
void
AddLengthDelimited(int number, const std::string & value)
std::string *
AddLengthDelimited(int number)
UnknownFieldSet *
AddGroup(int number)
void
AddField(const UnknownField & field)
Adds an unknown field from another set.
void
DeleteSubrange(int start, int num)
Delete fields with indices in the range [start . more...
void
DeleteByNumber(int number)
Delete all fields with a specific field number. more...

Parsing helpers

These work exactly like the similarly-named methods of Message.
bool
MergeFromCodedStream(io::CodedInputStream * input)
bool
ParseFromCodedStream(io::CodedInputStream * input)
bool
ParseFromZeroCopyStream(io::ZeroCopyInputStream * input)
bool
ParseFromArray(const void * data, int size)
bool
ParseFromString(const std::string & data)
template bool
MergeFromMessage(const MessageType & message)
Merges this message's unknown field data (if any). more...
static const UnknownFieldSet &
default_instance()

size_t UnknownFieldSet::SpaceUsedExcludingSelfLong() const

Computes (an estimate of) the total number of bytes currently used for storing the unknown fields in memory.

Does NOT include sizeof(*this) in the calculation.

-

const UnknownField &
    UnknownFieldSet::field(
        int index) const

Get a field in the set, where 0 <= index < field_count().

The fields appear in the order in which they were added.

-

UnknownField * UnknownFieldSet::mutable_field(
        int index)

Get a mutable pointer to a field in the set, where 0 <= index < field_count().

The fields appear in the order in which they were added.

-

static void UnknownFieldSet::MergeToInternalMetadata(
        const UnknownFieldSet & other,
        internal::InternalMetadata * metadata)

Merge the contents an UnknownFieldSet with the UnknownFieldSet in *metadata, if there is one.

If *metadata doesn't have an UnknownFieldSet then add one to it and make it be a copy of the first arg.

-

void UnknownFieldSet::DeleteSubrange(
        int start,
        int num)

Delete fields with indices in the range [start .

. start+num-1]. Caution: implementation moves all fields with indices [start+num .. ].

-

void UnknownFieldSet::DeleteByNumber(
        int number)

Delete all fields with a specific field number.

The order of left fields is preserved. Caution: implementation moves all fields after the first deleted field.

-

template bool UnknownFieldSet::MergeFromMessage(
        const MessageType & message)

Merges this message's unknown field data (if any).

This works whether the message is a lite or full proto (for legacy reasons, lite and full return different types for MessageType::unknown_fields()).

-

class UnknownField

#include <google/protobuf/unknown_field_set.h>
namespace google::protobuf

Represents one field in an UnknownFieldSet.

Members

enum
Type
uint64
varint_
uint32
fixed32_
uint64
fixed64_
union LengthDelimited
length_delimited_
UnknownFieldSet *
group_
int
number() const
The field's field number, as seen on the wire.
Type
type() const
The field type.

Accessors

Each method works only for UnknownFields of the corresponding type.
uint32
number_
uint32
type_
union google::protobuf::UnknownField::@35
data_
uint64
varint() const
uint32
fixed32() const
uint64
fixed64() const
const std::string &
length_delimited() const
const UnknownFieldSet &
group() const
void
set_varint(uint64 value)
void
set_fixed32(uint32 value)
void
set_fixed64(uint64 value)
void
set_length_delimited(const std::string & value)
std::string *
mutable_length_delimited()
UnknownFieldSet *
mutable_group()
void
SerializeLengthDelimitedNoTag(io::CodedOutputStream * output) const
Serialization API. more...
size_t
GetLengthDelimitedSize() const
uint8 *
InternalSerializeLengthDelimitedNoTag(uint8 * target, io::EpsCopyOutputStream * stream) const
void
Delete()
If this UnknownField contains a pointer, delete it.
void
DeepCopy(const UnknownField & other)
Make a deep copy of any pointers in this UnknownField.
void
SetType(Type type)
Set the wire type of this UnknownField. more...

enum UnknownField::Type {
  TYPE_VARINT,
  TYPE_FIXED32,
  TYPE_FIXED64,
  TYPE_LENGTH_DELIMITED,
  TYPE_GROUP
}

TYPE_VARINT
TYPE_FIXED32
TYPE_FIXED64
TYPE_LENGTH_DELIMITED
TYPE_GROUP

void UnknownField::SerializeLengthDelimitedNoTag(
        io::CodedOutputStream * output) const

Serialization API.

These methods can take advantage of the underlying implementation and may achieve a better performance than using getters to retrieve the data and do the serialization yourself.

-

void UnknownField::SetType(
        Type type)

Set the wire type of this UnknownField.

Should only be used when this UnknownField is being created.

-

union UnknownField::LengthDelimited

#include <google/protobuf/unknown_field_set.h>
namespace google::protobuf

Members

std::string *
string_value
diff --git a/content/reference/cpp/api-docs/google.protobuf.util.field_comparator.md b/content/reference/cpp/api-docs/google.protobuf.util.field_comparator.md deleted file mode 100644 index af327e911..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.util.field_comparator.md +++ /dev/null @@ -1,38 +0,0 @@ - - -+++ -title = "field_comparator.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/util/field_comparator.h>
namespace google::protobuf::util

Defines classes for field comparison.

Classes in this file

Base class specifying the interface for comparing protocol buffer fields.
Basic implementation of FieldComparator.

class FieldComparator

#include <google/protobuf/util/field_comparator.h>
namespace google::protobuf::util

Base class specifying the interface for comparing protocol buffer fields.

Regular users should consider using or subclassing DefaultFieldComparator rather than this interface. Currently, this does not support comparing unknown fields.

- -

Known subclasses:

Members

enum
ComparisonResult
FieldComparator()
virtual
~FieldComparator()
virtual ComparisonResult
Compare(const Message & message_1, const Message & message_2, const FieldDescriptor * field, int index_1, int index_2, const util::FieldContext * field_context) = 0
Compares the values of a field in two protocol buffer messages. more...

enum FieldComparator::ComparisonResult {
  SAME,
  DIFFERENT,
  RECURSE
}

SAME

Compared fields are equal.

In case of comparing submessages, user should not recursively compare their contents.

-
DIFFERENT

Compared fields are different.

In case of comparing submessages, user should not recursively compare their contents.

-
RECURSE

Compared submessages need to be compared recursively.

FieldComparator does not specify the semantics of recursive comparison. This value should not be returned for simple values.

-

virtual ComparisonResult FieldComparator::Compare(
        const Message & message_1,
        const Message & message_2,
        const FieldDescriptor * field,
        int index_1,
        int index_2,
        const util::FieldContext * field_context) = 0

Compares the values of a field in two protocol buffer messages.

Returns SAME or DIFFERENT for simple values, and SAME, DIFFERENT or RECURSE for submessages. Returning RECURSE for fields not being submessages is illegal. In case the given FieldDescriptor points to a repeated field, the indices need to be valid. Otherwise they should be ignored.

- -

FieldContext contains information about the specific instances of the fields being compared, versus FieldDescriptor which only contains general type information about the fields.

-

class SimpleFieldComparator: public FieldComparator

#include <google/protobuf/util/field_comparator.h>
namespace google::protobuf::util

Basic implementation of FieldComparator.

Supports three modes of floating point value comparison: exact, approximate using MathUtil::AlmostEqual method, and arbitrarily precise using MathUtil::WithinFractionOrMargin.

- -

Known subclasses:

Members

enum
FloatComparison
SimpleFieldComparator()
Creates new comparator with float comparison set to EXACT.
~SimpleFieldComparator()
void
set_float_comparison(FloatComparison float_comparison)
FloatComparison
float_comparison() const
void
set_treat_nan_as_equal(bool treat_nan_as_equal)
Set whether the FieldComparator shall treat floats or doubles that are both NaN as equal (treat_nan_as_equal = true) or as different (treat_nan_as_equal = false). more...
bool
treat_nan_as_equal() const
void
SetFractionAndMargin(const FieldDescriptor * field, double fraction, double margin)
Sets the fraction and margin for the float comparison of a given field. more...
void
SetDefaultFractionAndMargin(double fraction, double margin)
Sets the fraction and margin for the float comparison of all float and double fields, unless a field has been given a specific setting via SetFractionAndMargin() above. more...
protected ComparisonResult
SimpleCompare(const Message & message_1, const Message & message_2, const FieldDescriptor * field, int index_1, int index_2, const util::FieldContext * field_context)
Returns the comparison result for the given field in two messages. more...
protected bool
CompareWithDifferencer(MessageDifferencer * differencer, const Message & message1, const Message & message2, const util::FieldContext * field_context)
Compare using the provided message_differencer. more...
protected ComparisonResult
ResultFromBoolean(bool boolean_result) const
Returns FieldComparator::SAME if boolean_result is true and FieldComparator::DIFFERENT otherwise.

enum SimpleFieldComparator::FloatComparison {
  EXACT,
  APPROXIMATE
}

EXACTFloats and doubles are compared exactly.
APPROXIMATEFloats and doubles are compared using the MathUtil::AlmostEqual method or MathUtil::WithinFractionOrMargin method.

void SimpleFieldComparator::set_treat_nan_as_equal(
        bool treat_nan_as_equal)

Set whether the FieldComparator shall treat floats or doubles that are both NaN as equal (treat_nan_as_equal = true) or as different (treat_nan_as_equal = false).

Default is treating NaNs always as different.

-

void SimpleFieldComparator::SetFractionAndMargin(
        const FieldDescriptor * field,
        double fraction,
        double margin)

Sets the fraction and margin for the float comparison of a given field.

Uses MathUtil::WithinFractionOrMargin to compare the values.

- -

REQUIRES: field->cpp_type == FieldDescriptor::CPPTYPE_DOUBLE or

- -
field->cpp_type == FieldDescriptor::CPPTYPE_FLOAT
- -

REQUIRES: float_comparison_ == APPROXIMATE

-

void SimpleFieldComparator::SetDefaultFractionAndMargin(
        double fraction,
        double margin)

Sets the fraction and margin for the float comparison of all float and double fields, unless a field has been given a specific setting via SetFractionAndMargin() above.

Uses MathUtil::WithinFractionOrMargin to compare the values.

- -

REQUIRES: float_comparison_ == APPROXIMATE

-

protected ComparisonResult SimpleFieldComparator::SimpleCompare(
        const Message & message_1,
        const Message & message_2,
        const FieldDescriptor * field,
        int index_1,
        int index_2,
        const util::FieldContext * field_context)

Returns the comparison result for the given field in two messages.

This function is called directly by DefaultFieldComparator::Compare. Subclasses can call this function to compare fields they do not need to handle specially.

-

protected bool SimpleFieldComparator::CompareWithDifferencer(
        MessageDifferencer * differencer,
        const Message & message1,
        const Message & message2,
        const util::FieldContext * field_context)

Compare using the provided message_differencer.

For example, a subclass can use this method to compare some field in a certain way using the same message_differencer instance and the field context.

-

class DefaultFieldComparator: public SimpleFieldComparator

#include <google/protobuf/util/field_comparator.h>
namespace google::protobuf::util

Members

virtual ComparisonResult
Compare(const Message & message_1, const Message & message_2, const FieldDescriptor * field, int index_1, int index_2, const util::FieldContext * field_context)
Compares the values of a field in two protocol buffer messages. more...

virtual ComparisonResult DefaultFieldComparator::Compare(
        const Message & message_1,
        const Message & message_2,
        const FieldDescriptor * field,
        int index_1,
        int index_2,
        const util::FieldContext * field_context)

Compares the values of a field in two protocol buffer messages.

Returns SAME or DIFFERENT for simple values, and SAME, DIFFERENT or RECURSE for submessages. Returning RECURSE for fields not being submessages is illegal. In case the given FieldDescriptor points to a repeated field, the indices need to be valid. Otherwise they should be ignored.

- -

FieldContext contains information about the specific instances of the fields being compared, versus FieldDescriptor which only contains general type information about the fields.

- -
diff --git a/content/reference/cpp/api-docs/google.protobuf.util.field_mask_util.md b/content/reference/cpp/api-docs/google.protobuf.util.field_mask_util.md deleted file mode 100644 index 9b85ebf1b..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.util.field_mask_util.md +++ /dev/null @@ -1,28 +0,0 @@ -+++ -title = "field_mask_util.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/util/field_mask_util.h>
namespace google::protobuf::util

Defines utilities for the FieldMask well known type.

Classes in this file

class FieldMaskUtil

#include <google/protobuf/util/field_mask_util.h>
namespace google::protobuf::util

Members

static std::string
ToString(const FieldMask & mask)
Converts FieldMask to/from string, formatted by separating each path with a comma (e.g., "foo_bar,baz.quz").
static void
FromString(StringPiece str, FieldMask * out)
template static void
FromFieldNumbers(const std::vector< int64_t > & field_numbers, FieldMask * out)
Populates the FieldMask with the paths corresponding to the fields with the given numbers, after checking that all field numbers are valid.
static bool
ToJsonString(const FieldMask & mask, std::string * out)
Converts FieldMask to/from string, formatted according to proto3 JSON spec for FieldMask (e.g., "fooBar,baz.quz"). more...
static bool
FromJsonString(StringPiece str, FieldMask * out)
static bool
GetFieldDescriptors(const Descriptor * descriptor, StringPiece path, std::vector< const FieldDescriptor * > * field_descriptors)
Get the descriptors of the fields which the given path from the message descriptor traverses, if field_descriptors is not null. more...
template static bool
IsValidPath(StringPiece path)
Checks whether the given path is valid for type T.
template static bool
IsValidFieldMask(const FieldMask & mask)
Checks whether the given FieldMask is valid for type T.
template static void
AddPathToFieldMask(StringPiece path, FieldMask * mask)
Adds a path to FieldMask after checking whether the given path is valid. more...
template static FieldMask
GetFieldMaskForAllFields()
Creates a FieldMask with all fields of type T. more...
template static void
GetFieldMaskForAllFields(FieldMask * out)
static void
GetFieldMaskForAllFields(const Descriptor * descriptor, FieldMask * out)
This flavor takes the protobuf type descriptor as an argument. more...
static void
ToCanonicalForm(const FieldMask & mask, FieldMask * out)
Converts a FieldMask to the canonical form. more...
static void
Union(const FieldMask & mask1, const FieldMask & mask2, FieldMask * out)
Creates an union of two FieldMasks.
static void
Intersect(const FieldMask & mask1, const FieldMask & mask2, FieldMask * out)
Creates an intersection of two FieldMasks.
template static void
Subtract(const FieldMask & mask1, const FieldMask & mask2, FieldMask * out)
Subtracts mask2 from mask1 base of type T.
static void
Subtract(const Descriptor * descriptor, const FieldMask & mask1, const FieldMask & mask2, FieldMask * out)
This flavor takes the protobuf type descriptor as an argument. more...
static bool
IsPathInFieldMask(StringPiece path, const FieldMask & mask)
Returns true if path is covered by the given FieldMask. more...
static void
MergeMessageTo(const Message & source, const FieldMask & mask, const MergeOptions & options, Message * destination)
Merges fields specified in a FieldMask into another message.
static bool
TrimMessage(const FieldMask & mask, Message * message)
Removes from 'message' any field that is not represented in the given FieldMask. more...
static bool
TrimMessage(const FieldMask & mask, Message * message, const TrimOptions & options)
Removes from 'message' any field that is not represented in the given FieldMask with customized TrimOptions. more...

static bool FieldMaskUtil::ToJsonString(
        const FieldMask & mask,
        std::string * out)

Converts FieldMask to/from string, formatted according to proto3 JSON spec for FieldMask (e.g., "fooBar,baz.quz").

If the field name is not style conforming (i.e., not snake_case when converted to string, or not camelCase when converted from string), the conversion will fail.

-

static bool FieldMaskUtil::GetFieldDescriptors(
        const Descriptor * descriptor,
        StringPiece path,
        std::vector< const FieldDescriptor * > * field_descriptors)

Get the descriptors of the fields which the given path from the message descriptor traverses, if field_descriptors is not null.

Return false if the path is not valid, and the content of field_descriptors is unspecified.

-

template static void FieldMaskUtil::AddPathToFieldMask(
        StringPiece path,
        FieldMask * mask)

Adds a path to FieldMask after checking whether the given path is valid.

This method check-fails if the path is not a valid path for type T.

-

template static FieldMask FieldMaskUtil::GetFieldMaskForAllFields()

Creates a FieldMask with all fields of type T.

This FieldMask only contains fields of T but not any sub-message fields.

-

static void FieldMaskUtil::GetFieldMaskForAllFields(
        const Descriptor * descriptor,
        FieldMask * out)

This flavor takes the protobuf type descriptor as an argument.

Useful when the type is not known at compile time.

-

static void FieldMaskUtil::ToCanonicalForm(
        const FieldMask & mask,
        FieldMask * out)

Converts a FieldMask to the canonical form.

It will:

- -
1. Remove paths that are covered by another path. For example,
-   "foo.bar" is covered by "foo" and will be removed if "foo"
-   is also in the FieldMask.
-2. Sort all paths in alphabetical order.
- -

static void FieldMaskUtil::Subtract(
        const Descriptor * descriptor,
        const FieldMask & mask1,
        const FieldMask & mask2,
        FieldMask * out)

This flavor takes the protobuf type descriptor as an argument.

Useful when the type is not known at compile time.

-

static bool FieldMaskUtil::IsPathInFieldMask(
        StringPiece path,
        const FieldMask & mask)

Returns true if path is covered by the given FieldMask.

Note that path "foo.bar" covers all paths like "foo.bar.baz", "foo.bar.quz.x", etc. Also note that parent paths are not covered by explicit child path, i.e. "foo.bar" does NOT cover "foo", even if "bar" is the only child.

-

static bool FieldMaskUtil::TrimMessage(
        const FieldMask & mask,
        Message * message)

Removes from 'message' any field that is not represented in the given FieldMask.

If the FieldMask is empty, does nothing. Returns true if the message is modified.

-

static bool FieldMaskUtil::TrimMessage(
        const FieldMask & mask,
        Message * message,
        const TrimOptions & options)

Removes from 'message' any field that is not represented in the given FieldMask with customized TrimOptions.

If the FieldMask is empty, does nothing. Returns true if the message is modified.

-

class FieldMaskUtil::MergeOptions

#include <google/protobuf/util/field_mask_util.h>
namespace google::protobuf::util

Members

MergeOptions()
void
set_replace_message_fields(bool value)
When merging message fields, the default behavior is to merge the content of two message fields together. more...
bool
replace_message_fields() const
void
set_replace_repeated_fields(bool value)
The default merging behavior will append entries from the source repeated field to the destination repeated field. more...
bool
replace_repeated_fields() const

void MergeOptions::set_replace_message_fields(
        bool value)

When merging message fields, the default behavior is to merge the content of two message fields together.

If you instead want to use the field from the source message to replace the corresponding field in the destination message, set this flag to true. When this flag is set, specified submessage fields that are missing in source will be cleared in destination.

-

void MergeOptions::set_replace_repeated_fields(
        bool value)

The default merging behavior will append entries from the source repeated field to the destination repeated field.

If you only want to keep the entries from the source repeated field, set this flag to true.

-

class FieldMaskUtil::TrimOptions

#include <google/protobuf/util/field_mask_util.h>
namespace google::protobuf::util

Members

TrimOptions()
void
set_keep_required_fields(bool value)
When trimming message fields, the default behavior is to trim required fields of the present message if they are not specified in the field mask. more...
bool
keep_required_fields() const

void TrimOptions::set_keep_required_fields(
        bool value)

When trimming message fields, the default behavior is to trim required fields of the present message if they are not specified in the field mask.

If you instead want to keep required fields of the present message even they are not specified in the field mask, set this flag to true.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.util.json_util.md b/content/reference/cpp/api-docs/google.protobuf.util.json_util.md deleted file mode 100644 index 2e16994af..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.util.json_util.md +++ /dev/null @@ -1,27 +0,0 @@ -+++ -title = "json_util.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/util/json_util.h>
namespace google::protobuf::util

Utility functions to convert between protobuf binary format and proto3 JSON format.

Classes in this file

File Members

These definitions are not part of any class.
typedef
JsonPrintOptions JsonOptions
DEPRECATED. Use JsonPrintOptions instead.
util::Status
MessageToJsonString(const Message & message, std::string * output, const JsonOptions & options)
Converts from protobuf message to JSON and appends it to |output|. more...
util::Status
MessageToJsonString(const Message & message, std::string * output)
util::Status
JsonStringToMessage(StringPiece input, Message * message, const JsonParseOptions & options)
Converts from JSON to protobuf message. more...
util::Status
JsonStringToMessage(StringPiece input, Message * message)
util::Status
BinaryToJsonStream(TypeResolver * resolver, const std::string & type_url, io::ZeroCopyInputStream * binary_input, io::ZeroCopyOutputStream * json_output, const JsonPrintOptions & options)
Converts protobuf binary data to JSON. more...
util::Status
BinaryToJsonStream(TypeResolver * resolver, const std::string & type_url, io::ZeroCopyInputStream * binary_input, io::ZeroCopyOutputStream * json_output)
util::Status
BinaryToJsonString(TypeResolver * resolver, const std::string & type_url, const std::string & binary_input, std::string * json_output, const JsonPrintOptions & options)
util::Status
BinaryToJsonString(TypeResolver * resolver, const std::string & type_url, const std::string & binary_input, std::string * json_output)
util::Status
JsonToBinaryStream(TypeResolver * resolver, const std::string & type_url, io::ZeroCopyInputStream * json_input, io::ZeroCopyOutputStream * binary_output, const JsonParseOptions & options)
Converts JSON data to protobuf binary format. more...
util::Status
JsonToBinaryStream(TypeResolver * resolver, const std::string & type_url, io::ZeroCopyInputStream * json_input, io::ZeroCopyOutputStream * binary_output)
util::Status
JsonToBinaryString(TypeResolver * resolver, const std::string & type_url, StringPiece json_input, std::string * binary_output, const JsonParseOptions & options)
util::Status
JsonToBinaryString(TypeResolver * resolver, const std::string & type_url, StringPiece json_input, std::string * binary_output)

util::Status util::MessageToJsonString(
        const Message & message,
        std::string * output,
        const JsonOptions & options)

Converts from protobuf message to JSON and appends it to |output|.

This is a simple wrapper of BinaryToJsonString(). It will use the DescriptorPool of the passed-in message to resolve Any types.

-

util::Status util::JsonStringToMessage(
        StringPiece input,
        Message * message,
        const JsonParseOptions & options)

Converts from JSON to protobuf message.

This is a simple wrapper of JsonStringToBinary(). It will use the DescriptorPool of the passed-in message to resolve Any types.

-

util::Status util::BinaryToJsonStream(
        TypeResolver * resolver,
        const std::string & type_url,
        io::ZeroCopyInputStream * binary_input,
        io::ZeroCopyOutputStream * json_output,
        const JsonPrintOptions & options)

Converts protobuf binary data to JSON.

The conversion will fail if:

- -
1. TypeResolver fails to resolve a type.
-2. input is not valid protobuf wire format, or conflicts with the type
-   information returned by TypeResolver.
- -

Note that unknown fields will be discarded silently.

-

util::Status util::JsonToBinaryStream(
        TypeResolver * resolver,
        const std::string & type_url,
        io::ZeroCopyInputStream * json_input,
        io::ZeroCopyOutputStream * binary_output,
        const JsonParseOptions & options)

Converts JSON data to protobuf binary format.

The conversion will fail if:

- -
1. TypeResolver fails to resolve a type.
-2. input is not valid JSON format, or conflicts with the type
-   information returned by TypeResolver.
- -

struct JsonParseOptions

#include <google/protobuf/util/json_util.h>
namespace google::protobuf::util

Members

bool
ignore_unknown_fields
Whether to ignore unknown JSON fields during parsing.
bool
case_insensitive_enum_parsing
If true, when a lowercase enum value fails to parse, try convert it to UPPER_CASE and see if it matches a valid enum. more...
JsonParseOptions()

bool JsonParseOptions::case_insensitive_enum_parsing

If true, when a lowercase enum value fails to parse, try convert it to UPPER_CASE and see if it matches a valid enum.

WARNING: This option exists only to preserve legacy behavior. Avoid using this option. If your enum needs to support different casing, consider using allow_alias instead.

-

struct JsonPrintOptions

#include <google/protobuf/util/json_util.h>
namespace google::protobuf::util

Members

bool
add_whitespace
Whether to add spaces, line breaks and indentation to make the JSON output easy to read.
bool
always_print_primitive_fields
Whether to always print primitive fields. more...
bool
always_print_enums_as_ints
Whether to always print enums as ints. more...
bool
preserve_proto_field_names
Whether to preserve proto field names.
JsonPrintOptions()

bool JsonPrintOptions::always_print_primitive_fields

Whether to always print primitive fields.

By default proto3 primitive fields with default values will be omitted in JSON output. For example, an int32 field set to 0 will be omitted. Set this flag to true will override the default behavior and print primitive fields regardless of their values.

-

bool JsonPrintOptions::always_print_enums_as_ints

Whether to always print enums as ints.

By default they are rendered as strings.

-
diff --git a/content/reference/cpp/api-docs/google.protobuf.util.message_differencer.md b/content/reference/cpp/api-docs/google.protobuf.util.message_differencer.md deleted file mode 100644 index baaa1a7d1..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.util.message_differencer.md +++ /dev/null @@ -1,116 +0,0 @@ - - -+++ -title = "message_differencer.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

This file defines static methods and classes for comparing Protocol Messages.

Aug. 2008: Added Unknown Fields Comparison for messages. Aug. 2009: Added different options to compare repeated fields. Apr. 2010: Moved field comparison to FieldComparator Sep. 2020: Added option to output map keys in path

- -

Classes in this file

A basic differencer that can be used to determine the differences between two specified Protocol Messages.
Abstract base class from which all IgnoreCriteria derive.
MapKeyComparator is used to determine if two elements have the same key when comparing elements of a repeated field as a map.
Abstract base class from which all MessageDifferencer reporters derive.
Identifies an individual field in a message instance.
An implementation of the MessageDifferencer Reporter that outputs any differences found in human-readable form to the supplied ZeroCopyOutputStream or Printer.
Class for processing Any deserialization.
This class provides extra information to the FieldComparator::Compare function.

File Members

These definitions are not part of any class.
typedef
std::vector< const FieldDescriptor * > FieldDescriptorArray
Defines a collection of field descriptors. more...

typedef util::FieldDescriptorArray

Defines a collection of field descriptors.

In case of internal google codebase we are using absl::FixedArray instead of vector. It significantly speeds up proto comparison (by ~30%) by reducing the number of malloc/free operations

-

class MessageDifferencer

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

A basic differencer that can be used to determine the differences between two specified Protocol Messages.

If any differences are found, the Compare method will return false, and any differencer reporter specified via ReportDifferencesTo will have its reporting methods called (see below for implementation of the report). Based off of the original ProtocolDifferencer implementation in //net/proto/protocol-differencer.h (Thanks Todd!).

-

MessageDifferencer REQUIRES that compared messages be the same type, defined as messages that share the same descriptor. If not, the behavior of this class is undefined.

-

People disagree on what MessageDifferencer should do when asked to compare messages with different descriptors. Some people think it should always return false. Others expect it to try to look for similar fields and compare them anyway – especially if the descriptors happen to be identical. If we chose either of these behaviors, some set of people would find it surprising, and could end up writing code expecting the other behavior without realizing their error. Therefore, we forbid that usage.

-

This class is implemented based on the proto2 reflection. The performance should be good enough for normal usages. However, for places where the performance is extremely sensitive, there are several alternatives:

-
    -
  • Comparing serialized string Downside: false negatives (there are messages that are the same but their serialized strings are different).
  • -
  • Equals code generator by compiler plugin (net/proto2/contrib/equals_plugin) Downside: more generated code; maintenance overhead for the additional rule (must be in sync with the original proto_library).
  • -
-

Note on handling of google.protobuf.Any: MessageDifferencer automatically unpacks Any::value into a Message and compares its individual fields. Messages encoded in a repeated Any cannot be compared using TreatAsMap.

-

Note on thread-safety: MessageDifferencer is not thread-safe. You need to guard it with a lock to use the same MessageDifferencer instance from multiple threads. Note that it's fine to call static comparison methods (like MessageDifferencer::Equals) concurrently, but it's not recommended for performance critical code as it leads to extra allocations.

-

Members

enum
MessageFieldComparison
enum
Scope
enum
FloatComparison
DEPRECATED. Use FieldComparator::FloatComparison instead. more...
enum
RepeatedFieldComparison
DefaultFieldComparator *
default_impl
FieldComparator *
base
static bool
Equals(const Message & message1, const Message & message2)
Determines whether the supplied messages are equal. more...
static bool
Equivalent(const Message & message1, const Message & message2)
Determines whether the supplied messages are equivalent. more...
static bool
ApproximatelyEquals(const Message & message1, const Message & message2)
Determines whether the supplied messages are approximately equal. more...
static bool
ApproximatelyEquivalent(const Message & message1, const Message & message2)
Determines whether the supplied messages are approximately equivalent. more...
explicit
MessageDifferencer()
To add a Reporter, construct default here, then use ReportDifferencesTo or ReportDifferencesToString.
~MessageDifferencer()
void
TreatAsSet(const FieldDescriptor * field)
The elements of the given repeated field will be treated as a set for diffing purposes, so different orderings of the same elements will be considered equal. more...
void
TreatAsSmartSet(const FieldDescriptor * field)
void
TreatAsList(const FieldDescriptor * field)
The elements of the given repeated field will be treated as a list for diffing purposes, so different orderings of the same elements will NOT be considered equal. more...
void
TreatAsSmartList(const FieldDescriptor * field)
Note that the complexity is similar to treating as SET.
void
TreatAsMap(const FieldDescriptor * field, const FieldDescriptor * key)
The elements of the given repeated field will be treated as a map for diffing purposes, with |key| being the map key. more...
void
TreatAsMapWithMultipleFieldsAsKey(const FieldDescriptor * field, const std::vector< const FieldDescriptor * > & key_fields)
Same as TreatAsMap except that this method will use multiple fields as the key in comparison. more...
void
TreatAsMapWithMultipleFieldPathsAsKey(const FieldDescriptor * field, const std::vector< std::vector< const FieldDescriptor * > > & key_field_paths)
Same as TreatAsMapWithMultipleFieldsAsKey, except that each of the field do not necessarily need to be a direct subfield. more...
void
TreatAsMapUsingKeyComparator(const FieldDescriptor * field, const MapKeyComparator * key_comparator)
Uses a custom MapKeyComparator to determine if two elements have the same key when comparing a repeated field as a map. more...
MapKeyComparator *
CreateMultipleFieldsMapKeyComparator(const std::vector< std::vector< const FieldDescriptor * > > & key_field_paths)
Initiates and returns a new instance of MultipleFieldsMapKeyComparator.
void
AddIgnoreCriteria(IgnoreCriteria * ignore_criteria)
Add a custom ignore criteria that is evaluated in addition to the ignored fields added with IgnoreField. more...
void
IgnoreField(const FieldDescriptor * field)
Indicates that any field with the given descriptor should be ignored for the purposes of comparing two messages. more...
void
set_field_comparator(FieldComparator * comparator)
Sets the field comparator used to determine differences between protocol buffer fields. more...
void
SetFractionAndMargin(const FieldDescriptor * field, double fraction, double margin)
DEPRECATED. more...
void
set_message_field_comparison(MessageFieldComparison comparison)
Sets the type of comparison (as defined in the MessageFieldComparison enumeration above) that is used by this differencer when determining how to compare fields in messages.
void
set_report_matches(bool report_matches)
Tells the differencer whether or not to report matches. more...
void
set_report_moves(bool report_moves)
Tells the differencer whether or not to report moves (in a set or map repeated field). more...
void
set_report_ignores(bool report_ignores)
Tells the differencer whether or not to report ignored values. more...
void
set_scope(Scope scope)
Sets the scope of the comparison (as defined in the Scope enumeration above) that is used by this differencer when determining which fields to compare between the messages.
Scope
scope()
Returns the current scope used by this differencer.
void
set_float_comparison(FloatComparison comparison)
DEPRECATED. more...
void
set_repeated_field_comparison(RepeatedFieldComparison comparison)
Sets the type of comparison for repeated field (as defined in the RepeatedFieldComparison enumeration above) that is used by this differencer when compare repeated fields in messages.
RepeatedFieldComparison
repeated_field_comparison()
Returns the current repeated field comparison used by this differencer.
bool
Compare(const Message & message1, const Message & message2)
Compares the two specified messages, returning true if they are the same, false otherwise. more...
bool
CompareWithFields(const Message & message1, const Message & message2, const std::vector< const FieldDescriptor * > & message1_fields, const std::vector< const FieldDescriptor * > & message2_fields)
Same as above, except comparing only the list of fields specified by the two vectors of FieldDescriptors.
void
ReportDifferencesToString(std::string * output)
Automatically creates a reporter that will output the differences found (if any) to the specified output string pointer. more...
void
ReportDifferencesTo(Reporter * reporter)
Tells the MessageDifferencer to report differences via the specified reporter. more...

enum MessageDifferencer::MessageFieldComparison {
  EQUAL,
  EQUIVALENT
}

EQUALFields must be present in both messages for the messages to be considered the same.
EQUIVALENT

Fields with default values are considered set for comparison purposes even if not explicitly set in the messages themselves.

Unknown fields are ignored.

-

enum MessageDifferencer::Scope {
  FULL,
  PARTIAL
}

FULLAll fields of both messages are considered in the comparison.
PARTIALOnly fields present in the first message are considered; fields set only in the second message will be skipped during comparison.

enum MessageDifferencer::FloatComparison {
  EXACT,
  APPROXIMATE
}

DEPRECATED. Use FieldComparator::FloatComparison instead.

EXACTFloats and doubles are compared exactly.
APPROXIMATEFloats and doubles are compared using the MathUtil::AlmostEquals method.

enum MessageDifferencer::RepeatedFieldComparison {
  AS_LIST,
  AS_SET,
  AS_SMART_LIST,
  AS_SMART_SET
}

AS_LIST

Repeated fields are compared in order.

Differing values at the same index are reported using ReportModified(). If the repeated fields have different numbers of elements, the unpaired elements are reported using ReportAdded() or ReportDeleted().

-
AS_SET

Treat all the repeated fields as sets.

See TreatAsSet(), as below.

-
AS_SMART_LIST

Similar to AS_SET, but preserve the order and find the longest matching sequence from the first matching element.

To use an optimal solution, call SetMatchIndicesForSmartListCallback() to pass it in.

-
AS_SMART_SETSimilar to AS_SET, but match elements with fewest diffs.

static bool MessageDifferencer::Equals(
        const Message & message1,
        const Message & message2)

Determines whether the supplied messages are equal.

Equality is defined as all fields within the two messages being set to the same value. Primitive fields and strings are compared by value while embedded messages/groups are compared as if via a recursive call. Use Compare() with IgnoreField() if some fields should be ignored in the comparison. Use Compare() with TreatAsSet() if there are repeated fields where ordering does not matter.

-

This method REQUIRES that the two messages have the same Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).

-

static bool MessageDifferencer::Equivalent(
        const Message & message1,
        const Message & message2)

Determines whether the supplied messages are equivalent.

Equivalency is defined as all fields within the two messages having the same value. This differs from the Equals method above in that fields with default values are considered set to said value automatically. For details on how default values are defined for each field type, see: static bool MessageDifferencer::ApproximatelyEquals(
        const
Message & message1,
        const Message & message2)

Determines whether the supplied messages are approximately equal.

Approximate equality is defined as all fields within the two messages being approximately equal. Primitive (non-float) fields and strings are compared by value, floats are compared using MathUtil::AlmostEquals() and embedded messages/groups are compared as if via a recursive call. Use IgnoreField() and Compare() if some fields should be ignored in the comparison.

-

This method REQUIRES that the two messages have the same Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).

-

static bool MessageDifferencer::ApproximatelyEquivalent(
        const Message & message1,
        const Message & message2)

Determines whether the supplied messages are approximately equivalent.

Approximate equivalency is defined as all fields within the two messages being approximately equivalent. As in MessageDifferencer::ApproximatelyEquals, primitive (non-float) fields and strings are compared by value, floats are compared using MathUtil::AlmostEquals() and embedded messages/groups are compared as if via a recursive call. However, fields with default values are considered set to said value, as per MessageDiffencer::Equivalent. Use IgnoreField() and Compare() if some fields should be ignored in the comparison.

-

This method REQUIRES that the two messages have the same Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).

-

void MessageDifferencer::TreatAsSet(
        const FieldDescriptor * field)

The elements of the given repeated field will be treated as a set for diffing purposes, so different orderings of the same elements will be considered equal.

Elements which are present on both sides of the comparison but which have changed position will be reported with ReportMoved(). Elements which only exist on one side or the other are reported with ReportAdded() and ReportDeleted() regardless of their positions. ReportModified() is never used for this repeated field. If the only differences between the compared messages is that some fields have been moved, then the comparison returns true.

-

Note that despite the name of this method, this is really comparison as multisets: if one side of the comparison has a duplicate in the repeated field but the other side doesn't, this will count as a mismatch.

-

If the scope of comparison is set to PARTIAL, then in addition to what's above, extra values added to repeated fields of the second message will not cause the comparison to fail.

-

Note that set comparison is currently O(k * n^2) (where n is the total number of elements, and k is the average size of each element). In theory it could be made O(n * k) with a more complex hashing implementation. Feel free to contribute one if the current implementation is too slow for you. If partial matching is also enabled, the time complexity will be O(k * n^2

-
    -
  • n^3) in which n^3 is the time complexity of the maximum matching algorithm.
  • -
-

REQUIRES: field->is_repeated() and field not registered with TreatAsMap*

-

void MessageDifferencer::TreatAsList(
        const FieldDescriptor * field)

The elements of the given repeated field will be treated as a list for diffing purposes, so different orderings of the same elements will NOT be considered equal.

REQUIRES: field->is_repeated() and field not registered with TreatAsMap*

-

void MessageDifferencer::TreatAsMap(
        const FieldDescriptor * field,
        const FieldDescriptor * key)

The elements of the given repeated field will be treated as a map for diffing purposes, with |key| being the map key.

Thus, elements with the same key will be compared even if they do not appear at the same index. Differences are reported similarly to TreatAsSet(), except that ReportModified() is used to report elements with the same key but different values. Note that if an element is both moved and modified, only ReportModified() will be called. As with TreatAsSet, if the only differences between the compared messages is that some fields have been moved, then the comparison returns true. See TreatAsSet for notes on performance.

-

REQUIRES: field->is_repeated() REQUIRES: field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE REQUIRES: key->containing_type() == field->message_type()

-

void MessageDifferencer::TreatAsMapWithMultipleFieldsAsKey(
        const FieldDescriptor * field,
        const std::vector< const FieldDescriptor * > & key_fields)

Same as TreatAsMap except that this method will use multiple fields as the key in comparison.

All specified fields in 'key_fields' should be present in the compared elements. Two elements will be treated as having the same key iff they have the same value for every specified field. There are two steps in the comparison process. The first one is key matching. Every element from one message will be compared to every element from the other message. Only fields in 'key_fields' are compared in this step to decide if two elements have the same key. The second step is value comparison. Those pairs of elements with the same key (with equal value for every field in 'key_fields') will be compared in this step. Time complexity of the first step is O(s * m * n ^ 2) where s is the average size of the fields specified in 'key_fields', m is the number of fields in 'key_fields' and n is the number of elements. If partial matching is enabled, an extra O(n^3) will be incured by the maximum matching algorithm. The second step is O(k * n) where k is the average size of each element.

-

void MessageDifferencer::TreatAsMapWithMultipleFieldPathsAsKey(
        const FieldDescriptor * field,
        const std::vector< std::vector< const FieldDescriptor * > > & key_field_paths)

Same as TreatAsMapWithMultipleFieldsAsKey, except that each of the field do not necessarily need to be a direct subfield.

Each element in key_field_paths indicate a path from the message being compared, listing successive subfield to reach the key field.

-

REQUIRES:

-
for key_field_path in key_field_paths:
-  key_field_path[0]->containing_type() == field->message_type()
-  for i in [0, key_field_path.size() - 1):
-    key_field_path[i+1]->containing_type() ==
-        key_field_path[i]->message_type()
-    key_field_path[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
-    !key_field_path[i]->is_repeated()
-

void MessageDifferencer::TreatAsMapUsingKeyComparator(
        const FieldDescriptor * field,
        const MapKeyComparator * key_comparator)

Uses a custom MapKeyComparator to determine if two elements have the same key when comparing a repeated field as a map.

The caller is responsible to delete the key_comparator. This method varies from TreatAsMapWithMultipleFieldsAsKey only in the first key matching step. Rather than comparing some specified fields, it will invoke the IsMatch method of the given 'key_comparator' to decide if two elements have the same key.

-

void MessageDifferencer::AddIgnoreCriteria(
        IgnoreCriteria * ignore_criteria)

Add a custom ignore criteria that is evaluated in addition to the ignored fields added with IgnoreField.

Takes ownership of ignore_criteria.

-

void MessageDifferencer::IgnoreField(
        const FieldDescriptor * field)

Indicates that any field with the given descriptor should be ignored for the purposes of comparing two messages.

This applies to fields nested in the message structure as well as top level ones. When the MessageDifferencer encounters an ignored field, ReportIgnored is called on the reporter, if one is specified.

-

The only place where the field's 'ignored' status is not applied is when it is being used as a key in a field passed to TreatAsMap or is one of the fields passed to TreatAsMapWithMultipleFieldsAsKey. In this case it is compared in key matching but after that it's ignored in value comparison.

-

void MessageDifferencer::set_field_comparator(
        FieldComparator * comparator)

Sets the field comparator used to determine differences between protocol buffer fields.

By default it's set to a DefaultFieldComparator instance. MessageDifferencer doesn't take ownership over the passed object. Note that this method must be called before Compare for the comparator to be used.

-

void MessageDifferencer::SetFractionAndMargin(
        const FieldDescriptor * field,
        double fraction,
        double margin)

DEPRECATED.

Pass a DefaultFieldComparator instance instead. Sets the fraction and margin for the float comparison of a given field. Uses MathUtil::WithinFractionOrMargin to compare the values. NOTE: this method does nothing if differencer's field comparator has been

-
set to a custom object.
-

REQUIRES: field->cpp_type == FieldDescriptor::CPPTYPE_DOUBLE or

-
field->cpp_type == FieldDescriptor::CPPTYPE_FLOAT
-

REQUIRES: float_comparison_ == APPROXIMATE

-

void MessageDifferencer::set_report_matches(
        bool report_matches)

Tells the differencer whether or not to report matches.

This method must be called before Compare. The default for a new differencer is false.

-

void MessageDifferencer::set_report_moves(
        bool report_moves)

Tells the differencer whether or not to report moves (in a set or map repeated field).

This method must be called before Compare. The default for a new differencer is true.

-

void MessageDifferencer::set_report_ignores(
        bool report_ignores)

Tells the differencer whether or not to report ignored values.

This method must be called before Compare. The default for a new differencer is true.

-

void MessageDifferencer::set_float_comparison(
        FloatComparison comparison)

DEPRECATED.

Pass a DefaultFieldComparator instance instead. Sets the type of comparison (as defined in the FloatComparison enumeration above) that is used by this differencer when comparing float (and double) fields in messages. NOTE: this method does nothing if differencer's field comparator has been

-
set to a custom object.
-

bool MessageDifferencer::Compare(
        const Message & message1,
        const Message & message2)

Compares the two specified messages, returning true if they are the same, false otherwise.

If this method returns false, any changes between the two messages will be reported if a Reporter was specified via ReportDifferencesTo (see also ReportDifferencesToString).

-

This method REQUIRES that the two messages have the same Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).

-

void MessageDifferencer::ReportDifferencesToString(
        std::string * output)

Automatically creates a reporter that will output the differences found (if any) to the specified output string pointer.

Note that this method must be called before Compare.

-

void MessageDifferencer::ReportDifferencesTo(
        Reporter * reporter)

Tells the MessageDifferencer to report differences via the specified reporter.

Note that this method must be called before Compare for the reporter to be used. It is the responsibility of the caller to delete this object. If the provided pointer equals NULL, the MessageDifferencer stops reporting differences to any previously set reporters or output strings.

-

class MessageDifferencer::IgnoreCriteria

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

Abstract base class from which all IgnoreCriteria derive.

By adding IgnoreCriteria more complex ignore logic can be implemented. IgnoreCriteria are registered with AddIgnoreCriteria. For each compared field IsIgnored is called on each added IgnoreCriteria until one returns true or all return false. IsIgnored is called for fields where at least one side has a value.

-

Members

IgnoreCriteria()
virtual
~IgnoreCriteria()
virtual bool
IsIgnored(const Message & , const Message & , const FieldDescriptor * , const std::vector< SpecificField > & ) = 0
Returns true if the field should be ignored.
virtual bool
IsUnknownFieldIgnored(const Message & , const Message & , const SpecificField & , const std::vector< SpecificField > & )
Returns true if the unknown field should be ignored. more...

virtual bool IgnoreCriteria::IsUnknownFieldIgnored(
        const Message & ,
        const Message & ,
        const SpecificField & ,
        const std::vector< SpecificField > & )

Returns true if the unknown field should be ignored.

Note: This will be called for unknown fields as well in which case

-
field.field will be null.
-

class MessageDifferencer::MapKeyComparator

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

MapKeyComparator is used to determine if two elements have the same key when comparing elements of a repeated field as a map.

Members

MapKeyComparator()
virtual
~MapKeyComparator()
virtual bool
IsMatch(const Message & , const Message & , const std::vector< SpecificField > & ) const

class MessageDifferencer::Reporter

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

Abstract base class from which all MessageDifferencer reporters derive.

The five Report* methods below will be called when a field has been added, deleted, modified, moved, or matched. The third argument is a vector of FieldDescriptor pointers which describes the chain of fields that was taken to find the current field. For example, for a field found in an embedded message, the vector will contain two FieldDescriptors. The first will be the field of the embedded message itself and the second will be the actual field in the embedded message that was added/deleted/modified. Fields will be reported in PostTraversalOrder. For example, given the following proto, if both baz and mooo are changed. -

foo {
-  bar {
-    baz: 1
-    mooo: 2
-  }
-}
-

ReportModified will be invoked with following order:

-
    -
  1. foo.bar.baz or foo.bar.mooo
  2. -
  3. foo.bar.mooo or foo.bar.baz
  4. -
  5. foo.bar
  6. -
  7. foo
  8. -
-

Known subclasses:

Members

Reporter()
virtual
~Reporter()
virtual void
ReportAdded(const Message & message1, const Message & message2, const std::vector< SpecificField > & field_path) = 0
Reports that a field has been added into Message2.
virtual void
ReportDeleted(const Message & message1, const Message & message2, const std::vector< SpecificField > & field_path) = 0
Reports that a field has been deleted from Message1.
virtual void
ReportModified(const Message & message1, const Message & message2, const std::vector< SpecificField > & field_path) = 0
Reports that the value of a field has been modified.
virtual void
ReportMoved(const Message & , const Message & , const std::vector< SpecificField > & )
Reports that a repeated field has been moved to another location. more...
virtual void
ReportMatched(const Message & , const Message & , const std::vector< SpecificField > & )
Reports that two fields match. more...
virtual void
ReportIgnored(const Message & , const Message & , const std::vector< SpecificField > & )
Reports that two fields would have been compared, but the comparison has been skipped because the field was marked as 'ignored' using IgnoreField(). more...
virtual void
ReportUnknownFieldIgnored(const Message & , const Message & , const std::vector< SpecificField > & )
Report that an unknown field is ignored. more...

virtual void Reporter::ReportMoved(
        const Message & ,
        const Message & ,
        const std::vector< SpecificField > & )

Reports that a repeated field has been moved to another location.

This only applies when using TreatAsSet or TreatAsMap() – see below. Also note that for any given field, ReportModified and ReportMoved are mutually exclusive. If a field has been both moved and modified, then only ReportModified will be called.

-

virtual void Reporter::ReportMatched(
        const Message & ,
        const Message & ,
        const std::vector< SpecificField > & )

Reports that two fields match.

Useful for doing side-by-side diffs. This function is mutually exclusive with ReportModified and ReportMoved. Note that you must call set_report_matches(true) before calling Compare to make use of this function.

-

virtual void Reporter::ReportIgnored(
        const Message & ,
        const Message & ,
        const std::vector< SpecificField > & )

Reports that two fields would have been compared, but the comparison has been skipped because the field was marked as 'ignored' using IgnoreField().

This function is mutually exclusive with all the other Report() functions.

-

The contract of ReportIgnored is slightly different than the other Report() functions, in that |field_path.back().index| is always equal to -1, even if the last field is repeated. This is because while the other Report() functions indicate where in a repeated field the action (Addition, Deletion, etc...) happened, when a repeated field is 'ignored', the differencer simply calls ReportIgnored on the repeated field as a whole and moves on without looking at its individual elements.

-

Furthermore, ReportIgnored() does not indicate whether the fields were in fact equal or not, as Compare() does not inspect these fields at all. It is up to the Reporter to decide whether the fields are equal or not (perhaps with a second call to Compare()), if it cares.

-

virtual void Reporter::ReportUnknownFieldIgnored(
        const Message & ,
        const Message & ,
        const std::vector< SpecificField > & )

Report that an unknown field is ignored.

(see comment above). Note this is a different function since the last SpecificField in field path has a null field. This could break existing Reporter.

-

struct MessageDifferencer::SpecificField

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

Identifies an individual field in a message instance.

Used for field_path, below.

-

Members

const FieldDescriptor *
field = = nullptr
For known fields, "field" is filled in and "unknown_field_number" is -1. more...
int
unknown_field_number = = -1
UnknownField::Type
unknown_field_type = = UnknownField::Type::TYPE_VARINT
int
index = = -1
If this a repeated field, "index" is the index within it. more...
int
new_index = = -1
If "field" is a repeated field which is being treated as a map or a set (see TreatAsMap() and TreatAsSet(), below), new_index indicates the index the position to which the element has moved. more...
const UnknownFieldSet *
unknown_field_set1 = = nullptr
For unknown fields, these are the pointers to the UnknownFieldSet containing the unknown fields. more...
const UnknownFieldSet *
unknown_field_set2 = = nullptr
int
unknown_field_index1 = = -1
For unknown fields, these are the index of the field within the UnknownFieldSets. more...
int
unknown_field_index2 = = -1

const FieldDescriptor * SpecificField::field = = nullptr

For known fields, "field" is filled in and "unknown_field_number" is -1.

For unknown fields, "field" is NULL, "unknown_field_number" is the field number, and "unknown_field_type" is its type.

-

int SpecificField::index = = -1

If this a repeated field, "index" is the index within it.

For unknown fields, this is the index of the field among all unknown fields of the same field number and type.

-

int SpecificField::new_index = = -1

If "field" is a repeated field which is being treated as a map or a set (see TreatAsMap() and TreatAsSet(), below), new_index indicates the index the position to which the element has moved.

If the element has not moved, "new_index" will have the same value as "index".

-

const UnknownFieldSet * SpecificField::unknown_field_set1 = = nullptr

For unknown fields, these are the pointers to the UnknownFieldSet containing the unknown fields.

In certain cases (e.g. proto1's MessageSet, or nested groups of unknown fields), these may differ from the messages' internal UnknownFieldSets.

-

int SpecificField::unknown_field_index1 = = -1

For unknown fields, these are the index of the field within the UnknownFieldSets.

One or the other will be -1 when reporting an addition or deletion.

-

class MessageDifferencer::StreamReporter: public Reporter

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

An implementation of the MessageDifferencer Reporter that outputs any differences found in human-readable form to the supplied ZeroCopyOutputStream or Printer.

If a printer is used, the delimiter must be '$'.

-

WARNING: this reporter does not necessarily flush its output until it is destroyed. As a result, it is not safe to assume the output is valid or complete until after you destroy the reporter. For example, if you use a StreamReporter to write to a StringOutputStream, the target string may contain uninitialized data until the reporter is destroyed.

-

Members

explicit
StreamReporter(io::ZeroCopyOutputStream * output)
explicit
StreamReporter(io::Printer * printer)
delimiter '$'
~StreamReporter()
void
set_report_modified_aggregates(bool report)
When set to true, the stream reporter will also output aggregates nodes (i.e. more...
virtual void
ReportAdded(const Message & message1, const Message & message2, const std::vector< SpecificField > & field_path)
Reports that a field has been added into Message2.
virtual void
ReportDeleted(const Message & message1, const Message & message2, const std::vector< SpecificField > & field_path)
Reports that a field has been deleted from Message1.
virtual void
ReportModified(const Message & message1, const Message & message2, const std::vector< SpecificField > & field_path)
Reports that the value of a field has been modified.
virtual void
ReportMoved(const Message & , const Message & , const std::vector< SpecificField > & )
Reports that a repeated field has been moved to another location. more...
virtual void
ReportMatched(const Message & , const Message & , const std::vector< SpecificField > & )
Reports that two fields match. more...
virtual void
ReportIgnored(const Message & , const Message & , const std::vector< SpecificField > & )
Reports that two fields would have been compared, but the comparison has been skipped because the field was marked as 'ignored' using IgnoreField(). more...
virtual void
ReportUnknownFieldIgnored(const Message & , const Message & , const std::vector< SpecificField > & )
Report that an unknown field is ignored. more...
void
SetMessages(const Message & message1, const Message & message2)
Messages that are being compared must be provided to StreamReporter prior to processing.
protected virtual void
PrintPath(const std::vector< SpecificField > & field_path, bool left_side)
Prints the specified path of fields to the buffer.
protected virtual void
PrintValue(const Message & message, const std::vector< SpecificField > & field_path, bool left_side)
Prints the value of fields to the buffer. more...
protected virtual void
PrintUnknownFieldValue(const UnknownField * unknown_field)
Prints the specified path of unknown fields to the buffer.
protected void
Print(const std::string & str)
Just print a string.
protected void
PrintMapKey(const std::vector< SpecificField > & field_path, bool left_side, const SpecificField & specific_field, size_t target_field_index)
helper function for PrintPath that contains logic for printing maps

void StreamReporter::set_report_modified_aggregates(
        bool report)

When set to true, the stream reporter will also output aggregates nodes (i.e.

messages and groups) whose subfields have been modified. When false, will only report the individual subfields. Defaults to false.

-

virtual void StreamReporter::ReportMoved(
        const Message & ,
        const Message & ,
        const std::vector< SpecificField > & )

Reports that a repeated field has been moved to another location.

This only applies when using TreatAsSet or TreatAsMap() – see below. Also note that for any given field, ReportModified and ReportMoved are mutually exclusive. If a field has been both moved and modified, then only ReportModified will be called.

-

virtual void StreamReporter::ReportMatched(
        const Message & ,
        const Message & ,
        const std::vector< SpecificField > & )

Reports that two fields match.

Useful for doing side-by-side diffs. This function is mutually exclusive with ReportModified and ReportMoved. Note that you must call set_report_matches(true) before calling Compare to make use of this function.

-

virtual void StreamReporter::ReportIgnored(
        const Message & ,
        const Message & ,
        const std::vector< SpecificField > & )

Reports that two fields would have been compared, but the comparison has been skipped because the field was marked as 'ignored' using IgnoreField().

This function is mutually exclusive with all the other Report() functions.

-

The contract of ReportIgnored is slightly different than the other Report() functions, in that |field_path.back().index| is always equal to -1, even if the last field is repeated. This is because while the other Report() functions indicate where in a repeated field the action (Addition, Deletion, etc...) happened, when a repeated field is 'ignored', the differencer simply calls ReportIgnored on the repeated field as a whole and moves on without looking at its individual elements.

-

Furthermore, ReportIgnored() does not indicate whether the fields were in fact equal or not, as Compare() does not inspect these fields at all. It is up to the Reporter to decide whether the fields are equal or not (perhaps with a second call to Compare()), if it cares.

-

virtual void StreamReporter::ReportUnknownFieldIgnored(
        const Message & ,
        const Message & ,
        const std::vector< SpecificField > & )

Report that an unknown field is ignored.

(see comment above). Note this is a different function since the last SpecificField in field path has a null field. This could break existing Reporter.

-

protected virtual void StreamReporter::PrintValue(
        const Message & message,
        const std::vector< SpecificField > & field_path,
        bool left_side)

Prints the value of fields to the buffer.

left_side is true if the given message is from the left side of the comparison, false if it was the right. This is relevant only to decide whether to follow unknown_field_index1 or unknown_field_index2 when an unknown field is encountered in field_path.

-

class MessageDifferencer::UnpackAnyField

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

Class for processing Any deserialization.

This logic is used by both the MessageDifferencer and StreamReporter classes.

-

Members

UnpackAnyField()
~UnpackAnyField()
bool
UnpackAny(const Message & any, std::unique_ptr< Message > * data)
If "any" is of type google.protobuf.Any, extract its payload using DynamicMessageFactory and store in "data".

class FieldContext

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

This class provides extra information to the FieldComparator::Compare function.

Members

explicit
FieldContext(std::vector< MessageDifferencer::SpecificField > * parent_fields)
std::vector< MessageDifferencer::SpecificField > *
parent_fields() const
diff --git a/content/reference/cpp/api-docs/google.protobuf.util.time_util.md b/content/reference/cpp/api-docs/google.protobuf.util.time_util.md deleted file mode 100644 index fa98680de..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.util.time_util.md +++ /dev/null @@ -1,31 +0,0 @@ -+++ -title = "time_util.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

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

Defines utilities for the Timestamp and Duration well known types.

Classes in this file

Utility functions for Timestamp and Duration.

class TimeUtil

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

Utility functions for Timestamp and Duration.

Members

const int64_t
kTimestampMinSeconds = = -62135596800LL
The min/max Timestamp/Duration values we support. more...
const int64_t
kTimestampMaxSeconds = = 253402300799LL
For "9999-12-31T23:59:59.999999999Z".
const int64_t
kDurationMinSeconds = = -315576000000LL
const int64_t
kDurationMaxSeconds = = 315576000000LL
static std::string
ToString(const Timestamp & timestamp)
Converts Timestamp to/from RFC 3339 date string format. more...
static bool
FromString(const std::string & value, Timestamp * timestamp)
static std::string
ToString(const Duration & duration)
Converts Duration to/from string format. more...
static bool
FromString(const std::string & value, Duration * timestamp)
static Timestamp
GetCurrentTime()
Gets the current UTC time.
static Timestamp
GetEpoch()
Returns the Time representing "1970-01-01 00:00:00".
static Duration
NanosecondsToDuration(int64_t nanos)
Converts between Duration and integer types. more...
static Duration
MicrosecondsToDuration(int64_t micros)
static Duration
MillisecondsToDuration(int64_t millis)
static Duration
SecondsToDuration(int64_t seconds)
static Duration
MinutesToDuration(int64_t minutes)
static Duration
HoursToDuration(int64_t hours)
static int64_t
DurationToNanoseconds(const Duration & duration)
Result will be truncated towards zero. more...
static int64_t
DurationToMicroseconds(const Duration & duration)
static int64_t
DurationToMilliseconds(const Duration & duration)
static int64_t
DurationToSeconds(const Duration & duration)
static int64_t
DurationToMinutes(const Duration & duration)
static int64_t
DurationToHours(const Duration & duration)
static Timestamp
NanosecondsToTimestamp(int64_t nanos)
Creates Timestamp from integer types. more...
static Timestamp
MicrosecondsToTimestamp(int64_t micros)
static Timestamp
MillisecondsToTimestamp(int64_t millis)
static Timestamp
SecondsToTimestamp(int64_t seconds)
static int64_t
TimestampToNanoseconds(const Timestamp & timestamp)
Result will be truncated down to the nearest integer value. more...
static int64_t
TimestampToMicroseconds(const Timestamp & timestamp)
static int64_t
TimestampToMilliseconds(const Timestamp & timestamp)
static int64_t
TimestampToSeconds(const Timestamp & timestamp)
static Timestamp
TimeTToTimestamp(time_t value)
Conversion to/from other time/date types. more...
static time_t
TimestampToTimeT(const Timestamp & value)
static Timestamp
TimevalToTimestamp(const timeval & value)
Conversion to/from timeval.
static timeval
TimestampToTimeval(const Timestamp & value)
static Duration
TimevalToDuration(const timeval & value)
static timeval
DurationToTimeval(const Duration & value)

const int64_t TimeUtil::kTimestampMinSeconds = = -62135596800LL

The min/max Timestamp/Duration values we support.

For "0001-01-01T00:00:00Z".

-

static std::string TimeUtil::ToString(
        const Timestamp & timestamp)

Converts Timestamp to/from RFC 3339 date string format.

Generated output will always be Z-normalized and uses 3, 6 or 9 fractional digits as required to represent the exact time. When parsing, any fractional digits (or none) and any offset are accepted as long as they fit into nano-seconds precision. Note that Timestamp can only represent time from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. Converting a Timestamp outside of this range is undefined behavior. See https://www.ietf.org/rfc/rfc3339.txt.

- -

Example of generated format:

- -
"1972-01-01T10:00:20.021Z"
- -

Example of accepted format:

- -
"1972-01-01T10:00:20.021-05:00"
-

static std::string TimeUtil::ToString(
        const Duration & duration)

Converts Duration to/from string format.

The string format will contains 3, 6, or 9 fractional digits depending on the precision required to represent the exact Duration value. For example:

-
"1s", "1.010s", "1.000000100s", "-3.100s"
- -

The range that can be represented by Duration is from -315,576,000,000 to +315,576,000,000 inclusive (in seconds).

-

static Duration TimeUtil::NanosecondsToDuration(
        int64_t nanos)

Converts between Duration and integer types.

The behavior is undefined if the input value is not in the valid range of Duration.

-

static int64_t TimeUtil::DurationToNanoseconds(
        const Duration & duration)

Result will be truncated towards zero.

For example, "-1.5s" will be truncated to "-1s", and "1.5s" to "1s" when converting to seconds. It's undefined behavior if the input duration is not valid or the result exceeds the range of int64. A duration is not valid if it's not in the valid range of Duration, or have an invalid nanos value (i.e., larger than 999999999, less than -999999999, or have a different sign from the seconds part).

-

static Timestamp TimeUtil::NanosecondsToTimestamp(
        int64_t nanos)

Creates Timestamp from integer types.

The integer value indicates the time elapsed from Epoch time. The behavior is undefined if the input value is not in the valid range of Timestamp.

-

static int64_t TimeUtil::TimestampToNanoseconds(
        const Timestamp & timestamp)

Result will be truncated down to the nearest integer value.

For example, with "1969-12-31T23:59:59.9Z", TimestampToMilliseconds() returns -100 and TimestampToSeconds() returns -1. It's undefined behavior if the input Timestamp is not valid (i.e., its seconds part or nanos part does not fall in the valid range) or the return value doesn't fit into int64.

-

static Timestamp TimeUtil::TimeTToTimestamp(
        time_t value)

Conversion to/from other time/date types.

Note that these types may have a different precision and time range from Timestamp/Duration. When converting to a lower precision type, the value will be truncated to the nearest value that can be represented. If the value is out of the range of the result type, the return value is undefined.

- -

Conversion to/from time_t

- -
diff --git a/content/reference/cpp/api-docs/google.protobuf.util.type_resolver.md b/content/reference/cpp/api-docs/google.protobuf.util.type_resolver.md deleted file mode 100644 index 5d2070fca..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.util.type_resolver.md +++ /dev/null @@ -1,13 +0,0 @@ - - -+++ -title = "type_resolver.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/util/type_resolver.h>
namespace google::protobuf::util

Defines a TypeResolver for the Any message.

Classes in this file

Abstract interface for a type resolver.

class TypeResolver

#include <google/protobuf/util/type_resolver.h>
namespace google::protobuf::util

Abstract interface for a type resolver.

Implementations of this interface must be thread-safe.

- -

Members

TypeResolver()
virtual
~TypeResolver()
virtual util::Status
ResolveMessageType(const std::string & type_url, google::protobuf::Type * message_type) = 0
Resolves a type url for a message type.
virtual util::Status
ResolveEnumType(const std::string & type_url, google::protobuf::Enum * enum_type) = 0
Resolves a type url for an enum type.
diff --git a/content/reference/cpp/api-docs/google.protobuf.util.type_resolver_util.md b/content/reference/cpp/api-docs/google.protobuf.util.type_resolver_util.md deleted file mode 100644 index a6ed66cce..000000000 --- a/content/reference/cpp/api-docs/google.protobuf.util.type_resolver_util.md +++ /dev/null @@ -1,13 +0,0 @@ - - -+++ -title = "type_resolver_util.h" -toc_hide = "true" -linkTitle = "C++" -description = "This section contains reference documentation for working with protocol buffer classes in C++." -type = "docs" -+++ - -

#include <google/protobuf/util/type_resolver_util.h>
namespace google::protobuf::util

Defines utilities for the TypeResolver.

Classes in this file

File Members

These definitions are not part of any class.
TypeResolver *
NewTypeResolverForDescriptorPool(const std::string & url_prefix, const DescriptorPool * pool)
Creates a TypeResolver that serves type information in the given descriptor pool. more...

TypeResolver * util::NewTypeResolverForDescriptorPool(
        const std::string & url_prefix,
        const DescriptorPool * pool)

Creates a TypeResolver that serves type information in the given descriptor pool.

Caller takes ownership of the returned TypeResolver.

- -
diff --git a/content/reference/cpp/arenas.md b/content/reference/cpp/arenas.md deleted file mode 100644 index d33927597..000000000 --- a/content/reference/cpp/arenas.md +++ /dev/null @@ -1,580 +0,0 @@ -+++ -title = "C++ Arena Allocation Guide" -weight = 520 -linkTitle = "Arena Allocation Guide" -description = "Arena allocation is a C++-only feature that helps you optimize your memory usage and improve performance when working with protocol buffers." -type = "docs" -+++ - -This page describes exactly what C++ code the protocol -buffer compiler generates in addition to the code described in the -[C++ Generated Code Guide](/reference/cpp/cpp-generated) -when arena allocation is enabled. It assumes that you are familiar with the -material in the -[language guide](/programming-guides/editions) and the -[C++ Generated Code Guide](/reference/cpp/cpp-generated). - -## Why Use Arena Allocation? {#why} - -Memory allocation and deallocation constitutes a significant fraction of CPU -time spent in protocol buffers code. By default, protocol buffers performs heap -allocations for each message object, each of its subobjects, and several field -types, such as strings. These allocations occur in bulk when parsing a message -and when building new messages in memory, and associated deallocations happen -when messages and their subobject trees are freed. - -Arena-based allocation has been designed to reduce this performance cost. With -arena allocation, new objects are allocated out of a large piece of preallocated -memory called the arena. Objects can all be freed at once by discarding the -entire arena, ideally without running destructors of any contained object -(though an arena can still maintain a "destructor list" when required). This -makes object allocation faster by reducing it to a simple pointer increment, and -makes deallocation almost free. Arena allocation also provides greater cache -efficiency: when messages are parsed, they are more likely to be allocated in -continuous memory, which makes traversing messages more likely to hit hot cache -lines. - -To get these benefits you'll need to be aware of object lifetimes and find a -suitable granularity at which to use arenas (for servers, this is often -per-request). You can find out more about how to get the most from arena -allocation in [Usage patterns and best practices](#usage). - -This table summarizes the typical performance advantages and disadvantages of -using arenas: - -Operation | Heap-allocated proto messages | Arena-allocated proto messages -:-------------------- | :--------------------------------------------------------------------------------------------------------------------------- | :----------------------------- -*Message allocation* | Slower on average | Faster on average -*Message destruction* | Slower on average | Faster on average -*Message moves* | Always a move (equivalent to a [shallow copy](https://en.wikipedia.org/wiki/Object_copying#Shallow_copy) in cost) | Sometimes a [deep copy](https://en.wikipedia.org/wiki/Object_copying#Deep_copy) - -## Getting Started {#gettingstarted} - -The protocol buffer compiler generates code for arena allocation for the -messages in your file, as used in the following example. - -```cpp -#include -{ - google::protobuf::Arena arena; - MyMessage* message = google::protobuf::Arena::Create(&arena); - // ... -} -``` - -The message object created by `Create()` exists for as long as `arena` exists, -and you should not `delete` the returned message pointer. All of the message -object's internal storage (with a few exceptions[^1]) and submessages (for -example, submessages in a repeated field within `MyMessage`) are allocated on -the arena as well. - -For the most part, the rest of your code will be the same as if you weren't -using arena allocation. - -We'll look at the arena API in more detail in the following sections, and you -can see a more extensive [example](#example) at the end of the document. - -[^1]: Currently, string fields store their data on the heap even when the - containing message is on the arena. Unknown fields are also - heap-allocated. - -## Arena Class API {#arenaclass} - -You create message objects on the arena using the -[`google::protobuf::Arena`](/reference/cpp/api-docs/google.protobuf.arena) -class. This class implements the following public methods. - -### Constructors {#constructors} - -- `Arena()`: Creates a new arena with default parameters, tuned for average - use cases. -- `Arena(const ArenaOptions& options)`: Creates a new arena that uses the - specified allocation options. The options available in `ArenaOptions` - include the ability to use an initial block of user-provided memory for - allocations before resorting to the system allocator, control over the - initial and maximum request sizes for blocks of memory, and allowing you to - pass in custom block allocation and deallocation function pointers to build - freelists and others on top of the blocks. - -### Allocation Methods {#allocation} - -* `template static T* Create(Arena* arena)` or `template static T* Create(Arena* arena, args...)` - - * If `T` is fully compatible[^footnote], then the method creates a new - protocol buffer object of type `T` and its subobjects on the arena. - - If `arena` is not NULL, the returned object is allocated on the arena, - its internal storage and sub-types (if any) will be allocated on the - same arena, and its lifetime is the same as that of the arena. The - object must not be deleted/freed manually: the arena owns the object for - lifetime purposes. - - If `arena` is NULL, the returned object is allocated on the heap, and - the caller owns the object upon return. - - * If `T` is a user-type, the method lets you create an object but not the - subobjects on the arena. For example, let's say you have this C++ class: - - ```cpp - class MyCustomClass { - MyCustomClass(int arg1, int arg2); - // ... - }; - ``` - - ...you can create an instance of it on the arena like this: - - ```cpp - void func() { - // ... - google::protobuf::Arena arena; - MyCustomClass* c = google::protobuf::Arena::Create(&arena, constructor_arg1, constructor_arg2); - // ... - } - ``` - -- `template static T* CreateArray(Arena* arena, size_t n)`: If - `arena` is not NULL, this method allocates raw storage for `n` elements of - type `T` and returns it. The arena owns the returned memory and will free it - on its own destruction. If `arena` is NULL, this method allocates storage on - the heap and the caller receives ownership. - - `T` must have a trivial constructor: constructors are not called when the - array is created on the arena. - -[^footnote]: What it takes to be a "fully compatible" type is internal to the - protobuf library, and should not be assumed to be reliable. - -### "Owned list" Methods {#owned-list} - -The following methods let you specify that particular objects or destructors are -"owned" by the arena, ensuring that they are deleted or called when the arena -itself is deleted - -- `template void Own(T* object)`: Adds `object` to the arena's - list of owned heap objects. When the arena is destroyed, it traverses this - list and frees each object using operator delete, i.e., the system memory - allocator. This method is useful in cases when an object's lifetime should - be tied to the arena but, for whatever reason, the object itself cannot be - or was not already allocated on the arena. -- `template void OwnDestructor(T* object)`: Adds the destructor of - `object` to the arena's list of destructors to call. When the arena is - destroyed, it traverses this list and calls each destructor in turn. It does - not attempt to free the underlying memory of object. This method is useful - when an object is embedded in arena-allocated storage but its destructor - will not otherwise be called, for example because its containing class is a - protobuf message whose destructor won't be called, or because it was - manually constructed in a block allocated by `AllocateArray()`. - -### Other Methods {#other-methods} - -- `uint64 SpaceUsed() const`: Returns the total size of the arena, which is - the sum of the sizes of the underlying blocks. This method is thread-safe; - however, if there are concurrent allocations from multiple threads this - method's return value may not include the sizes of those new blocks. -- `uint64 Reset()`: Destroys the arena's storage, first calling all registered - destructors and freeing all registered heap objects and then discarding all - arena blocks. This teardown procedure is equivalent to that which occurs - when the arena's destructor runs, except the arena is reusable for new - allocations after this method returns. Returns the total size used by the - arena: this information is useful for tuning performance. -- `template Arena* GetArena()`: Returns a pointer to this arena. - Not directly very useful but allows `Arena` to be used in template - instantiations that expect `GetArena()` methods to be present. - -### Thread Safety {#thread-safety} - -`google::protobuf::Arena`'s allocation methods are thread-safe, and the -underlying implementation goes to some length to make multithreaded allocation -fast. The `Reset()` method is *not* thread-safe: the thread performing the arena -reset must synchronize with all threads performing allocations or using objects -allocated from that arena first. - -## Generated Message Class {#messageclass} - -The following message class members are changed or added when you enable arena -allocation. - -### Message Class Methods {#message-class-methods} - -- `Message(Message&& other)`: If the source message is not on arena, the move - constructor efficiently *moves* all fields from one message to another - without making copies or heap allocations (the time complexity of this - operation is `O(number-of-declared-fields)`). However, if the source message - is on arena, it performs a *deep copy* of the underlying data. In both cases - the source message is left in a valid but unspecified state. -- `Message& operator=(Message&& other)`: If both messages are not on arena or - are on the *same* arena, the move-assignment operator efficiently *moves* - all fields from one message to another without making copies or heap - allocations (the time complexity of this operation is - `O(number-of-declared-fields)`). However, if only one message is on arena, - or the messages are on different arenas, it performs a *deep copy* of the - underlying data. In both cases the source message is left in a valid but - unspecified state. -- `void Swap(Message* other)`: If both messages to be swapped are not on - arenas or are on the *same* arena, - [`Swap()`](/reference/cpp/cpp-generated#message) - behaves as it does without having arena allocation enabled: it efficiently - swaps the message objects' contents, almost exclusively through cheap - pointer swaps, avoiding copies. However, if only one message is on an arena, - or the messages are on different arenas, `Swap()` performs *deep copies* of - the underlying data. This new behavior is necessary because otherwise the - swapped sub-objects could have differing lifetimes, leading potentially to - use-after-free bugs. -- `Message* New(Arena* arena)`: An alternate override for the standard `New()` - method. It allows a new message object of this type to be created on the - given arena. Its semantics are identical to `Arena::Create(arena)` if the - concrete message type on which it is called is generated with arena - allocation enabled. If the message type is not generated with arena - allocation enabled, then it is equivalent to an ordinary allocation followed - by `arena->Own(message)` if `arena` is not NULL. -- `Arena* GetArena()`: Returns the arena on which this message object was - allocated, if any. -- `void UnsafeArenaSwap(Message* other)`: Identical to `Swap()`, except it - assumes both objects are on the same arena (or not on arenas at all) and - always uses the efficient pointer-swapping implementation of this operation. - Using this method can improve performance as, unlike `Swap()`, it doesn't - need to check which messages live on which arena before performing the swap. - As the `Unsafe` prefix suggests, you should only use this method if you are - sure the messages you want to swap aren't on different arenas; otherwise - this method could have unpredictable results. - -### Embedded Message Fields {#arenaembeddedmessage} - -When you allocate a message object on an arena, its embedded message field -objects (submessages) are automatically owned by the arena as well. How these -message objects are allocated depends on where they are defined: - -- If the message type is also defined in a `.proto` file with arena allocation - enabled, the object is allocated on the arena directly. -- If the message type is from another `.proto` without arena allocation - enabled, the object is heap-allocated but is "owned" by the parent message's - arena. This means that when the arena is destroyed, the object will be freed - along with the objects on the arena itself. - -For the field definition: - -```proto -Bar foo = 1; -``` - -The following methods are added or have some special behavior when arena -allocation is enabled. Otherwise, accessor methods just use the -[default behavior](/reference/cpp/cpp-generated#embeddedmessage). - -- `Bar* mutable_foo()`: Returns a mutable pointer to the submessage instance. - If the parent object is on an arena then the returned object will be as - well. -- `void set_allocated_foo(Bar* bar)`: Takes a new object and adopts it as the - new value for the field. Arena support adds additional copying semantics to - maintain proper ownership when objects cross arena/arena or arena/heap - boundaries: - - If the parent object is on the heap and `bar` is on the heap, or if the - parent and message are on the same arena, this method's behavior is - unchanged. - - If the parent is on an arena and `bar` is on the heap, the parent - message adds `bar` to its arena's ownership list with `arena->Own()`. - - If the parent is on an arena and `bar` is on a different arena, this - method makes a copy of message and takes the copy as the new field - value. -- `Bar* release_foo()`: Returns the existing submessage instance of the field, - if set, or a NULL pointer if not set, releasing ownership of this instance - to the caller and clearing the parent message's field. Arena support adds - additional copying semantics to maintain the contract that the returned - object is always *heap-allocated*: - - If the parent message is on an arena, this method will make a copy of - the submessage on the heap, clear the field value, and return the copy. - - If the parent message is on the heap, the method behavior is unchanged. -- `void unsafe_arena_set_allocated_foo(Bar* bar)`: Identical to - `set_allocated_foo`, but assumes both parent and submessage are on the same - arena. Using this version of the method can improve performance as it - doesn't need to check whether the messages are on a particular arena or the - heap. See [allocated/release patterns](#set-allocated) for details on safe - ways to use this. -- `Bar* unsafe_arena_release_foo()`: Similar to `release_foo()`, but skips all - ownership checking. See [allocated/release patterns](#set-allocated) for - details on safe ways to use this. - -### String Fields {#arenastring} - -String fields store their data on the heap even when their parent message is on the arena. Because of this, string accessor methods use the [default behavior](/reference/cpp/cpp-generated#string) even when arena allocation is enabled. - -### Repeated Fields {#arenarepeated} - -Repeated fields allocate their internal array storage on the arena when the -containing message is arena-allocated, and also allocate their elements on the -arena when these elements are separate objects retained by pointer (messages or -strings). At the message-class level, generated methods for repeated fields do -not change. However, the `RepeatedField` and `RepeatedPtrField` objects that are -returned by accessors do have new methods and modified semantics when arena -support is enabled. - -#### Repeated Numeric Fields {#repeated-numeric} - -`RepeatedField` objects that contain primitive types have the following -new/changed methods when arena allocation is enabled: - -- `void UnsafeArenaSwap(RepeatedField* other)`: Performs a swap of - `RepeatedField` contents without validating that this repeated field and - other are on the same arena. If they are not, the two repeated field objects - must be on arenas with equivalent lifetimes. The case where one is on an - arena and one is on the heap is checked and disallowed. -- `void Swap(RepeatedField* other)`: Checks each repeated field object's - arena, and if one is on an arena while one is on the heap or if both are on - arenas but on different ones, the underlying arrays are copied before the - swap occurs. This means that after the swap, each repeated field object - holds an array on its own arena or heap, as appropriate. - -#### Repeated Embedded Message Fields {#repeated-embedded} - -`RepeatedPtrField` objects that contain messages have the following new/changed -methods when arena allocation is enabled. - -- `void UnsafeArenaSwap(RepeatedPtrField* other)`: Performs a swap of - `RepeatedPtrField` contents without validating that this repeated field and - other have the same arena pointer. If they do not, the two repeated field - objects must have arena pointers with equivalent lifetimes. The case where - one has a non-NULL arena pointer and one has a NULL arena pointer is checked - and disallowed. -- `void Swap(RepeatedPtrField* other)`: Checks each repeated field object's - arena pointer, and if one is non-NULL (contents on arena) while one is NULL - (contents on heap) or if both are non-NULL but have different values, the - underlying arrays and their pointed-to objects are copied before the swap - occurs. This means that after the swap, each repeated field object holds an - array on its own arena or on the heap, as appropriate. -- `void AddAllocated(SubMessageType* value)`: Checks that the provided message - object is on the same arena as the repeated field's arena pointer. - - * The source and destination are both arena-allocated and on the same - arena: the object pointer is added directly to the underlying array. - * The source and destination are both arena-allocated and on different - arenas: a copy is made, the original is freed if it was heap-allocated, - and the copy is placed on the array. - * The source is heap-allocated and the destination is arena-allocated: No - copy is made. - * The source is arena-allocated and the destination is heap-allocated: A - copy is made and placed on the array. - * Both source and destination are heap allocated: The object pointer is - added directly to the underlying array. - - This maintains the invariant that all objects pointed to by a repeated field - are in the same ownership domain (heap or specific arena) as indicated by - the repeated field's arena pointer. - -- `SubMessageType* ReleaseLast()`: Returns a heap-allocated message equivalent - to the last message in the repeated field, removing it from the repeated - field. If the repeated field itself has a NULL arena pointer (and thus, all - of its pointed-to messages are heap-allocated), then this method simply - returns a pointer to the original object. Otherwise, if the repeated field - has a non-NULL arena pointer, this method makes a copy that is - heap-allocated and returns that copy. In both cases, the caller receives - ownership of a heap-allocated object and is responsible for deleting the - object. - -- `void UnsafeArenaAddAllocated(SubMessageType* value)`: Like - `AddAllocated()`, but does not perform heap/arena checks or any message - copies. It adds the provided pointer directly to the internal array of - pointers for this repeated field. See - [allocated/release patterns](#set-allocated) for details on safe ways to use - this. - -- `SubMessageType* UnsafeArenaReleaseLast()`: Like `ReleaseLast()` but - performs no copies, even if the repeated field has a non-NULL arena pointer. - Instead, it directly returns the pointer to the object as it was in the - repeated field. See [allocated/release patterns](#set-allocated) for details - on safe ways to use this. - -- `void ExtractSubrange(int start, int num, SubMessageType** elements)`: - Removes `num` elements from the repeated field, starting from index `start`, - and returns them in `elements` if it is not NULL. If the repeated field is - on an arena, and elements are being returned, the elements are copied to the - heap first. In both cases (arena or no arena), the caller owns the returned - objects on the heap. - -- `void UnsafeArenaExtractSubrange(int start, int num, SubMessageType** - elements)`: Removes `num` elements from the repeated field, starting from - index `start`, and returns them in `elements` if it is not NULL. Unlike - `ExtractSubrange()`, this method never copies the extracted elements. See - [allocated/release patterns](#set-allocated) for details on safe ways to use - this. - -#### Repeated String Fields {#repeated-string} - -Repeated fields of strings have the same new methods and modified semantics as -repeated fields of messages, because they also maintain their underlying objects -(namely, strings) by pointer reference. - -## Usage Patterns and Best Practices {#usage} - -When using arena-allocated messages, several usage patterns can result in -unintended copies or other negative performance effects. You should be aware of -the following common patterns that may need to be altered when adapting code for -arenas. (Note that we have taken care in the API design to ensure that correct -behavior still occurs --- but higher-performance solutions may require some -reworking.) - -### Unintended Copies {#unintended} - -Several methods that never create object copies when not using arena allocation -may end up doing so when arena support is enabled. These unwanted copies can be -avoided if you make sure that your objects are allocated appropriately and/or -use provided arena-specific method versions, as described in more detail below. - -#### Set Allocated/Add Allocated/Release {#set-allocated} - -By default, the `release_field()` and `set_allocated_field()` methods (for -singular message fields), and the `ReleaseLast()` and `AddAllocated()` methods -(for repeated message fields) allow user code to directly attach and detach -submessages, passing ownership of pointers without copying any data. - -However, when the parent message is on an arena, these methods now sometimes -need to copy the passed in or returned object to maintain compatibility with -existing ownership contracts. More specifically, methods that take ownership -(`set_allocated_field()` and `AddAllocated()`) may copy data if the parent is on -an arena and the new subobject is not, or vice versa, or they are on different -arenas. Methods that release ownership (`release_field()` and `ReleaseLast()`) -may copy data if the parent is on the arena, because the returned object must be -on the heap, by contract. - -To avoid such copies, we have added corresponding "unsafe arena" versions of -these methods where copies are **never performed**: -`unsafe_arena_set_allocated_field()`, `unsafe_arena_release_field()`, -`UnsafeArenaAddAllocated()`, and `UnsafeArenaRelease()` for singular and -repeated fields, respectively. These methods should be used only when you know -they are safe to do so. There are two common patterns for these methods: - -- Moving messages trees between parts of the same arena. Note that the - messages must be on the same arena for this case to be safe. -- Temporarily loaning an owned message to a tree to avoid copies. Pairing an - unsafe *add*/*set* method with an unsafe *release* method performs the loan - in the cheapest way possible regardless of how either message is owned (this - pattern works when they are on the same arena, different arena, or no arena - at all). Note that between the unsafe *add*/*set* and its corresponding - *release*, the borrower must not be swapped, moved, cleared or destroyed; - the loaned message must not be swapped or moved; the loaned message must not - be cleared or released by the borrower; and the loaned message must not be - destroyed. - -Here's an example of how you can avoid unnecessary copies with these methods. -Let's say you have created the following messages on an arena. - -```cpp -Arena* arena = new google::protobuf::Arena(); -MyFeatureMessage* arena_message_1 = - google::protobuf::Arena::Create(arena); -arena_message_1->mutable_nested_message()->set_feature_id(11); - -MyFeatureMessage* arena_message_2 = - google::protobuf::Arena::Create(arena); -``` - -The following code makes inefficient usage of the `release_...()` API: - -```cpp -arena_message_2->set_allocated_nested_message(arena_message_1->release_nested_message()); - -arena_message_1->release_message(); // returns a copy of the underlying nested_message and deletes underlying pointer -``` - -Using the "unsafe arena" version instead avoids the copy: - -```cpp -arena_message_2->unsafe_arena_set_allocated_nested_message( - arena_message_1->unsafe_arena_release_nested_message()); -``` - -You can find out more about these methods in the -[Embedded message fields](#arenaembeddedmessage) section above. - -#### Swap {#swap} - -When two messages' contents are swapped with `Swap()`, the underlying subobjects -may be copied if the two messages live on different arenas, or if one is on the -arena and the other is on the heap. If you want to avoid this copy and either -(i) know that the two messages are on the same arena or different arenas but the -arenas have equivalent lifetimes, or (ii) know that the two messages are on the -heap, you can use a new method, `UnsafeArenaSwap()`. This method both avoids the -overhead of performing the arena check and avoids the copy if one would have -occurred. - -For example, the following code incurs a copy in the `Swap()` call: - -```cpp -MyFeatureMessage* message_1 = - google::protobuf::Arena::Create(arena); -message_1->mutable_nested_message()->set_feature_id(11); - -MyFeatureMessage* message_2 = new MyFeatureMessage; -message_2->mutable_nested_message()->set_feature_id(22); - -message_1->Swap(message_2); // Inefficient swap! -``` - -To avoid the copy in this code, you allocate `message_2` on the same arena as -`message_1`: - -```cpp -MyFeatureMessage* message_2 = - google::protobuf::Arena::Create(arena); -``` - -### Granularity {#granularity} - -We have found in most application server use cases that an "arena-per-request" -model works well. You may be tempted to divide arena use further, either to -reduce heap overhead (by destroying smaller arenas more often) or to reduce -perceived thread-contention issues. However, the use of more fine-grained arenas -may lead to unintended message copying, as we describe above. We have also spent -effort to optimize the `Arena` implementation for the multithreaded use-case, so -a single arena should be appropriate for use throughout a request lifetime even -if multiple threads process that request. - -## Example {#example} - -Here's a simple complete example demonstrating some of the features of the arena -allocation API. - -```proto -// my_feature.proto -edition = "2023"; - -import "nested_message.proto"; - -package feature_package; - -// NEXT Tag to use: 4 -message MyFeatureMessage { - string feature_name = 1; - repeated int32 feature_data = 2; - NestedMessage nested_message = 3; -}; -``` - -```proto -// nested_message.proto -edition = "2023"; - -package feature_package; - -// NEXT Tag to use: 2 -message NestedMessage { - int32 feature_id = 1; -}; -``` - -Message construction and deallocation: - -```cpp -#include - -Arena arena; - -MyFeatureMessage* arena_message = - google::protobuf::Arena::Create(&arena); - -arena_message->set_feature_name("Editions Arena"); -arena_message->mutable_feature_data()->Add(2); -arena_message->mutable_feature_data()->Add(4); -arena_message->mutable_nested_message()->set_feature_id(247); -``` diff --git a/content/reference/cpp/cpp-generated.md b/content/reference/cpp/cpp-generated.md deleted file mode 100644 index ecd88c7ea..000000000 --- a/content/reference/cpp/cpp-generated.md +++ /dev/null @@ -1,1420 +0,0 @@ -+++ -title = "C++ Generated Code Guide" -weight = 510 -linkTitle = "Generated Code Guide" -description = "Describes exactly what C++ code the protocol buffer compiler generates for any given protocol definition. " -type = "docs" -+++ - -Any differences between proto2, proto3, and editions generated code are -highlighted. Note that these differences are in the generated code as described -in this document, not the base message classes/interfaces, which are the same in -all versions. You should read the -[proto2 language guide](/programming-guides/proto2), -[proto3 language guide](/programming-guides/proto3), or -[edition 2023 language guide](/programming-guides/editions) -before reading this document. - -## Compiler Invocation {#invocation} - -The protocol buffer compiler produces C++ output when invoked with the -`--cpp_out=` command-line flag. The parameter to the `--cpp_out=` option is the -directory where you want the compiler to write your C++ output. The compiler -creates a header file and an implementation file for each `.proto` file input. -The names of the output files are computed by taking the name of the `.proto` -file and making two changes: - -- The extension (`.proto`) is replaced with either `.pb.h` or `.pb.cc` for the - header or implementation file, respectively. -- The proto path (specified with the `--proto_path=` or `-I` command-line - flag) is replaced with the output path (specified with the `--cpp_out=` - flag). - -So, for example, let's say you invoke the compiler as follows: - -```shell -protoc --proto_path=src --cpp_out=build/gen src/foo.proto src/bar/baz.proto -``` - -The compiler will read the files `src/foo.proto` and `src/bar/baz.proto` and -produce four output files: `build/gen/foo.pb.h`, `build/gen/foo.pb.cc`, -`build/gen/bar/baz.pb.h`, `build/gen/bar/baz.pb.cc`. The compiler will -automatically create the directory `build/gen/bar` if necessary, but it will -*not* create `build` or `build/gen`; they must already exist. - -## Packages {#package} - -If a `.proto` file contains a `package` declaration, the entire contents of the -file will be placed in a corresponding C++ namespace. For example, given the -`package` declaration: - -```proto -package foo.bar; -``` - -All declarations in the file will reside in the `foo::bar` namespace. - -## Messages {#message} - -Given a simple message declaration: - -```proto -message Foo {} -``` - -The protocol buffer compiler generates a class called `Foo`, which publicly -derives from -[`google::protobuf::Message`](/reference/cpp/api-docs/google.protobuf.message). -The class is a concrete class; no pure-virtual methods are left unimplemented. -Methods that are virtual in `Message` but not pure-virtual may or may not be -overridden by `Foo`, depending on the optimization mode. By default, `Foo` -implements specialized versions of all methods for maximum speed. However, if -the `.proto` file contains the line: - -```proto -option optimize_for = CODE_SIZE; -``` - -then `Foo` will override only the minimum set of methods necessary to function -and rely on reflection-based implementations of the rest. This significantly -reduces the size of the generated code, but also reduces performance. -Alternatively, if the `.proto` file contains: - -```proto -option optimize_for = LITE_RUNTIME; -``` - -then `Foo` will include fast implementations of all methods, but will implement -the -[`google::protobuf::MessageLite`](/reference/cpp/api-docs/google.protobuf.message_lite) -interface, which only contains a subset of the methods of `Message`. In -particular, it does not support descriptors or reflection. However, in this -mode, the generated code only needs to link against `libprotobuf-lite.so` -(`libprotobuf-lite.lib` on Windows) instead of `libprotobuf.so` -(`libprotobuf.lib`). The "lite" library is much smaller than the full library, -and is more appropriate for resource-constrained systems such as mobile phones. - -You should *not* create your own `Foo` subclasses. If you subclass this class -and override a virtual method, the override may be ignored, as many generated -method calls are de-virtualized to improve performance. - -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(::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` - representation of the proto (should only be used for debugging). - -In addition to these methods, the `Foo` class defines the following methods: - -- `Foo()`: Default constructor. -- `~Foo()`: Default destructor. -- `Foo(const Foo& other)`: Copy constructor. -- `Foo(Foo&& other)`: Move constructor. -- `Foo& operator=(const Foo& other)`: Assignment operator. -- `Foo& operator=(Foo&& other)`: Move-assignment operator. -- `void Swap(Foo* other)`: Swap content with another message. -- `const UnknownFieldSet& unknown_fields() const`: Returns the set of unknown - fields encountered while parsing this message. If `option optimize_for = - LITE_RUNTIME` is specified in the `.proto` file, then the return type - changes to `std::string&`. -- `UnknownFieldSet* mutable_unknown_fields()`: Returns a pointer to the - mutable set of unknown fields encountered while parsing this message. If - `option optimize_for = LITE_RUNTIME` is specified in the `.proto` file, then - the return type changes to `std::string*`. - -**Note:** The copy constructor and assignment operator perform a deep copy of -the message data. This ensures that each message object owns and manages its own -copy of the data, preventing issues like double frees or use-after-free errors. -This behavior is consistent with standard C++ practice for objects that own -their data, such as `std::vector`. For developers coming from languages with -different copy semantics (such as JavaScript or TypeScript, where shallow copies -might be more common), it is important to note that modifications to a copied -message will not affect the original message, and vice-versa. - -The class also defines the following static methods: - -- `static const Descriptor* descriptor()`: Returns the type's descriptor. This - contains information about the type, including what fields it has and what - their types are. This can be used with - [reflection](/reference/cpp/api-docs/google.protobuf.message#Reflection) - to inspect fields programmatically. -- `static const Foo& default_instance()`: Returns a const singleton instance - of `Foo` which is identical to a newly-constructed instance of `Foo` (so all - singular fields are unset and all repeated fields are empty). Note that the - default instance of a message can be used as a factory by calling its - `New()` method. - -### Abseil flag support {#absl-flags-messages} - -`Message` objects have native support for Abseil's flag parse/unparse logic. -They can be used as the type for `ABSL_FLAG` declarations. The flag syntax is -`:format,options...:value` where: - -- `format` is one of `text`, `serialized`. -- `options` is a possibly-empty list of options. Each format has its supported - options. -- `value` is the payload in the specified format. - -The valid options are: - -* For `text`: - - `base64`: indicates that `value` is encoded as base64. - - `ignore_unknown`: when specified, unknown field/extensions are dropped. - Otherwise, they cause a parse failure. -* For `serialized`: - - `base64`: indicates that `value` is encoded as base64. It is recommended - to use `serialized` with `base64` given that passing binary data in - shells is difficult and error prone. - -Note that flag support for message types is not provided for `LITE_RUNTIME` -configurations. - -Example: - -```cpp -ABSL_FLAG(MyProtoType, my_proto_config, {}, - "This is a proto config description."); -``` - -### Nested Types {#nested-types} - -A message can be declared inside another message. For example: - -```proto -message Foo { - message Bar {} -} -``` - -In this case, the compiler generates two classes: `Foo` and `Foo_Bar`. In -addition, the compiler generates a typedef inside `Foo` as follows: - -```cpp -typedef Foo_Bar Bar; -``` - -This means that you can use the nested type's class as if it was the nested -class `Foo::Bar`. However, note that C++ does not allow nested types to be -forward-declared. If you want to forward-declare `Bar` in another file and use -that declaration, you must identify it as `Foo_Bar`. - -## Fields {#fields} - -In addition to the methods described in the previous section, the protocol -buffer compiler generates a set of accessor methods for each field defined -within the message in the `.proto` file. These methods are in -lower-case/snake-case, such as `has_foo()` and `clear_foo()`. - -As well as accessor methods, the compiler generates an integer constant for each -field containing its field number. The constant name is the letter `k`, followed -by the field name converted to camel-case, followed by `FieldNumber`. For -example, given the field `optional int32 foo_bar = 5;`, the compiler will -generate the constant `static const int kFooBarFieldNumber = 5;`. - -For field accessors returning a `const` reference, that reference may be -invalidated when the next modifying access is made to the message. This includes -calling any non-`const` accessor of any field, calling any non-`const` method -inherited from `Message` or modifying the message through other ways (for -example, by using the message as the argument of `Swap()`). Correspondingly, the -address of the returned reference is only guaranteed to be the same across -different invocations of the accessor if no modifying access was made to the -message in the meantime. - -For field accessors returning a pointer, that pointer may be invalidated when -the next modifying or non-modifying access is made to the message. This -includes, regardless of constness, calling any accessor of any field, calling -any method inherited from `Message` or accessing the message through other ways -(for example, by copying the message using the copy constructor). -Correspondingly, the value of the returned pointer is never guaranteed to be the -same across two different invocations of the accessor. - - - -### Generated Fieldnames {#generated-fieldnames} - -[Reserved keywords](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/compiler/cpp/helpers.cc#L4) -are appended with an underscore in the generated output. - -For example, the following proto3 definition syntax: - -```proto -message MyMessage { - string false = 1; - string myFalse = 2; -} -``` - -generates the following partial output: - -```cpp - void clear_false_() ; - const std::string& false_() const; - void set_false_(Arg_&& arg, Args_... args); - std::string* mutable_false_(); - PROTOBUF_NODISCARD std::string* release_false_(); - void set_allocated_false_(std::string* ptr); - - void clear_myfalse() ; - const std::string& myfalse() const; - void set_myfalse(Arg_&& arg, Args_... args); - std::string* mutable_myfalse(); - PROTOBUF_NODISCARD std::string* release_myfalse(); - void set_allocated_myfalse(std::string* ptr); -``` - -### Explicit Presence Numeric Fields {#numeric} - -For field definitions for numeric fields with -[explicit presence](/programming-guides/field_presence#presence-in-proto2-apis): - -```proto -int32 foo = 1; -``` - -The compiler will generate the following accessor methods: - -- `bool has_foo() const`: Returns `true` if the field is set. -- `int32_t foo() const`: Returns the current value of the field. If the field - is not set, returns the default value. -- `void set_foo(::int32_t value)`: Sets the value of the field. After calling - this, `has_foo()` will return `true` and `foo()` will return `value`. -- `void clear_foo()`: Clears the value of the field. After calling this, - `has_foo()` will return `false` and `foo()` will return the default value. - -For other numeric field types (including `bool`), `int32_t` is replaced with the -corresponding C++ type according to the -[scalar value types table](/programming-guides/editions#scalar). - -### Implicit Presence Numeric Fields {#implicit-numeric} - -For field definitions for numeric fields with -[implicit presence](/programming-guides/field_presence#presence-in-proto2-apis): - -```proto -int32 foo = 1; -``` - -The compiler will generate the following accessor methods: - -- `::int32_t foo() const`: Returns the current value of the field. If the - field is not set, returns 0. -- `void set_foo(::int32_t value)`: Sets the value of the field. After calling - this, `foo()` will return `value`. -- `void clear_foo()`: Clears the value of the field. After calling this, - `foo()` will return 0. - -For other numeric field types (including `bool`), `int32_t` is replaced with the -corresponding C++ type according to the -[scalar value types table](/programming-guides/editions#scalar). - -### Explicit Presence String/Bytes Fields {#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 these field definitions with -[explicit presence](/programming-guides/field_presence#presence-in-proto2-apis): - -```proto -string foo = 1; -bytes foo = 2; -``` - -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(...)`: Sets the value of the field. 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 - calling this, `has_foo()` will return `true` and `foo()` will return - whatever value is written into the given string. - - **Note:** This method will be removed in the new `string_view` APIs. - -- `void clear_foo()`: Clears the value of the field. After calling this, - `has_foo()` will return `false` and `foo()` will return the default value. - -- `void set_allocated_foo(string* value)`: - Sets the `string` - object to the field and frees the previous field value if it exists. If the - `string` pointer is not `NULL`, the message takes ownership of the allocated - `string` object and `has_foo()` will return `true`. The message is free to - delete the allocated `string` object at any time, so references to the - object may be invalidated. Otherwise, if the `value` is `NULL`, the behavior - is the same as calling `clear_foo()`. - -- `string* release_foo()`: - Releases the - ownership of the field and returns the pointer of the `string` object. After - calling this, caller takes the ownership of the allocated `string` object, - `has_foo()` will return `false`, and `foo()` will return the default value. - - - -### Implicit Presence String/Bytes Fields {#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 these field definitions with -[implicit presence](/programming-guides/field_presence#presence-in-proto2-apis): - -```proto -string foo = 1 [features.field_presence = IMPLICIT]; -bytes foo = 1 [features.field_presence = IMPLICIT]; -``` - -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(Arg_&& arg, Args_... args)`: Sets the value of the field. - 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 - return whatever value is written into the given string. -- `void clear_foo()`: Clears the value of the field. After calling this, - `foo()` will return the empty string/empty bytes. -- `void set_allocated_foo(string* value)`: - Sets the `string` - object to the field and frees the previous field value if it exists. If the - `string` pointer is not `NULL`, the message takes ownership of the allocated - `string` object. The message is free to delete the allocated `string` object - at any time, so references to the object may be invalidated. Otherwise, if - the `value` is `NULL`, the behavior is the same as calling `clear_foo()`. -- `string* release_foo()`: - Releases the - ownership of the field and returns the pointer of the `string` object. After - calling this, caller takes the ownership of the allocated `string` object - and `foo()` will return the empty string/empty bytes. - -### Singular Bytes Fields with Cord Support {#cord} - -v23.0 added support for -[`absl::Cord`](https://github.com/abseil/abseil-cpp/blob/master/absl/strings/cord.h) -for singular `bytes` fields (including -[`oneof` fields](#oneof-numeric)). Singular `string`, `repeated string`, and `repeated -bytes` fields do not support using `Cord`s. - -To set a singular `bytes` field to store data using `absl::Cord`, use the -following syntax: - -```proto -// edition (default settings) -bytes foo = 25 [ctype=CORD]; -bytes foo = 26 [ctype=CORD, features.field_presence = IMPLICIT]; -``` - -Using `cord` is not available for `repeated bytes` fields. Protoc ignores -`[ctype=CORD]` settings on those fields. - -The compiler will generate the following accessor methods: - -- `const ::absl::Cord& foo() const`: Returns the current value of the field. - If the field is not set, returns an empty `Cord` (proto3) or the default - value (proto2 and editions). -- `void set_foo(const ::absl::Cord& value)`: Sets the value of the field. - After calling this, `foo()` will return `value`. -- `void set_foo(::absl::string_view value)`: Sets the value of the field. - After calling this, `foo()` will return `value` as an `absl::Cord`. -- `void clear_foo()`: Clears the value of the field. After calling this, - `foo()` will return an empty `Cord` (proto3) or the default value (proto2 - and editions). -- `bool has_foo()`: Returns `true` if the field is set. Only applies for the - `optional` field in proto3 and the explicit presence field in editions. - -### Explicit Presence Enum Fields {#enum_field} - -Given the enum type: - -```proto -enum Bar { - BAR_UNSPECIFIED = 0; - BAR_VALUE = 1; - BAR_OTHER_VALUE = 2; -} -``` - -For this field definition with -[explicit presence](/programming-guides/field_presence#presence-in-proto2-apis): - -```proto -Bar bar = 1; -``` - -The compiler will generate the following accessor methods: - -- `bool has_bar() const`: Returns `true` if the field is set. -- `Bar bar() const`: Returns the current value of the field. If the field is - not set, returns the default value. -- `void set_bar(Bar value)`: Sets the value of the field. After calling this, - `has_bar()` will return `true` and `bar()` will return `value`. In debug - mode (i.e. NDEBUG is not defined), if `value` does not match any of the - values defined for `Bar`, this method will abort the process. -- `void clear_bar()`: Clears the value of the field. After calling this, - `has_bar()` will return `false` and `bar()` will return the default value. - -### Implicit Presence Enum Fields {#implicit-enum} - -Given the enum type: - -```proto -enum Bar { - BAR_UNSPECIFIED = 0; - BAR_VALUE = 1; - BAR_OTHER_VALUE = 2; -} -``` - -For this field definition with -[implicit presence](/programming-guides/field_presence#presence-in-proto2-apis): - -```proto -Bar bar = 1; -``` - -The compiler will generate the following accessor methods: - -- `Bar bar() const`: Returns the current value of the field. If the field is - not set, returns the default value (0). -- `void set_bar(Bar value)`: Sets the value of the field. After calling this, - `bar()` will return `value`. -- `void clear_bar()`: Clears the value of the field. After calling this, - `bar()` will return the default value. - -### Explicit Presence Embedded Message Fields {#embeddedmessage} - -Given the message type: - -```proto -message Bar {} -``` - -For this field definition with -[explicit presence](/programming-guides/field_presence#presence-in-proto2-apis): - -```proto -Bar bar = 1; -``` - -The compiler will generate the following accessor methods: - -- `bool has_bar() const`: Returns `true` if the field is set. -- `const Bar& bar() const`: Returns the current value of the field. If the - field is not set, returns a `Bar` with none of its fields set (possibly - `Bar::default_instance()`). -- `Bar* mutable_bar()`: Returns a pointer to the mutable `Bar` object that - stores the field's value. If the field was not set prior to the call, then - the returned `Bar` will have none of its fields set (i.e. it will be - identical to a newly-allocated `Bar`). After calling this, `has_bar()` will - return `true` and `bar()` will return a reference to the same instance of - `Bar`. -- `void clear_bar()`: Clears the value of the field. After calling this, - `has_bar()` will return `false` and `bar()` will return the default value. -- `void set_allocated_bar(Bar* value)`: Sets the `Bar` object to the field and - frees the previous field value if it exists. If the `Bar` pointer is not - `NULL`, the message takes ownership of the allocated `Bar` object and - `has_bar()` will return `true`. Otherwise, if the `Bar` is `NULL`, the - behavior is the same as calling `clear_bar()`. -- `Bar* release_bar()`: Releases the ownership of the field and returns the - pointer of the `Bar` object. After calling this, caller takes the ownership - of the allocated `Bar` object, `has_bar()` will return `false`, and `bar()` - will return the default value. - -### Repeated Numeric Fields {#repeatednumeric} - -For this field definition: - -```proto -repeated int32 foo = 1; -``` - -The compiler will generate the following accessor methods: - -- `int foo_size() const`: Returns the number of elements currently in the - field. To check for an empty set, consider using the - [`empty()`](/reference/cpp/api-docs/google.protobuf.repeated_field#RepeatedPtrField) - method in the underlying `RepeatedField` instead of this method. -- `int32_t foo(int index) const`: Returns the element at the given zero-based - index. Calling this method with index outside of [0, foo_size()) yields - undefined behavior. -- `void set_foo(int index, int32_t value)`: Sets the value of the element at - the given zero-based index. -- `void add_foo(int32_t value)`: Appends a new element to the end of the field - with the given value. -- `void clear_foo()`: Removes all elements from the field. After calling this, - `foo_size()` will return zero. -- `const RepeatedField& foo() const`: Returns the underlying - [`RepeatedField`](/reference/cpp/api-docs/google.protobuf.repeated_field#RepeatedField) - that stores the field's elements. This container class provides STL-like - iterators and other methods. -- `RepeatedField* mutable_foo()`: Returns a pointer to the underlying - mutable `RepeatedField` that stores the field's elements. This container - class provides STL-like iterators and other methods. - -For other numeric field types (including `bool`), `int32_t` is replaced with the -corresponding C++ type according to the -[scalar value types table](/programming-guides/editions#scalar). - -### 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 -repeated string foo = 1; -repeated bytes foo = 1; -``` - -The compiler will generate the following accessor methods: - -- `int foo_size() const`: Returns the number of elements currently in the - field. To check for an empty set, consider using the - [`empty()`](/reference/cpp/api-docs/google.protobuf.repeated_field#RepeatedPtrField) - method in the underlying `RepeatedField` instead of this method. -- `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)`: 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 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 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, - `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. - -### Repeated Enum Fields {#repeated_enum} - -Given the enum type: - -```proto -enum Bar { - BAR_UNSPECIFIED = 0; - BAR_VALUE = 1; - BAR_OTHER_VALUE = 2; -} -``` - -For this field definition: - -```proto -repeated Bar bar = 1; -``` - -The compiler will generate the following accessor methods: - -- `int bar_size() const`: Returns the number of elements currently in the - field. To check for an empty set, consider using the - [`empty()`](/reference/cpp/api-docs/google.protobuf.repeated_field#RepeatedPtrField) - method in the underlying `RepeatedField` instead of this method. -- `Bar bar(int index) const`: Returns the element at the given zero-based - index. Calling this method with index outside of [0, bar_size()) yields - undefined behavior. -- `void set_bar(int index, Bar value)`: Sets the value of the element at the - given zero-based index. In debug mode (i.e. NDEBUG is not defined), if - `value` does not match any of the values defined for `Bar` and it is a - closed enum, this method will abort the process. -- `void add_bar(Bar value)`: Appends a new element to the end of the field - with the given value. In debug mode (i.e. NDEBUG is not defined), if `value` - does not match any of the values defined for `Bar`, this method will abort - the process. -- `void clear_bar()`: Removes all elements from the field. After calling this, - `bar_size()` will return zero. -- `const RepeatedField& bar() const`: Returns the underlying - [`RepeatedField`](/reference/cpp/api-docs/google.protobuf.repeated_field#RepeatedField) - that stores the field's elements. This container class provides STL-like - iterators and other methods. -- `RepeatedField* mutable_bar()`: Returns a pointer to the underlying - mutable `RepeatedField` that stores the field's elements. This container - class provides STL-like iterators and other methods. - -### Repeated Embedded Message Fields {#repeatedmessage} - -Given the message type: - -```proto -message Bar {} -``` - -For this field definitions: - -```proto -repeated Bar bar = 1; -``` - -The compiler will generate the following accessor methods: - -- `int bar_size() const`: Returns the number of elements currently in the - field. To check for an empty set, consider using the - [`empty()`](/reference/cpp/api-docs/google.protobuf.repeated_field#RepeatedPtrField) - method in the underlying `RepeatedField` instead of this method. -- `const Bar& bar(int index) const`: Returns the element at the given - zero-based index. Calling this method with index outside of [0, bar_size()) - yields undefined behavior. -- `Bar* mutable_bar(int index)`: Returns a pointer to the mutable `Bar` object - that stores the value of the element at the given zero-based index. Calling - this method with index outside of [0, bar_size()) yields undefined behavior. -- `Bar* add_bar()`: Adds a new element to the end of the field and returns a - pointer to it. The returned `Bar` is mutable and will have none of its - fields set (i.e. it will be identical to a newly-allocated `Bar`). -- `void clear_bar()`: Removes all elements from the field. After calling this, - `bar_size()` will return zero. -- `const RepeatedPtrField& bar() 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_bar()`: Returns a pointer to the underlying - mutable `RepeatedPtrField` that stores the field's elements. This container - class provides STL-like iterators and other methods. - -### Oneof Numeric Fields {#oneof-numeric} - -For this [oneof](#oneof) field definition: - -```proto -oneof example_name { - int32 foo = 1; - ... -} -``` - -The compiler will generate the following accessor methods: - -- `bool has_foo() const`: Returns `true` if oneof case is `kFoo`. -- `int32 foo() const`: Returns the current value of the field if oneof case is - `kFoo`. Otherwise, returns the default value. -- `void set_foo(int32 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 `value`, and - `example_name_case()` will return `kFoo`. -- `void clear_foo()`: - - Nothing will be changed if oneof case is not `kFoo`. - - If oneof case is `kFoo`, clears the value of the field and oneof case. - `has_foo()` will return `false`, `foo()` will return the default value - and `example_name_case()` will return `EXAMPLE_NAME_NOT_SET`. - -For other numeric field types (including `bool`),`int32_t` is replaced with the -corresponding C++ type according to the -[scalar value types table](/programming-guides/editions#scalar). - -### 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 -oneof example_name { - string foo = 1; - ... -} -oneof example_name { - bytes foo = 1; - ... -} -``` - -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(::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 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()`. - - Sets the oneof case to `kFoo` and returns a pointer to the mutable - string object that stores the field's value. If the oneof case was not - `kFoo` prior to the call, then the returned string will be empty (not - the default value). - - `has_foo()` will return `true`, `foo()` will return whatever value is - written into the given string and `example_name_case()` will return - `kFoo`. -- `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`. -- `void set_allocated_foo(string* value)`: - - Calls `clear_example_name()`. - - If the string pointer is not `NULL`: Sets the string object to the field - and sets the oneof case to `kFoo`. The message takes ownership of the - allocated string object, `has_foo()` will return `true` and - `example_name_case()` will return `kFoo`. - - If the string pointer is `NULL`, `has_foo()` will return `false` and - `example_name_case()` will return `EXAMPLE_NAME_NOT_SET`. -- `string* release_foo()`: - - Returns `NULL` if oneof case is not `kFoo`. - - Clears the oneof case, releases the ownership of the field, and returns - the pointer of the string object. After calling this, caller takes the - ownership of the allocated string object, `has_foo()` will return false, - `foo()` will return the default value, and `example_name_case()` will - return `EXAMPLE_NAME_NOT_SET`. - -### Oneof Enum Fields {#oneof-enum} - -Given the enum type: - -```proto -enum Bar { - BAR_UNSPECIFIED = 0; - BAR_VALUE = 1; - BAR_OTHER_VALUE = 2; -} -``` - -For the [oneof](#oneof) field definition: - -```proto -oneof example_name { - Bar bar = 1; - ... -} -``` - -The compiler will generate the following accessor methods: - -- `bool has_bar() const`: Returns `true` if oneof case is `kBar`. -- `Bar bar() const`: Returns the current value of the field if oneof case is - `kBar`. Otherwise, returns the default value. -- `void set_bar(Bar 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 `kBar`. - - `has_bar()` will return `true`, `bar()` will return `value` and - `example_name_case()` will return `kBar`. - - In debug mode (that is, NDEBUG is not defined), if `value` does not - match any of the values defined for `Bar` and it is a closed enum, this - method will abort the process. -- `void clear_bar()`: - - Nothing will be changed if the oneof case is not `kBar`. - - If the oneof case is `kBar`, clears the value of the field and the oneof - case. `has_bar()` will return `false`, `bar()` will return the default - value and `example_name_case()` will return `EXAMPLE_NAME_NOT_SET`. - -### Oneof Embedded Message Fields {#oneof-embedded} - -Given the message type: - -```proto -message Bar {} -``` - -For the [oneof](#oneof) field definition: - -```proto -oneof example_name { - Bar bar = 1; - ... -} -``` - -The compiler will generate the following accessor methods: - -- `bool has_bar() const`: Returns true if oneof case is `kBar`. -- `const Bar& bar() const`: Returns the current value of the field if oneof - case is `kBar`. Otherwise, returns a Bar with none of its fields set - (possibly `Bar::default_instance()`). -- `Bar* mutable_bar()`: - - If any other oneof field in the same oneof is set, calls - `clear_example_name()`. - - Sets the oneof case to `kBar` and returns a pointer to the mutable Bar - object that stores the field's value. If the oneof case was not `kBar` - prior to the call, then the returned Bar will have none of its fields - set (that is, it will be identical to a newly-allocated Bar). - - After calling this, `has_bar()` will return `true`, `bar()` will return - a reference to the same instance of `Bar` and `example_name_case()` will - return `kBar`. -- `void clear_bar()`: - - Nothing will be changed if the oneof case is not `kBar`. - - If the oneof case equals `kBar`, frees the field and clears the oneof - case. `has_bar()` will return `false`, `bar()` will return the default - value and `example_name_case()` will return `EXAMPLE_NAME_NOT_SET`. -- `void set_allocated_bar(Bar* bar)`: - - Calls `clear_example_name()`. - - If the `Bar` pointer is not `NULL`: Sets the `Bar` object to the field - and sets the oneof case to `kBar`. The message takes ownership of the - allocated `Bar` object, has_bar() will return true and - `example_name_case()` will return `kBar`. - - If the pointer is `NULL`, `has_bar()` will return `false` and - `example_name_case()` will return `EXAMPLE_NAME_NOT_SET`. (The behavior - is like calling `clear_example_name()`) -- `Bar* release_bar()`: - - Returns `NULL` if oneof case is not `kBar`. - - If the oneof case is `kBar`, clears the oneof case, releases the - ownership of the field and returns the pointer of the `Bar` object. - After calling this, caller takes the ownership of the allocated `Bar` - object, `has_bar()` will return `false`, `bar()` will return the default - value, and `example_name_case()` will return `EXAMPLE_NAME_NOT_SET`. - -### Map Fields {#map} - -For this map field definition: - -```proto -map weight = 1; -``` - -The compiler will generate the following accessor methods: - -- `const google::protobuf::Map& weight();`: Returns an immutable - `Map`. -- `google::protobuf::Map* mutable_weight();`: Returns a mutable - `Map`. - -A -[`google::protobuf::Map`](/reference/cpp/api-docs/google.protobuf.map) -is a special container type used in protocol buffers to store map fields. As you -can see from its interface below, it uses a commonly-used subset of `std::map` -and `std::unordered_map` methods. - -{{% alert title="Note" color="note" %}} These maps -are -unordered.{{% /alert %}} - -```cpp -template { -class Map { - // Member types - typedef Key key_type; - typedef T mapped_type; - typedef MapPair< Key, T > value_type; - - // Iterators - iterator begin(); - const_iterator begin() const; - const_iterator cbegin() const; - iterator end(); - const_iterator end() const; - const_iterator cend() const; - // Capacity - int size() const; - bool empty() const; - - // Element access - T& operator[](const Key& key); - const T& at(const Key& key) const; - T& at(const Key& key); - - // Lookup - bool contains(const Key& key) const; - int count(const Key& key) const; - const_iterator find(const Key& key) const; - iterator find(const Key& key); - - // Modifiers - pair insert(const value_type& value); - template - void insert(InputIt first, InputIt last); - size_type erase(const Key& Key); - iterator erase(const_iterator pos); - iterator erase(const_iterator first, const_iterator last); - void clear(); - - // Copy - Map(const Map& other); - Map& operator=(const Map& other); -} -``` - -The easiest way to add data is to use normal map syntax, for example: - -```cpp -std::unique_ptr my_enclosing_proto(new ProtoName); -(*my_enclosing_proto->mutable_weight())[my_key] = my_value; -``` - -`pair insert(const value_type& value)` will implicitly cause a -deep copy of the `value_type` instance. The most efficient way to insert a new -value into a `google::protobuf::Map` is as follows: - -```cpp -T& operator[](const Key& key): map[new_key] = new_mapped; -``` - -#### Using `google::protobuf::Map` with standard maps {#protobuf-map} - -`google::protobuf::Map` supports the same iterator API as `std::map` and -`std::unordered_map`. If you don't want to use `google::protobuf::Map` directly, -you can convert a `google::protobuf::Map` to a standard map by doing the -following: - -```cpp -std::map standard_map(message.weight().begin(), - message.weight().end()); -``` - -Note that this will make a deep copy of the entire map. - -You can also construct a `google::protobuf::Map` from a standard map as follows: - -```cpp -google::protobuf::Map weight(standard_map.begin(), standard_map.end()); -``` - -#### Parsing unknown values {#parsing-unknown} - -On the wire, a .proto map is equivalent to a map entry message for each -key/value pair, while the map itself is a repeated field of map entries. Like -ordinary message types, it's possible for a parsed map entry message to have -unknown fields: for example a field of type `int64` in a map defined as -`map`. - -If there are unknown fields in the wire format of a map entry message, they will -be discarded. - -If there is an unknown enum value in the wire format of a map entry message, -it's handled differently in proto2, proto3, and editions. In proto2, the whole -map entry message is put into the unknown field set of the containing message. -In proto3, it is put into a map field as if it is a known enum value. With -editions, by default it mirrors the proto3 behavior. If `features.enum_type` is -set to `CLOSED`, then it mirrors the proto2 behavior. - -## Any {#any} - -Given an [`Any`](/programming-guides/proto3#any) field -like this: - -```proto -import "google/protobuf/any.proto"; - -message ErrorStatus { - string message = 1; - google.protobuf.Any details = 2; -} -``` - -In our generated code, the getter for the `details` field returns an instance of -`google::protobuf::Any`. This provides the following special methods to pack and -unpack the `Any`'s values: - -```cpp -class Any { - public: - // Packs the given message into this Any using the default type URL - // prefix “type.googleapis.com”. Returns false if serializing the message failed. - bool PackFrom(const google::protobuf::Message& message); - - // 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, - ::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. - bool UnpackTo(google::protobuf::Message* message) const; - - // Returns true if this Any represents the given protobuf type. - template bool Is() const; -} -``` - -## Oneof {#oneof} - -Given a oneof definition like this: - -```proto -oneof example_name { - int32 foo_int = 4; - string foo_string = 9; - ... -} -``` - -The compiler will generate the following C++ enum type: - -```cpp -enum ExampleNameCase { - kFooInt = 4, - kFooString = 9, - EXAMPLE_NAME_NOT_SET = 0 -} -``` - -In addition, it will generate these methods: - -- `ExampleNameCase example_name_case() const`: Returns the enum indicating - which field is set. Returns `EXAMPLE_NAME_NOT_SET` if none of them is set. -- `void clear_example_name()`: Frees the object if the oneof field set uses a - pointer (Message or String), and sets the oneof case to - `EXAMPLE_NAME_NOT_SET`. - -## 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 -enum Foo { - VALUE_A = 0; - VALUE_B = 5; - VALUE_C = 1234; -} -``` - -The protocol buffer compiler will generate a C++ enum type called `Foo` with the -same set of values. In addition, the compiler will generate the following -functions: - -- `const EnumDescriptor* Foo_descriptor()`: Returns the type's descriptor, - which contains information about what values this enum type defines. -- `bool Foo_IsValid(int value)`: Returns `true` if the given numeric value - matches one of `Foo`'s defined values. In the above example, it would return - `true` if the input were 0, 5, or 1234. -- `const string& 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"`. -- `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 - example). -- `const Foo Foo_MAX`: the largest valid value of the enum (VALUE_C in the - example). -- `const int Foo_ARRAYSIZE`: always defined as `Foo_MAX + 1`. - -**Be careful when casting integers to proto2 enums.** If an integer is cast to a -proto2 enum value, the integer *must* be one of the valid values for that enum, -or the results may be undefined. If in doubt, use the generated `Foo_IsValid()` -function to test if the cast is valid. Setting an enum-typed field of a proto2 -message to an invalid value may cause an assertion failure. If an invalid enum -value is read when parsing a proto2 message, it will be treated as an -[unknown field](/reference/cpp/api-docs/google.protobuf.unknown_field_set). -These semantics have been changed in proto3. It's safe to cast any integer to a -proto3 enum value as long as it fits into int32. Invalid enum values will also -be kept when parsing a proto3 message and returned by enum field accessors. - -**Be careful when using proto3 and editions enums in switch statements.** Proto3 -and editions enums are open enum types with possible values outside the range of -specified symbols. (Editions enums may be set to closed enums using the -[`enum_type`](/editions/features#enum_type) feature.) -Unrecognized enum values for open enums types will be kept when parsing a -message and returned by the enum field accessors. A switch statement on an open -enum without a default case will not be able to catch all cases, even if all the -known fields are listed. This could lead to unexpected behavior, including data -corruption and runtime crashes. **Always add a default case or explicitly call -`Foo_IsValid(int)` outside of the switch to handle unknown enum values.** - -You can define an enum inside a message type. In this case, the protocol buffer -compiler generates code that makes it appear that the enum type itself was -declared nested inside the message's class. The `Foo_descriptor()` and -`Foo_IsValid()` functions are declared as static methods. In reality, the enum -type itself and its values are declared at the global scope with mangled names, -and are imported into the class's scope with a `typedef` and a series of -constant definitions. This is done only to get around problems with declaration -ordering. Do not depend on the mangled top-level names; pretend the enum really -is nested in the message class. - -### Abseil flag support {#absl-flags-enums} - -Generated `enum` values have native support for Abseil's flag parse/unparse -logic. They can be used as the type for `ABSL_FLAG` declarations. - -The flag parser supports both labels and numbers. Labels can be lowercase, if -they are unambiguous. Invalid labels/numbers will cause a parse failure. - -## Extensions (proto2 and editions only) {#extension} - -Given a message with an extension range: - -```proto -message Foo { - extensions 100 to 199; -} -``` - -The protocol buffer compiler will generate some additional methods for `Foo`: -`HasExtension()`, `ExtensionSize()`, `ClearExtension()`, `GetExtension()`, -`SetExtension()`, `MutableExtension()`, `AddExtension()`, -`SetAllocatedExtension()` and `ReleaseExtension()`. Each of these methods takes, -as its first parameter, an extension identifier (described later in this -section), which identifies an extension field. The remaining parameters and the -return value are exactly the same as those for the corresponding accessor -methods that would be generated for a normal (non-extension) field of the same -type as the extension identifier. (`GetExtension()` corresponds to the accessors -with no special prefix.) - -Given an extension definition: - -```proto -extend Foo { - optional int32 bar = 123; - repeated int32 repeated_bar = 124; - optional Bar message_bar = 125; -} -``` - -For the singular extension field `bar`, the protocol buffer compiler generates -an "extension identifier" called `bar`, which you can use with `Foo`'s extension -accessors to access this extension, like so: - -```cpp -Foo foo; -assert(!foo.HasExtension(bar)); -foo.SetExtension(bar, 1); -assert(foo.HasExtension(bar)); -assert(foo.GetExtension(bar) == 1); -foo.ClearExtension(bar); -assert(!foo.HasExtension(bar)); -``` - -For the message extension field `message_bar`, if the field is not set -`foo.GetExtension(message_bar)` returns a `Bar` with none of its fields set -(possibly `Bar::default_instance()`). - -Similarly, for the repeated extension field `repeated_bar`, the compiler -generates an extension identifier called `repeated_bar`, which you can also use -with `Foo`'s extension accessors: - -```cpp -Foo foo; -for (int i = 0; i < kSize; ++i) { - foo.AddExtension(repeated_bar, i) -} -assert(foo.ExtensionSize(repeated_bar) == kSize) -for (int i = 0; i < kSize; ++i) { - assert(foo.GetExtension(repeated_bar, i) == i) -} -``` - -(The exact implementation of extension identifiers is complicated and involves -magical use of templates—however, you don't need to worry about how extension -identifiers work to use them.) - -Extensions can be declared nested inside of another type. For example, a common -pattern is to do something like this: - -```proto -message Baz { - extend Foo { - optional Baz foo_ext = 124; - } -} -``` - -In this case, the extension identifier `foo_ext` is declared nested inside -`Baz`. It can be used as follows: - -```cpp -Foo foo; -Baz* baz = foo.MutableExtension(Baz::foo_ext); -FillInMyBaz(baz); -``` - -## Arena Allocation {#arena} - -Arena allocation is a C++-only feature that helps you optimize your memory usage -and improve performance when working with protocol buffers. Enabling arena -allocation in your `.proto` adds additional code for working with arenas to your -C++ generated code. You can find out more about the arena allocation API in the -[Arena Allocation Guide](/reference/cpp/arenas). - -## Services {#service} - -If the `.proto` file contains the following line: - -```proto -option cc_generic_services = true; -``` - -then the protocol buffer compiler will generate code based on the service -definitions found in the file as described in this section. However, the -generated code may be undesirable as it is not tied to any particular RPC -system, and thus requires more levels of indirection than code tailored to one -system. If you do NOT want this code to be generated, add this line to the file: - -```proto -option cc_generic_services = false; -``` - -If neither of the above lines are given, the option defaults to `false`, as -generic services are deprecated. (Note that prior to 2.4.0, the option defaults -to `true`) - -RPC systems based on `.proto`-language service definitions should provide -[plugins](/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb) -to generate code appropriate for the system. These plugins are likely to require -that abstract services are disabled, so that they can generate their own classes -of the same names. - -The remainder of this section describes what the protocol buffer compiler -generates when abstract services are enabled. - -### Interface - -Given a service definition: - -```proto -service Foo { - rpc Bar(FooRequest) returns(FooResponse); -} -``` - -The protocol buffer compiler will generate a class `Foo` to represent this -service. `Foo` will have a virtual method for each method defined in the service -definition. In this case, the method `Bar` is defined as: - -```cpp -virtual void Bar(RpcController* controller, const FooRequest* request, - FooResponse* response, Closure* done); -``` - -The parameters are equivalent to the parameters of `Service::CallMethod()`, -except that the `method` argument is implied and `request` and `response` -specify their exact type. - -These generated methods are virtual, but not pure-virtual. The default -implementations simply call `controller->SetFailed()` with an error message -indicating that the method is unimplemented, then invoke the `done` callback. -When implementing your own service, you must subclass this generated service and -implement its methods as appropriate. - -`Foo` subclasses the `Service` interface. The protocol buffer compiler -automatically generates implementations of the methods of `Service` as follows: - -- `GetDescriptor`: Returns the service's - [`ServiceDescriptor`](/reference/cpp/api-docs/google.protobuf.descriptor#ServiceDescriptor). -- `CallMethod`: Determines which method is being called based on the provided - method descriptor and calls it directly, down-casting the request and - response messages objects to the correct types. -- `GetRequestPrototype` and `GetResponsePrototype`: Returns the default - instance of the request or response of the correct type for the given - method. - -The following static method is also generated: - -- `static ServiceDescriptor descriptor()`: Returns the type's descriptor, - which contains information about what methods this service has and what - their input and output types are. - -### Stub {#stub} - -The protocol buffer compiler also generates a "stub" implementation of every -service interface, which is used by clients wishing to send requests to servers -implementing the service. For the `Foo` service (described earlier), the stub -implementation `Foo_Stub` will be defined. As with nested message types, a -`typedef` is used so that `Foo_Stub` can also be referred to as `Foo::Stub`. - -`Foo_Stub` is a subclass of `Foo` which also implements the following methods: - -- `Foo_Stub(RpcChannel* channel)`: Constructs a new stub which sends requests - on the given channel. -- `Foo_Stub(RpcChannel* channel, ChannelOwnership ownership)`: Constructs a - new stub which sends requests on the given channel and possibly owns that - channel. If `ownership` is `Service::STUB_OWNS_CHANNEL` then when the stub - object is deleted it will delete the channel as well. -- `RpcChannel* channel()`: Returns this stub's channel, as passed to the - constructor. - -The stub additionally implements each of the service's methods as a wrapper -around the channel. Calling one of the methods simply calls -`channel->CallMethod()`. - -The Protocol Buffer library does not include an RPC implementation. However, it -includes all of the tools you need to hook up a generated service class to any -arbitrary RPC implementation of your choice. You need only provide -implementations of -[`RpcChannel`](/reference/cpp/api-docs/google.protobuf.service#RpcChannel) -and -[`RpcController`](/reference/cpp/api-docs/google.protobuf.service#RpcController). -See the documentation for -[`service.h`](/reference/cpp/api-docs/google.protobuf.service) -for more information. - -## Plugin Insertion Points {#plugins} - -[Code generator plugins](/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb) -which want to extend the output of the C++ code generator may insert code of the -following types using the given insertion point names. Each insertion point -appears in both the `.pb.cc` file and the `.pb.h` file unless otherwise noted. - -- `includes`: Include directives. -- `namespace_scope`: Declarations that belong in the file's package/namespace, - but not within any particular class. Appears after all other namespace-scope - code. -- `global_scope`: Declarations that belong at the top level, outside of the - file's namespace. Appears at the very end of the file. -- `class_scope:TYPENAME`: Member declarations that belong in a message class. - `TYPENAME` is the full proto name, such as `package.MessageType`. Appears - after all other public declarations in the class. This insertion point - appears only in the `.pb.h` file. - -Do not generate code which relies on private class members declared by the -standard code generator, as these implementation details may change in future -versions of Protocol Buffers. diff --git a/content/reference/cpp/string-view.md b/content/reference/cpp/string-view.md deleted file mode 100644 index da38053c0..000000000 --- a/content/reference/cpp/string-view.md +++ /dev/null @@ -1,185 +0,0 @@ -+++ -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/csharp/_index.md b/content/reference/csharp/_index.md deleted file mode 100644 index 9a01fbe58..000000000 --- a/content/reference/csharp/_index.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "C# Reference" -weight = 540 -linkTitle = "C#" -description = "Reference documentation for working with protocol buffer classes in C#" -type = "docs" -+++ diff --git a/content/reference/csharp/api-docs-link.md b/content/reference/csharp/api-docs-link.md deleted file mode 100644 index d16add2c0..000000000 --- a/content/reference/csharp/api-docs-link.md +++ /dev/null @@ -1,8 +0,0 @@ - - ---- -title: "C# API" -manualLink: "/reference/csharp/api-docs" -manualLinkTarget: "_blank" -weight: 560 ---- \ No newline at end of file diff --git a/content/reference/csharp/csharp-generated.md b/content/reference/csharp/csharp-generated.md deleted file mode 100644 index f0a55220a..000000000 --- a/content/reference/csharp/csharp-generated.md +++ /dev/null @@ -1,383 +0,0 @@ -+++ -title = "C# Generated Code Guide" -weight = 550 -linkTitle = "Generated Code Guide" -description = "Describes exactly what C# code the protocol buffer compiler generates for protocol definitions using editions syntax." -type = "docs" -+++ - -You should read the -[proto2 language guide](/programming-guides/proto2), -[proto3 language guide](/programming-guides/proto3), or -[editions language guide](/programming-guides/editions) -before reading this document. - -## Compiler Invocation {#invocation} - -The protocol buffer compiler produces C\# output when invoked with the -`--csharp_out` command-line flag. The parameter to the `--csharp_out` option is -the directory where you want the compiler to write your C\# output, although -depending on [other options](#compiler_options) the compiler may create -subdirectories of the specified directory. The compiler creates a single source -file for each `.proto` file input, defaulting to an extension of `.cs` but -configurable via compiler options. - -### C\#-specific Options {#compiler_options} - -You can provide further C\# options to the protocol buffer compiler using the -`--csharp_opt` command-line flag. The supported options are: - -- **file\_extension**: Sets the file extension for generated code. This - defaults to `.cs`, but a common alternative is `.g.cs` to indicate that the - file contains generated code. - -- **base\_namespace**: When this option is specified, the generator creates a - directory hierarchy for generated source code corresponding to the - namespaces of the generated classes, using the value of the option to - indicate which part of the namespace should be considered as the \"base\" - for the output directory. For example, with the following command-line: - - ```shell - protoc --proto_path=bar --csharp_out=src --csharp_opt=base_namespace=Example player.proto - ``` - - where `player.proto` has a `csharp_namespace` option of `Example.Game` the - protocol buffer compiler generates a file `src/Game/Player.cs` being - created. This option would usually correspond with the **default namespace** - option in a C\# project in Visual Studio. If the option is specified but - with an empty value, the full C\# namespace as used in the generated file - will be used for the directory hierarchy. If the option is not specified at - all, the generated files are simply written into the directory specified by - `--csharp_out` without any hierarchy being created. - -- **internal\_access**: When this option is specified, the generator creates - types with the `internal` access modifier instead of `public`. - -- **serializable**: When this option is specified, the generator adds the - `[Serializable]` attribute to generated message classes. - -Multiple options can be specified by separating them with commas, as in the -following example: - -```shell -protoc --proto_path=src --csharp_out=build/gen --csharp_opt=file_extension=.g.cs,base_namespace=Example,internal_access src/foo.proto -``` - -## File structure {#structure} - -The name of the output file is derived from the `.proto` filename by converting -it to Pascal-case, treating underscores as word separators. So, for example, a -file called `player_record.proto` will result in an output file called -`PlayerRecord.cs` (where the file extension can be specified using -`--csharp_opt`, [as shown above](#compiler_options)). - -Each generated file takes the following form, in terms of public members. (The -implementation is not shown here.) - -```csharp -namespace [...] -{ - public static partial class [... descriptor class name ...] - { - public static FileDescriptor Descriptor { get; } - } - - [... Enums ...] - [... Message classes ...] -} -``` - -The `namespace` is inferred from the proto's `package`, using the same -conversion rules as the file name. For example, a proto package of -`example.high_score` would result in a namespace of `Example.HighScore`. You can -override the default generated namespace for a particular .proto using the -`csharp_namespace` -[file option](/programming-guides/proto3#options). - -Each top-level enum and message results in an enum or class being declared as -members of the namespace. Additionally, a single static partial class is always -generated for the file descriptor. This is used for reflection-based operations. -The descriptor class is given the same name as the file, without the extension. -However, if there is a message with the same name (as is quite common), the -descriptor class is placed in a nested `Proto` namespace to avoid colliding with -the message. - -As an example of all of these rules, consider the `timestamp.proto` file which -is provided as part of Protocol Buffers. A cut down version of `timestamp.proto` -looks like this: - -```proto -edition = "2023"; - -package google.protobuf; -option csharp_namespace = "Google.Protobuf.WellKnownTypes"; - -message Timestamp { ... } -``` - -The generated `Timestamp.cs` file has the following structure: - -```csharp -namespace Google.Protobuf.WellKnownTypes -{ - namespace Proto - { - public static partial class Timestamp - { - public static FileDescriptor Descriptor { get; } - } - } - - public sealed partial class Timestamp : IMessage - { - [...] - } -} -``` - -## Messages {#message} - -Given a simple message declaration: - -```proto -message Foo {} -``` - -The protocol buffer compiler generates a sealed, partial class called `Foo`, -which implements the `IMessage` interface, as shown below with member -declarations. See the inline comments for more information. - -```csharp -public sealed partial class Foo : IMessage -{ - // Static properties for parsing and reflection - public static MessageParser Parser { get; } - public static MessageDescriptor Descriptor { get; } - - // Explicit implementation of IMessage.Descriptor, to avoid conflicting with - // the static Descriptor property. Typically the static property is used when - // referring to a type known at compile time, and the instance property is used - // when referring to an arbitrary message, such as during JSON serialization. - MessageDescriptor IMessage.Descriptor { get; } - - // Parameterless constructor which calls the OnConstruction partial method if provided. - public Foo(); - // Deep-cloning constructor - public Foo(Foo); - // Partial method which can be implemented in manually-written code for the same class, to provide - // a hook for code which should be run whenever an instance is constructed. - partial void OnConstruction(); - - // Implementation of IDeepCloneable.Clone(); creates a deep clone of this message. - public Foo Clone(); - - // Standard equality handling; note that IMessage extends IEquatable - public override bool Equals(object other); - public bool Equals(Foo other); - public override int GetHashCode(); - - // Converts the message to a JSON representation - public override string ToString(); - - // Serializes the message to the protobuf binary format - public void WriteTo(CodedOutputStream output); - // Calculates the size of the message in protobuf binary format - public int CalculateSize(); - - // Merges the contents of the given message into this one. Typically - // used by generated code and message parsers. - public void MergeFrom(Foo other); - - // Merges the contents of the given protobuf binary format stream - // into this message. Typically used by generated code and message parsers. - public void MergeFrom(CodedInputStream input); -} -``` - -Note that all of these members are always present; the `optimize_for` option -does not affect the output of the C\# code generator. - -### Nested Types - -A message can be declared inside another message. For example: - -```proto -message Foo { - message Bar { - } -} -``` - -In this case—or if a message contains a nested enum—the compiler -generates a nested `Types` class, and then a `Bar` class within the `Types` -class, so the full generated code would be: - -```csharp -namespace [...] -{ - public sealed partial class Foo : IMessage - { - public static partial class Types - { - public sealed partial class Bar : IMessage { ... } - } - } -} -``` - -Although the intermediate `Types` class is inconvenient, it is required to deal -with the common scenario of a nested type having a corresponding field in the -message. You would otherwise end up with both a property and a type with the -same name nested within the same class—and that would be invalid C\#. - -## Fields - -The protocol buffer compiler generates a C\# property for each field defined -within a message. The exact nature of the property depends on the nature of the -field: its type, and whether it is singular, repeated, or a map field. - -### Singular Fields {#singular} - -Any singular field generates a read/write property. A `string` or `bytes` field -will generate an `ArgumentNullException` if a null value is specified; fetching -a value from a field which hasn't been explicitly set will return an empty -string or `ByteString`. Message fields can be set to null values, which is -effectively clearing the field. This is not equivalent to setting the value to -an \"empty\" instance of the message type. - -### Repeated Fields {#repeated} - -Each repeated field generates a read-only property of type -`Google.Protobuf.Collections.RepeatedField` where `T` is the field's element -type. For the most part, this acts like `List`, but it has an additional -`Add` overload to allow a collection of items to be added in one go. This is -convenient when populating a repeated field in an object initializer. -Additionally, `RepeatedField` has direct support for serialization, -deserialization and cloning, but this is usually used by generated code instead -of manually-written application code. - -Repeated fields cannot contain null values, even of message types, except for -the nullable wrapper types [explained below](#wrapper_types). - -### Map Fields {#map} - -Each map field generates a read-only property of type -`Google.Protobuf.Collections.MapField` where `TKey` is the field's -key type and `TValue` is the field's value type. For the most part, this acts -like `Dictionary`, but it has an additional `Add` overload to -allow another dictionary to be added in one go. This is convenient when -populating a repeated field in an object initializer. Additionally, -`MapField` has direct support for serialization, deserialization -and cloning, but this is usually used by generated code instead of -manually-written application code. Keys in the map are not permitted to be null; -values may be if the corresponding singular field type would support null -values. - -### Oneof Fields {#oneof} - -Each field within a oneof has a separate property, like a regular -[singular field](#singular). However, the compiler also generates an additional -property to determine which field in the enum has been set, along with an enum -and a method to clear the oneof. For example, for this oneof field definition - -```proto -oneof avatar { - string image_url = 1; - bytes image_data = 2; -} -``` - -The compiler will generate these public members: - -```csharp -enum AvatarOneofCase -{ - None = 0, - ImageUrl = 1, - ImageData = 2 -} - -public AvatarOneofCase AvatarCase { get; } -public void ClearAvatar(); -public string ImageUrl { get; set; } -public ByteString ImageData { get; set; } -``` - -If a property is the current oneof \"case\", fetching that property will return -the value set for that property. Otherwise, fetching the property will return -the default value for the property's type—only one member of a oneof can -be set at a time. - -Setting any constituent property of the oneof will change the reported \"case\" -of the oneof. As with a regular [singular field](#singular), you cannot set a -oneof field with a `string` or `bytes` type to a null value. Setting a -message-type field to null is equivalent to calling the oneof-specific `Clear` -method. - -### Wrapper Type Fields {#wrapper_types} - -Most of the well-known types do not affect code generation, but the wrapper -types (such as `StringWrapper` and `Int32Wrapper`) change the type and behavior -of the properties. - -All of the wrapper types that correspond to C\# value types (such as -`Int32Wrapper`, `DoubleWrapper`, and `BoolWrapper`) are mapped to `Nullable` -where `T` is the corresponding non-nullable type. For example, a field of type -`DoubleValue` results in a C\# property of type `Nullable`. - -Fields of type `StringWrapper` or `BytesWrapper` result in C\# properties of -type `string` and `ByteString` being generated, but with a default value of -null, and allowing null to be set as the property value. - -For all wrapper types, null values are not permitted in a repeated field, but -are permitted as the values for map entries. - -## Enumerations {#enum} - -Given an enumeration definition like: - -```proto -enum Color { - COLOR_UNSPECIFIED = 0; - COLOR_RED = 1; - COLOR_GREEN = 5; - COLOR_BLUE = 1234; -} -``` - -The protocol buffer compiler will generate a C\# enum type called `Color` with -the same set of values. The names of the enum values are converted to make them -more idiomatic for C\# developers: - -- If the original name starts with the upper-cased form of the enum name - itself, that is removed -- The result is converted into Pascal case - -The `Color` proto enum above would therefore become the following C\# code: - -```csharp -enum Color -{ - Unspecified = 0, - Red = 1, - Green = 5, - Blue = 1234 -} -``` - -This name transformation does not affect the text used within the JSON -representation of messages. - -Note that the `.proto` language allows multiple enum symbols to have the same -numeric value. Symbols with the same numeric value are synonyms. These are -represented in C\# in exactly the same way, with multiple names corresponding to -the same numeric value. - -A non-nested enumeration leads to a C\# enum being generated as a new namespace -member being generated; a nested enumeration lead to a C\# enum being generated -in the `Types` nested class within the class corresponding to the message the -enumeration is nested within. - -## Services {#service} - -The C\# code generator ignores services entirely. diff --git a/content/reference/dart/_index.md b/content/reference/dart/_index.md deleted file mode 100644 index eefb1100b..000000000 --- a/content/reference/dart/_index.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "Dart Reference" -weight = 570 -linkTitle = "Dart" -description = "Reference documentation for working with protocol buffer classes in Dart" -type = "docs" -+++ diff --git a/content/reference/dart/api-docs-link.md b/content/reference/dart/api-docs-link.md deleted file mode 100644 index eddcc7414..000000000 --- a/content/reference/dart/api-docs-link.md +++ /dev/null @@ -1,8 +0,0 @@ - - ---- -title: "Dart API" -manualLink: "https://pub.dartlang.org/documentation/protobuf" -manualLinkTarget: "_blank" -weight: 590 ---- \ No newline at end of file diff --git a/content/reference/dart/dart-generated.md b/content/reference/dart/dart-generated.md deleted file mode 100644 index ff94ca5cd..000000000 --- a/content/reference/dart/dart-generated.md +++ /dev/null @@ -1,486 +0,0 @@ -+++ -title = "Dart Generated Code" -weight = 580 -linkTitle = "Generated Code" -description = "Describes what Dart code the protocol buffer compiler generates for any given protocol definition." -type = "docs" -+++ - -Any differences between -proto2, proto3, and editions generated code are highlighted - note that these -differences are in the generated code as described in this document, not the -base API, which are the same in both versions. You should read the -[proto2 language guide](/programming-guides/proto2), -[proto3 language guide](/programming-guides/proto3), or -[editions language guide](/programming-guides/editions) -before reading this document. - -## Compiler Invocation {#invocation} - -The protocol buffer compiler requires a -[plugin to generate Dart](https://github.com/dart-lang/dart-protoc-plugin) code. -Installing it following the -[instructions](https://github.com/dart-lang/dart-protoc-plugin#how-to-build-and-use) -provides a `protoc-gen-dart` binary which `protoc` uses when invoked with the -`--dart_out` command-line flag. The `--dart_out` flag tells the compiler where -to write the Dart source files. For a `.proto` file input, the compiler produces -among others a `.pb.dart` file. - -The name of the `.pb.dart` file is computed by taking the name of the `.proto` -file and making two changes: - -- The extension (`.proto`) is replaced with `.pb.dart`. For example, a file - called `foo.proto` results in an output file called `foo.pb.dart`. -- The proto path (specified with the `--proto_path` or `-I` command-line flag) - is replaced with the output path (specified with the `--dart_out` flag). - -For example, when you invoke the compiler as follows: - -```shell -protoc --proto_path=src --dart_out=build/gen src/foo.proto src/bar/baz.proto -``` - -the compiler will read the files `src/foo.proto` and `src/bar/baz.proto`. It -produces: `build/gen/foo.pb.dart` and `build/gen/bar/baz.pb.dart`. The compiler -automatically creates the directory `build/gen/bar` if necessary, but it will -*not* create `build` or `build/gen`; they must already exist. - -## Messages {#message} - -Given a simple message declaration: - -```proto -message Foo {} -``` - -The protocol buffer compiler generates a class called `Foo`, which extends the -class `GeneratedMessage`. - -The class `GeneratedMessage` defines methods that let you check, manipulate, -read, or write the entire message. In addition to these methods, the `Foo` class -defines the following methods and constructors: - -- `Foo()`: Default constructor. Creates an instance where all singular fields - are unset and repeated fields are empty. -- `Foo.fromBuffer(...)`: Creates a `Foo` from serialized protocol buffer data - representing the message. -- `Foo.fromJson(...)`: Creates a `Foo` from a JSON string encoding the - message. -- `Foo clone()`: Creates a deep clone of the fields in the message. -- `Foo copyWith(void Function(Foo) updates)`: Makes a writable copy of this - message, applies the `updates` to it, and marks the copy read-only before - returning it. -- `static Foo create()`: Factory function to create a single `Foo`. -- `static PbList createRepeated()`: Factory function to create a List - implementing a mutable repeated field of `Foo` elements. -- `static Foo getDefault()`: Returns a singleton instance of `Foo`, which is - identical to a newly-constructed instance of Foo (so all singular fields are - unset and all repeated fields are empty). - -### Nested Types - -A message can be declared inside another message. For example: - -```proto -message Foo { - message Bar { - } -} -``` - -In this case, the compiler generates two classes: `Foo` and `Foo_Bar`. - -## Fields - -In addition to the methods described in the previous section, the protocol -buffer compiler generates accessor methods for each field defined within the -message in the `.proto` file. - -Note that the generated names always use camel-case naming, even if the field -name in the `.proto` file uses lower-case with underscores -([as it should](/programming-guides/style)). The -case-conversion works as follows: - -1. For each underscore in the name, the underscore is removed, and the - following letter is capitalized. -2. If the name will have a prefix attached (e.g. \"has\"), the first letter is - capitalized. Otherwise, it is lower-cased. - -Thus, for the field `foo_bar_baz`, the getter becomes `get fooBarBaz` and a -method prefixed with `has` would be `hasFooBarBaz`. - -### Singular Primitive Fields - -All fields have -[explicit presence](/programming-guides/field_presence#presence-proto2) -in the Dart implementation. - -For the following field definition: - -```proto -int32 foo = 1; -``` - -The compiler will generate the following accessor methods in the message class: - -- `int get foo`: Returns the current value of the field. If the field is not - set, returns the default value. -- `bool hasFoo()`: Returns `true` if the field is set. -- `set foo(int value)`: Sets the value of the field. After calling this, - `hasFoo()` will return `true` and `get foo` will return `value`. -- `void clearFoo()`: Clears the value of the field. After calling this, - `hasFoo()` will return `false` and `get foo` will return the default value. - - {{% alert title="Note" color="note" %}} Due to a - quirk in the Dart proto3 implementation, the following methods are generated - even if implicit presence is - configured.{{% /alert %}} - -- `bool hasFoo()`: Returns `true` if the field is set. - - {{% alert title="Note" color="note" %}} This - value cannot really be trusted if the proto was serialized in another - language that supports implicit presence (for example, Java). Even though - Dart tracks presence, other languages do not, and round-tripping a - zero-valued implicit presence field will make it "disappear" from Dart's - perspective. - {{% /alert %}} - -- `void clearFoo()`: Clears the value of the field. After calling this, - `hasFoo()` will return `false` and `get foo` will return the default value. - -For other simple field types, the corresponding Dart type is chosen according to -the -[scalar value types table](/programming-guides/editions#scalar). -For message and enum types, the value type is replaced with the message or enum -class. - -### Singular Message Fields {#singular-message} - -Given the message type: - -```proto -message Bar {} -``` - -For a message with a `Bar` field: - -```proto -// proto2 -message Baz { - optional Bar bar = 1; - // The generated code is the same result if required instead of optional. -} - -// proto3 and editions -message Baz { - Bar bar = 1; -} -``` - -The compiler will generate the following accessor methods in the message class: - -- `Bar get bar`: Returns the current value of the field. If the field is not - set, returns the default value. -- `set bar(Bar value)`: Sets the value of the field. After calling this, - `hasBar()` will return `true` and `get bar` will return `value`. -- `bool hasBar()`: Returns `true` if the field is set. -- `void clearBar()`: Clears the value of the field. After calling this, - `hasBar()` will return `false` and `get bar` will return the default value. -- `Bar ensureBar()`: Sets `bar` to the empty instance if `hasBar()` returns - `false`, and then returns the value of `bar`. After calling this, `hasBar()` - will return `true`. - -### Repeated Fields - -For this field definition: - -```proto -repeated int32 foo = 1; -``` - -The compiler will generate: - -- `List get foo`: Returns the list backing the field. If the field is not - set, returns an empty list. Modifications to the list are reflected in the - field. - -### Int64 Fields - -For this field definition: - -```proto -int64 bar = 1; -``` - -The compiler will generate: - -- `Int64 get bar`: Returns an `Int64` object containing the field value. - -Note that `Int64` is not built into the Dart core libraries. To work with these -objects, you may need to import the Dart `fixnum` library: - -```dart -import 'package:fixnum/fixnum.dart'; -``` - -### Map Fields - -Given a [`map`](/programming-guides/editions#maps) field -definition like this: - -```proto -map map_field = 1; -``` - -The compiler will generate the following getter: - -- `Map get mapField`: Returns the Dart map backing the field. If the - field is not set, returns an empty map. Modifications to the map are - reflected in the field. - -### Any - -Given an [`Any`](/programming-guides/editions#any) field -like this: - -```proto -import "google/protobuf/any.proto"; - -message ErrorStatus { - string message = 1; - google.protobuf.Any details = 2; -} -``` - -In our generated code, the getter for the `details` field returns an instance of -`com.google.protobuf.Any`. This provides the following special methods to pack -and unpack the `Any`'s values: - -```dart - /// Unpacks the message in [value] into [instance]. - /// - /// Throws a [InvalidProtocolBufferException] if [typeUrl] does not correspond - /// to the type of [instance]. - /// - /// A typical usage would be `any.unpackInto(new Message())`. - /// - /// Returns [instance]. - T unpackInto(T instance, - {ExtensionRegistry extensionRegistry = ExtensionRegistry.EMPTY}); - - /// Returns `true` if the encoded message matches the type of [instance]. - /// - /// Can be used with a default instance: - /// `any.canUnpackInto(Message.getDefault())` - bool canUnpackInto(GeneratedMessage instance); - - /// Creates a new [Any] encoding [message]. - /// - /// The [typeUrl] will be [typeUrlPrefix]/`fullName` where `fullName` is - /// the fully qualified name of the type of [message]. - static Any pack(GeneratedMessage message, - {String typeUrlPrefix = 'type.googleapis.com'}); -``` - -### Oneof - -Given a [`oneof`](/programming-guides/editions#oneof) -definition like this: - -```proto -message Foo { - oneof test { - string name = 1; - SubMessage sub_message = 2; - } -} -``` - -The compiler will generate the following Dart enum type: - -```dart - enum Foo_Test { name, subMessage, notSet } -``` - -In addition, it will generate these methods: - -- `Foo_Test whichTest()`: Returns the enum indicating which field is set. - Returns `Foo_Test.notSet` if none of them is set. -- `void clearTest()`: Clears the value of the oneof field which is currently - set (if any), and sets the oneof case to `Foo_Test.notSet`. - -For each field inside the oneof definition the regular field accessor methods -are generated. For instance for `name`: - -- `String get name`: Returns the current value of the field if the oneof case - is `Foo_Test.name`. Otherwise, returns the default value. -- `set name(String value)`: Sets the value of the field and sets the oneof - case to `Foo_Test.name`. After calling this, `get name` will return `value` - and `whichTest()` will return `Foo_Test.name`. -- `void clearName()`: Nothing will be changed if the oneof case is not - `Foo_Test.name`. Otherwise, clears the value of the field. After calling - this, `get name` will return the default value and `whichTest()` will return - `Foo_Test.notSet`. - -### Enumerations {#enum} - -Given an enum definition like: - -```proto -enum Color { - COLOR_UNSPECIFIED = 0; - COLOR_RED = 1; - COLOR_GREEN = 2; - COLOR_BLUE = 3; -} -``` - -The protocol buffer compiler will generate a class called `Color`, which extends -the `ProtobufEnum` class. The class will include a `static const Color` for each -of the four values, as well as a `static const List` that contains the -values. - -```dart -static const List values = [ - COLOR_UNSPECIFIED, - COLOR_RED, - COLOR_GREEN, - COLOR_BLUE, -]; -``` - -It will also include the following method: - -- `static Color? valueOf(int value)`: Returns the `Color` corresponding to the - given numeric value. - -Each value will have the following properties: - -- `name`: The enum's name, as specified in the .proto file. -- `value`: The enum's integer value, as specified in the .proto file. - -Note that the `.proto` language allows multiple enum symbols to have the same -numeric value. Symbols with the same numeric value are synonyms. For example: - -```proto -enum Foo { - BAR = 0; - BAZ = 0; -} -``` - -In this case, `BAZ` is a synonym for `BAR` and will be defined like so: - -```dart -static const Foo BAZ = BAR; -``` - -An enum can be defined nested within a message type. For instance, given an enum -definition like: - -```proto -message Bar { - enum Color { - COLOR_UNSPECIFIED = 0; - COLOR_RED = 1; - COLOR_GREEN = 2; - COLOR_BLUE = 3; - } -} -``` - -The protocol buffer compiler will generate a class called `Bar`, which extends -`GeneratedMessage`, and a class called `Bar_Color`, which extends -`ProtobufEnum`. - -## Extensions (not available in proto3) {#extension} - -Given a file `foo_test.proto` including a message with an -[extension range](/programming-guides/editions#extensions) -and a top-level extension definition: - -```proto -message Foo { - extensions 100 to 199; -} - -extend Foo { - optional int32 bar = 101; -} -``` - -The protocol buffer compiler will generate, in addition to the `Foo` class, a -class `Foo_test` which will contain a `static Extension` for each extension -field in the file along with a method for registering all the extensions in an -`ExtensionRegistry` : - -- `static final Extension bar` -- `static void registerAllExtensions(ExtensionRegistry registry)` : Registers - all the defined extensions in the given registry. - -The extension accessors of `Foo` can be used as follows: - -```dart -Foo foo = Foo(); -foo.setExtension(Foo_test.bar, 1); -assert(foo.hasExtension(Foo_test.bar)); -assert(foo.getExtension(Foo_test.bar)) == 1); -``` - -Extensions can also be declared nested inside of another message: - -```proto -message Baz { - extend Foo { - int32 bar = 124; - } -} -``` - -In this case, the extension `bar` is instead declared as a static member of the -`Baz` class. - -When parsing a message that might have extensions, you must provide an -`ExtensionRegistry` in which you have registered any extensions that you want to -be able to parse. Otherwise, those extensions will just be treated like unknown -fields. For example: - -```dart -ExtensionRegistry registry = ExtensionRegistry(); -registry.add(Baz.bar); -Foo foo = Foo.fromBuffer(input, registry); -``` - -If you already have a parsed message with unknown fields, you can use -`reparseMessage` on an `ExtensionRegistry` to reparse the message. If the set of -unknown fields contains extensions that are present in the registry, these -extensions are parsed and removed from the unknown field set. Extensions already -present in the message are preserved. - -```dart -Foo foo = Foo.fromBuffer(input); -ExtensionRegistry registry = ExtensionRegistry(); -registry.add(Baz.bar); -Foo reparsed = registry.reparseMessage(foo); -``` - -Be aware that this method to retrieve extensions is more expensive overall. -Where possible we recommend using `ExtensionRegistry` with all the needed -extensions when doing `GeneratedMessage.fromBuffer`. - -## Services {#service} - -Given a service definition: - -```proto -service Foo { - rpc Bar(FooRequest) returns(FooResponse); -} -``` - -The protocol buffer compiler can be invoked with the \`grpc\` option (e.g. -`--dart_out=grpc:output_folder`), in which case it will generate code to support -[gRPC](//www.grpc.io/). See the -[gRPC Dart Quickstart guide](https://grpc.io/docs/quickstart/dart.html) -for more details. diff --git a/content/reference/go/_index.md b/content/reference/go/_index.md deleted file mode 100644 index f368a5f1f..000000000 --- a/content/reference/go/_index.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "Go Reference" -weight = 600 -linkTitle = "Go" -description = "Reference documentation for working with protocol buffer classes in Go" -type = "docs" -+++ diff --git a/content/reference/go/api-docs-link.md b/content/reference/go/api-docs-link.md deleted file mode 100644 index 04cb9a53d..000000000 --- a/content/reference/go/api-docs-link.md +++ /dev/null @@ -1,8 +0,0 @@ - - ---- -title: "Go API" -manualLink: "https://pkg.go.dev/google.golang.org/protobuf/proto" -manualLinkTarget: "_blank" -weight: 640 ---- diff --git a/content/reference/go/faq.md b/content/reference/go/faq.md deleted file mode 100644 index 922d3ae7f..000000000 --- a/content/reference/go/faq.md +++ /dev/null @@ -1,344 +0,0 @@ -+++ -title = "Go FAQ" -weight = 620 -linkTitle = "FAQ" -description = "A list of frequently asked questions about implementing protocol buffers in Go, with answer for each." -type = "docs" -+++ - -## Versions - -### What's the difference between `github.com/golang/protobuf` and `google.golang.org/protobuf`? {#modules} - -The -[`github.com/golang/protobuf`](https://pkg.go.dev/github.com/golang/protobuf?tab=overview) -module is the original Go protocol buffer API. - -The -[`google.golang.org/protobuf`](https://pkg.go.dev/google.golang.org/protobuf?tab=overview) -module is an updated version of this API designed for simplicity, ease of use, -and safety. The flagship features of the updated API are support for reflection -and a separation of the user-facing API from the underlying implementation. - -We recommend that you use `google.golang.org/protobuf` in new code. - -Version `v1.4.0` and higher of `github.com/golang/protobuf` wrap the new -implementation and permit programs to adopt the new API incrementally. For -example, the well-known types defined in `github.com/golang/protobuf/ptypes` are -simply aliases of those defined in the newer module. Thus, -[`google.golang.org/protobuf/types/known/emptypb`](https://pkg.go.dev/google.golang.org/protobuf/types/known/emptypb) -and -[`github.com/golang/protobuf/ptypes/empty`](https://pkg.go.dev/github.com/golang/protobuf/ptypes/empty) -may be used interchangeably. - -### What are `proto1`, `proto2`, `proto3`, and editions? {#proto-versions} - -These are revisions of the protocol buffer *language*. It is different from the -Go *implementation* of protobufs. - -* **Editions** are the newest and recommended way of writing Protocol Buffers. - New features will be released as part of new editions. For more information, - see [Protocol Buffer Editions](/editions). - -* `proto3` is a legacy version of the language. We encourage new code to use - editions. - -* `proto2` is a legacy version of the language. Despite being superseded by - proto3 and editions, proto2 is still fully supported. - -* `proto1` is an obsolete version of the language. It was never released as - open source. - -### There are several different `Message` types. Which should I use? {#message-types} - -* [`"google.golang.org/protobuf/proto".Message`](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#Message) - is an interface type implemented by all messages generated by the current - version of the protocol buffer compiler. Functions that operate on arbitrary - messages, such as - [`proto.Marshal`](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#Marshal) - or - [`proto.Clone`](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#Clone), - accept or return this type. - -* [`"google.golang.org/protobuf/reflect/protoreflect".Message`](https://pkg.go.dev/google.golang.org/protobuf/reflect/protoreflect?tab=doc#Message) - is an interface type describing a reflection view of a message. - - Call the `ProtoReflect` method on a `proto.Message` to get a - `protoreflect.Message`. - -* [`"google.golang.org/protobuf/reflect/protoreflect".ProtoMessage`](https://pkg.go.dev/google.golang.org/protobuf/reflect/protoreflect?tab=doc#ProtoMessage) - is an alias of `"google.golang.org/protobuf/proto".Message`. The two types - are interchangeable. - -* [`"github.com/golang/protobuf/proto".Message`](https://pkg.go.dev/github.com/golang/protobuf/proto?tab=doc#Message) - is an interface type defined by the legacy Go protocol buffer API. All - generated message types implement this interface, but the interface does not - describe the behavior expected from these messages. New code should avoid - using this type. - -## Common problems - -### "`go install`": `working directory is not part of a module` {#working-directory} - -On Go 1.15 and below, you have set the environment variable `GO111MODULE=on` and -are running the `go install` command outside of a module directory. Set -`GO111MODULE=auto`, or unset the environment variable. - -On Go 1.16 and above, `go install` can be invoked outside of a module by -specifying an explicit version: `go install -google.golang.org/protobuf/cmd/protoc-gen-go@latest` - -### `constant -1 overflows protoimpl.EnforceVersion` {#enforce-version} - -You are using a generated `.pb.go` file which requires a newer version of the -`"google.golang.org/protobuf"` module. - -Update to a newer version with: - -```shell -go get -u google.golang.org/protobuf/proto -``` - -### `undefined: "github.com/golang/protobuf/proto".ProtoPackageIsVersion4` {#enforce-version-apiv1} - -You are using a generated `.pb.go` file which requires a newer version of the -`"github.com/golang/protobuf"` module. - -Update to a newer version with: - -```shell -go get -u github.com/golang/protobuf/proto -``` - -### What is a protocol buffer namespace conflict? {#namespace-conflict} - -All protocol buffers declarations linked into a Go binary are inserted into a -global registry. - -Every protobuf declaration (for example, enums, enum values, or messages) has an -absolute name, which is the concatenation of the -[package name](/programming-guides/proto2#packages) with -the relative name of the declaration in the `.proto` source file (for example, -`my.proto.package.MyMessage.NestedMessage`). The protobuf language assumes that -all declarations are universally unique. - -If two protobuf declarations linked into a Go binary have the same name, then -this leads to a namespace conflict, and it is impossible for the registry to -properly resolve that declaration by name. Depending on which version of Go -protobufs is being used, this will either panic at init-time or silently drop -the conflict and lead to a potential bug later during runtime. - -### How do I fix a protocol buffer namespace conflict? {#fix-namespace-conflict} - -The way to best fix a namespace conflict depends on the reason why a conflict is -occurring. - -Common ways that namespace conflicts occur: - -* **Vendored .proto files.** When a single `.proto` file is generated into two - or more Go packages and linked into the same Go binary, it conflicts on - every protobuf declaration in the generated Go packages. This typically - occurs when a `.proto` file is vendored and a Go package is generated from - it, or the generated Go package itself is vendored. Users should avoid - vendoring and instead depend on a centralized Go package for that `.proto` - file. - - * If a `.proto` file is owned by an external party and is lacking a - `go_package` option, then you should coordinate with the owner of that - `.proto` file to specify a centralized Go package that a plurality of - users can all depend on. - -* **Missing or generic proto package names.** If a `.proto` file does not - specify a package name or uses an overly generic package name (for example, - "my_service"), then there is a high probability that declarations within - that file will conflict with other declarations elsewhere in the universe. - We recommend that every `.proto` file have a package name that is - deliberately chosen to be universally unique (for example, prefixed with the - name of a company). - -{{% alert title="Warning" color="warning" %}} -Retroactively changing the package name on a `.proto` file is not backwards -compatible for types used as extension fields, stored in `google.protobuf.Any`, -or for gRPC Service -definitions.{{% /alert %}} - -Starting with v1.26.0 of the `google.golang.org/protobuf` module, a hard error -will be reported when a Go program starts up that has multiple conflicting -protobuf names linked into it. While it is preferable that the source of the -conflict be fixed, the fatal error can be immediately worked around in one of -two ways: - -1. **At compile time.** The default behavior for handling conflicts can be - specified at compile time with a linker-initialized variable: `go build - -ldflags "-X - google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn"` - -2. **At program execution.** The behavior for handling conflicts when executing - a particular Go binary can be set with an environment variable: - `GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn ./main` - -### How do I use protocol buffer editions? {#using-editions} - -To use a protobuf edition, you must specify the edition in your `.proto` file. -For example, to use the 2023 edition, add the following to the top of your -`.proto` file: - -```proto -edition = "2023"; -``` - -The protocol buffer compiler will then generate Go code that is compatible with -the specified edition. With editions, you can also enable or disable specific -features for your `.proto` file. For more information, see -[Protocol Buffer Editions](/editions/overview). - -### How do I control the behavior of my generated Go code? {#controlling-generated-code} - -With editions, you can control the behavior of the generated Go code by enabling -or disabling specific features in your `.proto` file. For example, to set the -API behavior for your implementation, you would add the following to your -`.proto` file: - -```proto -edition = "2023"; - -option features.(pb.go).api_level = API_OPAQUE; -``` - -When `api_level` is set to `API_OPAQUE`, the Go code generated by the protocol -buffer compiler hides struct fields so they can no longer be directly accessed. -Instead, new accessor methods are created for getting, setting, or clearing a -field. - -For a complete list of available features and their descriptions, see -[Features for Editions](/editions/features). - -### Why does `reflect.DeepEqual` behave unexpectedly with protobuf messages? {#deepequal} - -Generated protocol buffer message types include internal state which can vary -even between equivalent messages. - -In addition, the `reflect.DeepEqual` function is not aware of the semantics of -protocol buffer messages, and can report differences where none exist. For -example, a map field containing a `nil` map and one containing a zero-length, -non-`nil` map are semantically equivalent, but will be reported as unequal by -`reflect.DeepEqual`. - -Use the -[`proto.Equal`](https://pkg.go.dev/google.golang.org/protobuf/proto#Equal) -function to compare message values. - -In tests, you can also use the -[`"github.com/google/go-cmp/cmp"`](https://pkg.go.dev/github.com/google/go-cmp/cmp?tab=doc) -package with the -[`protocmp.Transform()`](https://pkg.go.dev/google.golang.org/protobuf/testing/protocmp#Transform) -option. The `cmp` package can compare arbitrary data structures, and -[`cmp.Diff`](https://pkg.go.dev/github.com/google/go-cmp/cmp#Diff) produces -human-readable reports of the differences between values. - -```go -if diff := cmp.Diff(a, b, protocmp.Transform()); diff != "" { - t.Errorf("unexpected difference:\n%v", diff) -} -``` - -## Hyrum's Law - -### What is Hyrum's Law, and why is it in this FAQ? {#hyrums-law} - -[Hyrum's Law](https://www.hyrumslaw.com/) states: - -> With a sufficient number of users of an API, it does not matter what you -> promise in the contract: all observable behaviors of your system will be -> depended on by somebody. - -A design goal of the latest version of the Go protocol buffer API is to avoid, -where possible, providing observable behaviors that we cannot promise to keep -stable in the future. It is our philosophy that deliberate instability in areas -where we make no promises is better than giving the illusion of stability, only -for that to change in the future after a project has potentially been long -depending on that false assumption. - -### Why does the text of errors keep changing? {#unstable-errors} - -Tests depending on the exact text of errors are brittle and break often when -that text changes. To discourage unsafe use of error text in tests, the text of -errors produced by this module is deliberately unstable. - -If you need to identify whether an error is produced by the -[`protobuf`](https://pkg.go.dev/mod/google.golang.org/protobuf) module, we -guarantee that all errors will match -[`proto.Error`](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#Error) -according to [`errors.Is`](https://pkg.go.dev/errors?tab=doc#Is). - -### Why does the output of [`protojson`](https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson) keep changing? {#unstable-json} - -We make no promises about the long-term stability of Go's implementation of the -[JSON format for protocol buffers](/programming-guides/proto3#json). -The specification only specifies what is valid JSON, but provides no -specification for a *canonical* format for how a marshaler ought to *exactly* -format a given message. To avoid giving the illusion that the output is stable, -we deliberately introduce minor differences so that byte-for-byte comparisons -are likely to fail. - -To gain some degree of output stability, we recommend running the output through -a JSON formatter. - -### Why does the output of [`prototext`](https://pkg.go.dev/google.golang.org/protobuf/encoding/prototext) keep changing? {#unstable-text} - -We make no promises about the long-term stability of Go's implementation of the -text format. There is no canonical specification of the protobuf text format, -and we would like to preserve the ability to make improvements in the -`prototext` package output in the future. Since we don't promise stability in -the package's output, we've deliberately introduced instability to discourage -users from depending on it. - -To obtain some degree of stability, we recommend passing the output of -`prototext` through the -[`txtpbfmt`](https://github.com/protocolbuffers/txtpbfmt) program. The formatter -can be directly invoked in Go using -[`parser.Format`](https://pkg.go.dev/github.com/protocolbuffers/txtpbfmt/parser?tab=doc#Format). - -## Miscellaneous - -### How do I use a protocol buffer message as a hash key? {#hash} - -You need canonical serialization, where the marshaled output of a protocol -buffer message is guaranteed to be stable over time. Unfortunately, no -specification for canonical serialization exists at this time. You'll need to -write your own or find a way to avoid needing one. - -### Can I add a new feature to the Go protocol buffer implementation? {#new-feature} - -Maybe. We always like suggestions, but we're very cautious about adding new -things. - -The Go implementation of protocol buffers strives to be consistent with the -other language implementations. As such, we tend to shy away from feature that -are overly specialized to just Go. Go-specific features hinder the goal of -protocol buffers being a language-neutral data interchange format. - -Unless your idea is specific to the Go implementation, you should join the -[protobuf discussion group](http://groups.google.com/group/protobuf) and suggest -it there. - -If you have an idea for the Go implementation, file an issue on our issue -tracker: -[https://github.com/golang/protobuf/issues](https://github.com/golang/protobuf/issues) - -### Can I add an option to `Marshal` or `Unmarshal` to customize it? {#new-marshal-option} - -Only if that option exists in other implementations (e.g., C++, Java). The -encoding of protocol buffers (binary, JSON, and text) must be consistent across -implementations, so a program written in one language is able to read messages -written by another one. - -We will not add any options to the Go implementation that affect the data output -by `Marshal` functions or read by `Unmarshal` functions unless an equivalent -option exist in at least one other supported implementation. - -### Can I customize the code generated by `protoc-gen-go`? {#custom-code} - -In general, no. Protocol buffers are intended to be a language-agnostic data -interchange format, and implementation-specific customizations run counter to -that intent. diff --git a/content/reference/go/go-generated-opaque.md b/content/reference/go/go-generated-opaque.md deleted file mode 100644 index f1451f213..000000000 --- a/content/reference/go/go-generated-opaque.md +++ /dev/null @@ -1,717 +0,0 @@ -+++ -title = "Go Generated Code Guide (Opaque)" -weight = 615 -linkTitle = "Generated Code Guide (Opaque)" -description = "Describes exactly what Go code the protocol buffer compiler generates for any given protocol definition." -type = "docs" -+++ - -Any differences between -proto2 and proto3 generated code are highlighted - note that these differences -are in the generated code as described in this document, not the base API, which -are the same in both versions. You should read the -[proto2 language guide](/programming-guides/proto2) -and/or the -[proto3 language guide](/programming-guides/proto3) -before reading this document. - -{{% alert title="Note" color="warning" %}}You are -looking at documentation for the Opaque API, which is the current version. If -you are working with .proto files that use the older Open Struct API (you can -tell by the API level setting in the respective .proto files), see -[Go Generated Code (Open)](/reference/go/go-generated) -for the corresponding documentation. See -[Go Protobuf: The new Opaque API](https://go.dev/blog/protobuf-opaque) for the -introduction of the Opaque API. {{% /alert %}} - -## Compiler Invocation {#invocation} - -The protocol buffer compiler requires a plugin to generate Go code. Install it -using Go 1.16 or higher by running: - -```shell -go install google.golang.org/protobuf/cmd/protoc-gen-go@latest -``` - -This will install a `protoc-gen-go` binary in `$GOBIN`. Set the `$GOBIN` -environment variable to change the installation location. It must be in your -`$PATH` for the protocol buffer compiler to find it. - -The protocol buffer compiler produces Go output when invoked with the `go_out` -flag. The argument to the `go_out` flag is the directory where you want the -compiler to write your Go output. The compiler creates a single source file for -each `.proto` file input. The name of the output file is created by replacing -the `.proto` extension with `.pb.go`. - -Where in the output directory the generated `.pb.go` file is placed depends on -the compiler flags. There are several output modes: - -- If the `paths=import` flag is specified, the output file is placed in a - directory named after the Go package's import path (such as one provided by - the `go_package` option within the `.proto` file). For example, an input - file `protos/buzz.proto` with a Go import path of - `example.com/project/protos/fizz` results in an output file at - `example.com/project/protos/fizz/buzz.pb.go`. This is the default output - mode if a `paths` flag is not specified. -- If the `module=$PREFIX` flag is specified, the output file is placed in a - directory named after the Go package's import path (such as one provided by - the `go_package` option within the `.proto` file), but with the specified - directory prefix removed from the output filename. For example, an input - file `protos/buzz.proto` with a Go import path of - `example.com/project/protos/fizz` and `example.com/project` specified as the - `module` prefix results in an output file at `protos/fizz/buzz.pb.go`. - Generating any Go packages outside the module path results in an error. This - mode is useful for outputting generated files directly into a Go module. -- If the `paths=source_relative` flag is specified, the output file is placed - in the same relative directory as the input file. For example, an input file - `protos/buzz.proto` results in an output file at `protos/buzz.pb.go`. - -Flags specific to `protoc-gen-go` are provided by passing a `go_opt` flag when -invoking `protoc`. Multiple `go_opt` flags may be passed. For example, when -running: - -```shell -protoc --proto_path=src --go_out=out --go_opt=paths=source_relative foo.proto bar/baz.proto -``` - -the compiler will read input files `foo.proto` and `bar/baz.proto` from within -the `src` directory, and write output files `foo.pb.go` and `bar/baz.pb.go` to -the `out` directory. The compiler automatically creates nested output -sub-directories if necessary, but will not create the output directory itself. - -## Packages {#package} - -In order to generate Go code, the Go package's import path must be provided for -every `.proto` file (including those transitively depended upon by the `.proto` -files being generated). There are two ways to specify the Go import path: - -- by declaring it within the `.proto` file, or -- by declaring it on the command line when invoking `protoc`. - -We recommend declaring it within the `.proto` file so that the Go packages for -`.proto` files can be centrally identified with the `.proto` files themselves -and to simplify the set of flags passed when invoking `protoc`. If the Go import -path for a given `.proto` file is provided by both the `.proto` file itself and -on the command line, then the latter takes precedence over the former. - -The Go import path is locally specified in a `.proto` file by declaring a -`go_package` option with the full import path of the Go package. Example usage: - -```proto -option go_package = "example.com/project/protos/fizz"; -``` - -The Go import path may be specified on the command line when invoking the -compiler, by passing one or more `M${PROTO_FILE}=${GO_IMPORT_PATH}` flags. -Example usage: - -```shell -protoc --proto_path=src \ - --go_opt=Mprotos/buzz.proto=example.com/project/protos/fizz \ - --go_opt=Mprotos/bar.proto=example.com/project/protos/foo \ - protos/buzz.proto protos/bar.proto -``` - -Since the mapping of all `.proto` files to their Go import paths can be quite -large, this mode of specifying the Go import paths is generally performed by -some build tool (e.g., [Bazel](https://bazel.build/)) that has -control over the entire dependency tree. If there are duplicate entries for a -given `.proto` file, then the last one specified takes precedence. - -For both the `go_package` option and the `M` flag, the value may include an -explicit package name separated from the import path by a semicolon. For -example: `"example.com/protos/foo;package_name"`. This usage is discouraged -since the package name will be derived by default from the import path in a -reasonable manner. - -The import path is used to determine which import statements must be generated -when one `.proto` file imports another `.proto` file. For example, if `a.proto` -imports `b.proto`, then the generated `a.pb.go` file needs to import the Go -package which contains the generated `b.pb.go` file (unless both files are in -the same package). The import path is also used to construct output filenames. -See the \"Compiler Invocation\" section above for details. - -There is no correlation between the Go import path and the -[`package` specifier](/programming-guides/proto3#packages) -in the `.proto` file. The latter is only relevant to the protobuf namespace, -while the former is only relevant to the Go namespace. Also, there is no -correlation between the Go import path and the `.proto` import path. - -## API level {#apilevel} - -The generated code either uses the Open Struct API or the Opaque API. See the -[Go Protobuf: The new Opaque API](https://go.dev/blog/protobuf-opaque) -blog post for an introduction. - -Depending on the syntax your `.proto` file uses, here is which API will be used: - -`.proto` syntax | API level ---------------- | ---------- -proto2 | Open Struct API -proto3 | Open Struct API -edition 2023 | Open Struct API -edition 2024+ | Opaque API - -You can select the API by setting the `api_level` editions feature in your -`.proto` file. This can be set per file or per message: - -```proto -edition = "2023"; - -package log; - -import "google/protobuf/go_features.proto"; -option features.(pb.go).api_level = API_OPAQUE; - -message LogEntry { … } -``` - -For your convenience, you can also override the default API level with a -`protoc` command-line flag: - -``` -protoc […] --go_opt=default_api_level=API_HYBRID -``` - -To override the default API level for a specific file (instead of all files), -use the `apilevelM` mapping flag (similar to [the `M` flag for import -paths](#package)): - -``` -protoc […] --go_opt=apilevelMhello.proto=API_HYBRID -``` - -The command-line flags also work for `.proto` files still using proto2 or proto3 -syntax, but if you want to select the API level from within the `.proto` file, -you need to migrate said file to editions first. - -## Messages {#message} - -Given a simple message declaration: - -```proto -message Artist {} -``` - -the protocol buffer compiler generates a struct called `Artist`. An `*Artist` -implements the -[`proto.Message`](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#Message) -interface. - -The -[`proto` package](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc) -provides functions which operate on messages, including conversion to and from -binary format. - -The `proto.Message` interface defines a `ProtoReflect` method. This method -returns a -[`protoreflect.Message`](https://pkg.go.dev/google.golang.org/protobuf/reflect/protoreflect?tab=doc#Message) -which provides a reflection-based view of the message. - -The `optimize_for` option does not affect the output of the Go code generator. - -When multiple goroutines concurrently access the same message, the following -rules apply: - -* Accessing (reading) fields concurrently is safe, with one exception: - * Accessing a [lazy field](https://github.com/protocolbuffers/protobuf/blob/cacb096002994000f8ccc6d9b8e1b5b0783ee561/src/google/protobuf/descriptor.proto#L609) - for the first time is a modification. -* Modifying different fields in the same message is safe. -* Modifying a field concurrently is not safe. -* Modifying a message in any way concurrently with functions of the - [`proto` package](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc), - such as - [`proto.Marshal`](https://pkg.go.dev/google.golang.org/protobuf/proto#Marshal) - or [`proto.Size`](https://pkg.go.dev/google.golang.org/protobuf/proto#Size) - is not safe. - -### Nested Types - -A message can be declared inside another message. For example: - -```proto -message Artist { - message Name { - } -} -``` - -In this case, the compiler generates two structs: `Artist` and `Artist_Name`. - -## Fields - -The protocol buffer compiler generates accessor methods (setters and getters) -for each field defined within a message. - -Note that the generated Go accessor methods always use camel-case naming, even -if the field name in the `.proto` file uses lower-case with underscores -([as it should](/programming-guides/style)). The -case-conversion works as follows: - -1. The first letter is capitalized for export. If the first character is an - underscore, it is removed and a capital X is prepended. -2. If an interior underscore is followed by a lower-case letter, the underscore - is removed, and the following letter is capitalized. - -Thus, you can access the proto field `birth_year` using the `GetBirthYear()` -method in Go, and `_birth_year_2` using `GetXBirthYear_2()`. - -### Singular Fields - -For this field definition: - -```proto -// proto2 and proto3 -message Artist { - optional int32 birth_year = 1; -} - -// editions -message Artist { - int32 birth_year = 1 [features.field_presence = EXPLICIT]; -} -``` - -the compiler generates a Go struct with the following accessor methods: - -```go -func (m *Artist) GetBirthYear() int32 -func (m *Artist) SetBirthYear(v int32) -``` - -With implicit presence, the getter returns the `int32` value in `birth_year` or -the [zero value](https://golang.org/ref/spec#The_zero_value) of that -type if the field is unset (`0` for numbers, the empty string for strings). With -explicit presence, the getter returns the `int32` value in `birth_year` or the -default value if the field is unset. If the default is not explicitly set, the -zero value is used instead. - -For other scalar field types (including `bool`, `bytes`, and `string`), `int32` -is replaced with the corresponding Go type according to the -[scalar value types table](/programming-guides/proto3#scalar). - -In fields with explicit presence, you can also use these methods: - -```go -func (m *Artist) HasBirthYear() bool -func (m *Artist) ClearBirthYear() -``` - -### Singular Message Fields {#singular-message} - -Given the message type: - -```proto -message Band {} -``` - -For a message with a `Band` field: - -```proto -// proto2 -message Concert { - optional Band headliner = 1; - // The generated code is the same result if required instead of optional. -} - -// proto3 and editions -message Concert { - Band headliner = 1; -} -``` - -The compiler will generate a Go struct with the following accessor methods: - -```go -type Concert struct { ... } - -func (m *Concert) GetHeadliner() *Band { ... } -func (m *Concert) SetHeadliner(v *Band) { ... } -func (m *Concert) HasHeadliner() bool { ... } -func (m *Concert) ClearHeadliner() { ... } -``` - -The `GetHeadliner()` accessor method is safe to call even if `m` is nil. This -makes it possible to chain get calls without intermediate `nil` checks: - -```go -var m *Concert // defaults to nil -log.Infof("GetFoundingYear() = %d (no panic!)", m.GetHeadliner().GetFoundingYear()) -``` - -If the field is unset, the getter will return the default value of the field. -For messages, the default value is a nil pointer. - -Contrary to getters, setters do not perform nil checks for you. Therefore, you -cannot safely call setters on possibly-nil messages. - -### Repeated Fields {#repeated} - -For repeated fields, the accessor methods use a slice type. For this message -with a repeated field: - -```proto -message Concert { - // Best practice: use pluralized names for repeated fields: - // /programming-guides/style#repeated-fields - repeated Band support_acts = 1; -} -``` - -the compiler generates a Go struct with the following accessor methods: - -```go -type Concert struct { ... } - -func (m *Concert) GetSupportActs() []*Band { ... } -func (m *Concert) SetSupportActs(v []*Band) { ... } -``` - -Likewise, for the field definition `repeated bytes band_promo_images = 1;` the -compiler will generate accessors working with the `[][]byte` type. For a -repeated [enumeration](#enum) `repeated MusicGenre genres = 2;`, the compiler -generates accessors working with the `[]MusicGenre` type. - -The following example shows how to construct a `Concert` message using a -[builder](#builders). - -```go -concert := Concert_builder{ - SupportActs: []*Band{ - {}, // First element. - {}, // Second element. - }, -}.Build() -``` - -Alternatively, you can use setters: - -```go -concert := &Concert{} -concert.SetSupportActs([]*Band{ - {}, // First element. - {}, // Second element. -}) -``` - -To access the field, you can do the following: - -```go -support := concert.GetSupportActs() // support type is []*Band. -b1 := support[0] // b1 type is *Band, the first element in support_acts. -``` - -### Map Fields {#map} - -Each map field generates accessors working with type `map[TKey]TValue` where -`TKey` is the field's key type and `TValue` is the field's value type. For this -message with a map field: - -```proto -message MerchItem {} - -message MerchBooth { - // items maps from merchandise item name ("Signed T-Shirt") to - // a MerchItem message with more details about the item. - map items = 1; -} -``` - -the compiler generates a Go struct with the following accessor methods: - -```go -type MerchBooth struct { ... } - -func (m *MerchBooth) GetItems() map[string]*MerchItem { ... } -func (m *MerchBooth) SetItems(v map[string]*MerchItem) { ... } -``` - -### Oneof Fields {#oneof} - -For a oneof field, the protobuf compiler generates accessors for each of the -[singular fields](#singular-scalar-proto2) within the oneof. - -For this message with a oneof field: - -```proto -package account; -message Profile { - oneof avatar { - string image_url = 1; - bytes image_data = 2; - } -} -``` - -the compiler generates a Go struct with the following accessor methods: - -```go -type Profile struct { ... } - -func (m *Profile) WhichAvatar() case_Profile_Avatar { ... } -func (m *Profile) GetImageUrl() string { ... } -func (m *Profile) GetImageData() []byte { ... } - -func (m *Profile) SetImageUrl(v string) { ... } -func (m *Profile) SetImageData(v []byte) { ... } - -func (m *Profile) HasAvatar() bool { ... } -func (m *Profile) HasImageUrl() bool { ... } -func (m *Profile) HasImageData() bool { ... } - -func (m *Profile) ClearAvatar() { ... } -func (m *Profile) ClearImageUrl() { ... } -func (m *Profile) ClearImageData() { ... } -``` - -The following example shows how to set the field using a [builder](#builders): - -```go -p1 := accountpb.Profile_builder{ - ImageUrl: proto.String("https://example.com/image.png"), -}.Build() -``` - -...or, equivalently, using a setter: - -```go -// imageData is []byte -imageData := getImageData() -p2 := &accountpb.Profile{} -p2.SetImageData(imageData) -``` - -To access the field, you can use a switch statement on the `WhichAvatar()` -result: - -```go -switch m.WhichAvatar() { -case accountpb.Profile_ImageUrl_case: - // Load profile image based on URL - // using m.GetImageUrl() - -case accountpb.Profile_ImageData_case: - // Load profile image based on bytes - // using m.GetImageData() - -case accountpb.Profile_Avatar_not_set_case: - // The field is not set. - -default: - return fmt.Errorf("Profile.Avatar has an unexpected new oneof field %v", x) -} -``` - -### Builders {#builders} - -Builders are a convenient way to construct and initialize a message within a -single expression, especially when working with nested messages like unit tests. - -Contrary to builders in other languages (like Java), Go protobuf builders are -not meant to be passed around between functions. Instead, call `Build()` -immediately and pass the resulting proto message instead, using setters to -modify fields. - -Here is an example for using builders to create a `Band` message, which is the -only repeated field inside the enclosing `Concert` message: - -```go -concert := Concert_builder{ - SupportActs: []*Band{ - Band_builder{ - Name: proto.String("Varint and the Marshals"), - }.Build() - }, -}.Build() -``` - -## Enumerations {#enum} - -Given an enumeration like: - -```proto -message Venue { - enum Kind { - KIND_UNSPECIFIED = 0; - KIND_CONCERT_HALL = 1; - KIND_STADIUM = 2; - KIND_BAR = 3; - KIND_OPEN_AIR_FESTIVAL = 4; - } - Kind kind = 1; - // ... -} -``` - -the protocol buffer compiler generates a type and a series of constants with -that type: - -```go -type Venue_Kind int32 - -const ( - Venue_KIND_UNSPECIFIED Venue_Kind = 0 - Venue_KIND_CONCERT_HALL Venue_Kind = 1 - Venue_KIND_STADIUM Venue_Kind = 2 - Venue_KIND_BAR Venue_Kind = 3 - Venue_KIND_OPEN_AIR_FESTIVAL Venue_Kind = 4 -) -``` - -For enums within a message (like the one above), the type name begins with the -message name: - -```go -type Venue_Kind int32 -``` - -For a package-level enum: - -```proto -enum Genre { - GENRE_UNSPECIFIED = 0; - GENRE_ROCK = 1; - GENRE_INDIE = 2; - GENRE_DRUM_AND_BASS = 3; - // ... -} -``` - -the Go type name is unmodified from the proto enum name: - -```go -type Genre int32 -``` - -This type has a `String()` method that returns the name of a given value. - -The `Enum()` method initializes freshly allocated memory with a given value and -returns the corresponding pointer: - -```go -func (Genre) Enum() *Genre -``` - -The protocol buffer compiler generates a constant for each value in the enum. -For enums within a message, the constants begin with the enclosing message's -name: - -```go -const ( - Venue_KIND_UNSPECIFIED Venue_Kind = 0 - Venue_KIND_CONCERT_HALL Venue_Kind = 1 - Venue_KIND_STADIUM Venue_Kind = 2 - Venue_KIND_BAR Venue_Kind = 3 - Venue_KIND_OPEN_AIR_FESTIVAL Venue_Kind = 4 -) -``` - -For a package-level enum, the constants begin with the enum name instead: - -```go -const ( - Genre_GENRE_UNSPECIFIED Genre = 0 - Genre_GENRE_ROCK Genre = 1 - Genre_GENRE_INDIE Genre = 2 - Genre_GENRE_DRUM_AND_BASS Genre = 3 -) -``` - -The protobuf compiler also generates a map from integer values to the string -names and a map from the names to the values: - -```go -var Genre_name = map[int32]string{ - 0: "GENRE_UNSPECIFIED", - 1: "GENRE_ROCK", - 2: "GENRE_INDIE", - 3: "GENRE_DRUM_AND_BASS", -} -var Genre_value = map[string]int32{ - "GENRE_UNSPECIFIED": 0, - "GENRE_ROCK": 1, - "GENRE_INDIE": 2, - "GENRE_DRUM_AND_BASS": 3, -} -``` - -Note that the `.proto` language allows multiple enum symbols to have the same -numeric value. Symbols with the same numeric value are synonyms. These are -represented in Go in exactly the same way, with multiple names corresponding to -the same numeric value. The reverse mapping contains a single entry for the -numeric value to the name which appears first in the .proto file. - -## Extensions (proto2) {#extensions} - -Given an extension definition: - -```proto -extend Concert { - optional int32 promo_id = 123; -} -``` - -The protocol buffer compiler will generate a -[`protoreflect.ExtensionType`](https://pkg.go.dev/google.golang.org/protobuf/reflect/protoreflect?tab=doc#ExtensionType) -value named `E_Promo_id`. This value may be used with the -[`proto.GetExtension`](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#GetExtension), -[`proto.SetExtension`](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#SetExtension), -[`proto.HasExtension`](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#HasExtension), -and -[`proto.ClearExtension`](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#ClearExtension) -functions to access an extension in a message. The `GetExtension` function and -`SetExtension` functions respectively return and accept an `interface{}` value -containing the extension value type. - -For singular scalar extension fields, the extension value type is the -corresponding Go type from the -[scalar value types table](/programming-guides/proto3#scalar). - -For singular embedded message extension fields, the extension value type is -`*M`, where `M` is the field message type. - -For repeated extension fields, the extension value type is a slice of the -singular type. - -For example, given the following definition: - -```proto -extend Concert { - optional int32 singular_int32 = 1; - repeated bytes repeated_strings = 2; - optional Band singular_message = 3; -} -``` - -Extension values may be accessed as: - -```go -m := &somepb.Concert{} -proto.SetExtension(m, extpb.E_SingularInt32, int32(1)) -proto.SetExtension(m, extpb.E_RepeatedString, []string{"a", "b", "c"}) -proto.SetExtension(m, extpb.E_SingularMessage, &extpb.Band{}) - -v1 := proto.GetExtension(m, extpb.E_SingularInt32).(int32) -v2 := proto.GetExtension(m, extpb.E_RepeatedString).([][]byte) -v3 := proto.GetExtension(m, extpb.E_SingularMessage).(*extpb.Band) -``` - -Extensions can be declared nested inside of another type. For example, a common -pattern is to do something like this: - -```proto -message Promo { - extend Concert { - optional int32 promo_id = 124; - } -} -``` - -In this case, the `ExtensionType` value is named `E_Promo_Concert`. - -## Services {#service} - -The Go code generator does not produce output for services by default. If you -enable the [gRPC](https://www.grpc.io/) plugin (see the -[gRPC Go Quickstart guide](https://github.com/grpc/grpc-go/tree/master/examples)) -then code will be generated to support gRPC. diff --git a/content/reference/go/go-generated.md b/content/reference/go/go-generated.md deleted file mode 100644 index b571e3a07..000000000 --- a/content/reference/go/go-generated.md +++ /dev/null @@ -1,689 +0,0 @@ -+++ -title = "Go Generated Code Guide (Open)" -weight = 610 -linkTitle = "Generated Code Guide (Open)" -description = "Describes exactly what Go code the protocol buffer compiler generates for any given protocol definition." -type = "docs" -+++ - -Any differences between -proto2, proto3, and editions generated code are highlighted - note that these -differences are in the generated code as described in this document, not the -base API, which are the same in both versions. You should read the -[proto2 language guide](/programming-guides/proto2), -[proto3 language guide](/programming-guides/proto3), or -[editions language guide](/programming-guides/editions) -before reading this document. - -{{% alert title="Note" color="warning" %}}You are -looking at documentation for the old generated code API (Open Struct API). -See -[Go Generated Code (Opaque)](/reference/go/go-generated-opaque) -for the corresponding documentation of the (new) Opaque API. See -[Go Protobuf: The new Opaque API](https://go.dev/blog/protobuf-opaque) for the -introduction of the Opaque API. {{% /alert %}} - -## Compiler Invocation {#invocation} - -The protocol buffer compiler requires a plugin to generate Go code. Install it -using Go 1.16 or higher by running: - -```shell -go install google.golang.org/protobuf/cmd/protoc-gen-go@latest -``` - -This will install a `protoc-gen-go` binary in `$GOBIN`. Set the `$GOBIN` -environment variable to change the installation location. It must be in your -`$PATH` for the protocol buffer compiler to find it. - -The protocol buffer compiler produces Go output when invoked with the `go_out` -flag. The argument to the `go_out` flag is the directory where you want the -compiler to write your Go output. The compiler creates a single source file for -each `.proto` file input. The name of the output file is created by replacing -the `.proto` extension with `.pb.go`. - -Where in the output directory the generated `.pb.go` file is placed depends on -the compiler flags. There are several output modes: - -- If the `paths=import` flag is specified, the output file is placed in a - directory named after the Go package's import path (such as one provided by - the `go_package` option within the `.proto` file). For example, an input - file `protos/buzz.proto` with a Go import path of - `example.com/project/protos/fizz` results in an output file at - `example.com/project/protos/fizz/buzz.pb.go`. This is the default output - mode if a `paths` flag is not specified. -- If the `module=$PREFIX` flag is specified, the output file is placed in a - directory named after the Go package's import path (such as one provided by - the `go_package` option within the `.proto` file), but with the specified - directory prefix removed from the output filename. For example, an input - file `protos/buzz.proto` with a Go import path of - `example.com/project/protos/fizz` and `example.com/project` specified as the - `module` prefix results in an output file at `protos/fizz/buzz.pb.go`. - Generating any Go packages outside the module path results in an error. This - mode is useful for outputting generated files directly into a Go module. -- If the `paths=source_relative` flag is specified, the output file is placed - in the same relative directory as the input file. For example, an input file - `protos/buzz.proto` results in an output file at `protos/buzz.pb.go`. - -Flags specific to `protoc-gen-go` are provided by passing a `go_opt` flag when -invoking `protoc`. Multiple `go_opt` flags may be passed. For example, when -running: - -```shell -protoc --proto_path=src --go_out=out --go_opt=paths=source_relative foo.proto bar/baz.proto -``` - -the compiler will read input files `foo.proto` and `bar/baz.proto` from within -the `src` directory, and write output files `foo.pb.go` and `bar/baz.pb.go` to -the `out` directory. The compiler automatically creates nested output -sub-directories if necessary, but will not create the output directory itself. - -## Packages {#package} - -In order to generate Go code, the Go package's import path must be provided for -every `.proto` file (including those transitively depended upon by the `.proto` -files being generated). There are two ways to specify the Go import path: - -- by declaring it within the `.proto` file, or -- by declaring it on the command line when invoking `protoc`. - -We recommend declaring it within the `.proto` file so that the Go packages for -`.proto` files can be centrally identified with the `.proto` files themselves -and to simplify the set of flags passed when invoking `protoc`. If the Go import -path for a given `.proto` file is provided by both the `.proto` file itself and -on the command line, then the latter takes precedence over the former. - -The Go import path is locally specified in a `.proto` file by declaring a -`go_package` option with the full import path of the Go package. Example usage: - -```proto -option go_package = "example.com/project/protos/fizz"; -``` - -The Go import path may be specified on the command line when invoking the -compiler, by passing one or more `M${PROTO_FILE}=${GO_IMPORT_PATH}` flags. -Example usage: - -```shell -protoc --proto_path=src \ - --go_opt=Mprotos/buzz.proto=example.com/project/protos/fizz \ - --go_opt=Mprotos/bar.proto=example.com/project/protos/foo \ - protos/buzz.proto protos/bar.proto -``` - -Since the mapping of all `.proto` files to their Go import paths can be quite -large, this mode of specifying the Go import paths is generally performed by -some build tool (e.g., [Bazel](https://bazel.build/)) that has -control over the entire dependency tree. If there are duplicate entries for a -given `.proto` file, then the last one specified takes precedence. - -For both the `go_package` option and the `M` flag, the value may include an -explicit package name separated from the import path by a semicolon. For -example: `"example.com/protos/foo;package_name"`. This usage is discouraged -since the package name will be derived by default from the import path in a -reasonable manner. - -The import path is used to determine which import statements must be generated -when one `.proto` file imports another `.proto` file. For example, if `a.proto` -imports `b.proto`, then the generated `a.pb.go` file needs to import the Go -package which contains the generated `b.pb.go` file (unless both files are in -the same package). The import path is also used to construct output filenames. -See the \"Compiler Invocation\" section above for details. - -There is no correlation between the Go import path and the -[`package` specifier](/programming-guides/proto3#packages) -in the `.proto` file. The latter is only relevant to the protobuf namespace, -while the former is only relevant to the Go namespace. Also, there is no -correlation between the Go import path and the `.proto` import path. - -## API level {#apilevel} - -The generated code either uses the Open Struct API or the Opaque API. See the -[Go Protobuf: The new Opaque API](https://go.dev/blog/protobuf-opaque) -blog post for an introduction. - -Depending on the syntax your `.proto` file uses, here is which API will be used: - -`.proto` syntax | API level ---------------- | ---------- -proto2 | Open Struct API -proto3 | Open Struct API -edition 2023 | Open Struct API -edition 2024+ | Opaque API - -You can select the API by setting the `api_level` editions feature in your -`.proto` file. This can be set per file or per message: - -```proto -edition = "2023"; - -package log; - -import "google/protobuf/go_features.proto"; -option features.(pb.go).api_level = API_OPAQUE; - -message LogEntry { … } -``` - -For your convenience, you can also override the default API level with a -`protoc` command-line flag: - -``` -protoc […] --go_opt=default_api_level=API_HYBRID -``` - -To override the default API level for a specific file (instead of all files), -use the `apilevelM` mapping flag (similar to [the `M` flag for import -paths](/reference/go/go-generated/#package)): - -``` -protoc […] --go_opt=apilevelMhello.proto=API_HYBRID -``` - -The command-line flags also work for `.proto` files still using proto2 or proto3 -syntax, but if you want to select the API level from within the `.proto` file, -you need to migrate said file to editions first. - -## Messages {#message} - -Given a simple message declaration: - -```proto -message Artist {} -``` - -the protocol buffer compiler generates a struct called `Artist`. An `*Artist` -implements the -[`proto.Message`](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#Message) -interface. - -The -[`proto` package](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc) -provides functions which operate on messages, including conversion to and from -binary format. - -The `proto.Message` interface defines a `ProtoReflect` method. This method -returns a -[`protoreflect.Message`](https://pkg.go.dev/google.golang.org/protobuf/reflect/protoreflect?tab=doc#Message) -which provides a reflection-based view of the message. - -The `optimize_for` option does not affect the output of the Go code generator. - -When multiple goroutines concurrently access the same message, the following -rules apply: - -* Accessing (reading) fields concurrently is safe, with one exception: - * Accessing a [lazy field](https://github.com/protocolbuffers/protobuf/blob/cacb096002994000f8ccc6d9b8e1b5b0783ee561/src/google/protobuf/descriptor.proto#L609) - for the first time is a modification. -* Modifying different fields in the same message is safe. -* Modifying a field concurrently is not safe. -* Modifying a message in any way concurrently with functions of the - [`proto` package](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc), - such as - [`proto.Marshal`](https://pkg.go.dev/google.golang.org/protobuf/proto#Marshal) - or [`proto.Size`](https://pkg.go.dev/google.golang.org/protobuf/proto#Size) - is not safe. - -### Nested Types - -A message can be declared inside another message. For example: - -```proto -message Artist { - message Name { - } -} -``` - -In this case, the compiler generates two structs: `Artist` and `Artist_Name`. - -## Fields - -The protocol buffer compiler generates a struct field for each field defined -within a message. The exact nature of this field depends on its type and whether -it is a singular, repeated, map, or oneof field. - -Note that the generated Go field names always use camel-case naming, even if the -field name in the `.proto` file uses lower-case with underscores -([as it should](/programming-guides/style#message-field-names)). -The case-conversion works as follows: - -1. The first letter is capitalized for export. If the first character is an - underscore, it is removed and a capital X is prepended. -2. If an interior underscore is followed by a lower-case letter, the underscore - is removed, and the following letter is capitalized. - -Thus, the proto field `birth_year` becomes `BirthYear` in Go, and -`_birth_year_2` becomes `XBirthYear_2`. - - - -### Singular Explicit Presence Scalar Fields {#singular-explicit} - -For the field definition: - -```proto -int32 birth_year = 1; -``` - -the compiler generates a struct with an `*int32` field named `BirthYear` and an -accessor method `GetBirthYear()` which returns the `int32` value in `Artist` or -the default value if the field is unset. If the default is not explicitly set, -the [zero value](https://golang.org/ref/spec#The_zero_value) of that -type is used instead (`0` for numbers, the empty string for strings). - -For other scalar field types (including `bool`, `bytes`, and `string`), `*int32` -is replaced with the corresponding Go type according to the -[scalar value types table](/programming-guides/proto2#scalar). - - - -### Singular Implicit Presence Scalar Fields {#singular-implicit} - -For this field definition: - -```proto -int32 birth_year = 1; -``` - -The compiler will generate a struct with an `int32` field named `BirthYear` and -an accessor method `GetBirthYear()` which returns the `int32` value in -`birth_year` or the -[zero value](https://golang.org/ref/spec#The_zero_value) of that type -if the field is unset (`0` for numbers, the empty string for strings). - -The `FirstActiveYear` struct field will be of type `*int32`, because it is -marked `optional`. - -For other scalar field types (including `bool`, `bytes`, and `string`), `int32` -is replaced with the corresponding Go type according to the -[scalar value types table](/programming-guides/proto3#scalar). -Unset values in the proto will be represented as the -[zero value](https://golang.org/ref/spec#The_zero_value) of that type (`0` for -numbers, the empty string for strings). - -### Singular Message Fields {#singular-message} - -Given the message type: - -```proto -message Band {} -``` - -For a message with a `Band` field: - -```proto -// proto2 -message Concert { - optional Band headliner = 1; - // The generated code is the same result if required instead of optional. -} - -// proto3 -message Concert { - Band headliner = 1; -} - -// editions -message Concer { - Band headliner = 1; -} -``` - -The compiler will generate a Go struct - -```go -type Concert struct { - Headliner *Band -} -``` - -Message fields can be set to `nil`, which means that the field is unset, -effectively clearing the field. This is not equivalent to setting the value to -an \"empty\" instance of the message struct. - -The compiler also generates a `func (m *Concert) GetHeadliner() *Band` helper -function. This function returns a `nil` `*Band` if `m` is nil or `headliner` is -unset. This makes it possible to chain get calls without intermediate `nil` -checks: - -```go -var m *Concert // defaults to nil -log.Infof("GetFoundingYear() = %d (no panic!)", m.GetHeadliner().GetFoundingYear()) -``` - -### Repeated Fields {#repeated} - -Each repeated field generates a slice of `T` field in the struct in Go, where -`T` is the field's element type. For this message with a repeated field: - -```proto -message Concert { - // Best practice: use pluralized names for repeated fields: - // /programming-guides/style#repeated-fields - repeated Band support_acts = 1; -} -``` - -the compiler generates the Go struct: - -```go -type Concert struct { - SupportActs []*Band -} -``` - -Likewise, for the field definition `repeated bytes band_promo_images = 1;` the -compiler will generate a Go struct with a `[][]byte` field named -`BandPromoImage`. For a repeated [enumeration](#enum) like `repeated MusicGenre -genres = 2;`, the compiler generates a struct with a `[]MusicGenre` field called -`Genre`. - -The following example shows how to set the field: - -```go -concert := &Concert{ - SupportActs: []*Band{ - {}, // First element. - {}, // Second element. - }, -} -``` - -To access the field, you can do the following: - -```go -support := concert.GetSupportActs() // support type is []*Band. -b1 := support[0] // b1 type is *Band, the first element in support_acts. -``` - -### Map Fields {#map} - -Each map field generates a field in the struct of type `map[TKey]TValue` where -`TKey` is the field's key type and `TValue` is the field's value type. For this -message with a map field: - -```proto -message MerchItem {} - -message MerchBooth { - // items maps from merchandise item name ("Signed T-Shirt") to - // a MerchItem message with more details about the item. - map items = 1; -} -``` - -the compiler generates the Go struct: - -```go -type MerchBooth struct { - Items map[string]*MerchItem -} -``` - -### Oneof Fields {#oneof} - -For a oneof field, the protobuf compiler generates a single field with an -interface type `isMessageName_MyField`. It also generates a struct for each of -the [singular fields](#singular-scalar-proto2) within the oneof. These all -implement this `isMessageName_MyField` interface. - -For this message with a oneof field: - -```proto -package account; -message Profile { - oneof avatar { - string image_url = 1; - bytes image_data = 2; - } -} -``` - -the compiler generates the structs: - -```go -type Profile struct { - // Types that are valid to be assigned to Avatar: - // *Profile_ImageUrl - // *Profile_ImageData - Avatar isProfile_Avatar `protobuf_oneof:"avatar"` -} - -type Profile_ImageUrl struct { - ImageUrl string -} -type Profile_ImageData struct { - ImageData []byte -} -``` - -Both `*Profile_ImageUrl` and `*Profile_ImageData` implement `isProfile_Avatar` -by providing an empty `isProfile_Avatar()` method. - -The following example shows how to set the field: - -```go -p1 := &account.Profile{ - Avatar: &account.Profile_ImageUrl{ImageUrl: "http://example.com/image.png"}, -} - -// imageData is []byte -imageData := getImageData() -p2 := &account.Profile{ - Avatar: &account.Profile_ImageData{ImageData: imageData}, -} -``` - -To access the field, you can use a type switch on the value to handle the -different message types. - -```go -switch x := m.Avatar.(type) { -case *account.Profile_ImageUrl: - // Load profile image based on URL - // using x.ImageUrl -case *account.Profile_ImageData: - // Load profile image based on bytes - // using x.ImageData -case nil: - // The field is not set. -default: - return fmt.Errorf("Profile.Avatar has unexpected type %T", x) -} -``` - -The compiler also generates get methods `func (m *Profile) GetImageUrl() string` -and `func (m *Profile) GetImageData() []byte`. Each get function returns the -value for that field or the zero value if it is not set. - -## Enumerations {#enum} - -Given an enumeration like: - -```proto -message Venue { - enum Kind { - KIND_UNSPECIFIED = 0; - KIND_CONCERT_HALL = 1; - KIND_STADIUM = 2; - KIND_BAR = 3; - KIND_OPEN_AIR_FESTIVAL = 4; - } - Kind kind = 1; - // ... -} -``` - -the protocol buffer compiler generates a type and a series of constants with -that type: - -```go -type Venue_Kind int32 - -const ( - Venue_KIND_UNSPECIFIED Venue_Kind = 0 - Venue_KIND_CONCERT_HALL Venue_Kind = 1 - Venue_KIND_STADIUM Venue_Kind = 2 - Venue_KIND_BAR Venue_Kind = 3 - Venue_KIND_OPEN_AIR_FESTIVAL Venue_Kind = 4 -) -``` - -For enums within a message (like the one above), the type name begins with the -message name: - -```go -type Venue_Kind int32 -``` - -For a package-level enum: - -```proto -enum Genre { - GENRE_UNSPECIFIED = 0; - GENRE_ROCK = 1; - GENRE_INDIE = 2; - GENRE_DRUM_AND_BASS = 3; - // ... -} -``` - -the Go type name is unmodified from the proto enum name: - -```go -type Genre int32 -``` - -This type has a `String()` method that returns the name of a given value. - -The `Enum()` method initializes freshly allocated memory with a given value and -returns the corresponding pointer: - -```go -func (Genre) Enum() *Genre -``` - -The protocol buffer compiler generates a constant for each value in the enum. -For enums within a message, the constants begin with the enclosing message's -name: - -```go -const ( - Venue_KIND_UNSPECIFIED Venue_Kind = 0 - Venue_KIND_CONCERT_HALL Venue_Kind = 1 - Venue_KIND_STADIUM Venue_Kind = 2 - Venue_KIND_BAR Venue_Kind = 3 - Venue_KIND_OPEN_AIR_FESTIVAL Venue_Kind = 4 -) -``` - -For a package-level enum, the constants begin with the enum name instead: - -```go -const ( - Genre_GENRE_UNSPECIFIED Genre = 0 - Genre_GENRE_ROCK Genre = 1 - Genre_GENRE_INDIE Genre = 2 - Genre_GENRE_DRUM_AND_BASS Genre = 3 -) -``` - -The protobuf compiler also generates a map from integer values to the string -names and a map from the names to the values: - -```go -var Genre_name = map[int32]string{ - 0: "GENRE_UNSPECIFIED", - 1: "GENRE_ROCK", - 2: "GENRE_INDIE", - 3: "GENRE_DRUM_AND_BASS", -} -var Genre_value = map[string]int32{ - "GENRE_UNSPECIFIED": 0, - "GENRE_ROCK": 1, - "GENRE_INDIE": 2, - "GENRE_DRUM_AND_BASS": 3, -} -``` - -Note that the `.proto` language allows multiple enum symbols to have the same -numeric value. Symbols with the same numeric value are synonyms. These are -represented in Go in exactly the same way, with multiple names corresponding to -the same numeric value. The reverse mapping contains a single entry for the -numeric value to the name which appears first in the .proto file. - -## Extensions {#extensions} - -Given an extension definition: - -```proto -extend Concert { - int32 promo_id = 123; -} -``` - -The protocol buffer compiler will generate a -[`protoreflect.ExtensionType`](https://pkg.go.dev/google.golang.org/protobuf/reflect/protoreflect?tab=doc#ExtensionType) -value named `E_Promo_id`. This value may be used with the -[`proto.GetExtension`](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#GetExtension), -[`proto.SetExtension`](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#SetExtension), -[`proto.HasExtension`](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#HasExtension), -and -[`proto.ClearExtension`](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#ClearExtension) -functions to access an extension in a message. The `GetExtension` function and -`SetExtension` functions respectively return and accept an `interface{}` value -containing the extension value type. - -For singular scalar extension fields, the extension value type is the -corresponding Go type from the -[scalar value types table](/programming-guides/proto3#scalar). - -For singular embedded message extension fields, the extension value type is -`*M`, where `M` is the field message type. - -For repeated extension fields, the extension value type is a slice of the -singular type. - -For example, given the following definition: - -```proto -extend Concert { - int32 singular_int32 = 1; - repeated bytes repeated_strings = 2; - Band singular_message = 3; -} -``` - -Extension values may be accessed as: - -```go -m := &somepb.Concert{} -proto.SetExtension(m, extpb.E_SingularInt32, int32(1)) -proto.SetExtension(m, extpb.E_RepeatedString, []string{"a", "b", "c"}) -proto.SetExtension(m, extpb.E_SingularMessage, &extpb.Band{}) - -v1 := proto.GetExtension(m, extpb.E_SingularInt32).(int32) -v2 := proto.GetExtension(m, extpb.E_RepeatedString).([][]byte) -v3 := proto.GetExtension(m, extpb.E_SingularMessage).(*extpb.Band) -``` - -Extensions can be declared nested inside of another type. For example, a common -pattern is to do something like this: - -```proto -message Promo { - extend Concert { - int32 promo_id = 124; - } -} -``` - -In this case, the `ExtensionType` value is named `E_Promo_Concert`. - -## Services {#service} - -The Go code generator does not produce output for services by default. If you -enable the [gRPC](https://www.grpc.io/) plugin (see the -[gRPC Go Quickstart guide](https://github.com/grpc/grpc-go/tree/master/examples)) -then code will be generated to support gRPC. diff --git a/content/reference/go/opaque-faq.md b/content/reference/go/opaque-faq.md deleted file mode 100644 index 64426f98f..000000000 --- a/content/reference/go/opaque-faq.md +++ /dev/null @@ -1,384 +0,0 @@ -+++ -title = "Go Opaque API FAQ" -weight = 670 -linkTitle = "Opaque API FAQ" -description = "A list of frequently asked questions about the Opaque API." -type = "docs" -+++ - - - -The Opaque API is the latest version of the Protocol Buffers implementation for -the Go programming language. The old version is now called Open Struct API. See -the [Go Protobuf: The new Opaque API](https://go.dev/blog/protobuf-opaque) blog -post for an introduction. - -This FAQ answers common questions about the new API and the migration process. - -## Which API Should I Use When Creating a New .proto File? {#which} - -We recommend you select the Opaque API for new development. - -Protobuf Edition 2024 (see [Protobuf Editions Overview](/editions/overview/)) made the Opaque API the default. - -## How Do I Enable the New Opaque API for My Messages? {#enable} - -Starting with Protobuf Edition 2023, you can select the Opaque API by setting -the `api_level` editions feature to `API_OPAQUE` in your `.proto` file. This can -be set per file or per message: - -```proto -edition = "2023"; - -package log; - -import "google/protobuf/go_features.proto"; -option features.(pb.go).api_level = API_OPAQUE; - -message LogEntry { … } -``` - -Protobuf Edition 2024 defaults to the Opaque API, meaning you will not need -extra imports or options anymore: - -```proto -edition = "2024"; - -package log; - -message LogEntry { … } -``` - -For your convenience, you can also override the default API level with a -`protoc` command-line flag: - -``` -protoc […] --go_opt=default_api_level=API_HYBRID -``` - -To override the default API level for a specific file (instead of all files), -use the `apilevelM` mapping flag (similar to -[the `M` flag for import paths](/reference/go/go-generated/#package)): - -``` -protoc […] --go_opt=apilevelMhello.proto=API_HYBRID -``` - -The command-line flags also work for `.proto` files still using proto2 or proto3 -syntax, but if you want to select the API level from within the `.proto` file, -you need to migrate said file to editions first. - -## How Do I Enable Lazy Decoding? {#lazydecoding} - -1. Migrate your code to use the opaque implementation. -1. Set the `[lazy = true]` option on the proto submessage fields that should be - lazily decoded. -1. Run your unit and integration tests, and then roll out to a staging - environment. - -## Are Errors Ignored with Lazy Decoding? {#lazydecodingerrors} - -No. -[`proto.Marshal`](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#Marshal) -will always validate the wire format data, even when decoding is deferred until -first access. - -## Where Can I Ask Questions or Report Issues? {#questions} - -If you found an issue with the `open2opaque` migration tool (such as incorrectly -rewritten code), please report it in the -[open2opaque issue tracker](https://github.com/golang/open2opaque/issues). - -If you found an issue with Go Protobuf, please report it in the -[Go Protobuf issue tracker](https://github.com/golang/protobuf/issues/). - -## What Are the Benefits of the Opaque API? {#benefits} - -The Opaque API comes with numerous benefits: - -* It uses a more efficient memory representation, thereby reducing memory and - Garbage Collection cost. -* It makes lazy decoding possible, which can significantly improve - performance. -* It fixes a number of sharp edges. Bugs resulting from pointer address - comparison, accidental sharing, or undesired use of Go reflection are all - prevented when using the Opaque API. -* It makes the ideal memory layout possible by enabling profile-driven - optimizations. - -See -[the Go Protobuf: The new Opaque API blog post](https://go.dev/blog/protobuf-opaque) -for more details on these points. - -## Which Is Faster, Builders or Setters? {#builders-faster} - -Generally, code using builders: - -```go -_ = pb.M_builder{ - F: &val, -}.Build() -``` - -is slower than the following equivalent: - -```go -m := &pb.M{} -m.SetF(val) -``` - -for the following reasons: - -1. The `Build()` call iterates over all fields in the message (even ones that - are not explicitly set) and copies their values (if any) to the final - message. This linear performance matters for messages with many fields. -1. There's a potential extra heap allocation (`&val`). -1. The builder can be significantly larger and use more memory in presence of - oneof fields. Builders have a field per oneof union member while the message - can store the oneof itself as a single field. - -Aside from runtime performance, if binary size is a concern for you, avoiding -builders will result in less code. - -## How Do I Use Builders? {#builders-how} - -Builders are designed to be used as *values* and with an immediate `Build()` -call. Avoid using pointers to builders or storing builders in variables. - -```go {.good} -m := pb.M_builder{ - // ... -}.Build() -``` - -```go {.bad} -// BAD: Avoid using a pointer -m := (&pb.M_builder{ - // ... -}).Build() -``` - -```go {.bad highlight="content:b.:= "} -// BAD: avoid storing in a variable -b := pb.M_builder{ - // ... -} -m := b.Build() -``` - -Proto messages are immutable in some other languages, hence users tend to pass -the builder type into function calls when constructing a proto message. Go proto -messages are mutable, hence there's no need for passing the builder into -function calls. Simply pass the proto message. - -```go {.bad} -// BAD: avoid passing a builder around -func populate(mb *pb.M_builder) { - mb.Field1 = proto.Int32(4711) - //... -} -// ... -mb := pb.M_builder{} -populate(&mb) -m := mb.Build() -``` - -```go {.good} -func populate(mb *pb.M) { - mb.SetField1(4711) - //... -} -// ... -m := &pb.M{} -populate(m) -``` - -Builders are designed to imitate the composite literal construction of the Open -Struct API, not as an alternative representation of a proto message. - -The recommended pattern is also more performant. The intended use of `Build()` -where it is called directly on the builder struct literal can be optimized well. -A separate call to `Build()` is much harder to optimize, as the compiler may not -easily identify which fields are populated. If the builder lives longer, there's -also a high chance that small objects like scalars have to be heap allocated and -later need to be freed by the garbage collector. - -## Should I Use Builders or Setters? {#builders-vs-setters} - -When constructing an empty protocol buffer, you should use `new` or an empty -composite literals. Both are equivalently idiomatic to construct a zero -initialized value in Go and are more performant than an empty builder. - -```go {.good} -m1 := new(pb.M) -m2 := &pb.M{} -``` - -```go {.bad} -// BAD: avoid: unnecessarily complex -m1 := pb.M_builder{}.Build() -``` - -In cases where you need to construct non-empty protocol buffers, you have the -choice between using setters or using builders. Either is fine, but most people -will find builders more readable. If the code you are writing needs to perform -well, -[setters are generally slightly more performant than builders](#builders-faster). - -```go {.good} -// Recommended: using builders -m1 := pb.M1_builder{ - Submessage: pb.M2_builder{ - Submessage: pb.M3_builder{ - String: proto.String("hello world"), - Int: proto.Int32(42), - }.Build(), - Bytes: []byte("hello"), - }.Build(), -}.Build() -``` - -```go -// Also okay: using setters -m3 := &pb.M3{} -m3.SetString("hello world") -m3.SetInt(42) -m2 := &pb.M2{} -m2.SetSubmessage(m3) -m2.SetBytes([]byte("hello")) -m1 := &pb.M1{} -m1.SetSubmessage(m2) -``` - -You can combine the use of builder and setters if certain fields require -conditional logic before setting. - -```go {.good} -m1 := pb.M1_builder{ - Field1: value1, -}.Build() -if someCondition() { - m1.SetField2(value2) - m1.SetField3(value3) -} -``` - -## How Can I Influence open2opaque’s Builder Behavior? {#builders-flags} - -The `open2opaque` tool’s `--use_builders` flag can have the following values: - -* `--use_builders=everywhere`: always use builders, no exceptions. -* `--use_builders=tests`: use builders only in tests, setters otherwise. -* `--use_builders=nowhere`: never use builders. - -## How Much Performance Benefit Can I Expect? {#performance-benefit} - -This depends heavily on your workload. The following questions can guide your -performance exploration: - -* How big a percentage of your CPU usage is Go Protobuf? Some workloads, like - logs analysis pipelines that compute statistics based on Protobuf input - records, can spend about 50% of their CPU usage in Go Protobuf. Performance - improvements will likely be clearly visible in such workloads. On the other - end of the spectrum, in programs that only spend 3-5% of their CPU usage in - Go Protobuf, performance improvements will often be insignificant compared - to other opportunities. -* How amenable to lazy decoding is your program? If large portions of the - input messages are never accessed, lazy decoding can save a lot of work. - This pattern is usually encountered in jobs like proxy servers (which pass - through the input as-is), or logs analysis pipelines with high selectivity - (which discard many records based on a high-level predicate). -* Do your message definitions contain many elementary fields with explicit - presence? The Opaque API uses a more efficient memory representation for - elementary fields like integers, booleans, enums and floats, but not - strings, repeated fields or submessages. - -## How Does Proto2, Proto3, and Editions Relate to the Opaque API? {#proto23editions} - -The terms proto2 and proto3 refer to different syntax versions in your `.proto` -files. [Protobuf Editions](/editions/overview) is the -successor to both proto2 and proto3. - -The Opaque API affects only the generated code in `.pb.go` files, not what you -write in your `.proto` files. - -The Opaque API works the same, independent of which syntax or edition your -`.proto` files use. However, if you want to select the Opaque API on a per-file -basis (as opposed to using a command-line flag when you are running `protoc`), -you must migrate the file to editions first. See -[How Do I Enable the New Opaque API for My Messages?](#enable) for details. - -## Why Only Change the Memory Layout of Elementary Fields? {#memorylayout} - -The -[announcement blog post’s “Opaque structs use less memory” section](https://go.dev/blog/protobuf-opaque#lessmemory) -explains: - -> This performance improvement [modeling field presence more efficiently] -> depends heavily on your protobuf message shape: The change only affects -> elementary fields like integers, booleans, enums and floats, but not strings, -> repeated fields or submessages. - -A natural follow-up question is why strings, repeated fields, and submessages -remain pointers in the Opaque API. The answer is twofold. - -### Consideration 1: Memory Usage - -Representing submessages as values instead of pointers would increase memory -usage: each Protobuf message type carries internal state, which would consume -memory even when the submessage is not actually set. - -For strings and repeated fields, the situation is more nuanced. Let’s compare -the memory usage of using a string value compared to a string pointer: - -Go variable type | set? | [word]s | #bytes ----------------- | ---- | ------------------------ | ------ -`string` | yes | 2 (data, len) | 16 -`string` | no | 2 (data, len) | 16 -`*string` | yes | 1 (data) + 2 (data, len) | 24 -`*string` | no | 1 (data) | 8 - -[word]: https://en.wikipedia.org/wiki/Word_(computer_architecture) - -(The situation is similar for slices, but slice headers need 3 words: data, len, -cap.) - -If your string fields are overwhelmingly not set, using a pointer saves RAM. Of -course, this saving comes at the cost of introducing more allocations and -pointers into the program, which increases load on the Garbage Collector. - -The advantage of the Opaque API is that we can change the representation without -any changes to user code. The current memory layout was optimal for us when we -introduced it, but if we measured today or 5 years into the future, maybe we -would have chosen a different layout. - -As described in the -[announcement blog post’s “Making the ideal memory layout possible” section](https://go.dev/blog/protobuf-opaque#idealmemory), -we aim to make these optimization decisions on a per-workload basis in the -future. - -### Consideration 2: Lazy Decoding - -Aside from the memory usage consideration, there is another restriction: fields -for which [lazy decoding](#lazydecoding) is enabled must be represented by -pointers. - -Protobuf messages are safe for concurrent access (but not concurrent mutation), -so if two different goroutines trigger lazy decoding, they need to coordinate -somehow. This coordination is implemented through using the -[`sync/atomic` package](https://pkg.go.dev/sync/atomic), which can update -pointers atomically, but not slice headers (which exceed a [word]). - -While `protoc` currently only permits lazy decoding for (non-repeated) -submessages, this reasoning holds for all field types. diff --git a/content/reference/go/opaque-migration-manual.md b/content/reference/go/opaque-migration-manual.md deleted file mode 100644 index e32b8fe19..000000000 --- a/content/reference/go/opaque-migration-manual.md +++ /dev/null @@ -1,669 +0,0 @@ -+++ -title = "Go Opaque API: Manual Migration" -weight = 660 -linkTitle = "Opaque API: Manual Migration" -description = "Describes a manual migration to the Opaque API." -type = "docs" -+++ - -The Opaque API is the latest version of the Protocol Buffers implementation for -the Go programming language. The old version is now called Open Struct API. See -the [Go Protobuf: Releasing the Opaque API](https://go.dev/blog/protobuf-opaque) -blog post for an introduction. - -This is a user guide for migrating Go Protobuf usages from the older Open Struct -API to the new Opaque API. - -{{% alert title="Warning" color="warning" %}} You -are looking at the manual migration guide. Typically you’re better off using the -`open2opaque` tool to automate the migration. See -[Opaque API Migration](/reference/go/opaque-migration) -instead. {{% /alert %}} - -The -[Generated Code Guide](/reference/go/go-generated-opaque) -provides more detail. This guide compares the old and new API side-by-side. - -### Message Construction - -Suppose there is a protobuf message defined like this: - -```proto -message Foo { - uint32 uint32 = 1; - bytes bytes = 2; - oneof union { - string string = 4; - MyMessage message = 5; - } - enum Kind { … }; - Kind kind = 9; -} -``` - -Here is an example of how to construct this message from literal values: - - - - - - - - - - -
Open Struct API (old)Opaque API (new)
- -```go -m := &pb.Foo{ - Uint32: proto.Uint32(5), - Bytes: []byte("hello"), -} -``` - - - -```go -m := pb.Foo_builder{ - Uint32: proto.Uint32(5), - Bytes: []byte("hello"), -}.Build() -``` - -
- -As you can see, the builder structs allow for an almost 1:1 translation between -Open Struct API (old) and Opaque API (new). - -Generally, prefer using builders for readability. Only in rare cases, like -creating Protobuf messages in a hot inner loop, might it be preferable to use -setters instead of builders. See -[the Opaque API FAQ: Should I use builders or setters?](/reference/go/opaque-faq#builders-vs-setters) -for more detail. - -An exception to the above example is when working with [oneofs](#oneofs): The -Open Struct API (old) uses a wrapper struct type for each oneof case, whereas -the Opaque API (new) treats oneof fields like regular message fields: - - - - - - - - - - -
Open Struct API (old)Opaque API (new)
- -```go -m := &pb.Foo{ - Uint32: myScalar, // could be nil - Union: &pb.Foo_String{myString}, - Kind: pb.Foo_SPECIAL_KIND.Enum(), -} -``` - - - -```go -m := pb.Foo_builder{ - Uint32: myScalar, - String: myString, - Kind: pb.Foo_SPECIAL_KIND.Enum(), -}.Build() -``` - -
- -For the set of Go struct fields associated with a oneof union, only one field -may be populated. If multiple oneof case fields are populated, the last one (in -field declaration order in your .proto file) wins. - -### Scalar fields - -Suppose there is a message defined with a scalar field: - -```proto -message Artist { - int32 birth_year = 1; -} -``` - -Protobuf message fields for which Go uses scalar types (bool, int32, int64, -uint32, uint64, float32, float64, string, []byte, and enum) will have `Get` and -`Set` accessor methods. Fields with -[explicit presence](/programming-guides/field_presence/) -will also have `Has` and `Clear` methods. - -For a field of type `int32` named `birth_year`, the following accessor methods -will be generated for it: - -```go -func (m *Artist) GetBirthYear() int32 -func (m *Artist) SetBirthYear(v int32) -func (m *Artist) HasBirthYear() bool -func (m *Artist) ClearBirthYear() -``` - -`Get` returns a value for the field. If the field is not set or the message -receiver is nil, it returns the default value. The default value is the -[zero value](https://go.dev/ref/spec#The_zero_value), unless explicitly set with -the default option. - -`Set` stores the provided value into the field. It panics when called on a nil -message receiver. - -For bytes fields, calling `Set` with a nil []byte will be considered set. For -example, calling `Has` immediately after returns true. Calling `Get` immediately -after will return a zero-length slice (can either be nil or empty slice). Users -should use `Has` for determining presence and not rely on whether `Get` returns -nil. - -`Has` reports whether the field is populated. It returns false when called on a -nil message receiver. - -`Clear` clears the field. It panics when called on a nil message receiver. - -**Example code snippets using a string field in:** - - - - - - - - - - -
Open Struct API (old)Opaque API (new)
- -```go -// Getting the value. -s := m.GetBirthYear() - -// Setting the field. -m.BirthYear = proto.Int32(1989) - -// Check for presence. -if s.BirthYear != nil { … } - -// Clearing the field. -m.BirthYear = nil -``` - - - -```go -// Getting the field value. -s := m.GetBirthYear() - -// Setting the field. -m.SetBirthYear(1989) - -// Check for presence. -if m.HasBirthYear() { … } - -// Clearing the field -m.ClearBirthYear() -``` - -
- -### Message fields - -Suppose there is a message defined with a message-typed field: - -```proto -message Band {} - -message Concert { - Band headliner = 1; -} -``` - -Protobuf message fields of type message will have `Get`, `Set`, `Has` and -`Clear` methods. - -For a message-typed field named `headliner`, the following accessor methods will -be generated for it: - -```go -func (m *Concert) GetHeadliner() *Band -func (m *Concert) SetHeadliner(*Band) -func (m *Concert) HasHeadliner() bool -func (m *Concert) ClearHeadliner() -``` - -`Get` returns a value for the field. It returns nil if not set or when called on -a nil message receiver. Checking if `Get` returns nil is equivalent to checking -if `Has` returns false. - -`Set` stores the provided value into the field. It panics when called on a nil -message receiver. Calling `Set` with a nil pointer is equivalent to calling -`Clear`. - -`Has` reports whether the field is populated. It returns false when called on a -nil message receiver. - -`Clear` clears the field. It panics when called on a nil message receiver. - -**Example code snippets** - - - - - - - - - - -
Open Struct API (old)Opaque (new)
- -```go -// Getting the value. -b := m.GetHeadliner() - -// Setting the field. -m.Headliner = &pb.Band{} - -// Check for presence. -if s.Headliner != nil { … } - -// Clearing the field. -m.Headliner = nil -``` - - - -```go -// Getting the value. -s := m.GetHeadliner() - -// Setting the field. -m.SetHeadliner(&pb.Band{}) - -// Check for presence. -if m.HasHeadliner() { … } - -// Clearing the field -m.ClearHeadliner() -``` - -
- -### Repeated fields - -Suppose there is a message defined with a repeated message-typed field: - -```proto -message Concert { - repeated Band support_acts = 2; -} -``` - -Repeated fields will have `Get` and `Set` methods. - -`Get` returns a value for the field. It returns nil if the field is not set or -the message receiver is nil. - -`Set` stores the provided value into the field. It panics when called on a nil -message receiver. `Set` will store a copy of the slice header that is provided. -Changes to the slice contents are observable in the repeated field. Hence, if -`Set` is called with an empty slice, calling `Get` immediately after will return -the same slice. For the wire or text marshaling output, a passed-in nil slice is -indistinguishable from an empty slice. - -For a repeated message-typed field named `support_acts` on message `Concert`, -the following accessor methods will be generated for it: - -```go -func (m *Concert) GetSupportActs() []*Band -func (m *Concert) SetSupportActs([]*Band) -``` - -**Example code snippets** - - - - - - - - - - -
Open Struct API (old)Opaque API (new)
- -```go -// Getting the entire repeated value. -v := m.GetSupportActs() - -// Setting the field. -m.SupportActs = v - -// Get an element in a repeated field. -e := m.SupportActs[i] - -// Set an element in a repeated field. -m.SupportActs[i] = e - -// Get the length of a repeated field. -n := len(m.GetSupportActs()) - -// Truncate a repeated field. -m.SupportActs = m.SupportActs[:i] - -// Append to a repeated field. -m.SupportActs = append(m.GetSupportActs(), e) -m.SupportActs = append(m.GetSupportActs(), v...) - -// Clearing the field. -m.SupportActs = nil -``` - - - -```go -// Getting the entire repeated value. -v := m.GetSupportActs() - -// Setting the field. -m.SetSupportActs(v) - -// Get an element in a repeated field. -e := m.GetSupportActs()[i] - -// Set an element in a repeated field. -m.GetSupportActs()[i] = e - -// Get the length of a repeated field. -n := len(m.GetSupportActs()) - -// Truncate a repeated field. -m.SetSupportActs(m.GetSupportActs()[:i]) - -// Append to a repeated field. -m.SetSupportActs(append(m.GetSupportActs(), e)) -m.SetSupportActs(append(m.GetSupportActs(), v...)) - -// Clearing the field. -m.SetSupportActs(nil) -``` - -
- -### Maps - -Suppose there is a message defined with a map-typed field: - -```proto -message MerchBooth { - map items = 1; -} -``` - -Map fields will have `Get` and `Set` methods. - -`Get` returns a value for the field. It returns nil if the field is not set or -the message receiver is nil. - -`Set` stores the provided value into the field. It panics when called on a nil -message receiver. `Set` will store a copy of the provided map reference. Changes -to the provided map are observable in the map field. - -For a map field named `items` on message `MerchBooth`, the following accessor -methods will be generated for it: - -```go -func (m *MerchBooth) GetItems() map[string]*MerchItem -func (m *MerchBooth) SetItems(map[string]*MerchItem) -``` - -**Example code snippets** - - - - - - - - - - -
Open Struct API (old)Opaque API (new)
- -```go -// Getting the entire map value. -v := m.GetItems() - -// Setting the field. -m.Items = v - -// Get an element in a map field. -v := m.Items[k] - -// Set an element in a map field. -// This will panic if m.Items is nil. -// You should check m.Items for nil -// before doing the assignment to ensure -// it won't panic. -m.Items[k] = v - -// Delete an element in a map field. -delete(m.Items, k) - -// Get the size of a map field. -n := len(m.GetItems()) - -// Clearing the field. -m.Items = nil -``` - - - -```go -// Getting the entire map value. -v := m.GetItems() - -// Setting the field. -m.SetItems(v) - -// Get an element in a map field. -v := m.GetItems()[k] - -// Set an element in a map field. -// This will panic if m.GetItems() is nil. -// You should check m.GetItems() for nil -// before doing the assignment to ensure -// it won't panic. -m.GetItems()[k] = v - -// Delete an element in a map field. -delete(m.GetItems(), k) - -// Get the size of a map field. -n := len(m.GetItems()) - -// Clearing the field. -m.SetItems(nil) -``` - -
- -### Oneofs - -For each oneof union grouping, there will be a `Which`, `Has` and `Clear` method -on the message. There will also be a `Get`, `Set`, `Has`, and `Clear` method on -each oneof case field in that union. - -Suppose there is a message defined with oneof fields `image_url` and -`image_data` in oneof `avatar` like: - -```proto -message Profile { - oneof avatar { - string image_url = 1; - bytes image_data = 2; - } -} -``` - -The generated Opaque API for this oneof will be: - -```go -func (m *Profile) WhichAvatar() case_Profile_Avatar { … } -func (m *Profile) HasAvatar() bool { … } -func (m *Profile) ClearAvatar() { … } - -type case_Profile_Avatar protoreflect.FieldNumber - -const ( - Profile_Avatar_not_set_case case_Profile_Avatar = 0 - Profile_ImageUrl_case case_Profile_Avatar = 1 - Profile_ImageData_case case_Profile_Avatar = 2 -) -``` - -`Which` reports which case field is set by returning the field number. It -returns 0 when none are set or when called on a nil message receiver. - -`Has` reports whether any of the fields within the oneof is set. It returns -false when called on a nil message receiver. - -`Clear` clears the currently set case field in the oneof. It panics on a nil -message receiver. - -The generated Opaque API for each oneof case field will be: - -```go -func (m *Profile) GetImageUrl() string { … } -func (m *Profile) GetImageData() []byte { … } - -func (m *Profile) SetImageUrl(v string) { … } -func (m *Profile) SetImageData(v []byte) { … } - -func (m *Profile) HasImageUrl() bool { … } -func (m *Profile) HasImageData() bool { … } - -func (m *Profile) ClearImageUrl() { … } -func (m *Profile) ClearImageData() { … } -``` - -`Get` returns a value for the case field. It will return the zero value if the -case field is not set or when called on a nil message receiver. - -`Set` stores the provided value into the case field. It also implicitly clears -the case field that was previously populated within the oneof union. Calling -`Set` on a oneof message case field with nil value will set the field to an -empty message. It panics when called on a nil message receiver. - -`Has` reports whether the case field is set or not. It returns false when called -on a nil message receiver. - -`Clear` clears the case field. If it was previously set, the oneof union is also -cleared. If the oneof union is set to different field, it will not clear the -oneof union. It panics when called on a nil message receiver. - -**Example code snippets** - - - - - - - - - - - -
Open Struct API (old)Opaque API (new)
- -```go -// Getting the oneof field that is set. -switch m.GetAvatar().(type) { -case *pb.Profile_ImageUrl: - … = m.GetImageUrl() -case *pb.Profile_ImageData: - … = m.GetImageData() -} - -// Setting the fields. -m.Avatar = &pb.Profile_ImageUrl{"http://"} -m.Avatar = &pb.Profile_ImageData{img} - -// Checking whether any oneof field is set -if m.Avatar != nil { … } - -// Clearing the field. -m.Avatar = nil - -// Checking if a specific field is set. -_, ok := m.GetAvatar().(*pb.Profile_ImageUrl) -if ok { … } - -// Clearing a specific field -_, ok := m.GetAvatar().(*pb.Profile_ImageUrl) -if ok { - m.Avatar = nil -} - -// Copy a oneof field. -m.Avatar = src.Avatar -``` - - - -```go -// Getting the oneof field that is set. -switch m.WhichAvatar() { -case pb.Profile_ImageUrl_case: - … = m.GetImageUrl() -case pb.Profile_ImageData_case: - … = m.GetImageData() -} - -// Setting the fields. -m.SetImageUrl("http://") -m.SetImageData([]byte("…")) - -// Checking whether any oneof field is set -if m.HasAvatar() { … } - -// Clearing the field. -m.ClearAvatar() - -// Checking if a specific field is set. -if m.HasImageUrl() { … } - -// Clearing a specific field. -m.ClearImageUrl() - -// Copy a oneof field -switch src.WhichAvatar() { -case pb.Profile_ImageUrl_case: - m.SetImageUrl(src.GetImageUrl()) -case pb.Profile_ImageData_case: - m.SetImageData(src.GetImageData()) -} -``` - -
- -### Reflection - -Code that use Go `reflect` package on proto message types to access struct -fields and tags will no longer work when migrating away from the Open Struct -API. Code will need to migrate to use -[protoreflect](https://pkg.go.dev/google.golang.org/protobuf/reflect/protoreflect) - -Some common libraries do use Go `reflect` under the hood, examples are: - -* [encoding/json](https://pkg.go.dev/encoding/json/) - * Use - [protobuf/encoding/protojson](https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson). -* [pretty](https://pkg.go.dev/github.com/kr/pretty) -* [cmp](https://pkg.go.dev/github.com/google/go-cmp/cmp) - * To use `cmp.Equal` properly with protobuf messages, use - [protocmp.Transform](https://pkg.go.dev/google.golang.org/protobuf/testing/protocmp#Transform) diff --git a/content/reference/go/opaque-migration.md b/content/reference/go/opaque-migration.md deleted file mode 100644 index f96eb396e..000000000 --- a/content/reference/go/opaque-migration.md +++ /dev/null @@ -1,214 +0,0 @@ -+++ -title = "Go Opaque API Migration" -weight = 650 -linkTitle = "Opaque API Migration" -description = "Describes the automated migration to the Opaque API." -type = "docs" -+++ - -The Opaque API is the latest version of the Protocol Buffers implementation for -the Go programming language. The old version is now called Open Struct API. See -the [Go Protobuf: Releasing the Opaque API](https://go.dev/blog/protobuf-opaque) -blog post for an introduction. - -The migration to the Opaque API happens incrementally, on a per-proto-message or -per-`.proto`-file basis, by setting the `api_level` feature to one of its -possible values: - -* `API_OPEN` selects the Open Struct API. This was backported into edition - 2023, so older versions of the Go plugin may not honor it. -* `API_HYBRID` is a step between Open and Opaque: The Hybrid API also includes - accessor methods (so you can update your code), but still exports the struct - fields as before. There is no performance difference; this API level only - helps with the migration. -* `API_OPAQUE` selects the Opaque API; this is the default for Edition 2024 - and newer. - -To override the default for a specific `.proto` file, set the `api_level` -feature: - -```proto -edition = "2024"; - -package log; - -import "google/protobuf/go_features.proto"; -option features.(pb.go).api_level = API_OPEN; - -message LogEntry { … } -``` - -Before you can change the `api_level` to `API_OPAQUE` for existing files, all -existing usages of the generated proto code need to be updated. The -`open2opaque` tool helps with this. - -For your convenience, you can also override the default API level with a -`protoc` command-line flag: - -``` -protoc […] --go_opt=default_api_level=API_OPEN -``` - -To override the default API level for a specific file (instead of all files), -use the `apilevelM` mapping flag (similar to -[the `M` flag for import paths](/reference/go/go-generated/#package)): - -``` -protoc […] --go_opt=apilevelMhello.proto=API_OPEN -``` - -## Automated Migration {#automated} - -We try to make migrating existing projects to the Opaque API as easy as possible -for you: our open2opaque tool does most of the work! - -To install the migration tool, use: - -``` -go install google.golang.org/open2opaque@latest -go install golang.org/x/tools/cmd/goimports@latest -``` - -{{% alert title="Note" color="info" %}} If -you encounter any issues with the automated migration approach, refer to the -[Opaque API: Manual Migration](/reference/go/opaque-migration-manual) -guide. {{% /alert %}} - -### Project Preparation {#projectprep} - -Ensure your build environment and project are using recent-enough versions of -Protocol Buffers and Go Protobuf: - -1. Update the protobuf compiler (protoc) from - [the protobuf release page](https://github.com/protocolbuffers/protobuf/releases/latest) - to version 29.0 or newer. - -1. Update the protobuf compiler Go plugin (protoc-gen-go) to version 1.36.0 or - newer: - - ``` - go install google.golang.org/protobuf/cmd/protoc-gen-go@latest - ``` - -1. In each project, update the `go.mod` file to use the protobuf module in - version 1.36.0 or newer: - - ``` - go get google.golang.org/protobuf@latest - ``` - - {{% alert title="Note" color="note" %}} If you - are not yet importing `google.golang.org/protobuf`, you might still be on an - older module. See - [the `google.golang.org/protobuf` announcement (from 2020)](https://go.dev/blog/protobuf-apiv2) - and migrate your code before returning to this - page. {{% /alert %}} - -### Step 1. Switch to the Hybrid API {#setup} - -Use the `open2opaque` tool to switch your `.proto` files to the Hybrid API: - -``` -open2opaque setapi -api HYBRID $(find . -name "*.proto") -``` - -Then, -[re-compile](/getting-started/gotutorial#compiling-protocol-buffers) -your protocol buffers. - -Your existing code will continue to build. The Hybrid API is a step between the -Open and Opaque API which adds the new accessor methods but keeps struct fields -visible. - -### Step 2. `open2opaque rewrite` {#rewrite} - -To rewrite your Go code to use the Opaque API, run the `open2opaque rewrite` -command: - -``` -open2opaque rewrite -levels=red github.com/robustirc/robustirc/... -``` - -You can specify one or more -[packages or patterns](https://pkg.go.dev/cmd/go#hdr-Package_lists_and_patterns). - -As an example, if you had code like this: - -```go -logEntry := &logpb.LogEntry{} -if req.IPAddress != nil { - logEntry.IPAddress = redactIP(req.IPAddress) -} -logEntry.BackendServer = proto.String(host) -``` - -The tool would rewrite it to use accessors: - -```go -logEntry := &logpb.LogEntry{} -if req.HasIPAddress() { - logEntry.SetIPAddress(redactIP(req.GetIPAddress())) -} -logEntry.SetBackendServer(host) -``` - -Another common example is to initialize a protobuf message with a struct -literal: - -```go -return &logpb.LogEntry{ - BackendServer: proto.String(host), -} -``` - -In the Opaque API, the equivalent is to use a Builder: - -```go -return logpb.LogEntry_builder{ - BackendServer: proto.String(host), -}.Build() -``` - -The tool classifies its available rewrites into different levels. The -`-levels=red` argument enables all rewrites, including those that require human -review. The following levels are available: - -* green: Safe rewrites (high - confidence). Includes most changes the tool makes. These changes do not - require a close look and could even be submitted by automation, without any - human oversight. -* yellow: (reasonable - confidence) These rewrites require human review. They should be correct, but - please review them. -* red: Potentially dangerous - rewrites, changing rare and complicated patterns. These require careful - human review. For example, when an existing function takes a `*string` - parameter, the typical fix of using `proto.String(msg.GetFoo())` does not - work if the function meant to change the field value by writing to the - pointer (`*foo = "value"`). - -Many programs can be fully migrated with only green changes. Before you can -migrate a proto message or file to the Opaque API, you need to complete all -rewrites of all levels, at which point no direct struct access remains in your -code. - -### Step 3. Migrate and Verify {#migrate-and-verify} - -To complete the migration, use the `open2opaque` tool to switch your `.proto` -files to the Opaque API: - -``` -open2opaque setapi -api OPAQUE $(find . -name "*.proto") -``` - -Now, any remaining code that was not rewritten to the Opaque API yet will no -longer compile. - -Run your unit tests, integration tests and other verification steps, if any. - -## Questions? Issues? - -First, check out the -[Opaque API FAQ](/reference/go/opaque-faq). If that -doesn't answer your question or resolve your issue, see -[Where can I ask questions or report issues?](/reference/go/opaque-faq#questions) diff --git a/content/reference/go/size.md b/content/reference/go/size.md deleted file mode 100644 index 3841d98ea..000000000 --- a/content/reference/go/size.md +++ /dev/null @@ -1,162 +0,0 @@ -+++ -title = "Go Size Semantics" -weight = 630 -linkTitle = "Size Semantics" -description = "Explains how (not) to use proto.Size" -type = "docs" -+++ - -The [`proto.Size`](https://pkg.go.dev/google.golang.org/protobuf/proto#Size) -function returns the size in bytes of the wire-format encoding of a -`proto.Message` by traversing all its fields (including submessages). - -In particular, it returns the size of **how Go Protobuf will encode the -message**. - -## A note on Protobuf Editions - -With Protobuf Editions, `.proto` files can enable features that change -serialization behavior. This can affect the value returned by `proto.Size`. For -example, setting `features.field_presence = IMPLICIT` will cause scalar fields -that are set to their defaults to not be serialized, and therefore don't -contribute to the size of the message. - -## Typical usages - -### Identifying empty messages - -Checking if -[`proto.Size`](https://pkg.go.dev/google.golang.org/protobuf/proto#Size) returns -0 is a common way to check for empty messages: - -```go -if proto.Size(m) == 0 { - // No fields set; skip processing this message, - // or return an error, or similar. -} -``` - -### Size-limiting program output - -Let’s say you’re writing a batch processing pipeline which produces work tasks -for another system that we’ll call “downstream system” in this example. The -downstream system is provisioned for handling small to medium-sized tasks, but -load testing has shown that the system runs into a cascading failure when -presented with a work task of over 500 MB. - -The best fix is to add protection to the downstream system (see -https://cloud.google.com/blog/products/gcp/using-load-shedding-to-survive-a-success-disaster-cre-life-lessons), -but when implementing load-shedding is infeasible, you could decide to add a -quick fix to your pipeline: - -```go {highlight="context:1,proto.Size,1"} -func (*beamFn) ProcessElement(key string, value []byte, emit func(proto.Message)) { - task := produceWorkTask(value) - if proto.Size(task) > 500 * 1024 * 1024 { - // Skip every work task over 500 MB to not overwhelm - // the brittle downstream system. - return - } - emit(task) -} -``` - -## Incorrect usage: no relation to Unmarshal - -Because [`proto.Size`](https://pkg.go.dev/google.golang.org/protobuf/proto#Size) -returns the number of bytes for how Go Protobuf will encode the message, it is -not safe to use `proto.Size` when unmarshaling (decoding) a stream of incoming -Protobuf messages: - -```go {highlight="context:1,proto.Size,1"} -func bytesToSubscriptionList(data []byte) ([]*vpb.EventSubscription, error) { - subList := []*vpb.EventSubscription{} - for len(data) > 0 { - subscription := &vpb.EventSubscription{} - if err := proto.Unmarshal(data, subscription); err != nil { - return nil, err - } - subList = append(subList, subscription) - data = data[:len(data)-proto.Size(subscription)] - } - return subList, nil -} -``` - -When `data` contains a message in [non-minimal wire format](#non-minimal), -`proto.Size` can return a different size than was actually unmarshaled, -resulting in a parsing error (best case) or incorrectly parsed data in the worst -case. - -Hence, this example only works reliably as long as all input messages are -generated by (the same version of) Go Protobuf. This is surprising and likely -not intended. - -**Tip:** Use the -[`protodelim` package](https://pkg.go.dev/google.golang.org/protobuf/encoding/protodelim) -instead to read/write size-delimited streams of Protobuf messages. - -## Advanced usage: pre-sizing buffers - -An advanced usage of -[`proto.Size`](https://pkg.go.dev/google.golang.org/protobuf/proto#Size) is to -determine the required size for a buffer before marshaling: - -```go -opts := proto.MarshalOptions{ - // Possibly avoid an extra proto.Size in Marshal itself (see docs): - UseCachedSize: true, -} -// DO NOT SUBMIT without implementing this Optimization opportunity: -// instead of allocating, grab a sufficiently-sized buffer from a pool. -// Knowing the size of the buffer means we can discard -// outliers from the pool to prevent uncontrolled -// memory growth in long-running RPC services. -buf := make([]byte, 0, opts.Size(m)) -var err error -buf, err = opts.MarshalAppend(buf, m) // does not allocate -// Note that len(buf) might be less than cap(buf)! Read below: -``` - -Note that when lazy decoding is enabled, `proto.Size` might return more bytes -than `proto.Marshal` (and variants like `proto.MarshalAppend`) will write! So -when you are placing encoded bytes on the wire (or on disk), be sure to work -with `len(buf)` and discard any previous `proto.Size` results. - -Specifically, a (sub-)message can “shrink” between `proto.Size` and -`proto.Marshal` when: - -1. Lazy decoding is enabled -2. and the message arrived in [non-minimal wire format](#non-minimal) -3. and the message is not accessed before `proto.Size` is called, meaning it is - not decoded yet -4. and the message is accessed after `proto.Size` (but before `proto.Marshal`), - causing it to be lazily decoded - -The decoding results in any subsequent `proto.Marshal` calls encoding the -message (as opposed to merely copying its wire format), which results in -implicit normalization to how Go encodes messages, which is currently in minimal -wire format (but don’t rely on that!). - -As you can see, the scenario is rather specific, but nevertheless it is **best -practice to treat `proto.Size` results as an upper bound** and never assume that -the result matches the actually encoded message size. - -## Background: Non-minimal wire format {#non-minimal} - -When encoding Protobuf messages, there is one *minimal wire format size* and a -number of larger *non-minimal wire formats* that decode to the same message. - -Non-minimal wire format (also called “denormalized wire format” sometimes) -refers to scenarios like non-repeated fields appearing multiple times, -non-optimal varint encoding, packed repeated fields that appear non-packed on -the wire and others. - -We can encounter non-minimal wire format in different scenarios: - -* **Intentionally.** Protobuf supports concatenating messages by concatenating - their wire format. -* **Accidentally.** A (possibly third-party) Protobuf encoder does not encode - ideally (e.g. uses more space than necessary when encoding a varint). -* **Maliciously.** An attacker could craft Protobuf messages specifically to - trigger crashes over the network. diff --git a/content/reference/java/_index.md b/content/reference/java/_index.md deleted file mode 100644 index 8636a1c9c..000000000 --- a/content/reference/java/_index.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "Java Reference" -weight = 640 -linkTitle = "Java" -description = "Reference documentation for working with protocol buffer classes in Java." -type = "docs" -+++ diff --git a/content/reference/java/api-docs-link.md b/content/reference/java/api-docs-link.md deleted file mode 100644 index 347a29b89..000000000 --- a/content/reference/java/api-docs-link.md +++ /dev/null @@ -1,8 +0,0 @@ - - ---- -title: "Java API" -manualLink: "/reference/java/api-docs/overview-summary.html" -manualLinkTarget: "_blank" -weight: 660 ---- \ No newline at end of file diff --git a/content/reference/java/java-generated.md b/content/reference/java/java-generated.md deleted file mode 100644 index da2d73284..000000000 --- a/content/reference/java/java-generated.md +++ /dev/null @@ -1,1051 +0,0 @@ -+++ -title = "Java Generated Code Guide" -weight = 650 -linkTitle = "Generated Code Guide" -description = "Describes exactly what Java code the protocol buffer compiler generates for any given protocol definition." -type = "docs" -+++ - -Any -differences between proto2, proto3, and Editions generated code are -highlighted—note that these differences are in the generated code as -described in this document, not the base message classes/interfaces, which are -the same in all versions. You should read the -[proto2 language guide](/programming-guides/proto2), -[proto3 language guide](/programming-guides/proto3), -and/or -[Editions language guide](/programming-guides/editions) -before reading this document. - -Note that no Java protocol buffer methods accept or return nulls unless -otherwise specified. - -## Compiler Invocation {#invocation} - -The protocol buffer compiler produces Java output when invoked with the -`--java_out=` command-line flag. The parameter to the `--java_out=` option is -the directory where you want the compiler to write your Java output. For each -`.proto` file input, the compiler creates a wrapper `.java` file containing a -Java class that represents the `.proto` file itself. - -If the `.proto` file contains a line like the following: - -```proto -option java_multiple_files = true; -``` - -Then the compiler will also create separate `.java` files for each of the -classes/enums which it will generate for each top-level message, enumeration, -and service declared in the `.proto` file. - -Otherwise (when the `java_multiple_files` option is disabled, which is the -default), the aforementioned wrapper class will also be used as an outer class, -and the generated classes/enums for each top-level message, enumeration, and -service declared in the `.proto` file will all be nested within the outer -wrapper class. Thus the compiler will only generate a single `.java` file for -the entire `.proto` file, and it will have an extra layer in the package - -The wrapper class's name is chosen as follows: If the `.proto` file contains a -line like the following: - -```proto -option java_outer_classname = "Foo"; -``` - -Then the wrapper class name will be `Foo`. Otherwise, the wrapper class name is -determined by converting the `.proto` file base name to camel case. For example, -`foo_bar.proto` will generate a class name of `FooBar`. If there's a service, -enum, or message (including nested types) in the file with the same name, -"OuterClass" will be appended to the wrapper class's name. Examples: - -- If `foo_bar.proto` contains a message called `FooBar`, the wrapper class - will generate a class name of `FooBarOuterClass`. -- If `foo_bar.proto` contains a service called `FooService`, and - `java_outer_classname` is also set to the string `FooService`, then the - wrapper class will generate a class name of `FooServiceOuterClass`. - -{{% alert title="Note" color="note" %}}If you are -using the deprecated v1 of the protobuf API, `OuterClass` is added regardless of -any collisions with message -names.{{% /alert %}} - -In addition to any nested classes, the wrapper class itself will have the -following API (assuming the wrapper class is named `Foo` and was generated from -`foo.proto`): - -```java -public final class Foo { - private Foo() {} // Not instantiable. - - /** Returns a FileDescriptor message describing the contents of {@code foo.proto}. */ - public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor(); - /** Adds all extensions defined in {@code foo.proto} to the given registry. */ - public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry registry); - public static void registerAllExtensions(com.google.protobuf.ExtensionRegistryLite registry); - - // (Nested classes omitted) -} -``` - -The Java package name is chosen as described under [Packages](#package), below. - -The output file is chosen by concatenating the parameter to `--java_out=`, the -package name (with `.`s replaced with `/`s), and the `.java` file name. - -So, for example, let's say you invoke the compiler as follows: - -```shell -protoc --proto_path=src --java_out=build/gen src/foo.proto -``` - -If `foo.proto`'s Java package is `com.example` and it doesn't enable -`java_multiple_files` and its outer classname is `FooProtos`, then the protocol -buffer compiler will generate the file `build/gen/com/example/FooProtos.java`. -The protocol buffer compiler will automatically create the `build/gen/com` and -`build/gen/com/example` directories if needed. However, it will not create -`build/gen` or `build`; they must already exist. You can specify multiple -`.proto` files in a single invocation; all output files will be generated at -once. - -When outputting Java code, the protocol buffer compiler's ability to output -directly to JAR archives is particularly convenient, as many Java tools are able -to read source code directly from JAR files. To output to a JAR file, simply -provide an output location ending in `.jar`. Note that only the Java source code -is placed in the archive; you must still compile it separately to produce Java -class files. - -## Packages {#package} - -The generated class is placed in a Java package based on the `java_package` -option. If the option is omitted, the `package` declaration is used instead. - -For example, if the `.proto` file contains: - -```proto -package foo.bar; -``` - -Then the resulting Java class will be placed in Java package -`foo.bar`. However, if the `.proto` file also -contains a `java_package` option, like so: - -```proto -package foo.bar; -option java_package = "com.example.foo.bar"; -``` - -Then the class is placed in the `com.example.foo.bar` package instead. The -`java_package` option is provided because normal `.proto` `package` declarations -are not expected to start with a backwards domain name. - -## Messages {#message} - -If you are designing a new protocol buffer schema, see -[the recommendations for Java proto names](/reference/java/java-proto-names). - -Given a simple message declaration: - -```proto -message Foo {} -``` - -The protocol buffer compiler generates a class called `Foo`, which implements -the `Message` interface. The class is declared `final`; no further subclassing -is allowed. `Foo` extends `GeneratedMessage`, but this should be considered an -implementation detail. By default, `Foo` overrides many methods of -`GeneratedMessage` with specialized versions for maximum speed. However, if the -`.proto` file contains the line: - -```proto -option optimize_for = CODE_SIZE; -``` - -then `Foo` will override only the minimum set of methods necessary to function -and rely on `GeneratedMessage`'s reflection-based implementations of the rest. -This significantly reduces the size of the generated code, but also reduces -performance. Alternatively, if the `.proto` file contains: - -```proto -option optimize_for = LITE_RUNTIME; -``` - -then `Foo` will include fast implementations of all methods, but will implement -the `MessageLite` interface, which contains a subset of the methods of -`Message`. In particular, it does not support descriptors, nested builders, or -reflection. However, in this mode, the generated code only needs to link against -`libprotobuf-lite.jar` instead of `libprotobuf.jar`. The "lite" library is much -smaller than the full library, and is more appropriate for resource-constrained -systems such as mobile phones. - -The `Message` interface defines methods that let you check, manipulate, read, or -write the entire message. In addition to these methods, the `Foo` class defines -the following static methods: - -- `static Foo getDefaultInstance()`: Returns the *singleton* instance of - `Foo`. This instance's contents are identical to what you'd get if you - called `Foo.newBuilder().build()` (so all singular fields are unset and all - repeated fields are empty). Note that the default instance of a message can - be used as a factory by calling its `newBuilderForType()` method. -- `static Descriptor getDescriptor()`: Returns the type's descriptor. This - contains information about the type, including what fields it has and what - their types are. This can be used with the reflection methods of the - `Message`, such as `getField()`. -- `static Foo parseFrom(...)`: Parses a message of type `Foo` from the given - source and returns it. There is one `parseFrom` method corresponding to each - variant of `mergeFrom()` in the `Message.Builder` interface. Note that - `parseFrom()` never throws `UninitializedMessageException`; it throws - `InvalidProtocolBufferException` if the parsed message is missing required - fields. This makes it subtly different from calling - `Foo.newBuilder().mergeFrom(...).build()`. -- `static Parser parser()`: Returns an instance of the `Parser`, which - implements various `parseFrom()` methods. -- `Foo.Builder newBuilder()`: Creates a new builder (described below). -- `Foo.Builder newBuilder(Foo prototype)`: Creates a new builder with all - fields initialized to the same values that they have in `prototype`. Since - embedded message and string objects are immutable, they are shared between - the original and the copy. - -### Builders {#builders} - -Message objects—such as instances of the `Foo` class described -above—are immutable, just like a Java `String`. To construct a message -object, you need to use a *builder*. Each message class has its own builder -class—so in our `Foo` example, the protocol buffer compiler generates a -nested class `Foo.Builder` which can be used to build a `Foo`. `Foo.Builder` -implements the `Message.Builder` interface. It extends the -`GeneratedMessage.Builder` class, but, again, this should be considered an -implementation detail. Like `Foo`, `Foo.Builder` may rely on generic method -implementations in `GeneratedMessage.Builder` or, when the `optimize_for` option -is used, generated custom code that is much faster. You can get a `Foo.Builder` -by calling the static method `Foo.newBuilder()`. - -`Foo.Builder` does not define any static methods. Its interface is exactly as -defined by the `Message.Builder` interface, with the exception that return types -are more specific: methods of `Foo.Builder` that modify the builder return type -`Foo.Builder`, and `build()` returns type `Foo`. - -Methods that modify the contents of a builder—including field -setters—always return a reference to the builder (i.e. they "`return -this;`"). This allows multiple method calls to be chained together in one line. -For example: `builder.mergeFrom(obj).setFoo(1).setBar("abc").clearBaz();` - -Note that builders are not thread-safe, so Java synchronization should be used -whenever it is necessary for multiple different threads to be modifying the -contents of a single builder. - -### Sub-Builders {#sub-builders} - -For messages containing sub-messages, the compiler also generates sub-builders. -This allows you to repeatedly modify deep-nested sub-messages without rebuilding -them. For example: - -```proto -message Foo { - int32 val = 1; - // some other fields. -} - -message Bar { - Foo foo = 1; - // some other fields. -} - -message Baz { - Bar bar = 1; - // some other fields. -} -``` - -If you have a `Baz` message already, and want to change the deeply nested `val` -in `Foo`. Instead of: - -```java -baz = baz.toBuilder().setBar( - baz.getBar().toBuilder().setFoo( - baz.getBar().getFoo().toBuilder().setVal(10).build() - ).build()).build(); -``` - -You can write: - -```java -Baz.Builder builder = baz.toBuilder(); -builder.getBarBuilder().getFooBuilder().setVal(10); -baz = builder.build(); -``` - -### Nested Types {#nested} - -A message can be declared inside another message. For example: - -```proto -message Foo { - message Bar { } -} -``` - -In this case, the compiler simply generates `Bar` as an inner class nested -inside `Foo`. - -## Fields {#fields} - -In addition to the methods described in the previous section, the protocol -buffer compiler generates a set of accessor methods for each field defined -within the message in the `.proto` file. The methods that read the field value -are defined both in the message class and its corresponding builder; the methods -that modify the value are defined in the builder only. - -Note that method names always use camel-case naming, even if the field name in -the `.proto` file uses lower-case with underscores -([as it should](/programming-guides/style)). The -case-conversion works as follows: - -* For each underscore in the name, the underscore is removed, and the - following letter is capitalized. -* If the name will have a prefix attached (e.g. "get"), the first letter is - capitalized. Otherwise, it is lower-cased. -* The letter following the last digit in each number in a method name is - capitalized. - -Thus, the field `foo_bar_baz` becomes `fooBarBaz`. If prefixed with `get`, it -would be `getFooBarBaz`. And `foo_ba23r_baz` becomes `fooBa23RBaz`. - -As well as accessor methods, the compiler generates an integer constant for each -field containing its field number. The constant name is the field name converted -to upper-case followed by `_FIELD_NUMBER`. For example, given the field `int32 -foo_bar = 5;`, the compiler will generate the constant `public static final int -FOO_BAR_FIELD_NUMBER = 5;`. - -The following sections are divided between explicit and implicit presence. -Proto2 has explicit presence and proto3 defaults to implicit presence. Editions -defaults to explicit presence, but you can override that using -[`features.field_presence`](/editions/features#field_presence). - - - -### Singular Fields with Explicit Presence {#singular-explicit} - -For any of these field definitions: - -```proto -optional int32 foo = 1; -required int32 foo = 1; -``` - -The compiler will generate the following accessor methods in both the message -class and its builder: - -- `boolean hasFoo()`: Returns `true` if the field is set. -- `int getFoo()`: Returns the current value of the field. If the field is not - set, returns the default value. - -The compiler will generate the following methods only in the message's builder: - -- `Builder setFoo(int value)`: Sets the value of the field. After calling - this, `hasFoo()` will return `true` and `getFoo()` will return `value`. -- `Builder clearFoo()`: Clears the value of the field. After calling this, - `hasFoo()` will return `false` and `getFoo()` will return the default value. - -For other simple field types, the corresponding Java type is chosen according to -the -[scalar value types table](/programming-guides/proto2#scalar). -For message and enum types, the value type is replaced with the message or enum -class. - -#### Embedded Message Fields {#embedded-message-proto2} - -For message types, `setFoo()` also accepts an instance of the message's builder -type as the parameter. This is just a shortcut which is equivalent to calling -`.build()` on the builder and passing the result to the method. Further -modifying the sub-builder passed to `setFoo` will **not** be reflected in the -message class's builder. The message class's builder "takes ownership" of the -sub-message. - -If the field is not set, `getFoo()` will return a Foo instance with none of its -fields set (possibly the instance returned by `Foo.getDefaultInstance()`). - -In addition, the compiler generates two accessor methods that allow you to -access the relevant sub-builders for message types. The following method is -generated in both the message class and its builder: - -- `FooOrBuilder getFooOrBuilder()`: Returns the builder for the field, if it - already exists, or the message if not. Calling this method on builders will - not create a sub-builder for the field. - -The compiler generates the following method only in the message's builder. - -- `Builder getFooBuilder()`: Returns the builder for the field. - - - -### Singular Fields with Implicit Presence {#singular-implicit} - -For this field definition: - -```proto -int32 foo = 1; -``` - -The compiler will generate the following accessor method in both the message -class and its builder: - -- `int getFoo()`: Returns the current value of the field. If the field is not - set, returns the default value for the field's type. - -The compiler will generate the following methods only in the message's builder: - -- `Builder setFoo(int value)`: Sets the value of the field. After calling - this, `getFoo()` will return `value`. -- `Builder clearFoo()`: Clears the value of the field. After calling this, - `getFoo()` will return the default value for the field's type. - -For other simple field types, the corresponding Java type is chosen according to -the -[scalar value types table](/programming-guides/proto2#scalar). -For message and enum types, the value type is replaced with the message or enum -class. - -#### Enum Fields {#enum-proto3} - -For enum field types, an additional accessor method is generated in both the -message class and its builder: - -- `int getFooValue()`: Returns the integer value of the enum. - -The compiler will generate the following additional method only in the message's -builder: - -- `Builder setFooValue(int value)`: Sets the integer value of the enum. - -In addition, `getFoo()` will return `UNRECOGNIZED` if the enum value is -unknown—this is a special additional value added by the proto3 compiler to -the generated [enum type](#enum). - -### Repeated Fields {#repeated} - -For this field definition: - -```proto -repeated string foos = 1; -``` - -The compiler will generate the following accessor methods in both the message -class and its builder: - -- `int getFoosCount()`: Returns the number of elements currently in the field. -- `String getFoos(int index)`: Returns the element at the given zero-based - index. -- `ProtocolStringList getFoosList()`: Returns the entire field as a - `ProtocolStringList`. If the field is not set, returns an empty list. - -The compiler will generate the following methods only in the message's builder: - -- `Builder setFoos(int index, String value)`: Sets the value of the element at - the given zero-based index. -- `Builder addFoos(String value)`: Appends a new element to the field with the - given value. -- `Builder addAllFoos(Iterable value)`: Appends all elements - in the given `Iterable` to the field. -- `Builder clearFoos()`: Removes all elements from the field. After calling - this, `getFoosCount()` will return zero. - -For other simple field types, the corresponding Java type is chosen according to -the -[scalar value types table](/programming-guides/proto2#scalar). -For message and enum types, the type is the message or enum class. - -#### Repeated Embedded Message Fields {#repeated-embedded} - -For message types, `setFoos()` and `addFoos()` also accept an instance of the -message's builder type as the parameter. This is just a shortcut which is -equivalent to calling `.build()` on the builder and passing the result to the -method. There is also an additional generated method: - -- `Builder addFoos(int index, Field value)`: Inserts a new element at the - given zero-based index. Shifts the element currently at that position (if - any) and any subsequent elements to the right (adds one to their indices). - -In addition, the compiler generates the following additional accessor methods in -both the message class and its builder for message types, allowing you to access -the relevant sub-builders: - -- `FooOrBuilder getFoosOrBuilder(int index)`: Returns the builder for the - specified element, if it already exists, or throws - `IndexOutOfBoundsException` if not. If this is called from a message class, - it will always return a message (or throw an exception) rather than a - builder. Calling this method on builders will not create a sub-builder for - the field. -- `List getFoosOrBuilderList()`: Returns the entire field as an - unmodifiable list of builders (if available) or messages if not. If this is - called from a message class, it will always return an immutable list of - messages rather than an unmodifiable list of builders. - -The compiler will generate the following methods only in the message's builder: - -- `Builder getFoosBuilder(int index)`: Returns the builder for the element at - the specified index, or throws `IndexOutOfBoundsException` if the index is - out of bounds. -- `Builder addFoosBuilder(int index)`: Inserts and returns a builder for a - default message instance of the repeated message at the specified index. The - existing entries are shifted to higher indices to make room for the inserted - builder. -- `Builder addFoosBuilder()`: Appends and returns a builder for a default - message instance of the repeated message. -- `Builder removeFoos(int index)`: Removes the element at the given zero-based - index. -- `List getFoosBuilderList()`: Returns the entire field as an - unmodifiable list of builders. - -#### Repeated Enum Fields (proto3 only) {#repeated-enum-proto3} - -The compiler will generate the following additional methods in both the message -class and its builder: - -- `int getFoosValue(int index)`: Returns the integer value of the enum at the - specified index. -- `List getFoosValueList()`: Returns the entire field as a - list of Integers. - -The compiler will generate the following additional method only in the message's -builder: - -- `Builder setFoosValue(int index, int value)`: Sets the integer value of the - enum at the specified index. - -#### Name Conflicts {#conflicts} - -If another non-repeated field has a name that conflicts with one of the repeated -field's generated methods, then both field names will have their protobuf field -number appended to the end. - -For these field definitions: - -```proto -int32 foos_count = 1; -repeated string foos = 2; -``` - -The compiler will first rename them to the following: - -```proto -int32 foos_count_1 = 1; -repeated string foos_2 = 2; -``` - -The accessor methods will subsequently be generated as described above. - - - -### Oneof Fields {#oneof-fields} - -For this oneof field definition: - -```proto -oneof choice { - int32 foo_int = 4; - string foo_string = 9; - ... -} -``` - -All the fields in the `choice` oneof will use a single private field for their -value. In addition, the protocol buffer compiler will generate a Java enum type -for the oneof case, as follows: - -```java -public enum ChoiceCase - implements com.google.protobuf.Internal.EnumLite { - FOO_INT(4), - FOO_STRING(9), - ... - CHOICE_NOT_SET(0); - ... - }; -``` - -The values of this enum type have the following special methods: - -- `int getNumber()`: Returns the object's numeric value as defined in the - .proto file. -- `static ChoiceCase forNumber(int value)`: Returns the enum object - corresponding to the given numeric value (or `null` for other numeric - values). - -The compiler will generate the following accessor methods in both the message -class and its builder: - -- `boolean hasFooInt()`: Returns `true` if the oneof case is `FOO_INT`. -- `int getFooInt()`: Returns the current value of `foo` if the oneof case is - `FOO_INT`. Otherwise, returns the default value of this field. -- `ChoiceCase getChoiceCase()`: Returns the enum indicating which field is - set. Returns `CHOICE_NOT_SET` if none of them is set. - -The compiler will generate the following methods only in the message's builder: - -- `Builder setFooInt(int value)`: Sets `Foo` to this value and sets the oneof - case to `FOO_INT`. After calling this, `hasFooInt()` will return `true`, - `getFooInt()` will return `value` and `getChoiceCase()` will return - `FOO_INT`. -- `Builder clearFooInt()`: - - Nothing will be changed if the oneof case is not `FOO_INT`. - - If the oneof case is `FOO_INT`, sets `Foo` to null and the oneof case to - `CHOICE_NOT_SET`. After calling this, `hasFooInt()` will return `false`, - `getFooInt()` will return the default value and `getChoiceCase()` will - return `CHOICE_NOT_SET`. -- `Builder.clearChoice()`: Resets the value for `choice`, returning the - builder. - -For other simple field types, the corresponding Java type is chosen according to -the -[scalar value types table](/programming-guides/proto2#scalar). -For message and enum types, the value type is replaced with the message or enum -class. - -### Map Fields {#map-fields} - -For this map field definition: - -```proto -map weight = 1; -``` - -The compiler will generate the following accessor methods in both the message -class and its builder: - -- `Map getWeightMap();`: Returns an unmodifiable `Map`. -- `int getWeightOrDefault(int key, int default);`: Returns the value for key - or the default value if not present. -- `int getWeightOrThrow(int key);`: Returns the value for key or throws - IllegalArgumentException if not present. -- `boolean containsWeight(int key);`: Indicates if the key is present in this - field. -- `int getWeightCount();`: Returns the number of elements in the map. - -The compiler will generate the following methods only in the message's builder: - -- `Builder putWeight(int key, int value);`: Add the weight to this field. -- `Builder putAllWeight(Map value);`: Adds all entries in - the given map to this field. -- `Builder removeWeight(int key);`: Removes the weight from this field. -- `Builder clearWeight();`: Removes all weights from this field. -- `@Deprecated Map getMutableWeight();`: Returns a mutable - `Map`. Note that multiple calls to this method may return different map - instances. The returned map reference may be invalidated by any subsequent - method calls to the Builder. - -#### Message Value Map Fields {#message-value-map-fields} - -For maps with message types as values, the compiler will generate an additional -method in the message's builder: - -- `Foo.Builder putFooBuilderIfAbsent(int key);`: Ensures that `key` is present - in the mapping, and inserts a new `Foo.Builder` if one does not already - exist. Changes to the returned `Foo.Builder` will be reflected in the final - message. - -## Any {#any-fields} - -Given an [`Any`](/programming-guides/proto3#any) field -like this: - -```proto -import "google/protobuf/any.proto"; - -message ErrorStatus { - string message = 1; - google.protobuf.Any details = 2; -} -``` - -In our generated code, the getter for the `details` field returns an instance of -`com.google.protobuf.Any`. This provides the following special methods to pack -and unpack the `Any`'s values: - -```java -class Any { - // Packs the given message into an Any using the default type URL - // prefix “type.googleapis.com”. - public static Any pack(Message message); - // Packs the given message into an Any using the given type URL - // prefix. - public static Any pack(Message message, - String typeUrlPrefix); - - // Checks whether this Any message’s payload is the given type. - public boolean is(class clazz); - - // Checks whether this Any message’s payload has the same type as the given - // message. - public boolean isSameTypeAs(Message message); - - // Unpacks Any into a message with the same type as the given messsage. - // Throws exception if the type doesn’t match or parsing the payload fails. - public T unpackSameTypeAs(T message) - throws InvalidProtocolBufferException; - - // Unpacks Any into the given message type. Throws exception if - // the type doesn’t match or parsing the payload has failed. - public T unpack(class clazz) - throws InvalidProtocolBufferException; -} -``` - -## Enumerations {#enum} - -Given an enum definition like: - -```proto -enum Foo { - VALUE_A = 0; - VALUE_B = 5; - VALUE_C = 1234; -} -``` - -The protocol buffer compiler will generate a Java enum type called `Foo` with -the same set of values. If you are using proto3, it also adds the special value -`UNRECOGNIZED` to the enum type. In Editions, `OPEN` enums also have a -`UNRECOGNIZED` value, while `CLOSED` enums do not. The values of the generated -enum type have the following special methods: - -- `int getNumber()`: Returns the object's numeric value as defined in the - `.proto` file. -- `EnumValueDescriptor getValueDescriptor()`: Returns the value's descriptor, - which contains information about the value's name, number, and type. -- `EnumDescriptor getDescriptorForType()`: Returns the enum type's descriptor, - which contains e.g. information about each defined value. - -Additionally, the `Foo` enum type contains the following static methods: - -- `static Foo forNumber(int value)`: Returns the enum object corresponding to - the given numeric value. Returns null when there is no corresponding enum - object. -- `static Foo valueOf(int value)`: Returns the enum object corresponding to - the given numeric value. This method is deprecated in favor of - `forNumber(int value)` and will be removed in an upcoming release. -- `static Foo valueOf(EnumValueDescriptor descriptor)`: Returns the enum - object corresponding to the given value descriptor. May be faster than - `valueOf(int)`. In proto3 and `OPEN` enums, returns `UNRECOGNIZED` if passed - an unknown value descriptor. -- `EnumDescriptor getDescriptor()`: Returns the enum type's descriptor, which - contains e.g. information about each defined value. (This differs from - `getDescriptorForType()` only in that it is a static method.) - -An integer constant is also generated with the suffix \_VALUE for each enum -value. - -Note that the `.proto` language allows multiple enum symbols to have the same -numeric value. Symbols with the same numeric value are synonyms. For example: - -```proto -enum Foo { - BAR = 0; - BAZ = 0; -} -``` - -In this case, `BAZ` is a synonym for `BAR`. In Java, `BAZ` will be defined as a -static final field like so: - -```java -static final Foo BAZ = BAR; -``` - -Thus, `BAR` and `BAZ` compare equal, and `BAZ` should never appear in switch -statements. The compiler always chooses the first symbol defined with a given -numeric value to be the "canonical" version of that symbol; all subsequent -symbols with the same number are just aliases. - -An enum can be defined nested within a message type. The compiler generates the -Java enum definition nested within that message type's class. - -**Caution: when generating Java code, the maximum number of values in a protobuf -enum may be surprisingly low**—in the worst case, the maximum is slightly -over 1,700 values. This limit is due to per-method size limits for Java -bytecode, and it varies across Java implementations, different versions of the -protobuf suite, and any options set on the enum in the `.proto` file. - -## Extensions {#extension} - -Given a message with an extension range: - -```proto -edition = "2023"; - -message Foo { - extensions 100 to 199; -} -``` - -The protocol buffer compiler will make `Foo` extend -`GeneratedMessage.ExtendableMessage` instead of the usual `GeneratedMessage`. -Similarly, `Foo`'s builder will extend `GeneratedMessage.ExtendableBuilder`. You -should never refer to these base types by name (`GeneratedMessage` is considered -an implementation detail). However, these superclasses define a number of -additional methods that you can use to manipulate extensions. - -In particular `Foo` and `Foo.Builder` will inherit the methods `hasExtension()`, -`getExtension()`, and `getExtensionCount()`. Additionally, `Foo.Builder` will -inherit methods `setExtension()` and `clearExtension()`. Each of these methods -takes, as its first parameter, an extension identifier (described below), which -identifies an extension field. The remaining parameters and the return value are -exactly the same as those for the corresponding accessor methods that would be -generated for a normal (non-extension) field of the same type as the extension -identifier. - -Given an extension definition: - -```proto -edition = "2023"; - -import "foo.proto"; - -extend Foo { - int32 bar = 123; -} -``` - -The protocol buffer compiler generates an "extension identifier" called `bar`, -which you can use with `Foo`'s extension accessors to access this extension, -like so: - -```java -Foo foo = - Foo.newBuilder() - .setExtension(bar, 1) - .build(); -assert foo.hasExtension(bar); -assert foo.getExtension(bar) == 1; -``` - -(The exact implementation of extension identifiers is complicated and involves -magical use of generics—however, you don't need to worry about how -extension identifiers work to use them.) - -Note that `bar` would be declared as a static field of the wrapper class for the -`.proto` file, as described above; we have omitted the wrapper class name in the -example. - -Extensions can be declared inside the scope of another type to prefix their -generated symbol names. For example, a common pattern is to extend a message by -a field *inside* the declaration of the field's type: - -```proto -edition = "2023"; - -import "foo.proto"; - -message Baz { - extend Foo { - Baz foo_ext = 124; - } -} -``` - -In this case, an extension with identifier `foo_ext` and type `Baz` is declared -inside the declaration of `Baz`, and referring to `foo_ext` requires the -addition of a `Baz.` prefix: - -```java -Baz baz = createMyBaz(); -Foo foo = - Foo.newBuilder() - .setExtension(Baz.fooExt, baz) - .build(); -assert foo.hasExtension(Baz.fooExt); -assert foo.getExtension(Baz.fooExt) == baz; -``` - -When parsing a message that might have extensions, you must provide an -[`ExtensionRegistry`](/reference/java/api-docs/com/google/protobuf/ExtensionRegistry.html) -in which you have registered any extensions that you want to be able to parse. -Otherwise, those extensions will be treated like unknown fields and the methods -observing extensions will behave as if they don't exist. - -```java -ExtensionRegistry registry = ExtensionRegistry.newInstance(); -registry.add(Baz.fooExt); -Foo foo = Foo.parseFrom(input, registry); -assert foo.hasExtension(Baz.fooExt); -``` - -```java -ExtensionRegistry registry = ExtensionRegistry.newInstance(); -Foo foo = Foo.parseFrom(input, registry); -assert foo.hasExtension(Baz.fooExt) == false; -``` - -## Services {#service} - -If the `.proto` file contains the following line: - -```proto -option java_generic_services = true; -``` - -Then the protocol buffer compiler will generate code based on the service -definitions found in the file as described in this section. However, the -generated code may be undesirable as it is not tied to any particular RPC -system, and thus requires more levels of indirection than code tailored to one -system. If you do NOT want this code to be generated, add this line to the file: - -```proto -option java_generic_services = false; -``` - -If neither of the above lines are given, the option defaults to `false`, as -generic services are deprecated. (Note that prior to 2.4.0, the option defaults -to `true`) - -RPC systems based on `.proto`-language service definitions should provide -[plugins](/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb) -to generate code appropriate for the system. These plugins are likely to require -that abstract services are disabled, so that they can generate their own classes -of the same names. - -The remainder of this section describes what the protocol buffer compiler -generates when abstract services are enabled. - -### Interface {#interface} - -Given a service definition: - -```proto -service Foo { - rpc Bar(FooRequest) returns(FooResponse); -} -``` - -The protocol buffer compiler will generate an abstract class `Foo` to represent -this service. `Foo` will have an abstract method for each method defined in the -service definition. In this case, the method `Bar` is defined as: - -```java -abstract void bar(RpcController controller, FooRequest request, - RpcCallback done); -``` - -The parameters are equivalent to the parameters of `Service.CallMethod()`, -except that the `method` argument is implied and `request` and `done` specify -their exact type. - -`Foo` subclasses the `Service` interface. The protocol buffer compiler -automatically generates implementations of the methods of `Service` as follows: - -- `getDescriptorForType`: Returns the service's `ServiceDescriptor`. -- `callMethod`: Determines which method is being called based on the provided - method descriptor and calls it directly, down-casting the request message - and callback to the correct types. -- `getRequestPrototype` and `getResponsePrototype`: Returns the default - instance of the request or response of the correct type for the given - method. - -The following static method is also generated: - -- `static ServiceDescriptor getServiceDescriptor()`: Returns the type's - descriptor, which contains information about what methods this service has - and what their input and output types are. - -`Foo` will also contain a nested interface `Foo.Interface`. This is a pure -interface that again contains methods corresponding to each method in your -service definition. However, this interface does not extend the `Service` -interface. This is a problem because RPC server implementations are usually -written to use abstract `Service` objects, not your particular service. To solve -this problem, if you have an object `impl` implementing `Foo.Interface`, you can -call `Foo.newReflectiveService(impl)` to construct an instance of `Foo` that -simply delegates to `impl`, and implements `Service`. - -To recap, when implementing your own service, you have two options: - -- Subclass `Foo` and implement its methods as appropriate, then hand instances - of your subclass directly to the RPC server implementation. This is usually - easiest, but some consider it less "pure". -- Implement `Foo.Interface` and use `Foo.newReflectiveService(Foo.Interface)` - to construct a `Service` wrapping it, then pass the wrapper to your RPC - implementation. - -### Stub {#stub} - -The protocol buffer compiler also generates a "stub" implementation of every -service interface, which is used by clients wishing to send requests to servers -implementing the service. For the `Foo` service (above), the stub implementation -`Foo.Stub` will be defined as a nested class. - -`Foo.Stub` is a subclass of `Foo` which also implements the following methods: - -- `Foo.Stub(RpcChannel channel)`: Constructs a new stub which sends requests - on the given channel. -- `RpcChannel getChannel()`: Returns this stub's channel, as passed to the - constructor. - -The stub additionally implements each of the service's methods as a wrapper -around the channel. Calling one of the methods simply calls -`channel.callMethod()`. - -The Protocol Buffer library does not include an RPC implementation. However, it -includes all of the tools you need to hook up a generated service class to any -arbitrary RPC implementation of your choice. You need only provide -implementations of `RpcChannel` and `RpcController`. - -### Blocking Interfaces {#blocking} - -The RPC classes described above all have non-blocking semantics: when you call a -method, you provide a callback object which will be invoked once the method -completes. Often it is easier (though possibly less scalable) to write code -using blocking semantics, where the method simply doesn't return until it is -done. To accommodate this, the protocol buffer compiler also generates blocking -versions of your service class. `Foo.BlockingInterface` is equivalent to -`Foo.Interface` except that each method simply returns the result rather than -call a callback. So, for example, `bar` is defined as: - -```java -abstract FooResponse bar(RpcController controller, FooRequest request) - throws ServiceException; -``` - -Analogous to non-blocking services, -`Foo.newReflectiveBlockingService(Foo.BlockingInterface)` returns a -`BlockingService` wrapping some `Foo.BlockingInterface`. Finally, -`Foo.BlockingStub` returns a stub implementation of `Foo.BlockingInterface` that -sends requests to a particular `BlockingRpcChannel`. - -## Plugin Insertion Points {#plugins} - -[Code generator plugins](/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb) -that want to extend the output of the Java code generator may insert code of the -following types using the given insertion point names. - -- `outer_class_scope`: Member declarations that belong in the file's wrapper - class. -- `class_scope:TYPENAME`: Member declarations that belong in a message class. - `TYPENAME` is the full proto name, e.g. `package.MessageType`. -- `builder_scope:TYPENAME`: Member declarations that belong in a message's - builder class. `TYPENAME` is the full proto name, e.g. - `package.MessageType`. -- `enum_scope:TYPENAME`: Member declarations that belong in an enum class. - `TYPENAME` is the full proto enum name, e.g. `package.EnumType`. -- `message_implements:TYPENAME`: Class implementation declarations for a - message class. `TYPENAME` is the full proto name, e.g. - `package.MessageType`. -- `builder_implements:TYPENAME`: Class implementation declarations for a - builder class. `TYPENAME` is the full proto name, e.g. - `package.MessageType`. - -Generated code cannot contain import statements, as these are prone to conflict -with type names defined within the generated code itself. Instead, when -referring to an external class, you must always use its fully-qualified name. - -The logic for determining output file names in the Java code generator is fairly -complicated. You should probably look at the `protoc` source code, particularly -`java_headers.cc`, to make sure you have covered all cases. - -Do not generate code which relies on private class members declared by the -standard code generator, as these implementation details may change in future -versions of Protocol Buffers. - -## Utility Classes {#utility-classes} - -Protocol buffer provides -[utility classes](/reference/java/api-docs/com/google/protobuf/util/package-summary.html) -for message comparison, JSON conversion and working with -[well-known types (predefined protocol buffer messages for common use-cases).](/reference/protobuf/google.protobuf) diff --git a/content/reference/java/java-proto-names.md b/content/reference/java/java-proto-names.md deleted file mode 100644 index 938cd9524..000000000 --- a/content/reference/java/java-proto-names.md +++ /dev/null @@ -1,100 +0,0 @@ -+++ -title = "Java Proto Names" -weight = 655 -linkTitle = "Generated Proto Names" -description = "Names that are generated by the Java protoc plugin." -type = "docs" -+++ - -This document contains information on what the fully-qualified Java name of a -proto is, based on the different proto options. This name corresponds to the -package you need to import to use that message. - -## Recommendation { #recommendation } - -Starting with Edition 2024, best practice is to: - -* Set `option java_package = "com.example.package"` -* **Do not set** `java_outer_classname` or - `features.(pb.java).nest_in_file_class = YES`. - -Starting with Edition 2024, the default behaviors have otherwise been improved -so that now the default behavior is considered current best practice. - -When using Proto2, Proto3, or Edition 2023, best practice is to: - -* Set `option java_multiple_files = true;` -* Set `option java_outer_classname = "FileNameProto";` -* Set `option java_package = "com.google.package";` - -### Explanation {#explanation} - -#### Multiple Files {#multiple-files} - -With `java_multiple_files = true`, the generated Java class for each message -will be placed in a separate `.java` file. This makes it much easier to move -messages from one `.proto` file to another. - -Starting in Edition 2024 this has been replaced by the feature -`features.(pb.java).nest_in_file_class` which has default value of `NO`, -matching the `java_multiple_files = true` behavior in older syntax. - -#### Outer Classname {#outer-classname} - -There is a Java class generated for the `.proto` file itself. The name of the -class for the file will be automatically generated if not specified. However, -the rules for how that name is generated are overly-complicated and non-obvious. -The best policy is to explicitly set the `java_outer_classname` option to the -`.proto` file name converted to PascalCase with the `'.'` removed. For example: - -* The file `student_record_request.proto` should set: - - ```proto - option java_outer_classname = "StudentRecordRequestProto"; - ``` - -Starting in Edition 2024, `java_outer_classname` is still available, but the -default behavior has been changed to match this recommendation and so does not -need to be set. - -#### Java Package {#java-package} - -The Java package for generated bindings will be automatically set to the proto -package. However, this is usually not conformant with Java conventions. To -ensure a conventional Java package name, we recommend explicitly setting the -`java_package` option. For example, within Google, the convention is to prepend -`com.google.` to the proto package. - -## Immutable API Message Names { #immutable-api-message-names } - -The Java plugin for protoc will generate names according to this table. - -java_multiple_files | java_package | java_outer_classname | Generated full message name -:-----------------: | ------------ | -------------------- | --------------------------- -true | Not defined | *ignored* | `com.google.protos.$package.$message` -true | Defined | *ignored* | `$java_package.$message` -false | Not defined | Not defined | `com.google.protos.$package.$derived_outer_class.$message` -false | Not defined | Defined | `com.google.protos.$package.$java_outer_classname.$message` -false | Defined | Not defined | `$java_package.$derived_outer_class.$message` -false | Defined | Defined | `$java_package.$java_outer_classname.$message` - -**Legend** - -* `$message` is the actual name of the proto message. -* `$package` is the name of the proto package. This is the name specified by - the `package` directive in the proto file, which is usually at the top of - the file. -* `$derived_outer_class` is a name generated from the proto file name. - Generally it's computed by removing punctuation from the file name and - converting it to PascalCase. For example, if the proto is `foo_bar.proto`, - the `$derived_outer_class` value is `FooBar`. - - If the generated class name would be the same as one of the messages defined - in the proto file, `derived_outer_class` has `OuterClass` appended to it. - For example, if the proto is `foo_bar.proto` and contains a `FooBar` - message, the `$derived_outer_class` value is `FooBarOuterClass`. The same is - true when using the v1 API, whether or not the class name would be the same - as one of the messages defined. - -* All other `$names` are the values of the corresponding file options defined - in the `.proto` file. diff --git a/content/reference/kotlin/_index.md b/content/reference/kotlin/_index.md deleted file mode 100644 index 82de16ff8..000000000 --- a/content/reference/kotlin/_index.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "Kotlin Reference" -weight = 670 -linkTitle = "Kotlin" -description = "Reference documentation for working with protocol buffer classes in Kotlin." -type = "docs" -+++ diff --git a/content/reference/kotlin/api-docs/_index.md b/content/reference/kotlin/api-docs/_index.md deleted file mode 100644 index a773cb705..000000000 --- a/content/reference/kotlin/api-docs/_index.md +++ /dev/null @@ -1,13 +0,0 @@ -+++ -title = "Kotlin Reference" -weight = 670 -linkTitle = "Kotlin" -description = "This section contains reference documentation for working with protocol buffers in Kotlin." -type = "docs" -+++ - -## Packages - -Name | ----- | -[com.google.protobuf.kotlin](protobuf-kotlin/com.google.protobuf.kotlin/) | diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/-dsl-list.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/-dsl-list.md deleted file mode 100644 index 868d33bab..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/-dsl-list.md +++ /dev/null @@ -1,8 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[DslList]()/DslList - -# DslList - -[JVM] \ -Content \ -fun <[E]()> [DslList]()(delegate: -[List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E]()>) diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/_index.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/_index.md deleted file mode 100644 index b5245e02c..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/_index.md +++ /dev/null @@ -1,51 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/DslList - -# DslList - -[JVM] class [DslList]()<[E](), [P]() : -[DslProxy](../-dsl-proxy)>constructor(**delegate**: -[List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E]()>) : -[List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E]()> - -A simple wrapper around a -[List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html) -with an extra generic parameter that can be used to disambiguate extension -methods. - -

This class is used by Kotlin protocol buffer extensions, and its constructor -is public only because generated message code is in a different compilation -unit. Others should not use this class directly in any way. - -## Constructors - -Name | Summary ---- | --- -[DslList]() | [JVM] fun <[E]()> [DslList]()(delegate: [List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E]()>) - -## Functions - -Name | Summary ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- -[contains](../-extension-list/#765883978%2FFunctions%2F-246181541) | [JVM]
Content
open operator override fun [contains](../-extension-list/#765883978%2FFunctions%2F-246181541)(element: [E]()): [Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)


-[containsAll](../-extension-list/#-225903147%2FFunctions%2F-246181541) | [JVM]
Content
open override fun [containsAll](../-extension-list/#-225903147%2FFunctions%2F-246181541)(elements: [Collection](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-collection/index.html)<[E]()>): [Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)


-[equals](equals) | [JVM]
Content
open operator override fun [equals](equals)(other: [Any](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/index.html)?): [Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)


-[forEach](../-extension-list/#1532301601%2FFunctions%2F-246181541) | [JVM]
Content
open fun [forEach](../-extension-list/#1532301601%2FFunctions%2F-246181541)(p0: [Consumer](https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html))


-[get](../-extension-list/#961975567%2FFunctions%2F-246181541) | [JVM]
Content
open operator override fun [get](../-extension-list/#961975567%2FFunctions%2F-246181541)(index: [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)): [E]()


-[hashCode](hash-code) | [JVM]
Content
open override fun [hashCode](hash-code)(): [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)


-[indexOf](../-extension-list/#-407930336%2FFunctions%2F-246181541) | [JVM]
Content
open override fun [indexOf](../-extension-list/#-407930336%2FFunctions%2F-246181541)(element: [E]()): [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)


-[isEmpty](../-extension-list/#-1000881820%2FFunctions%2F-246181541) | [JVM]
Content
open override fun [isEmpty](../-extension-list/#-1000881820%2FFunctions%2F-246181541)(): [Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)


-[iterator](iterator) | [JVM]
Content
open operator override fun [iterator](iterator)(): [Iterator](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-iterator/index.html)<[E]()>


-[lastIndexOf](../-extension-list/#1327716778%2FFunctions%2F-246181541) | [JVM]
Content
open override fun [lastIndexOf](../-extension-list/#1327716778%2FFunctions%2F-246181541)(element: [E]()): [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)


-[listIterator](list-iterator) | [JVM]
Content
open override fun [listIterator](list-iterator)(): [ListIterator](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list-iterator/index.html)<[E]()>
open override fun [listIterator](list-iterator)(index: [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)): [ListIterator](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list-iterator/index.html)<[E]()>


-[parallelStream](../-extension-list/#-1592339412%2FFunctions%2F-246181541) | [JVM]
Content
open fun [parallelStream](../-extension-list/#-1592339412%2FFunctions%2F-246181541)(): [Stream](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html)<[E]()>


-[spliterator](../-extension-list/#703021258%2FFunctions%2F-246181541) | [JVM]
Content
open override fun [spliterator](../-extension-list/#703021258%2FFunctions%2F-246181541)(): [Spliterator](https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html)<[E]()>


-[stream](../-extension-list/#135225651%2FFunctions%2F-246181541) | [JVM]
Content
open fun [stream](../-extension-list/#135225651%2FFunctions%2F-246181541)(): [Stream](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html)<[E]()>


-[subList](../-extension-list/#423386006%2FFunctions%2F-246181541) | [JVM]
Content
open override fun [subList](../-extension-list/#423386006%2FFunctions%2F-246181541)(fromIndex: [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html), toIndex: [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)): [List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E]()>


-[toArray](../-extension-list/#-1215154575%2FFunctions%2F-246181541) | [JVM]
Content
~~open~~ ~~fun~~ ~~<~~[T](../-extension-list/#-1215154575%2FFunctions%2F-246181541) : [Any](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/index.html)~~>~~ [~~toArray~~](../-extension-list/#-1215154575%2FFunctions%2F-246181541)~~(~~~~p0~~~~:~~ [IntFunction](https://docs.oracle.com/javase/8/docs/api/java/util/function/IntFunction.html)<[Array](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/index.html)<[T](../-extension-list/#-1215154575%2FFunctions%2F-246181541)>>~~)~~~~:~~ [Array](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/index.html)<[T](../-extension-list/#-1215154575%2FFunctions%2F-246181541)>


-[toString](to-string) | [JVM]
Content
open override fun [toString](to-string)(): [String](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html)


- -## Properties - -Name | Summary ------------------------------------------------------------------------------------------------------------------------------------- | ------- -[size](#1874448885%2FProperties%2F-246181541) | [JVM] open override val [size](#1874448885%2FProperties%2F-246181541): [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)
diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/equals.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/equals.md deleted file mode 100644 index 504c09b0a..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/equals.md +++ /dev/null @@ -1,9 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[DslList]()/equals - -# equals - -[JVM] \ -Content \ -open operator override fun [`equals`]()(other: -[`Any`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/index.html)?): -[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html) diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/hash-code.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/hash-code.md deleted file mode 100644 index 57dccb396..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/hash-code.md +++ /dev/null @@ -1,8 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[DslList]()/hashCode - -# hashCode - -[JVM] \ -Content \ -open override fun [hashCode]()(): -[Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html) diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/iterator.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/iterator.md deleted file mode 100644 index 54ac64f90..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/iterator.md +++ /dev/null @@ -1,8 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[DslList]()/iterator - -# iterator - -[JVM] \ -Content \ -open operator override fun [iterator]()(): -[Iterator](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-iterator/index.html)<[E]()> diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/list-iterator.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/list-iterator.md deleted file mode 100644 index f820e3664..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/list-iterator.md +++ /dev/null @@ -1,12 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[DslList]()/listIterator - -# listIterator - -[JVM] \ -Content \ -open override fun [listIterator]()(): -[ListIterator](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list-iterator/index.html)<[E]()> -\ -open override fun [listIterator]()(index: -[Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)): -[ListIterator](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list-iterator/index.html)<[E]()> diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/to-string.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/to-string.md deleted file mode 100644 index 0bd1be208..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/to-string.md +++ /dev/null @@ -1,8 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[DslList]()/toString - -# toString - -[JVM] \ -Content \ -open override fun [toString]()(): -[String](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html) diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/-dsl-map.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/-dsl-map.md deleted file mode 100644 index 908e39e5b..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/-dsl-map.md +++ /dev/null @@ -1,9 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[DslMap]()/DslMap - -# DslMap - -[JVM] \ -Content \ -fun <[K](), [V]()> [DslMap]()(delegate: -[Map](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/index.html)<[K](), -[V]()>) diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/_index.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/_index.md deleted file mode 100644 index 30b83d8ba..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/_index.md +++ /dev/null @@ -1,48 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/DslMap - -# DslMap - -[JVM] class [DslMap]()<[K](), [V](), [P]() : -[DslProxy](../-dsl-proxy/)>constructor(**delegate**: -[Map](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/index.html)<[K](), -[V]()>) : -[Map](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/index.html)<[K](), -[V]()> - -A simple wrapper around a -[Map](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/index.html) -with an extra generic parameter that can be used to disambiguate extension -methods. - -

This class is used by Kotlin protocol buffer extensions, and its constructor -is public only because generated message code is in a different compilation -unit. Others should not use this class directly in any way. - -## Constructors - -Name | Summary ---- | --- -[DslMap]) | [JVM] fun <[K](), [V]()> [DslMap]()(delegate: [Map](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/index.html)<[K](), [V]()>) - -## Functions - -Name | Summary ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- -[containsKey](#189495335%2FFunctions%2F-246181541) | [JVM]
Content
open override fun [containsKey](#189495335%2FFunctions%2F-246181541)(key: [K]()): [Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)


-[containsValue](#-337993863%2FFunctions%2F-246181541) | [JVM]
Content
open override fun [containsValue](#-337993863%2FFunctions%2F-246181541)(value: [V]()): [Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)


-[equals](equals) | [JVM]
Content
open operator override fun [equals](equals)(other: [Any](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/index.html)?): [Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)


-[forEach](#1890068580%2FFunctions%2F-246181541) | [JVM]
Content
open fun [forEach](#1890068580%2FFunctions%2F-246181541)(p0: [BiConsumer](https://docs.oracle.com/javase/8/docs/api/java/util/function/BiConsumer.html))


-[get](#1589144509%2FFunctions%2F-246181541) | [JVM]
Content
open operator override fun [get](#1589144509%2FFunctions%2F-246181541)(key: [K]()): [V]()?


-[getOrDefault](#1493482850%2FFunctions%2F-246181541) | [JVM]
Content
open fun [getOrDefault](#1493482850%2FFunctions%2F-246181541)(key: [K](), defaultValue: [V]()): [V]()


-[hashCode](hash-code) | [JVM]
Content
open override fun [hashCode](hash-code)(): [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)


-[isEmpty](#-1708477740%2FFunctions%2F-246181541) | [JVM]
Content
open override fun [isEmpty](#-1708477740%2FFunctions%2F-246181541)(): [Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)


-[toString](to-string) | [JVM]
Content
open override fun [toString](to-string)(): [String](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html)


- -## Properties - -Name | Summary ------------------------------------------------------------------------------------------------------------------------------------- | ------- -[entries](entries) | [JVM] open override val [entries](entries): [Set](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-set/index.html)<[Map.Entry](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/-entry/index.html)<[K](), [V]()>>
-[keys](keys) | [JVM] open override val [keys](keys): [Set](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-set/index.html)<[K]()>
-[size](#-2063973537%2FProperties%2F-246181541) | [JVM] open override val [size](#-2063973537%2FProperties%2F-246181541): [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)
-[values](values) | [JVM] open override val [values](values): [Collection](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-collection/index.html)<[V]()>
diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/entries.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/entries.md deleted file mode 100644 index 9555268b0..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/entries.md +++ /dev/null @@ -1,9 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[DslMap]()/entries - -# entries - -[JVM] \ -Content \ -open override val [entries](): -[Set](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-set/index.html)<[Map.Entry](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/-entry/index.html)<[K](), -[V]()>> diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/equals.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/equals.md deleted file mode 100644 index 8023cb680..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/equals.md +++ /dev/null @@ -1,9 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[DslMap]()/equals - -# equals - -[JVM] \ -Content \ -open operator override fun [equals]()(other: -[Any](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/index.html)?): -[Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html) diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/hash-code.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/hash-code.md deleted file mode 100644 index b7dd94084..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/hash-code.md +++ /dev/null @@ -1,8 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[DslMap]()/hashCode - -# hashCode - -[JVM] \ -Content \ -open override fun [hashCode]()(): -[Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html) diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/keys.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/keys.md deleted file mode 100644 index be30a76fc..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/keys.md +++ /dev/null @@ -1,8 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[DslMap]()/keys - -# keys - -[JVM] \ -Content \ -open override val [keys](): -[Set](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-set/index.html)<[K]()> diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/to-string.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/to-string.md deleted file mode 100644 index 4be12f8c8..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/to-string.md +++ /dev/null @@ -1,8 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[DslMap]()/toString - -# toString - -[JVM] \ -Content \ -open override fun [toString]()(): -[String](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html) diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/values.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/values.md deleted file mode 100644 index 3d5a4f842..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/values.md +++ /dev/null @@ -1,8 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[DslMap]()/values - -# values - -[JVM] \ -Content \ -open override val [values](): -[Collection](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-collection/index.html)<[V]()> diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-proxy/_index.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-proxy/_index.md deleted file mode 100644 index 0ca1b647c..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-proxy/_index.md +++ /dev/null @@ -1,9 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/DslProxy - -# DslProxy - -[JVM] abstract class [DslProxy]() - -A type meaningful only for its existence, never intended to be instantiated. For -example, a DslList can be given different extension methods than -a DslList. diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/-extension-list.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/-extension-list.md deleted file mode 100644 index 32bdf0841..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/-extension-list.md +++ /dev/null @@ -1,13 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[ExtensionList]()/ExtensionList - -# ExtensionList - -[JVM] \ -Content \ -fun <[E](), [M]() : -[MessageLite](/reference/java/api-docs/com/google/protobuf/MessageLite.html)> -[ExtensionList]()(extension: -[ExtensionLite](/reference/java/api-docs/com/google/protobuf/ExtensionLite.html)<[M](), -[List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E]()>>, -delegate: -[List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E]()>) diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/_index.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/_index.md deleted file mode 100644 index 46b9e2344..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/_index.md +++ /dev/null @@ -1,52 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/ExtensionList - -# ExtensionList - -[JVM] class [ExtensionList]()<[E](), [M]() : -[MessageLite](/reference/java/api-docs/com/google/protobuf/MessageLite.html)>constructor(**extension**: -[ExtensionLite](/reference/java/api-docs/com/google/protobuf/ExtensionLite.html)<[M](), -[List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E]()>>, -**delegate**: -[List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E]()>) : -[List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E]()> - -Implementation for ExtensionList and ExtensionListLite. Like -[DslList](../-dsl-list/), represents an unmodifiable view of a repeated proto -field -- in this case, an extension field -- but supports querying the -extension. - -## Constructors - -Name | Summary ---- | --- -[ExtensionList]() | [JVM] fun <[E](), [M]() : [MessageLite](/reference/java/api-docs/com/google/protobuf/MessageLite.html)> [ExtensionList]()(extension: [ExtensionLite](/reference/java/api-docs/com/google/protobuf/ExtensionLite.html)<[M](), [List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E]()\>\>, delegate: [List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E]()>) - - -## Functions - -Name | Summary ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- -[contains](#765883978%2FFunctions%2F-246181541) | [JVM]
Content
open operator override fun [contains](#765883978%2FFunctions%2F-246181541)(element: [E]()): [Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)


-[containsAll](#-225903147%2FFunctions%2F-246181541) | [JVM]
Content
open override fun [containsAll](#-225903147%2FFunctions%2F-246181541)(elements: [Collection](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-collection/index.html)<[E]()>): [Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)


-[equals](equals) | [JVM]
Content
open operator override fun [equals](equals)(other: [Any](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/index.html)?): [Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)


-[forEach](#1532301601%2FFunctions%2F-246181541) | [JVM]
Content
open fun [forEach](#1532301601%2FFunctions%2F-246181541)(p0: [Consumer](https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html))


-[get](#961975567%2FFunctions%2F-246181541) | [JVM]
Content
open operator override fun [get](#961975567%2FFunctions%2F-246181541)(index: [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)): [E]()


-[hashCode](hash-code) | [JVM]
Content
open override fun [hashCode](hash-code)(): [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)


-[indexOf](#-407930336%2FFunctions%2F-246181541) | [JVM]
Content
open override fun [indexOf](#-407930336%2FFunctions%2F-246181541)(element: [E]()): [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)


-[isEmpty](#-1000881820%2FFunctions%2F-246181541) | [JVM]
Content
open override fun [isEmpty](#-1000881820%2FFunctions%2F-246181541)(): [Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)


-[iterator](iterator) | [JVM]
Content
open operator override fun [iterator](iterator)(): [Iterator](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-iterator/index.html)<[E]()>


-[lastIndexOf](#1327716778%2FFunctions%2F-246181541) | [JVM]
Content
open override fun [lastIndexOf](#1327716778%2FFunctions%2F-246181541)(element: [E]()): [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)


-[listIterator](list-iterator) | [JVM]
Content
open override fun [listIterator](list-iterator)(): [ListIterator](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list-iterator/index.html)<[E]()>
open override fun [listIterator](list-iterator)(index: [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)): [ListIterator](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list-iterator/index.html)<[E]()>


-[parallelStream](#-1592339412%2FFunctions%2F-246181541) | [JVM]
Content
open fun [parallelStream](#-1592339412%2FFunctions%2F-246181541)(): [Stream](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html)<[E]()>


-[spliterator](#703021258%2FFunctions%2F-246181541) | [JVM]
Content
open override fun [spliterator](#703021258%2FFunctions%2F-246181541)(): [Spliterator](https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html)<[E]()>


-[stream](#135225651%2FFunctions%2F-246181541) | [JVM]
Content
open fun [stream](#135225651%2FFunctions%2F-246181541)(): [Stream](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html)<[E]()>


-[subList](#423386006%2FFunctions%2F-246181541) | [JVM]
Content
open override fun [subList](#423386006%2FFunctions%2F-246181541)(fromIndex: [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html), toIndex: [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)): [List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E]()>


-[toArray](#-1215154575%2FFunctions%2F-246181541) | [JVM]
Content
~~open~~ ~~fun~~ ~~<~~[T](#-1215154575%2FFunctions%2F-246181541) : [Any](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/index.html)~~>~~ [~~toArray~~](#-1215154575%2FFunctions%2F-246181541)~~(~~~~p0~~~~:~~ [IntFunction](https://docs.oracle.com/javase/8/docs/api/java/util/function/IntFunction.html)<[Array](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/index.html)<[T](#-1215154575%2FFunctions%2F-246181541)>>~~)~~~~:~~ [Array](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/index.html)<[T](#-1215154575%2FFunctions%2F-246181541)>


-[toString](to-string) | [JVM]
Content
open override fun [toString](to-string)(): [String](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html)


- -## Properties - -Name | Summary ---------------------------------------------------------------------------------------------------------------------------------- | ------- -[extension](extension) | [JVM] val [extension](extension): [ExtensionLite](/reference/java/api-docs/com/google/protobuf/ExtensionLite.html)<[M](), [List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E]()>>
-[size](#648753719%2FProperties%2F-246181541) | [JVM] open override val [size](#648753719%2FProperties%2F-246181541): [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)
diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/equals.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/equals.md deleted file mode 100644 index ed11b9460..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/equals.md +++ /dev/null @@ -1,9 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[ExtensionList]()/equals - -# equals - -[JVM] \ -Content \ -open operator override fun [equals]()(other: -[Any](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/index.html)?): -[Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html) diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/extension.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/extension.md deleted file mode 100644 index 40e43e1c7..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/extension.md +++ /dev/null @@ -1,9 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[ExtensionList]()/extension - -# extension - -[JVM] \ -Content \ -val [extension](): -[ExtensionLite](/reference/java/api-docs/com/google/protobuf/ExtensionLite.html)<[M](), -[List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E]()>> diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/hash-code.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/hash-code.md deleted file mode 100644 index 5e5e04189..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/hash-code.md +++ /dev/null @@ -1,8 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[ExtensionList]()/hashCode - -# hashCode - -[JVM] \ -Content \ -open override fun [hashCode]()(): -[Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html) diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/iterator.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/iterator.md deleted file mode 100644 index 1619ef9a5..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/iterator.md +++ /dev/null @@ -1,8 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[ExtensionList]()/iterator - -# iterator - -[JVM] \ -Content \ -open operator override fun iterator(): -[Iterator](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-iterator/index.html)<[E]()> diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/list-iterator.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/list-iterator.md deleted file mode 100644 index 2b19a33af..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/list-iterator.md +++ /dev/null @@ -1,12 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[ExtensionList]()/listIterator - -# listIterator - -[JVM] \ -Content \ -open override fun [listIterator]()(): -[ListIterator](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list-iterator/index.html)<[E]()> -\ -open override fun [listIterator]()(index: -[Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)): -[ListIterator](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list-iterator/index.html)<[E]()> diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/to-string.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/to-string.md deleted file mode 100644 index b85c4e618..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/to-string.md +++ /dev/null @@ -1,8 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[ExtensionList]()/toString - -# toString - -[JVM] \ -Content \ -open override fun [toString]()(): -[String](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html) diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/-only-for-use-by-generated-proto-code.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/-only-for-use-by-generated-proto-code.md deleted file mode 100644 index 297dba225..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/-only-for-use-by-generated-proto-code.md +++ /dev/null @@ -1,7 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[OnlyForUseByGeneratedProtoCode]()/OnlyForUseByGeneratedProtoCode - -# OnlyForUseByGeneratedProtoCode - -[JVM] \ -Content \ -fun [OnlyForUseByGeneratedProtoCode]()() diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/_index.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/_index.md deleted file mode 100644 index 4ffd55c12..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/_index.md +++ /dev/null @@ -1,21 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/OnlyForUseByGeneratedProtoCode - -# OnlyForUseByGeneratedProtoCode - -[JVM] -@[Target](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.annotation/-target/index.html)(allowedTargets = -[[AnnotationTarget.CONSTRUCTOR](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.annotation/-annotation-target/-c-o-n-s-t-r-u-c-t-o-r.html#kotlin.annotation.AnnotationTarget.CONSTRUCTOR), -[AnnotationTarget.ANNOTATION_CLASS](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.annotation/-annotation-target/-c-l-a-s-s.html#kotlin.annotation.AnnotationTarget.CLASS)]) - -annotation class [OnlyForUseByGeneratedProtoCode]() - -Opt-in annotation to make it difficult to accidentally use APIs only intended -for use by proto generated code. See -https://kotlinlang.org/docs/reference/opt-in-requirements.html for details on -how this API works. - -## Constructors - -Name | Summary ---- | --- -[OnlyForUseByGeneratedProtoCode]() | [JVM] fun [OnlyForUseByGeneratedProtoCode]()()
diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/-proto-dsl-marker.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/-proto-dsl-marker.md deleted file mode 100644 index deb76062b..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/-proto-dsl-marker.md +++ /dev/null @@ -1,7 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[ProtoDslMarker]()/[ProtoDslMarker]() - -# ProtoDslMarker - -[JVM] \ -Content \ -fun [ProtoDslMarker]()() diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/_index.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/_index.md deleted file mode 100644 index 6b1708523..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/_index.md +++ /dev/null @@ -1,19 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[ProtoDslMarker]() - -# ProtoDslMarker - -[JVM] -@[DslMarker](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-dsl-marker/index.html)() -\ -@[Target](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.annotation/-target/index.html)(allowedTargets = -[[AnnotationTarget.CLASS](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.annotation/-annotation-target/-c-l-a-s-s/index.html)]) - -annotation class [ProtoDslMarker]() - -Indicates an API that is part of a DSL to generate protocol buffer messages. - -## Constructors - -Name | Summary ---- | --- -[ProtoDslMarker]() | [JVM] fun [ProtoDslMarker]()() diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/_index.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/_index.md deleted file mode 100644 index cf93d1b6b..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/_index.md +++ /dev/null @@ -1,27 +0,0 @@ -# Package com.google.protobuf.kotlin - -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/) - -## Types - -Name | Summary ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- -[DslList](-dsl-list/) | [JVM]
Content
class [DslList](-dsl-list/)<[E](-dsl-list/), [P](-dsl-list/) : [DslProxy](-dsl-proxy/)>constructor(**delegate**: [List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E](-dsl-list/)>) : [List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E](-dsl-list/)>
A simple wrapper around a [List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html) with an extra generic parameter that can be used to disambiguate extension methods.


-[DslMap](-dsl-map/) | [JVM]
Content
class [DslMap](-dsl-map/)<[K](-dsl-map/), [V](-dsl-map/), [P](-dsl-map/) : [DslProxy](-dsl-proxy/)>constructor(**delegate**: [Map](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/index.html)<[K](-dsl-map/), [V](-dsl-map/)>) : [Map](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/index.html)<[K](-dsl-map/), [V](-dsl-map/)>
A simple wrapper around a [Map](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/index.html) with an extra generic parameter that can be used to disambiguate extension methods.


-[DslProxy](-dsl-proxy/) | [JVM]
Content
abstract class [DslProxy](-dsl-proxy/)
A type meaningful only for its existence, never intended to be instantiated.


-[ExtensionList](-extension-list/) | [JVM]
Content
class [ExtensionList](-extension-list/)<[E](-extension-list/), [M](-extension-list/) : [MessageLite](/reference/java/api-docs/com/google/protobuf/MessageLite.html)>constructor(**extension**: [ExtensionLite](/reference/java/api-docs/com/google/protobuf/ExtensionLite.html)<[M](-extension-list/), [List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E](-extension-list/)>>, **delegate**: [List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E](-extension-list/)>) : [List](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)<[E](-extension-list/)>
Implementation for ExtensionList and ExtensionListLite.


-[OnlyForUseByGeneratedProtoCode](-only-for-use-by-generated-proto-code/) | [JVM]
Content
@[Target](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.annotation/-target/index.html)(allowedTargets = [[AnnotationTarget.CONSTRUCTOR](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.annotation/-annotation-target/-c-o-n-s-t-r-u-c-t-o-r.html#kotlin.annotation.AnnotationTarget.CONSTRUCTOR), [AnnotationTarget.ANNOTATION_CLASS](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.annotation/-annotation-target/-c-l-a-s-s.html#kotlin.annotation.AnnotationTarget.CLASS)])

annotation class [OnlyForUseByGeneratedProtoCode](-only-for-use-by-generated-proto-code/)
Opt-in annotation to make it difficult to accidentally use APIs only intended for use by proto generated code.


-[ProtoDslMarker](-proto-dsl-marker/) | [JVM]
Content
@[DslMarker](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-dsl-marker/index.html)()
@[Target](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.annotation/-target/index.html)(allowedTargets = [[AnnotationTarget.CLASS](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.annotation/-annotation-target/-c-l-a-s-s/index.html)])

annotation class [ProtoDslMarker](-proto-dsl-marker/)
Indicates an API that is part of a DSL to generate protocol buffer messages.


- -## Functions - -Name | Summary ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- -[contains](contains) | [JVM]
Content
operator fun <[M](contains) : [GeneratedMessageV3.ExtendableMessage](https://github.com/protocolbuffers/protobuf/blob/master/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java)<[M](contains)>, [MorBT](contains) : [GeneratedMessageV3.ExtendableMessageOrBuilder](https://github.com/protocolbuffers/protobuf/blob/master/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java)<[M](contains)>> [MorBT](contains).[contains](contains)(extension: [ExtensionLite](/reference/java/api-docs/com/google/protobuf/ExtensionLite.html)<[M](contains), *>): [Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)
Returns true if the specified extension is set on this builder.


-[get](get) | [JVM]
Content
operator fun <[M](get) : [GeneratedMessageV3.ExtendableMessage](https://github.com/protocolbuffers/protobuf/blob/master/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java)<[M](get)>, [MorBT](get) : [GeneratedMessageV3.ExtendableMessageOrBuilder](https://github.com/protocolbuffers/protobuf/blob/master/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java)<[M](get)>, [T](get) : [Any](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/index.html)> [MorBT](get).[get](get)(extension: [ExtensionLite](/reference/java/api-docs/com/google/protobuf/ExtensionLite.html)<[M](get), [T](get)>): [T](get)
Gets the current value of the proto extension.


[JVM]
Content
operator fun [ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html).[get](get)(index: [Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)): [Byte](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-byte/index.html)
Gets the byte at [index](get).


-[isA](is-a) | [JVM]
Content
inline fun <[T](is-a) : [Message](/reference/java/api-docs/com/google/protobuf/Message.html)> [Any](/reference/java/api-docs/com/google/protobuf/Any.html).[isA](is-a)(): [Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)
Returns true if this [com.google.protobuf.Any](/reference/java/api-docs/com/google/protobuf/Any.html) contains a message of type T.


-[plus](plus) | [JVM]
Content
operator fun [ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html).[plus](plus)(other: [ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html)): [ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html)
Concatenates the given [ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html) to this one.


-[set](set) | [JVM]
Content
operator fun <[M](set) : [GeneratedMessageV3.ExtendableMessage](https://github.com/protocolbuffers/protobuf/blob/master/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java)<[M](set)>, [B](set) : [GeneratedMessageV3.ExtendableBuilder](/reference/java/api-docs/com/google/protobuf/GeneratedMessageV3.ExtendableBuilder.html)<[M](set), [B](set)>, [T](set) : [Any](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/index.html)> [B](set).[set](set)(extension: [ExtensionLite](/reference/java/api-docs/com/google/protobuf/ExtensionLite.html)<[M](set), [T](set)>, value: [T](set))
Sets the current value of the proto extension in this builder.


-[toByteString](to-byte-string) | [JVM]
Content
fun [ByteBuffer](https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html).[toByteString](to-byte-string)(): [ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html)
Copies the remaining bytes from this [ByteBuffer](https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html) to a [ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html).


[JVM]
Content
fun [ByteArray](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-byte-array/index.html).[toByteString](to-byte-string)(): [ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html)
Returns a copy of this [ByteArray](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-byte-array/index.html) as an immutable [ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html).


-[toByteStringUtf8](to-byte-string-utf8) | [JVM]
Content
fun [String](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html).[toByteStringUtf8](to-byte-string-utf8)(): [ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html)
Encodes this String into a sequence of UTF-8 bytes and returns the result as a [ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html).


-[unpack](unpack) | [JVM]
Content
inline fun <[T](unpack) : [Message](/reference/java/api-docs/com/google/protobuf/Message.html)> [Any](/reference/java/api-docs/com/google/protobuf/Any.html).[unpack](unpack)(): [T](unpack)
Returns the message of type T encoded in this [com.google.protobuf.Any](/reference/java/api-docs/com/google/protobuf/Any.html).


diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/contains.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/contains.md deleted file mode 100644 index a51cf5ef9..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/contains.md +++ /dev/null @@ -1,16 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/contains - -# contains - -[JVM] \ -Content \ -operator fun <[M]() : -[GeneratedMessageV3.ExtendableMessage](https://github.com/protocolbuffers/protobuf/blob/master/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java)<[M]()>, -[MorBT]() : -[GeneratedMessageV3.ExtendableMessageOrBuilder](https://github.com/protocolbuffers/protobuf/blob/master/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java)<[M]()>> -[MorBT]().[contains]()(extension: -[ExtensionLite](/reference/java/api-docs/com/google/protobuf/ExtensionLite.html)<[M](), -*>): -[Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html) - -Returns true if the specified extension is set on this builder. diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/get.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/get.md deleted file mode 100644 index 4152d4e8a..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/get.md +++ /dev/null @@ -1,26 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[get]() - -# get - -[JVM] \ -Content \ -operator fun -[ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html).[get]()(index: -[Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html)): -[Byte](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-byte/index.html) - -Gets the byte at [index](). - -[JVM] \ -Content \ -operator fun <[M]() : -[GeneratedMessageV3.ExtendableMessage](https://github.com/protocolbuffers/protobuf/blob/master/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java)<[M]()>, -[MorBT]() : -[GeneratedMessageV3.ExtendableMessageOrBuilder](https://github.com/protocolbuffers/protobuf/blob/master/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java)<[M]()>, -[T]() : -[Any](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/index.html)> -[MorBT]().[get]()(extension: -[ExtensionLite](/reference/java/api-docs/com/google/protobuf/ExtensionLite.html)<[M](), -[T]()>): [T]() - -Gets the current value of the proto extension. diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/is-a.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/is-a.md deleted file mode 100644 index c9e512cae..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/is-a.md +++ /dev/null @@ -1,15 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/[isA]() - -# isA - -[JVM] \ -Content \ -inline fun <[T]() : -[Message](/reference/java/api-docs/com/google/protobuf/Message.html)> -[Any](/reference/java/api-docs/com/google/protobuf/Any.html).[isA]()(): -[Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html) - - -Returns true if this -[com.google.protobuf.Any](/reference/java/api-docs/com/google/protobuf/Any.html) -contains a message of type T. diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/plus.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/plus.md deleted file mode 100644 index f9346a40a..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/plus.md +++ /dev/null @@ -1,16 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/plus - -# plus - -[JVM] \ -Content \ -operator fun -[ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html).plus(other: -[ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html)): -[ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html) -\ - - -Concatenates the given -[ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html) -to this one. diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/set.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/set.md deleted file mode 100644 index 7d702fe7d..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/set.md +++ /dev/null @@ -1,17 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/set - -# set - -[JVM] \ -Content \ -operator fun <[M]() : -[GeneratedMessageV3.ExtendableMessage](https://github.com/protocolbuffers/protobuf/blob/master/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java)<[M]()>, -[B]() : -[GeneratedMessageV3.ExtendableBuilder](/reference/java/api-docs/com/google/protobuf/GeneratedMessageV3.ExtendableBuilder.html)<[M](), -[B]()>, [T]() : -[Any](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/index.html)> -[B]().[set]()(extension: -[ExtensionLite](/reference/java/api-docs/com/google/protobuf/ExtensionLite.html)<[M](set), -[T]()>, value: [T]()) - -Sets the current value of the proto extension in this builder. diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string-utf8.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string-utf8.md deleted file mode 100644 index e3a379fdd..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string-utf8.md +++ /dev/null @@ -1,13 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/toByteStringUtf8 - -# toByteStringUtf8 - -[JVM] \ -Content \ -fun -[String](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html).[toByteStringUtf8]()(): -[ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html) - - -Encodes this String into a sequence of UTF-8 bytes and returns the result as a -[ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html). diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string.md deleted file mode 100644 index 6b46a7c2d..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string.md +++ /dev/null @@ -1,27 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/toByteString - -# toByteString - -[JVM] \ -Content \ -fun -[ByteArray](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-byte-array/index.html).[toByteString]()(): -[ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html) - - -Returns a copy of this -[ByteArray](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-byte-array/index.html) -as an immutable -[ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html). - -[JVM] \ -Content \ -fun -[ByteBuffer](https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html).[toByteString]()(): -[ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html) - - -Copies the remaining bytes from this -[ByteBuffer](https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html) -to a -[ByteString](/reference/java/api-docs/com/google/protobuf/ByteString.html). diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/unpack.md b/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/unpack.md deleted file mode 100644 index c4f8a0396..000000000 --- a/content/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/unpack.md +++ /dev/null @@ -1,19 +0,0 @@ -//[protobuf-kotlin](/reference/kotlin/api-docs/)/[com.google.protobuf.kotlin](/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/)/unpack - -# unpack - -[JVM] \ -Content \ -inline fun <[T]() : -[Message](/reference/java/api-docs/com/google/protobuf/Message.html)> -[Any](/reference/java/api-docs/com/google/protobuf/Any.html).[unpack]()(): -[T]() - -Returns the message of type T encoded in this -[com.google.protobuf.Any](/reference/java/api-docs/com/google/protobuf/Any.html). - -#### Throws - - | | -------------------------------------------------------------------------------------------------------------------------------- | --- -InvalidProtocolBufferException |

if this [com.google.protobuf.Any](/reference/java/api-docs/com/google/protobuf/Any.html) does not contain a T message.

diff --git a/content/reference/kotlin/kotlin-generated.md b/content/reference/kotlin/kotlin-generated.md deleted file mode 100644 index 703324afa..000000000 --- a/content/reference/kotlin/kotlin-generated.md +++ /dev/null @@ -1,322 +0,0 @@ -+++ -title = "Kotlin Generated Code Guide" -weight = 680 -linkTitle = "Generated Code Guide" -description = "Describes exactly what Kotlin code the protocol buffer compiler generates for any given protocol definition, in addition to the code generated for Java." -type = "docs" -+++ - -Any differences between proto2, proto3, and editions -generated code are highlighted—note that these differences are in the -generated code as described in this document, not the base message -classes/interfaces, which are the same in both versions. You should read the -[proto2 language guide](/programming-guides/proto2), -[proto3 language guide](/programming-guides/proto3), -and/or the [Editions guide](/programming-guides/editions) -before reading this document. - -## Compiler Invocation {#invocation} - -The protocol buffer compiler produces Kotlin code that builds on top of Java -code. As a result, it must be invoked with two command-line flags, `--java_out=` -and `--kotlin_out=`. The parameter to the `--java_out=` option is the directory -where you want the compiler to write your Java output, and the same for the -`--kotlin_out=`. For each `.proto` file input, the compiler creates a wrapper -`.java` file containing a Java class which represents the `.proto` file itself. - -**Regardless** of whether or not your `.proto` file contains a line like the -following: - -```proto -option java_multiple_files = true; -``` - -The compiler will create separate `.kt` files for each of the classes and -factory methods which it will generate for each top-level message declared in -the `.proto` file. - -The Java package name for each file is the same as that used by the generated -Java code as described in the -[Java generated code reference](/reference/java/java-generated#package). - -The output file is chosen by concatenating the parameter to `--kotlin_out=`, the -package name (with periods [.] replaced with slashes [/]), and the suffix -`Kt.kt` file name. - -So, for example, let's say you invoke the compiler as follows: - -```shell -protoc --proto_path=src --java_out=build/gen/java --kotlin_out=build/gen/kotlin src/foo.proto -``` - -If `foo.proto`'s Java package is `com.example` and it contains a message named -`Bar`, then the protocol buffer compiler will generate the file -`build/gen/kotlin/com/example/BarKt.kt`. The protocol buffer compiler will -automatically create the `build/gen/kotlin/com` and -`build/gen/kotlin/com/example` directories if needed. However, it will not -create `build/gen/kotlin`, `build/gen`, or `build`; they must already exist. You -can specify multiple `.proto` files in a single invocation; all output files -will be generated at once. - -## Messages {#message} - -Given a simple message declaration: - -```proto -message FooBar {} -``` - -The protocol buffer compiler generates—in addition to the generated Java -code—an object called `FooBarKt`, as well as two top-level functions, -having the following structure: - -```kotlin -object FooBarKt { - class Dsl private constructor { ... } -} -inline fun fooBar(block: FooBarKt.Dsl.() -> Unit): FooBar -inline fun FooBar.copy(block: FooBarKt.Dsl.() -> Unit): FooBar -``` - -### Nested Types - -A message can be declared inside another message. For example: - -```proto -message Foo { - message Bar { } -} -``` - -In this case, the compiler nests the `BarKt` object and the `bar` factory method -inside `FooKt`, though the `copy` method remains top-level: - -```kotlin -object FooKt { - class Dsl { ... } - object BarKt { - class Dsl private constructor { ... } - } - inline fun bar(block: FooKt.BarKt.Dsl.() -> Unit): Foo.Bar -} -inline fun foo(block: FooKt.Dsl.() -> Unit): Foo -inline fun Foo.copy(block: FooKt.Dsl.() -> Unit): Foo -inline fun Foo.Bar.copy(block: FooKt.BarKt.Dsl.() -> Unit): Foo.Bar -``` - -## Fields - -In addition to the methods described in the previous section, the protocol -buffer compiler generates mutable properties in the DSL for each field defined -within the message in the `.proto` file. (Kotlin already infers read-only -properties on the message object from the getters generated by Java.) - -Note that properties always use camel-case naming, even if the field name in the -`.proto` file uses lower-case with underscores -([as it should](/programming-guides/style)). The -case-conversion works as follows: - -1. For each underscore in the name, the underscore is removed, and the - following letter is capitalized. -2. If the name will have a prefix attached (for example, "clear"), the first - letter is capitalized. Otherwise, it is lower-cased. - -Thus, the field `foo_bar_baz` becomes `fooBarBaz`. - -In a few special cases in which a field name conflicts with reserved words in -Kotlin or methods already defined in the protobuf library, an extra underscore -is appended. For instance, the clearer for a field named `in` is `clearIn_()`. - -### Singular Fields - -For this field definition: - -```proto -int32 foo = 1; -``` - -The compiler will generate the following accessors in the DSL: - -- `fun hasFoo(): Boolean`: Returns `true` if the field is set. This is not - generated for fields using implicit presence. -- `var foo: Int`: The current value of the field. If the field is not set, - returns the default value. -- `fun clearFoo()`: Clears the value of the field. After calling this, - `hasFoo()` will return `false` and `getFoo()` will return the default value. - -For other simple field types, the corresponding Java type is chosen according to -the -[scalar value types table](/programming-guides/proto2#scalar). -For message and enum types, the value type is replaced with the message or enum -class. As the message type is still defined in Java, unsigned types in the -message are represented using the standard corresponding signed types in the -DSL, for compatibility with Java and older versions of Kotlin. - -#### Embedded Message Fields - -Note that there is no special handling of submessages. For example, if you have -a field - -```proto -optional Foo my_foo = 1; -``` - -you must write - -```kotlin -myFoo = foo { - ... -} -``` - -In general, this is because the compiler does not know whether `Foo` has a -Kotlin DSL at all, or e.g. only has the Java APIs generated. This means that you -do not have to wait for messages you depend on to add Kotlin code generation. - -### Repeated Fields {#repeated} - -For this field definition: - -```proto -repeated string foo = 1; -``` - -The compiler will generate the following members in the DSL: - -- `class FooProxy: DslProxy`, an unconstructable type used only in generics -- `val fooList: DslList`, a read-only view of the list of - current elements in the repeated field -- `fun DslList.add(value: String)`, an extension function - allowing elements to be added to the repeated field -- `operator fun DslList.plusAssign(value: String)`, an alias - for `add` -- `fun DslList.addAll(values: Iterable)`, an - extension function allowing an `Iterable` of elements to be added to the - repeated field -- `operator fun DslList.plusAssign(values: - Iterable)`, an alias for `addAll` -- `operator fun DslList.set(index: Int, value: String)`, an - extension function setting the value of the element at the given zero-based - inde -- `fun DslList.clear()`, an extension function clearing the - contents of the repeated field - -This unusual construction allows `fooList` to \"behave like\" a mutable list -within the scope of the DSL, supporting only the methods supported by the -underlying builder, while preventing mutability from \"escaping\" the DSL, which -could cause confusing side effects. - -For other simple field types, the corresponding Java type is chosen according to -the -[scalar value types table](/programming-guides/proto2#scalar). -For message and enum types, the type is the message or enum class. - -### Oneof Fields - -For this oneof field definition: - -```proto -oneof oneof_name { - int32 foo = 1; - ... -} -``` - -The compiler will generate the following accessor methods in the DSL: - -- `val oneofNameCase: OneofNameCase`: gets which, if any, of the `oneof_name` - fields are set; see the - [Java code reference](/reference/java/java-generated#oneof) - for the return type -- `fun hasFoo(): Boolean`: Returns `true` if the oneof case is `FOO`. -- `val foo: Int`: Returns the current value of `oneof_name` if the oneof case - is `FOO`. Otherwise, returns the default value of this field. - -For other simple field types, the corresponding Java type is chosen according to -the -[scalar value types table](/programming-guides/proto2#scalar). -For message and enum types, the value type is replaced with the message or enum -class. - -### Map Fields - -For this map field definition: - -```proto -map weight = 1; -``` - -The compiler will generate the following members in the DSL class: - -- `class WeightProxy private constructor(): DslProxy()`, an unconstructable - type used only in generics -- `val weight: DslMap`, a read-only view of the current - entries in the map field -- `fun DslMap.put(key: Int, value: Int)`: add the entry - to this map field -- `operator fun DslMap.put(key: Int, value: Int)`: - alias for `put` using operator syntax -- `fun DslMap.remove(key: Int)`: removes the entry - associated with `key`, if present -- `fun DslMap.putAll(map: Map)`: adds all - entries from the specified map to this map field, overwriting prior values - for already present keys -- `fun DslMap.clear()`: clears all entries from this - map field - -## Extensions {#extension} - -Given a proto2 or editions message with an extension range: - -```proto -message Foo { - extensions 100 to 199; -} -``` - -The protocol buffer compiler will add the following methods to `FooKt.Dsl`: - -- `operator fun get(extension: ExtensionLite): T`: gets the - current value of the extension field in the DSL -- `operator fun get(extension: ExtensionLite>): - ExtensionList`: gets the current value of the repeated extension - field in the DSL as a read-only `List` -- `operator fun > set(extension: ExtensionLite)`: - sets the current value of the extension field in the DSL (for `Comparable` - field types) -- `operator fun set(extension: ExtensionLite)`: sets - the current value of the extension field in the DSL (for message field - types) -- `operator fun set(extension: ExtensionLite)`: sets the - current value of the extension field in the DSL (for `bytes` fields) -- `operator fun contains(extension: ExtensionLite): Boolean`: returns - true if the extension field has a value -- `fun clear(extension: ExtensionLite)`: clears the extension field -- `fun ExtensionList.add(value: E)`: adds a value to the repeated - extension field -- `operator fun ExtensionList.plusAssign(value: E)`: alias for - `add` using operator syntax -- `operator fun ExtensionList.addAll(values: Iterable)`: adds - multiple values to the repeated extension field -- `operator fun ExtensionList.plusAssign(values: Iterable)`: - alias for `addAll` using operator syntax -- `operator fun ExtensionList.set(index: Int, value: E)`: sets the - element of the repeated extension field at the specified index -- `inline fun ExtensionList.clear()`: clears the elements of the - repeated extension field - -The generics here are complex, but the effect is that `this[extension] = value` -works for every extension type except repeated extensions, and repeated -extensions have \"natural\" list syntax that works similarly to -[non-extension repeated fields](#repeated). - -Given an extension definition: - -```proto -extend Foo { - int32 bar = 123; -} -``` - -Java generates the "extension identifier" `bar`, which is used to "key" -extension operations above. diff --git a/content/reference/objective-c/_index.md b/content/reference/objective-c/_index.md deleted file mode 100644 index 8ef6e6014..000000000 --- a/content/reference/objective-c/_index.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "Objective-C Reference" -weight = 700 -linkTitle = "Objective-C" -description = "Reference documentation for working with protocol buffer classes in Objective-C." -type = "docs" -+++ diff --git a/content/reference/objective-c/objective-c-generated.md b/content/reference/objective-c/objective-c-generated.md deleted file mode 100644 index 1679d4704..000000000 --- a/content/reference/objective-c/objective-c-generated.md +++ /dev/null @@ -1,1290 +0,0 @@ -+++ -title = "Objective-C Generated Code Guide" -weight = 710 -linkTitle = "Generated Code Guide" -description = "Describes exactly what Objective-C code the protocol buffer compiler generates for any given protocol definition." -type = "docs" -+++ - -Any -differences between proto2, proto3, and Editions generated code are highlighted. -You should read the -[proto2 language guide](/programming-guides/proto2) -and/or -[proto3 language guide](/programming-guides/proto3) -and/or the [Editions guide](/programming-guides/editions) -before reading this document. - -## Compiler invocation {#invocation} - -The protocol buffer compiler produces Objective-C output when invoked with the -`--objc_out=` command-line flag. The parameter to the `--objc_out=` option is -the directory where you want the compiler to write your Objective-C output. The -compiler creates a header file and an implementation file for each `.proto` file -input. The names of the output files are computed by taking the name of the -`.proto` file and making the following changes: - -- The file name is determined by converting the `.proto` file base name to - camel case. For example, `foo_bar.proto` will become `FooBar`. -- The extension (`.proto`) is replaced with either `pbobjc.h` or `pbobjc.m` - for the header or implementation file, respectively. -- The proto path (specified with the `--proto_path=` or `-I` command-line - flag) is replaced with the output path (specified with the `--objc_out=` - flag). - -So, for example, if you invoke the compiler as follows: - -```shell -protoc --proto_path=src --objc_out=build/gen src/foo.proto src/bar/baz.proto -``` - -The compiler will read the files `src/foo.proto` and `src/bar/baz.proto` and -produce four output files: `build/gen/Foo.pbobjc.h`, `build/gen/Foo.pbobjc.m`, -`build/gen/bar/Baz.pbobjc.h`, and `build/gen/bar/Baz.pbobjc.m`. The compiler -will automatically create the directory `build/gen/bar` if necessary, but it -will *not* create `build` or `build/gen`; they must already exist. - -## Packages {#package} - -The Objective-C code generated by the protocol buffer compiler is completely -unaffected by the package name defined in the `.proto` file, as Objective-C has -no language-enforced namespacing. Instead, Objective-C class names are -distinguished using prefixes, which you can find out about in the next section. - -## Class prefix {#prefix} - -Given the following -[file option](/programming-guides/proto3#options): - -```proto -option objc_class_prefix = "CGOOP"; -``` - -The specified string - in this case, `CGOOP` - is prefixed in front of all -Objective-C classes generated for this `.proto` file. Use prefixes that are 3 or -more characters as recommended by Apple. Note that all 2 letter prefixes are -reserved by Apple. - -## Camel case conversion {#case} - -Idiomatic Objective-C uses camel case for all identifiers. - -Messages will not have their names converted because the standard for proto -files is to name messages in camel case already. It is assumed that the user has -bypassed the convention for good reason, and the implementation will conform -with their intentions. - -Methods generated from field names and `oneof`s, `enum` declarations, and -extension accessors will have their names camel cased. In general to convert -from a proto name to a camel cased Objective-C name: - -- The first letter converted to uppercase (except for fields, which always - start with a lowercase letter). -- For each underscore in the name, the underscore is removed, and the - following letter is capitalized. - -So, for example, the field `foo_bar_baz` becomes `fooBarBaz`. The field -`FOO_bar` becomes `fooBar`. - -## Messages {#message} - -Given a simple message declaration: - -```proto -message Foo {} -``` - -The protocol buffer compiler generates a class called `Foo`. If you specify an -[`objc_class_prefix` file option](#prefix), the value of this option is -prepended to the generated class name. - -In the case of outer messages that have names matching any C/C++ or Objective-C -keywords: - -```proto -message static {} -``` - -the generated interfaces are suffixed by `_Class`, as follows: - -```objc -@interface static_Class {} -``` - -Note that as per the [camel case conversion rules](#case) the name `static` is -*not* converted. In the case of an inner message that has a camel cased name -that is `FieldNumber` or `OneOfCase`, the generated interface will be the camel -cased name suffixed by `_Class` to make sure that the generated names do not -conflict with the `FieldNumber` enumerations or `OneOfCase` enumerations. - -A message can also be declared inside another message. - -```proto -message Foo { - message Bar {} -} -``` - -This generates: - -```objc -@interface Foo_Bar : GPBMessage -@end -``` - -As you can see, the generated nested message name is the name of the generated -containing message name (`Foo`) appended with underscore (`_`) and the nested -message name (`Bar`). - -> **Note:** While we have tried to ensure that conflicts are kept to a minimum, -> there are still potential cases where message names may conflict due to the -> conversion between underscores and camel case. As an example: -> -> ```proto -> message foo_bar {} -> message foo { message bar {} } -> ``` -> -> will both generate `@interface foo_bar` and will conflict. The most pragmatic -> solution may be to rename the conflicting messages. - -### `GPBMessage` interface - -`GPBMessage` is the superclass of all generated message classes. It is required -to support a superset of the following interface: - -```objc -@interface GPBMessage : NSObject -@end -``` - -The behaviors for this interface are as follows: - -```objc -// Will do a deep copy. -- (id)copy; -// Will perform a deep equality comparison. -- (BOOL)isEqual:(id)value; -``` - -### Unknown fields - -When a message is parsed, it may contain fields that are not known to the -parsing code. This can happen when a message is created with an -[older version](/programming-guides/proto2#updating) of a -.proto definition and is then parsed with code generated from a newer version -(or vice versa). - -These fields are not discarded and are stored in the message's `unknownFields` -property: - -```objc -@property(nonatomic, copy, nullable) GPBUnknownFieldSet *unknownFields; -``` - -You can use the `GPBUnknownFieldSet` interface to fetch these fields by number -or loop over them as an array. - -## Fields - -The following sections describe the code generated by the protocol buffer -compiler for message fields. They are divided by those with implicit and -explicit presence. You can learn more about this distinction in -[Field Presence](/programming-guides/field_presence). - - - -### Singular Fields with Implicit Presence {#singular-implicit} - -For every singular field the compiler generates a property to store data and an -integer constant containing the field number. Message type fields also get a -`has..` property that lets you check if the field is set in the encoded message. -So, for example, given the following message: - -```proto -message Foo { - message Bar { - int32 int32_value = 1; - } - enum Qux {...} - int32 int32_value = 1; - string string_value = 2; - Bar message_value = 3; - Qux enum_value = 4; - bytes bytes_value = 5; -} -``` - -The compiler will generate the following: - -```objc -typedef GPB_ENUM(Foo_Bar_FieldNumber) { - // The generated field number name is the enclosing message names delimited by - // underscores followed by "FieldNumber", followed by the field name - // camel cased. - Foo_Bar_FieldNumber_Int32Value = 1, -}; - -@interface Foo_Bar : GPBMessage -@property(nonatomic, readwrite) int32_t int32Value; -@end - -typedef GPB_ENUM(Foo_FieldNumber) { - Foo_FieldNumber_Int32Value = 1, - Foo_FieldNumber_StringValue = 2, - Foo_FieldNumber_MessageValue = 3, - Foo_FieldNumber_EnumValue = 4, - Foo_FieldNumber_BytesValue = 5, -}; - -typedef GPB_ENUM(Foo_Qux) { - Foo_Qux_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, - ... -}; - -@interface Foo : GPBMessage -// Field names are camel cased. -@property(nonatomic, readwrite) int32_t int32Value; -@property(nonatomic, readwrite, copy, null_resettable) NSString *stringValue; -@property(nonatomic, readwrite) BOOL hasMessageValue; -@property(nonatomic, readwrite, strong, null_resettable) Foo_Bar *messageValue; -@property(nonatomic, readwrite) Foo_Qux enumValue; -@property(nonatomic, readwrite, copy, null_resettable) NSData *bytesValue; -@end -``` - -#### Special naming cases - -There are cases where the field name generation rules may result in name -conflicts and names will need to be \"uniqued\". Such conflicts are resolved by -appending `_p` to the end of the field (`_p` was selected because it's pretty -unique, and stands for \"property\"). - -```proto -message Foo { - int32 foo_array = 1; // Ends with Array - int32 bar_OneOfCase = 2; // Ends with oneofcase - int32 id = 3; // Is a C/C++/Objective-C keyword -} -``` - -generates: - -```objc -typedef GPB_ENUM(Foo_FieldNumber) { - // If a non-repeatable field name ends with "Array" it will be suffixed - // with "_p" to keep the name distinct from repeated types. - Foo_FieldNumber_FooArray_p = 1, - // If a field name ends with "OneOfCase" it will be suffixed with "_p" to - // keep the name distinct from OneOfCase properties. - Foo_FieldNumber_BarOneOfCase_p = 2, - // If a field name is a C/C++/ObjectiveC keyword it will be suffixed with - // "_p" to allow it to compile. - Foo_FieldNumber_Id_p = 3, -}; - -@interface Foo : GPBMessage -@property(nonatomic, readwrite) int32_t fooArray_p; -@property(nonatomic, readwrite) int32_t barOneOfCase_p; -@property(nonatomic, readwrite) int32_t id_p; -@end -``` - -#### Default values {#default} - -The [default value](/programming-guides/proto3#default) -for numeric types is `0`. - -The default value for strings is `@""`, and the default value for bytes is -`[NSData data]`. - -Assigning `nil` to a string field will assert in debug, and set the field to -`@""` in release. Assigning `nil` to a bytes field will assert in debug and set -the field to `[NSData data]` in release. To test whether a bytes or string field -is set requires testing its length property and comparing it to 0. - -The default \"empty\" value for a message is an instance of the default message. -To clear a message value it should be set to `nil`. Accessing a cleared message -will return an instance of the default message and the `hasFoo` method will -return false. - -The default message returned for a field is a local instance. The reason behind -returning a default message instead of `nil` is that in the case of: - -```proto -message Foo { - message Bar { - int32 b; - } - Bar a; -} -``` - -The implementation will support: - -```objc -Foo *foo = [[Foo alloc] init]; -foo.a.b = 2; -``` - -where `a` will be automatically created via the accessors if necessary. If -`foo.a` returned `nil`, the `foo.a.b` setter pattern would not work. - - - -### Singular Fields with Explicit Presence {#singular-explicit} - -For every singular field the compiler generates a property to store data, an -integer constant containing the field number, and a `has..` property that lets -you check if the field is set in the encoded message. So, for example, given the -following message: - -```proto -message Foo { - message Bar { - int32 int32_value = 1; - } - enum Qux {...} - optional int32 int32_value = 1; - optional string string_value = 2; - optional Bar message_value = 3; - optional Qux enum_value = 4; - optional bytes bytes_value = 5; -} -``` - -The compiler will generate the following: - -```objc -# Enum Foo_Qux - -typedef GPB_ENUM(Foo_Qux) { - Foo_Qux_Flupple = 0, -}; - -GPBEnumDescriptor *Foo_Qux_EnumDescriptor(void); - -BOOL Foo_Qux_IsValidValue(int32_t value); - -# Message Foo - -typedef GPB_ENUM(Foo_FieldNumber) { - Foo_FieldNumber_Int32Value = 2, - Foo_FieldNumber_MessageValue = 3, - Foo_FieldNumber_EnumValue = 4, - Foo_FieldNumber_BytesValue = 5, - Foo_FieldNumber_StringValue = 6, -}; - -@interface Foo : GPBMessage - -@property(nonatomic, readwrite) BOOL hasInt32Value; -@property(nonatomic, readwrite) int32_t int32Value; - -@property(nonatomic, readwrite) BOOL hasStringValue; -@property(nonatomic, readwrite, copy, null_resettable) NSString *stringValue; - -@property(nonatomic, readwrite) BOOL hasMessageValue; -@property(nonatomic, readwrite, strong, null_resettable) Foo_Bar *messageValue; - -@property(nonatomic, readwrite) BOOL hasEnumValue; -@property(nonatomic, readwrite) Foo_Qux enumValue; - -@property(nonatomic, readwrite) BOOL hasBytesValue; -@property(nonatomic, readwrite, copy, null_resettable) NSData *bytesValue; - -@end - -# Message Foo_Bar - -typedef GPB_ENUM(Foo_Bar_FieldNumber) { - Foo_Bar_FieldNumber_Int32Value = 1, -}; - -@interface Foo_Bar : GPBMessage - -@property(nonatomic, readwrite) BOOL hasInt32Value; -@property(nonatomic, readwrite) int32_t int32Value; - -@end -``` - -#### Special naming cases - -There are cases where the field name generation rules may result in name -conflicts and names will need to be \"uniqued\". Such conflicts are resolved by -appending `_p` to the end of the field (`_p` was selected because it's pretty -unique, and stands for \"property\"). - -```proto -message Foo { - optional int32 foo_array = 1; // Ends with Array - optional int32 bar_OneOfCase = 2; // Ends with oneofcase - optional int32 id = 3; // Is a C/C++/Objective-C keyword -} -``` - -generates: - -```objc -typedef GPB_ENUM(Foo_FieldNumber) { - // If a non-repeatable field name ends with "Array" it will be suffixed - // with "_p" to keep the name distinct from repeated types. - Foo_FieldNumber_FooArray_p = 1, - // If a field name ends with "OneOfCase" it will be suffixed with "_p" to - // keep the name distinct from OneOfCase properties. - Foo_FieldNumber_BarOneOfCase_p = 2, - // If a field name is a C/C++/ObjectiveC keyword it will be suffixed with - // "_p" to allow it to compile. - Foo_FieldNumber_Id_p = 3, -}; - -@interface Foo : GPBMessage -@property(nonatomic, readwrite) int32_t fooArray_p; -@property(nonatomic, readwrite) int32_t barOneOfCase_p; -@property(nonatomic, readwrite) int32_t id_p; -@end -``` - -#### Default values (optional fields only) {#default} - -The [default value](/programming-guides/proto2#optional) -for numeric types, if no explicit default was specified by the user, is `0`. - -The default value for strings is `@""`, and the default value for bytes is -`[NSData data]`. - -Assigning `nil` to a string field will assert in debug, and set the field to -`@""` in release. Assigning `nil` to a bytes field will assert in debug and set -the field to `[NSData data]` in release. To test whether a bytes or string field -is set requires testing its length property and comparing it to 0. - -The default \"empty\" value for a message is an instance of the default message. -To clear a message value it should be set to `nil`. Accessing a cleared message -will return an instance of the default message and the `hasFoo` method will -return false. - -The default message returned for a field is a local instance. The reason behind -returning a default message instead of `nil` is that in the case of: - -```proto -message Foo { - message Bar { - int32 b; - } - Bar a; -} -``` - -The implementation will support: - -```objc -Foo *foo = [[Foo alloc] init]; -foo.a.b = 2; -``` - -where `a` will be automatically created via the accessors if necessary. If -`foo.a` returned `nil`, the `foo.a.b` setter pattern would not work. - -### Repeated fields {#repeated} - -Like singular fields ([proto2](#singular2) [proto3](#singular3)), the protocol -buffer compiler generates one data property for each repeated field. This data -property is a `GPBArray` depending on the field type where `` can -be one of `UInt32`, `Int32`, `UInt64`, `Int64`, `Bool`, `Float`, `Double`, or -`Enum`. `NSMutableArray` will be used for `string`, `bytes` and `message` types. -Field names for repeated types have `Array` appended to them. The reason for -appending `Array` in the Objective-C interface is to make the code more -readable. Repeated fields in proto files tend to have singular names which do -not read well in standard Objective-C usage. Making the singular names plural -would be more idiomatic Objective-C, however pluralization rules are too complex -to support in the compiler. - -```proto -message Foo { - message Bar {} - enum Qux {} - repeated int32 int32_value = 1; - repeated string string_value = 2; - repeated Bar message_value = 3; - repeated Qux enum_value = 4; -} -``` - -generates: - -```objc -typedef GPB_ENUM(Foo_FieldNumber) { - Foo_FieldNumber_Int32ValueArray = 1, - Foo_FieldNumber_StringValueArray = 2, - Foo_FieldNumber_MessageValueArray = 3, - Foo_FieldNumber_EnumValueArray = 4, -}; - -@interface Foo : GPBMessage -// Field names for repeated types are the camel case name with -// "Array" suffixed. -@property(nonatomic, readwrite, strong, null_resettable) - GPBInt32Array *int32ValueArray; -@property(nonatomic, readonly) NSUInteger int32ValueArray_Count; - -@property(nonatomic, readwrite, strong, null_resettable) - NSMutableArray *stringValueArray; -@property(nonatomic, readonly) NSUInteger stringValueArray_Count; - -@property(nonatomic, readwrite, strong, null_resettable) - NSMutableArray *messageValueArray; -@property(nonatomic, readonly) NSUInteger messageValueArray_Count; - -@property(nonatomic, readwrite, strong, null_resettable) - GPBEnumArray *enumValueArray; -@property(nonatomic, readonly) NSUInteger enumValueArray_Count; -@end -``` - -**Note:** The behavior of repeated fields can be configured in Editions with the -[`features.repeated_field_encoding` feature](/editions/features#repeated_field_encoding). - -For string, bytes and message fields, elements of the array are `NSString*`, -`NSData*` and pointers to subclasses of `GPBMessage` respectively. - -#### Default values {#repeateddefault} - -The [default value](/programming-guides/proto3#default) -for a repeated field is to be empty. In Objective-C generated code, this is an -empty `GPBArray`. If you access an empty repeated field, you'll get back -an empty array that you can update like any other repeated field array. - -```objc -Foo *myFoo = [[Foo alloc] init]; -[myFoo.stringValueArray addObject:@"A string"] -``` - -You can also use the provided `Array_Count` property to check if the -array for a particular repeated field is empty without having to create the -array: - -```objc -if (myFoo.messageValueArray_Count) { - // There is something in the array... -} -``` - -#### `GPBArray` interface - -`GPBArray`s (aside from `GPBEnumArray`, which we'll look at below) have -the following interface: - -```objc -@interface GPBArray : NSObject -@property (nonatomic, readonly) NSUInteger count; -+ (instancetype)array; -+ (instancetype)arrayWithValue:()value; -+ (instancetype)arrayWithValueArray:(GPBArray *)array; -+ (instancetype)arrayWithCapacity:(NSUInteger)count; - -// Initializes the array, copying the values. -- (instancetype)initWithValueArray:(GPBArray *)array; -- (instancetype)initWithValues:(const [])values - count:(NSUInteger)count NS_DESIGNATED_INITIALIZER; -- (instancetype)initWithCapacity:(NSUInteger)count; - -- ()valueAtIndex:(NSUInteger)index; - -- (void)enumerateValuesWithBlock: - (void (^)( value, NSUInteger idx, BOOL *stop))block; -- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts - usingBlock:(void (^)( value, NSUInteger idx, BOOL *stop))block; - -- (void)addValue:()value; -- (void)addValues:(const [])values count:(NSUInteger)count; -- (void)addValuesFromArray:(GPBArray *)array; - -- (void)removeValueAtIndex:(NSUInteger)count; -- (void)removeAll; - -- (void)exchangeValueAtIndex:(NSUInteger)idx1 - withValueAtIndex:(NSUInteger)idx2; -- (void)insertValue:()value atIndex:(NSUInteger)count; -- (void)replaceValueAtIndex:(NSUInteger)index withValue:()value; - - -@end -``` - -`GPBEnumArray` has a slightly different interface to handle the validation -function and to access raw values. - -```objc -@interface GPBEnumArray : NSObject -@property (nonatomic, readonly) NSUInteger count; -@property (nonatomic, readonly) GPBEnumValidationFunc validationFunc; - -+ (instancetype)array; -+ (instancetype)arrayWithValidationFunction:(nullable GPBEnumValidationFunc)func; -+ (instancetype)arrayWithValidationFunction:(nullable GPBEnumValidationFunc)func - rawValue:value; -+ (instancetype)arrayWithValueArray:(GPBEnumArray *)array; -+ (instancetype)arrayWithValidationFunction:(nullable GPBEnumValidationFunc)func - capacity:(NSUInteger)count; - -- (instancetype)initWithValidationFunction: - (nullable GPBEnumValidationFunc)func; - -// Initializes the array, copying the values. -- (instancetype)initWithValueArray:(GPBEnumArray *)array; -- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func - values:(const int32_t [])values - count:(NSUInteger)count NS_DESIGNATED_INITIALIZER; -- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func - capacity:(NSUInteger)count; - -// These will return kGPBUnrecognizedEnumeratorValue if the value at index -// is not a valid enumerator as defined by validationFunc. If the actual -// value is desired, use the "raw" version of the method. -- (int32_t)valueAtIndex:(NSUInteger)index; -- (void)enumerateValuesWithBlock: - (void (^)(int32_t value, NSUInteger idx, BOOL *stop))block; -- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts - usingBlock:(void (^)(int32_t value, NSUInteger idx, BOOL *stop))block; - -// These methods bypass the validationFunc to provide access to values -// that were not known at the time the binary was compiled. -- (int32_t)rawValueAtIndex:(NSUInteger)index; - -- (void)enumerateRawValuesWithBlock: - (void (^)(int32_t value, NSUInteger idx, BOOL *stop))block; -- (void)enumerateRawValuesWithOptions:(NSEnumerationOptions)opts - usingBlock:(void (^)(int32_t value, NSUInteger idx, BOOL *stop))block; - -// If value is not a valid enumerator as defined by validationFunc, these -// methods will assert in debug, and will log in release and assign the value -// to the default value. Use the rawValue methods below to assign -// non enumerator values. -- (void)addValue:(int32_t)value; -- (void)addValues:(const int32_t [])values count:(NSUInteger)count; -- (void)insertValue:(int32_t)value atIndex:(NSUInteger)count; -- (void)replaceValueAtIndex:(NSUInteger)index withValue:(int32_t)value; - -// These methods bypass the validationFunc to provide setting of values that -// were not known at the time the binary was compiled. -- (void)addRawValue:(int32_t)rawValue; -- (void)addRawValuesFromEnumArray:(GPBEnumArray *)array; -- (void)addRawValues:(const int32_t [])values count:(NSUInteger)count; -- (void)replaceValueAtIndex:(NSUInteger)index withRawValue:(int32_t)rawValue; -- (void)insertRawValue:(int32_t)value atIndex:(NSUInteger)count; - -// No validation applies to these methods. -- (void)removeValueAtIndex:(NSUInteger)count; -- (void)removeAll; -- (void)exchangeValueAtIndex:(NSUInteger)idx1 - withValueAtIndex:(NSUInteger)idx2; - -@end -``` - -### Oneof fields {#oneof} - -Given a message with -[oneof](/programming-guides/proto3#oneof) field -definitions: - -```proto -message Order { - oneof OrderID { - string name = 1; - int32 address = 2; - }; - int32 quantity = 3; -}; -``` - -The protocol buffer compiler generates: - -```objc -typedef GPB_ENUM(Order_OrderID_OneOfCase) { - Order_OrderID_OneOfCase_GPBUnsetOneOfCase = 0, - Order_OrderID_OneOfCase_Name = 1, - Order_OrderID_OneOfCase_Address = 2, -}; - -typedef GPB_ENUM(Order_FieldNumber) { - Order_FieldNumber_Name = 1, - Order_FieldNumber_Address = 2, - Order_FieldNumber_Quantity = 3, -}; - -@interface Order : GPBMessage -@property (nonatomic, readwrite) Order_OrderID_OneOfCase orderIDOneOfCase; -@property (nonatomic, readwrite, copy, null_resettable) NSString *name; -@property (nonatomic, readwrite) int32_t address; -@property (nonatomic, readwrite) int32_t quantity; -@end - -void Order_ClearOrderIDOneOfCase(Order *message); -``` - -Setting one of the oneof properties will clear all the other properties -associated with the oneof. - -`_OneOfCase_GPBUnsetOneOfCase` will always be equivalent to 0 to -allow for easy testing to see if any field in the oneof is set. - -### Map Fields - -For this message definition: - -```proto -message Bar {...} -message Foo { - map a_map = 1; - map b_map = 2; -}; -``` - -The compiler generates the following: - -```objc -typedef GPB_ENUM(Foo_FieldNumber) { - Foo_FieldNumber_AMap = 1, - Foo_FieldNumber_BMap = 2, -}; - -@interface Foo : GPBMessage -// Map names are the camel case version of the field name. -@property (nonatomic, readwrite, strong, null_resettable) GPBInt32ObjectDictionary *aMap; -@property(nonatomic, readonly) NSUInteger aMap_Count; -@property (nonatomic, readwrite, strong, null_resettable) NSMutableDictionary *bMap; -@property(nonatomic, readonly) NSUInteger bMap_Count; -@end -``` - -Cases where keys are strings and values are strings, bytes, or messages are -handled by `NSMutableDictionary`. - -Other cases are: - -```objc -GBPDictionary -``` - -where: - -- `` is Uint32, Int32, UInt64, Int64, Bool or String. -- `` is UInt32, Int32, UInt64, Int64, Bool, Float, Double, Enum, or - Object. `Object` is used for values of type `string` `bytes` or `message` to - cut down on the number of classes and is in line with how Objective-C works - with `NSMutableDictionary`. - -#### Default values {#repeateddefault} - -The [default value](/programming-guides/proto3#default) -for a map field is empty. In Objective-C generated code, this is an empty -`GBPDictionary`. If you access an empty map field, you'll get back -an empty dictionary that you can update like any other map field. - -You can also use the provided `_Count` property to check if a -particular map is empty: - -```objc -if (myFoo.myMap_Count) { - // There is something in the map... -} -``` - -#### `GBPDictionary` interface - -The `GBPDictionary` (apart from `GBPObjectDictionary` and -`GBPEnumDictionary`) interface is as follows: - -```objc -@interface GPBDictionary : NSObject -@property (nonatomic, readonly) NSUInteger count; - -+ (instancetype)dictionary; -+ (instancetype)dictionaryWithValue:(const )value - forKey:(const )key; -+ (instancetype)dictionaryWithValues:(const [])values - forKeys:(const [])keys - count:(NSUInteger)count; -+ (instancetype)dictionaryWithDictionary:(GPBDictionary *)dictionary; -+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems; - -- (instancetype)initWithValues:(const [])values - forKeys:(const [])keys - count:(NSUInteger)count NS_DESIGNATED_INITIALIZER; -- (instancetype)initWithDictionary:(GPBDictionary *)dictionary; -- (instancetype)initWithCapacity:(NSUInteger)numItems; - -- (BOOL)valueForKey:()key value:(VALUE *)value; - -- (void)enumerateKeysAndValuesUsingBlock: - (void (^)( key, value, BOOL *stop))block; - -- (void)removeValueForKey:()aKey; -- (void)removeAll; -- (void)setValue:()value forKey:()key; -- (void)addEntriesFromDictionary:(GPBDictionary *)otherDictionary; -@end -``` - -The `GBPObjectDictionary` interface is: - -```objc -@interface GPBObjectDictionary : NSObject -@property (nonatomic, readonly) NSUInteger count; - -+ (instancetype)dictionary; -+ (instancetype)dictionaryWithObject:(id)object - forKey:(const )key; -+ (instancetype) - dictionaryWithObjects:(const id GPB_UNSAFE_UNRETAINED [])objects - forKeys:(const [])keys - count:(NSUInteger)count; -+ (instancetype)dictionaryWithDictionary:(GPBObjectDictionary *)dictionary; -+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems; - -- (instancetype)initWithObjects:(const id GPB_UNSAFE_UNRETAINED [])objects - forKeys:(const [])keys - count:(NSUInteger)count NS_DESIGNATED_INITIALIZER; -- (instancetype)initWithDictionary:(GPBObjectDictionary *)dictionary; -- (instancetype)initWithCapacity:(NSUInteger)numItems; - -- (id)objectForKey:(uint32_t)key; - -- (void)enumerateKeysAndObjectsUsingBlock: - (void (^)( key, id object, BOOL *stop))block; - -- (void)removeObjectForKey:()aKey; -- (void)removeAll; -- (void)setObject:(id)object forKey:()key; -- (void)addEntriesFromDictionary:(GPBObjectDictionary *)otherDictionary; -@end -``` - -`GBPEnumDictionary` has a slightly different interface to handle the -validation function and to access raw values. - -```objc -@interface GPBEnumDictionary : NSObject - -@property(nonatomic, readonly) NSUInteger count; -@property(nonatomic, readonly) GPBEnumValidationFunc validationFunc; - -+ (instancetype)dictionary; -+ (instancetype)dictionaryWithValidationFunction:(nullable GPBEnumValidationFunc)func; -+ (instancetype)dictionaryWithValidationFunction:(nullable GPBEnumValidationFunc)func - rawValue:(int32_t)rawValue - forKey:(_t)key; -+ (instancetype)dictionaryWithValidationFunction:(nullable GPBEnumValidationFunc)func - rawValues:(const int32_t [])values - forKeys:(const _t [])keys - count:(NSUInteger)count; -+ (instancetype)dictionaryWithDictionary:(GPBEnumDictionary *)dictionary; -+ (instancetype)dictionaryWithValidationFunction:(nullable GPBEnumValidationFunc)func - capacity:(NSUInteger)numItems; - -- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func; -- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func - rawValues:(const int32_t [])values - forKeys:(const _t [])keys - count:(NSUInteger)count NS_DESIGNATED_INITIALIZER; -- (instancetype)initWithDictionary:(GPBEnumDictionary *)dictionary; -- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func - capacity:(NSUInteger)numItems; - -// These will return kGPBUnrecognizedEnumeratorValue if the value for the key -// is not a valid enumerator as defined by validationFunc. If the actual value is -// desired, use "raw" version of the method. - -- (BOOL)valueForKey:(_t)key value:(nullable int32_t *)value; - -- (void)enumerateKeysAndValuesUsingBlock: - (void (^)(_t key, int32_t value, BOOL *stop))block; - -// These methods bypass the validationFunc to provide access to values that were not -// known at the time the binary was compiled. - -- (BOOL)valueForKey:(_t)key rawValue:(nullable int32_t *)rawValue; - -- (void)enumerateKeysAndRawValuesUsingBlock: - (void (^)(_t key, int32_t rawValue, BOOL *stop))block; - -- (void)addRawEntriesFromDictionary:(GPBEnumDictionary *)otherDictionary; - -// If value is not a valid enumerator as defined by validationFunc, these -// methods will assert in debug, and will log in release and assign the value -// to the default value. Use the rawValue methods below to assign non enumerator -// values. - -- (void)setValue:(int32_t)value forKey:(_t)key; - -// This method bypass the validationFunc to provide setting of values that were not -// known at the time the binary was compiled. -- (void)setRawValue:(int32_t)rawValue forKey:(_t)key; - -// No validation applies to these methods. - -- (void)removeValueForKey:(_t)aKey; -- (void)removeAll; - -@end -``` - -## Enumerations {#enum} - -Given an enum definition like: - -```proto -enum Foo { - VALUE_A = 0; - VALUE_B = 1; - VALUE_C = 5; -} -``` - -the generated code will be: - -```objc -// The generated enum value name will be the enumeration name followed by -// an underscore and then the enumerator name converted to camel case. -// GPB_ENUM is a macro defined in the Objective-C Protocol Buffer headers -// that enforces all enum values to be int32 and aids in Swift Enumeration -// support. -typedef GPB_ENUM(Foo) { - Foo_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, //proto3 only - Foo_ValueA = 0, - Foo_ValueB = 1; - Foo_ValueC = 5; -}; - -// Returns information about what values this enum type defines. -GPBEnumDescriptor *Foo_EnumDescriptor(); -``` - -Each enumeration has a validation function declared for it: - -```objc -// Returns YES if the given numeric value matches one of Foo's -// defined values (0, 1, 5). -BOOL Foo_IsValidValue(int32_t value); -``` - -and an enumeration descriptor accessor function declared for it: - -```objc -// GPBEnumDescriptor is defined in the runtime and contains information -// about the enum definition, such as the enum name, enum value and enum value -// validation function. -typedef GPBEnumDescriptor *(*GPBEnumDescriptorAccessorFunc)(); -``` - -The enum descriptor accessor functions are C functions, as opposed to methods on -the enumeration class, because they are rarely used by client software. This -will cut down on the amount of Objective-C runtime information generated, and -potentially allow the linker to deadstrip them. - -In the case of outer enums that have names matching any C/C++ or Objective-C -keywords, such as: - -```proto -enum method {} -``` - -the generated interfaces are suffixed with `_Enum`, as follows: - -```objc -// The generated enumeration name is the keyword suffixed by _Enum. -typedef GPB_ENUM(Method_Enum) {} -``` - -An enum can also be declared inside another message. For example: - -```proto -message Foo { - enum Bar { - VALUE_A = 0; - VALUE_B = 1; - VALUE_C = 5; - } - Bar aBar = 1; - Bar aDifferentBar = 2; - repeated Bar aRepeatedBar = 3; -} -``` - -generates: - -```objc -typedef GPB_ENUM(Foo_Bar) { - Foo_Bar_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, //proto3 only - Foo_Bar_ValueA = 0; - Foo_Bar_ValueB = 1; - Foo_Bar_ValueC = 5; -}; - -GPBEnumDescriptor *Foo_Bar_EnumDescriptor(); - -BOOL Foo_Bar_IsValidValue(int32_t value); - -@interface Foo : GPBMessage -@property (nonatomic, readwrite) Foo_Bar aBar; -@property (nonatomic, readwrite) Foo_Bar aDifferentBar; -@property (nonatomic, readwrite, strong, null_resettable) - GPBEnumArray *aRepeatedBarArray; -@end - -// proto3 only Every message that has an enum field will have an accessor function to get -// the value of that enum as an integer. This allows clients to deal with -// raw values if they need to. -int32_t Foo_ABar_RawValue(Foo *message); -void SetFoo_ABar_RawValue(Foo *message, int32_t value); -int32_t Foo_ADifferentBar_RawValue(Foo *message); -void SetFoo_ADifferentBar_RawValue(Foo *message, int32_t value); -``` - -All enumeration fields have the ability to access the value as a typed -enumerator (`Foo_Bar` in the example above), or, if using proto3, as a raw -`int32_t` value (using the accessor functions in the example above). This is to -support the case where the server returns values that the client may not -recognize due to the client and server being compiled with different versions of -the proto file. - -Unrecognized enum values are treated differently depending on the language -version and the `features.enum_type` feature in Editions. - -* In open enums, `kGPBUnrecognizedEnumeratorValue` is returned for the typed - enumerator value if the enumerator value in the parsed message data is not - one that the code reading it was compiled to support. If the actual value is - desired, use the raw value accessors to get the value as an `int32_t`. -* In closed enums, unrecognized enum values are treated as unknown fields. -* Proto2 enums are closed, and proto3 enums are open. In Editions, the - behavior is configurable with the `features.enum_type` feature. - -`kGPBUnrecognizedEnumeratorValue` is defined as `0xFBADBEEF`, and it will be an -error if any enumerator in an enumeration has this value. Attempting to set any -enumeration field to this value is a runtime error. Similarly, attempting to set -any enumeration field to an enumerator not defined by its enumeration type using -the typed accessors is a runtime error. In both error cases, debug builds will -cause an assertion and release builds will log and set the field to its default -value (`0`). - -The raw value accessors are defined as C functions instead of as Objective-C -methods because they are not used in most cases. Declaring them as C functions -cuts down on wasted Objective-C runtime information and allows the linker to -potentially dead strip them. - -### Swift Enumeration Support - -Apple documents how they import Objective-C enumerations to Swift enumerations -in -[Interacting with C APIs](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html#//apple_ref/doc/uid/TP40014216-CH8-XID_11). -Protocol buffer-generated enumerations support Objective-C to Swift conversions. - -```proto -// Proto -enum Foo { - VALUE_A = 0; -} -``` - -generates: - -```objc -// Objective-C -typedef GPB_ENUM(Foo) { - Foo_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, - Foo_ValueA = 0, -}; -``` - -which in Swift code will allow: - -```swift -// Swift -let aValue = Foo.ValueA -let anotherValue: Foo = .GPBUnrecognizedEnumeratorValue -``` - -## Well-known types {#wellknown} - -If you use any of the message types provided with protocol buffers, they will in -general just use their proto definitions in generated Objective-C code, though -we supply some basic conversion methods in categories to make using them -simpler. Note that we do not have special APIs for all well-known types yet, -including [`Any`](/programming-guides/proto3#any) (there -is currently no helper method to convert an `Any`'s message value into a message -of the appropriate type). - -### Time Stamps - -```objc -@interface GPBTimeStamp (GPBWellKnownTypes) -@property (nonatomic, readwrite, strong) NSDate *date; -@property (nonatomic, readwrite) NSTimeInterval timeIntervalSince1970; -- (instancetype)initWithDate:(NSDate *)date; -- (instancetype)initWithTimeIntervalSince1970: - (NSTimeInterval)timeIntervalSince1970; -@end -``` - -### Duration - -```objc -@interface GPBDuration (GPBWellKnownTypes) -@property (nonatomic, readwrite) NSTimeInterval timeIntervalSince1970; -- (instancetype)initWithTimeIntervalSince1970: - (NSTimeInterval)timeIntervalSince1970; -@end -``` - -## Extensions (proto2 and editions only) {#extensions} - -You can control the generation of extensions by using the -`extension_generation_mode` option. There are three modes: - -* `class_based`: Generates Objective-C classes and methods for extensions - (Legacy). -* `c_function`: Generates C functions for extensions (New). -* `migration`: Generates both. - -### Class-based (Legacy) {#extensions-legacy} - -Given a message with an -[extension range](/programming-guides/proto2#extensions): - -```proto -message Foo { - extensions 100 to 199; -} - -extend Foo { - int32 foo = 101; - repeated int32 repeated_foo = 102; -} - -message Bar { - extend Foo { - int32 bar = 103; - repeated int32 repeated_bar = 104; - } -} -``` - -The compiler generates the following: - -```objc -# File Test2Root - -@interface Test2Root : GPBRootObject - -// The base class provides: -// + (GPBExtensionRegistry *)extensionRegistry; -// which is an GPBExtensionRegistry that includes all the extensions defined by -// this file and all files that it depends on. - -@end - -@interface Test2Root (DynamicMethods) -+ (GPBExtensionDescriptor *)foo; -+ (GPBExtensionDescriptor *)repeatedFoo; -@end - -# Message Foo - -@interface Foo : GPBMessage - -@end - -# Message Bar - -@interface Bar : GPBMessage - -@end - -@interface Bar (DynamicMethods) - -+ (GPBExtensionDescriptor *)bar; -+ (GPBExtensionDescriptor *)repeatedBar; -@end -``` - -To get and set these extension fields, you use the following: - -```objc -Foo *fooMsg = [[Foo alloc] init]; - -// Set the single field extensions -[fooMsg setExtension:[Test2Root foo] value:@5]; -NSAssert([fooMsg hasExtension:[Test2Root foo]]); -NSAssert([[fooMsg getExtension:[Test2Root foo]] intValue] == 5); - -// Add two things to the repeated extension: -[fooMsg addExtension:[Test2Root repeatedFoo] value:@1]; -[fooMsg addExtension:[Test2Root repeatedFoo] value:@2]; -NSAssert([fooMsg hasExtension:[Test2Root repeatedFoo]]); -NSAssert([[fooMsg getExtension:[Test2Root repeatedFoo]] count] == 2); - -// Clearing -[fooMsg clearExtension:[Test2Root foo]]; -[fooMsg clearExtension:[Test2Root repeatedFoo]]; -NSAssert(![fooMsg hasExtension:[Test2Root foo]]); -NSAssert(![fooMsg hasExtension:[Test2Root repeatedFoo]]); -``` - -### C-functions (New) {#extensions-c-functions} - -When using `c_function` mode, C functions are generated instead of Objective-C -classes. This reduces binary size and avoids name conflicts. - -The naming convention for the generated functions involves the proto package and -the extension name. If an `objc_class_prefix` is defined, it is prepended. - -* File-scoped registry: `__Registry()` -* File-scoped extension: `_extension_()` -* Message-scoped extension: - `__extension_()` - -(Note: `Package` is the CamelCased proto package name. `File` is the file name. -`ScopeMessage` is the message containing the extension definition.) - -Using the same example as above, but assuming `package my.package;` and file -`test2.proto`: - -The compiler generates C functions declared in the header: - -```objc -// Registry function for the file. -GPBExtensionRegistry *MyPackage_Test2_Registry(void); - -// File-scoped extensions. -GPBExtensionDescriptor *MyPackage_extension_Foo(void); -GPBExtensionDescriptor *MyPackage_extension_RepeatedFoo(void); - -// Message-scoped extensions (scoped to Bar). -GPBExtensionDescriptor *MyPackage_Bar_extension_Bar(void); -GPBExtensionDescriptor *MyPackage_Bar_extension_RepeatedBar(void); -``` - -To get and set these extension fields: - -```objc -Foo *fooMsg = [[Foo alloc] init]; - -// Set the single field extensions -[fooMsg setExtension:MyPackage_extension_Foo() value:@5]; -NSAssert([fooMsg hasExtension:MyPackage_extension_Foo()]); -NSAssert([[fooMsg getExtension:MyPackage_extension_Foo()] intValue] == 5); - -// Add two things to the repeated extension: -[fooMsg addExtension:MyPackage_extension_RepeatedFoo() value:@1]; -[fooMsg addExtension:MyPackage_extension_RepeatedFoo() value:@2]; -NSAssert([fooMsg hasExtension:MyPackage_extension_RepeatedFoo()]); -NSAssert([[fooMsg getExtension:MyPackage_extension_RepeatedFoo()] count] == 2); - -// Clearing -[fooMsg clearExtension:MyPackage_extension_Foo()]; -[fooMsg clearExtension:MyPackage_extension_RepeatedFoo()]; -NSAssert(![fooMsg hasExtension:MyPackage_extension_Foo()]); -NSAssert(![fooMsg hasExtension:MyPackage_extension_RepeatedFoo()]); -``` diff --git a/content/reference/other.md b/content/reference/other.md deleted file mode 100644 index 3db124d62..000000000 --- a/content/reference/other.md +++ /dev/null @@ -1,37 +0,0 @@ -+++ -title = "Other Languages" -weight = 840 -description = "protoc, the Protocol Buffers Compiler, can be extended to support new languages via plugins." -type = "docs" -+++ - -While the current release includes compilers and APIs for C++, Java, Go, Ruby, -C\#, and Python, the compiler code is designed so that it's easy to add support -for other languages. There are several ongoing projects to add new language -implementations to Protocol Buffers, including C, Haskell, Perl, Rust, and more. - -For a list of links to projects we know about, see the -[third-party add-ons wiki page](https://github.com/protocolbuffers/protobuf/blob/main/docs/third_party.md). - -## Compiler Plugins {#plugins} - -`protoc`, the Protocol Buffers Compiler, can be extended to support new -languages via plugins. A plugin is just a program which reads a -`CodeGeneratorRequest` protocol buffer from standard input and then writes a -`CodeGeneratorResponse` protocol buffer to standard output. These message types -are defined in -[`plugin.proto`](/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb). -We recommend that all third-party code generators be written as plugins, as this -allows all generators to provide a consistent interface and share a single -parser implementation. - -Plugins can be written in any programming language, but Google owned plugins are -written in C++. If you are writing your own plugin you may find it easiest to -use C++ for the plugin to be able to follow those examples and reuse utilities. - -Additionally, plugins are able to insert code into the files generated by other -code generators. See the comments about \"insertion points\" in `plugin.proto` -for more on this. This could be used, for example, to write a plugin which -generates RPC service code that is tailored for a particular RPC system. See the -documentation for the generated code in each language to find out what insertion -points they provide. diff --git a/content/reference/php/_index.md b/content/reference/php/_index.md deleted file mode 100644 index a2f9f457e..000000000 --- a/content/reference/php/_index.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "PHP Reference" -weight = 720 -linkTitle = "PHP" -description = "Reference documentation for working with protocol buffer classes in PHP." -type = "docs" -+++ diff --git a/content/reference/php/api-docs-link.md b/content/reference/php/api-docs-link.md deleted file mode 100644 index 6b55e1445..000000000 --- a/content/reference/php/api-docs-link.md +++ /dev/null @@ -1,8 +0,0 @@ - - ---- -title: "PHP API" -manualLink: "/reference/php/api-docs/" -manualLinkTarget: "_blank" -weight: 735 ---- \ No newline at end of file diff --git a/content/reference/php/php-generated.md b/content/reference/php/php-generated.md deleted file mode 100644 index 957132899..000000000 --- a/content/reference/php/php-generated.md +++ /dev/null @@ -1,337 +0,0 @@ -+++ -title = "PHP Generated Code Guide" -weight = 730 -linkTitle = "Generated Code Guide" -description = "Describes the PHP code that the protocol buffer compiler generates for any given protocol definition." -type = "docs" -+++ - -You should read the -[proto3 language guide](/programming-guides/proto3) or -[Editions language guide](/programming-guides/editions) -before reading this document. Note that the protocol buffer compiler currently -only supports proto3 and editions code generation for PHP. - -## Compiler Invocation {#invocation} - -The protocol buffer compiler produces PHP output when invoked with the -`--php_out=` command-line flag. The parameter to the `--php_out=` option is the -directory where you want the compiler to write your PHP output. In order to -conform to PSR-4, the compiler creates a sub-directory corresponding to the -package defined in the proto file. In addition, for each message in the proto -file input the compiler creates a separate file in the package's subdirectory. -The names of the output files of messages are composed of three parts: - -- Base directory: The proto path (specified with the `--proto_path=` or `-I` - command-line flag) is replaced with the output path (specified with the - `--php_out=` flag). -- Sub-directory: `.` in the package name are replaced by the operating system - directory separator. Each package name component is capitalized. -- File: The message name is appended by `.php`. - -So, for example, let's say you invoke the compiler as follows: - -```shell -protoc --proto_path=src --php_out=build/gen src/example.proto -``` - -And `src/example.proto` is defined as: - -```proto -edition = "2023"; -package foo.bar; -message MyMessage {} -``` - -The compiler will read the files `src/foo.proto` and produce the output file: -`build/gen/Foo/Bar/MyMessage.php`. The compiler will automatically create the -directory `build/gen/Foo/Bar` if necessary, but it will *not* create `build` or -`build/gen`; they must already exist. - -## Packages {#package} - -The package name defined in the `.proto` file is used by default to generate a -module structure for the generated PHP classes. Given a file like: - -```proto -package foo.bar; - -message MyMessage {} -``` - -The protocol compiler generates an output class with the name -`Foo\Bar\MyMessage`. - -### Namespace Options {#namespace-options} - -The compiler supports additional options to define the PHP and metadata -namespace. When defined, these are used to generate the module structure and the -namespace. Given options like: - -```proto -package foo.bar; -option php_namespace = "baz\\qux"; -option php_metadata_namespace = "Foo"; -message MyMessage {} -``` - -The protocol compiler generates an output class with the name -`baz\qux\MyMessage`. The class will have the namespace `namespace baz\qux`. - -The protocol compiler generates a metadata class with the name `Foo\Metadata`. -The class will have the namespace `namespace Foo`. - -*The options generated are case-sensitive. By default, the package is converted -to Pascal case.* - -## Messages {#message} - -Given a simple message declaration: - -```proto -message Foo { - int32 int32_value = 1; - string string_value = 2; - repeated int32 repeated_int32_value = 3; - map map_int32_int32_value = 4; -} -``` - -The protocol buffer compiler generates a PHP class called `Foo`. This class -inherits from a common base class, `Google\Protobuf\Internal\Message`, which -provides methods for encoding and decoding your message types, as shown in the -following example: - -```php -$from = new Foo(); -$from->setInt32Value(1); -$from->setStringValue('a'); -$from->getRepeatedInt32Value()[] = 1; -$from->getMapInt32Int32Value()[1] = 1; -$data = $from->serializeToString(); -$to = new Foo(); -try { - $to->mergeFromString($data); -} catch (Exception $e) { - // Handle parsing error from invalid data. - ... -} -``` - -You should *not* create your own `Foo` subclasses. Generated classes are not -designed for subclassing and may lead to \"fragile base class\" problems. - -Nested messages result in a PHP class of the same name prefixed by their -containing message and separated by underscores, as PHP doesn't support nested -classes. So, for example, if you have this in your `.proto`: - -```proto -message TestMessage { - message NestedMessage { - int32 a = 1; - } -} -``` - -The compiler will generate the following class: - -```php -// PHP doesn’t support nested classes. -class TestMessage_NestedMessage { - public function __construct($data = NULL) {...} - public function getA() {...} - public function setA($var) {...} -} -``` - -If the message class name is reserved (for example, `Empty`), the prefix `PB` is -prepended to the class name: - -```php -class PBEmpty {...} -``` - -We have also provided the file level option `php_class_prefix`. If this is -specified, it is prepended to all generated message classes. - -## Fields - -For each field in a message type, the protocol buffer compiler generates a set -of accessor methods to set and get the field. The accessor methods are named -using `snake_case` field names converted to `PascalCase`. So, given a field -`field_name`, the accessor methods will be `getFieldName` and `setFieldName`. - -```php -// optional MyEnum optional_enum -$m->getOptionalEnum(); -$m->setOptionalEnum(MyEnum->FOO); -$m->hasOptionalEnum(); -$m->clearOptionalEnum(); - -// MyEnum implicit_enum -$m->getImplicitEnum(); -$m->setImplicitEnum(MyEnum->FOO); -``` - -Whenever you set a field, the value is type-checked against the declared type of -that field. If the value is of the wrong type (or out of range), an exception -will be raised. By default type conversions (for example, when assigning a value -to a field or adding an element to a repeated field) are permitted to and from -integer, float, and numeric strings. Conversions that are not permitted include -all conversions to/from arrays or objects. Float to integer overflow conversions -are undefined. - -You can see the corresponding PHP type for each scalar protocol buffers type in -the -[scalar value types table](/programming-guides/proto3#scalar). - -### `has...` and `clear...` - -For fields with explicit presence, the compiler generates a `has...()` method. -This method returns `true` if the field is set. - -The compiler also generates a `clear...()` method. This method unsets the field. -After calling this method, `has...()` will return `false`. - -For fields with implicit presence, the compiler does not generate `has...()` or -`clear...()` methods. For these fields, you can check for presence by comparing -the field value with the default value. - -### Singular Message Fields {#embedded_message} - -For a field with a message type, the compiler generates the same accessor -methods as for scalar types. - -A field with a message type defaults to `null`, and is not automatically created -when the field is accessed. Thus you need to explicitly create sub messages, as -in the following: - -```php -$m = new MyMessage(); -$m->setZ(new SubMessage()); -$m->getZ()->setFoo(42); - -$m2 = new MyMessage(); -$m2->getZ()->setFoo(42); // FAILS with an exception -``` - -You can assign any instance to a message field, even if the instance is also -held elsewhere (for example, as a field value on another message). - -### Repeated Fields - -The protocol buffer compiler generates a special `RepeatedField` for each -repeated field. So, for example, given the following field: - -```proto -repeated int32 foo = 1; -``` - -The generated code lets you do this: - -```php -$m->getFoo()[] =1; -$m->setFoo($array); -``` - -### Map Fields - -The protocol buffer compiler generates a `MapField` for each map field. So given -this field: - -```proto -map weight = 1; -``` - -You can do the following with the generated code: - -```php -$m->getWeight()[1] = 1; -``` - -## Enumerations {#enum} - -PHP doesn't have native enums, so instead the protocol buffer compiler generates -a PHP class for each enum type in your `.proto` file, just like for -[messages](#message), with constants defined for each value. So, given this -enum: - -```proto -enum TestEnum { - Default = 0; - A = 1; -} -``` - -The compiler generates the following class: - -```php -class TestEnum { - const DEFAULT = 0; - const A = 1; -} -``` - -Also as with messages, a nested enum will result in a PHP class of the same name -prefixed by its containing message(s) and separated with underscores, as PHP -does not support nested classes. - -```php -class TestMessage_NestedEnum {...} -``` - -If an enum class or value name is reserved (for example, `Empty`), the prefix -`PB` is prepended to the class or value name: - -```php -class PBEmpty { - const PBECHO = 0; -} -``` - -We have also provided the file level option `php_class_prefix`. If this is -specified, it is prepended to all generated enum classes. - -## Oneof - -For a [oneof](/programming-guides/editions#oneof), the -protocol buffer compiler generates a `has` and `clear` method for each field in -the oneof, as well as a special accessor method that lets you find out which -oneof field (if any) is set. So, given this message: - -```proto -message TestMessage { - oneof test_oneof { - int32 oneof_int32 = 1; - int64 oneof_int64 = 2; - } -} -``` - -The compiler generates the following fields and special method: - -```php -class TestMessage { - private oneof_int32; - private oneof_int64; - public function getOneofInt32(); - public function setOneofInt32($var); - public function getOneofInt64(); - public function setOneofInt64($var); - public function getTestOneof(); // Return field name -} -``` - -The accessor method's name is based on the oneof's name, and returns a string -representing the field in the oneof that is currently set. If the oneof is not -set, the method returns an empty string. - -When you set a field in a oneof, it automatically clears all other fields in the -oneof. If you want to set multiple fields in a oneof, you must do so in separate -statements. - -```php -$m = new TestMessage(); -$m->setOneofInt32(42); // $m->hasOneofInt32() is true -$m->setOneofInt64(123); // $m->hasOneofInt32() is now false -``` diff --git a/content/reference/protobuf/_index.md b/content/reference/protobuf/_index.md deleted file mode 100644 index b28b99303..000000000 --- a/content/reference/protobuf/_index.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "Protocol Buffers Reference" -weight = 790 -linkTitle = "Protocol Buffers" -description = "Language-agnostic information about how to use protocol buffers." -type = "docs" -+++ diff --git a/content/reference/protobuf/edition-2023-spec.md b/content/reference/protobuf/edition-2023-spec.md deleted file mode 100644 index 02d485d60..000000000 --- a/content/reference/protobuf/edition-2023-spec.md +++ /dev/null @@ -1,422 +0,0 @@ -+++ -title = "Protocol Buffers Edition 2023 Language Specification" -weight = 800 -linkTitle = "2023 Language Specification" -description = "Language specification reference for edition 2023 of the Protocol Buffers language." -type = "docs" -+++ - -The syntax is specified using -[Extended Backus-Naur Form (EBNF)](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form): - -``` -| alternation -() grouping -[] option (zero or one time) -{} repetition (any number of times) -``` - -## Lexical Elements {#lexical_elements} - -### Letters and Digits {#letters_and_digits} - -``` -letter = "A" ... "Z" | "a" ... "z" -capitalLetter = "A" ... "Z" -decimalDigit = "0" ... "9" -octalDigit = "0" ... "7" -hexDigit = "0" ... "9" | "A" ... "F" | "a" ... "f" -``` - -### Identifiers - -``` -ident = letter { letter | decimalDigit | "_" } -fullIdent = ident { "." ident } -messageName = ident -enumName = ident -fieldName = ident -oneofName = ident -mapName = ident -serviceName = ident -rpcName = ident -streamName = ident -messageType = [ "." ] { ident "." } messageName -enumType = [ "." ] { ident "." } enumName -groupName = capitalLetter { letter | decimalDigit | "_" } -``` - -### Integer Literals {#integer_literals} - -``` -intLit = decimalLit | octalLit | hexLit -decimalLit = [-] ( "1" ... "9" ) { decimalDigit } -octalLit = [-] "0" { octalDigit } -hexLit = [-] "0" ( "x" | "X" ) hexDigit { hexDigit } -``` - -### Floating-point Literals - -``` -floatLit = [-] ( decimals "." [ decimals ] [ exponent ] | decimals exponent | "."decimals [ exponent ] ) | "inf" | "nan" -decimals = [-] decimalDigit { decimalDigit } -exponent = ( "e" | "E" ) [ "+" | "-" ] decimals -``` - -### Boolean - -``` -boolLit = "true" | "false" -``` - -### String Literals {#string_literals} - -``` -strLit = strLitSingle { strLitSingle } -strLitSingle = ( "'" { charValue } "'" ) | ( '"' { charValue } '"' ) -charValue = hexEscape | octEscape | charEscape | unicodeEscape | unicodeLongEscape | /[^\0\n\\]/ -hexEscape = '\' ( "x" | "X" ) hexDigit [ hexDigit ] -octEscape = '\' octalDigit [ octalDigit [ octalDigit ] ] -charEscape = '\' ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | '\' | "'" | '"' ) -unicodeEscape = '\' "u" hexDigit hexDigit hexDigit hexDigit -unicodeLongEscape = '\' "U" ( "000" hexDigit hexDigit hexDigit hexDigit hexDigit | - "0010" hexDigit hexDigit hexDigit hexDigit -``` - -### EmptyStatement - -``` -emptyStatement = ";" -``` - -### Constant - -``` -constant = fullIdent | ( [ "-" | "+" ] intLit ) | ( [ "-" | "+" ] floatLit ) | - strLit | boolLit | MessageValue -``` - -`MessageValue` is defined in the -[Text Format Language Specification](/reference/protobuf/textformat-spec#fields). - -## Edition - -The edition statement replaces the legacy `syntax` keyword, and is used to -define the edition that this file is using. - -``` -edition = "edition" "=" [ ( "'" decimalLit "'" ) | ( '"' decimalLit '"' ) ] ";" -``` - -## Import Statement {#import_statement} - -The import statement is used to import another .proto's definitions. - -``` -import = "import" [ "weak" | "public" ] strLit ";" -``` - -Example: - -```proto -import public "other.proto"; -``` - -## Package - -The package specifier can be used to prevent name clashes between protocol -message types. - -``` -package = "package" fullIdent ";" -``` - -Example: - -```proto -package foo.bar; -``` - -## Option - -Options can be used in proto files, messages, enums and services. An option can -be a protobuf defined option or a custom option. For more information, see -[Options](/programming-guides/proto2#options) in the -language guide. Options are also be used to control -[Feature Settings](/editions/features). - -``` -option = "option" optionName "=" constant ";" -optionName = ( ident | "(" ["."] fullIdent ")" ) -``` - -For examples: - -```proto -option java_package = "com.example.foo"; -option features.enum_type = CLOSED; -``` - -## Fields - -Fields are the basic elements of a protocol buffer message. Fields can be normal -fields, group fields, oneof fields, or map fields. A field has a label, type and -field number. - -``` -label = [ "repeated" ] -type = "double" | "float" | "int32" | "int64" | "uint32" | "uint64" - | "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64" - | "bool" | "string" | "bytes" | messageType | enumType -fieldNumber = intLit; -``` - -### Normal field {#normal_field} - -Each field has a label, type, name, and field number. It may have field options. - -``` -field = [label] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";" -fieldOptions = fieldOption { "," fieldOption } -fieldOption = optionName "=" constant -``` - -Examples: - -```proto -foo.bar nested_message = 2; -repeated int32 samples = 4 [packed=true]; -``` - -### Oneof and oneof field {#oneof_and_oneof_field} - -A oneof consists of oneof fields and a oneof name. Oneof fields do not have -labels. - -``` -oneof = "oneof" oneofName "{" { option | oneofField } "}" -oneofField = type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";" -``` - -Example: - -```proto -oneof foo { - string name = 4; - SubMessage sub_message = 9; -} -``` - -### Map field {#map_field} - -A map field has a key type, value type, name, and field number. The key type can -be any integral or string type. Note, the key type may not be an enum. - -``` -mapField = "map" "<" keyType "," type ">" mapName "=" fieldNumber [ "[" fieldOptions "]" ] ";" -keyType = "int32" | "int64" | "uint32" | "uint64" | "sint32" | "sint64" | - "fixed32" | "fixed64" | "sfixed32" | "sfixed64" | "bool" | "string" -``` - -Example: - -```proto -map projects = 3; -``` - -## Extensions and Reserved {#extensions_and_reserved} - -Extensions and reserved are message elements that declare a range of field -numbers or field names. - -### Extensions - -Extensions declare that a range of field numbers in a message are available for -third-party extensions. Other people can declare new fields for your message -type with those numeric tags in their own .proto files without having to edit -the original file. - -``` -extensions = "extensions" ranges ";" -ranges = range { "," range } -range = intLit [ "to" ( intLit | "max" ) ] -``` - -Examples: - -```proto -extensions 100 to 199; -extensions 4, 20 to max; -``` - -### Reserved - -Reserved declares a range of field numbers or names in a message or enum that -can't be used. - -``` -reserved = "reserved" ( ranges | reservedIdent ) ";" -fieldNames = fieldName { "," fieldName } -``` - -Examples: - -```proto -reserved 2, 15, 9 to 11; -reserved foo, bar; -``` - -## Top Level definitions {#top_level_definitions} - -### Enum definition {#enum_definition} - -The enum definition consists of a name and an enum body. The enum body can have -options, enum fields, and reserved statements. - -``` -enum = "enum" enumName enumBody -enumBody = "{" { option | enumField | emptyStatement | reserved } "}" -enumField = fieldName "=" [ "-" ] intLit [ "[" enumValueOption { "," enumValueOption } "]" ]";" -enumValueOption = optionName "=" constant -``` - -Example: - -```proto -enum EnumAllowingAlias { - option allow_alias = true; - EAA_UNSPECIFIED = 0; - EAA_STARTED = 1; - EAA_RUNNING = 2 [(custom_option) = "hello world"]; -} -``` - -### Message definition {#message_definition} - -A message consists of a message name and a message body. The message body can -have fields, nested enum definitions, nested message definitions, extend -statements, extensions, groups, options, oneofs, map fields, and reserved -statements. A message cannot contain two fields with the same name in the same -message schema. - -``` -message = "message" messageName messageBody -messageBody = "{" { field | enum | message | extend | extensions | group | -option | oneof | mapField | reserved | emptyStatement } "}" -``` - -Example: - -```proto -message Outer { - option (my_option).a = true; - message Inner { // Level 2 - required int64 ival = 1; - } - map my_map = 2; - extensions 20 to 30; -} -``` - -None of the entities declared inside a message may have conflicting names. All -of the following are prohibited: - -``` -message MyMessage { - string foo = 1; - message foo {} -} - -message MyMessage { - string foo = 1; - oneof foo { - string bar = 2; - } -} - -message MyMessage { - string foo = 1; - extend Extendable { - string foo = 2; - } -} - -message MyMessage { - string foo = 1; - enum E { - foo = 0; - } -} -``` - -### Extend - -If a message in the same or imported .proto file has reserved a range for -extensions, the message can be extended. - -``` -extend = "extend" messageType "{" {field | group} "}" -``` - -Example: - -```proto -extend Foo { - int32 bar = 126; -} -``` - -### Service definition {#service_definition} - -``` -service = "service" serviceName "{" { option | rpc | emptyStatement } "}" -rpc = "rpc" rpcName "(" [ "stream" ] messageType ")" "returns" "(" [ "stream" ] -messageType ")" (( "{" { option | emptyStatement } "}" ) | ";" ) -``` - -Example: - -```proto -service SearchService { - rpc Search (SearchRequest) returns (SearchResponse); -} -``` - -## Proto file {#proto_file} - -``` -proto = [syntax] { import | package | option | topLevelDef | emptyStatement } -topLevelDef = message | enum | extend | service -``` - -An example .proto file: - -```proto -edition = "2023"; -import public "other.proto"; -option java_package = "com.example.foo"; -enum EnumAllowingAlias { - option allow_alias = true; - EAA_UNSPECIFIED = 0; - EAA_STARTED = 1; - EAA_RUNNING = 1; - EAA_FINISHED = 2 [(custom_option) = "hello world"]; -} -message Outer { - option (my_option).a = true; - message Inner { // Level 2 - int64 ival = 1 [features.field_presence = LEGACY_REQUIRED]; - } - repeated Inner inner_message = 2; - EnumAllowingAlias enum_field = 3; - map my_map = 4; - extensions 20 to 30; - reserved reserved_field; -} -message Foo { - message GroupMessage { - bool a = 1; - } - GroupMessage groupmessage = [features.message_encoding = DELIMITED]; -} -``` diff --git a/content/reference/protobuf/edition-2024-spec.md b/content/reference/protobuf/edition-2024-spec.md deleted file mode 100644 index d802110ca..000000000 --- a/content/reference/protobuf/edition-2024-spec.md +++ /dev/null @@ -1,434 +0,0 @@ -+++ -title = "Protocol Buffers Edition 2024 Language Specification" -weight = 801 -linkTitle = "2024 Language Specification" -description = "Language specification reference for edition 2024 of the Protocol Buffers language." -type = "docs" -+++ - -The syntax is specified using -[Extended Backus-Naur Form (EBNF)](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form): - -``` -| alternation -() grouping -[] option (zero or one time) -{} repetition (any number of times) -``` - -## Lexical Elements {#lexical_elements} - -### Letters and Digits {#letters_and_digits} - -``` -letter = "A" ... "Z" | "a" ... "z" -capitalLetter = "A" ... "Z" -decimalDigit = "0" ... "9" -octalDigit = "0" ... "7" -hexDigit = "0" ... "9" | "A" ... "F" | "a" ... "f" -``` - -### Identifiers - -``` -ident = letter { letter | decimalDigit | "_" } -fullIdent = ident { "." ident } -messageName = ident -enumName = ident -fieldName = ident -oneofName = ident -mapName = ident -serviceName = ident -rpcName = ident -streamName = ident -messageType = [ "." ] { ident "." } messageName -enumType = [ "." ] { ident "." } enumName -groupName = capitalLetter { letter | decimalDigit | "_" } -``` - -### Integer Literals {#integer_literals} - -``` -intLit = decimalLit | octalLit | hexLit -decimalLit = [-] ( "1" ... "9" ) { decimalDigit } -octalLit = [-] "0" { octalDigit } -hexLit = [-] "0" ( "x" | "X" ) hexDigit { hexDigit } -``` - -### Floating-point Literals - -``` -floatLit = [-] ( decimals "." [ decimals ] [ exponent ] | decimals exponent | "."decimals [ exponent ] ) | "inf" | "nan" -decimals = [-] decimalDigit { decimalDigit } -exponent = ( "e" | "E" ) [ "+" | "-" ] decimals -``` - -### Boolean - -``` -boolLit = "true" | "false" -``` - -### String Literals {#string_literals} - -``` -strLit = strLitSingle { strLitSingle } -strLitSingle = ( "'" { charValue } "'" ) | ( '"' { charValue } '"' ) -charValue = hexEscape | octEscape | charEscape | unicodeEscape | unicodeLongEscape | /[^\0\n\\]/ -hexEscape = '\' ( "x" | "X" ) hexDigit [ hexDigit ] -octEscape = '\' octalDigit [ octalDigit [ octalDigit ] ] -charEscape = '\' ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | '\' | "'" | '"' ) -unicodeEscape = '\' "u" hexDigit hexDigit hexDigit hexDigit -unicodeLongEscape = '\' "U" ( "000" hexDigit hexDigit hexDigit hexDigit hexDigit | - "0010" hexDigit hexDigit hexDigit hexDigit -``` - -### EmptyStatement - -``` -emptyStatement = ";" -``` - -### Constant - -``` -constant = fullIdent | ( [ "-" | "+" ] intLit ) | ( [ "-" | "+" ] floatLit ) | - strLit | boolLit | MessageValue -``` - -`MessageValue` is defined in the -[Text Format Language Specification](/reference/protobuf/textformat-spec#fields). - -## Edition - -The edition statement replaces the legacy `syntax` keyword, and is used to -define the edition that this file is using. - -``` -edition = "edition" "=" [ ( "'" decimalLit "'" ) | ( '"' decimalLit '"' ) ] ";" -``` - -## Import Statement {#import_statement} - -The import statement is used to import another .proto's definitions. - -``` -import = "import" [ "public" | "option" ] strLit ";" -``` - -Example: - -```proto -import public "other.proto"; -import option "custom_option.proto"; -``` - -## Package - -The package specifier can be used to prevent name clashes between protocol -message types. - -``` -package = "package" fullIdent ";" -``` - -Example: - -```proto -package foo.bar; -``` - -## Option - -Options can be used in proto files, messages, enums and services. An option can -be a protobuf defined option or a custom option. For more information, see -[Options](/programming-guides/proto2#options) in the -language guide. Options are also be used to control -[Feature Settings](/editions/features). - -``` -option = "option" optionName "=" constant ";" -optionName = ( ident | "(" ["."] fullIdent ")" ) -``` - -For examples: - -```proto -option java_package = "com.example.foo"; -option features.enum_type = CLOSED; -``` - -## Fields - -Fields are the basic elements of a protocol buffer message. Fields can be normal -fields, group fields, oneof fields, or map fields. A field has a label, type and -field number. - -``` -label = [ "repeated" ] -type = "double" | "float" | "int32" | "int64" | "uint32" | "uint64" - | "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64" - | "bool" | "string" | "bytes" | messageType | enumType -fieldNumber = intLit; -``` - -### Normal field {#normal_field} - -Each field has a label, type, name, and field number. It may have field options. - -``` -field = [label] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";" -fieldOptions = fieldOption { "," fieldOption } -fieldOption = optionName "=" constant -``` - -Examples: - -```proto -foo.bar nested_message = 2; -repeated int32 samples = 4 [packed=true]; -``` - -### Oneof and oneof field {#oneof_and_oneof_field} - -A oneof consists of oneof fields and a oneof name. Oneof fields do not have -labels. - -``` -oneof = "oneof" oneofName "{" { option | oneofField } "}" -oneofField = type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";" -``` - -Example: - -```proto -oneof foo { - string name = 4; - SubMessage sub_message = 9; -} -``` - -### Map field {#map_field} - -A map field has a key type, value type, name, and field number. The key type can -be any integral or string type. Note, the key type may not be an enum. - -``` -mapField = "map" "<" keyType "," type ">" mapName "=" fieldNumber [ "[" fieldOptions "]" ] ";" -keyType = "int32" | "int64" | "uint32" | "uint64" | "sint32" | "sint64" | - "fixed32" | "fixed64" | "sfixed32" | "sfixed64" | "bool" | "string" -``` - -Example: - -```proto -map projects = 3; -``` - -## Extensions and Reserved {#extensions_and_reserved} - -Extensions and reserved are message elements that declare a range of field -numbers or field names. - -### Extensions - -Extensions declare that a range of field numbers in a message are available for -third-party extensions. Other people can declare new fields for your message -type with those numeric tags in their own .proto files without having to edit -the original file. - -``` -extensions = "extensions" ranges ";" -ranges = range { "," range } -range = intLit [ "to" ( intLit | "max" ) ] -``` - -Examples: - -```proto -extensions 100 to 199; -extensions 4, 20 to max; -``` - -### Reserved - -Reserved declares a range of field numbers or names in a message or enum that -can't be used. - -``` -reserved = "reserved" ( ranges | reservedIdent ) ";" -fieldNames = fieldName { "," fieldName } -``` - -Examples: - -```proto -reserved 2, 15, 9 to 11; -reserved foo, bar; -``` - -## Top Level definitions {#top_level_definitions} - -### Symbol Visibility {#symbol_visibility} - -Some message and enum definitions can be annotated to override their default -symbol visibility. - -This is controlled by [`features.default_symbol_visibility`](/editions/features/#symbol-vis) and symbol visibility is further documented in [export / local Keywords](/editions/overview/#export-local) - -``` -symbolVisibility = "export" | "local" -``` - -### Enum definition {#enum_definition} - -The enum definition consists of a name and an enum body. The enum body can have options, enum fields, and reserved statements. - -``` -enum = [ symbolVisibility ] "enum" enumName enumBody -enumBody = "{" { option | enumField | emptyStatement | reserved } "}" -enumField = fieldName "=" [ "-" ] intLit [ "[" enumValueOption { "," enumValueOption } "]" ]";" -enumValueOption = optionName "=" constant -``` - -Example: - -```proto -enum EnumAllowingAlias { - option allow_alias = true; - EAA_UNSPECIFIED = 0; - EAA_STARTED = 1; - EAA_RUNNING = 2 [(custom_option) = "hello world"]; -} -``` - -### Message definition {#message_definition} - -A message consists of a message name and a message body. The message body can -have fields, nested enum definitions, nested message definitions, extend -statements, extensions, groups, options, oneofs, map fields, and reserved -statements. A message cannot contain two fields with the same name in the same -message schema. - -``` -message = [ symbolVisibility ] "message" messageName messageBody -messageBody = "{" { field | enum | message | extend | extensions | group | -option | oneof | mapField | reserved | emptyStatement } "}" -``` - -Example: - -```proto -message Outer { - option (my_option).a = true; - message Inner { // Level 2 - required int64 ival = 1; - } - map my_map = 2; - extensions 20 to 30; -} -``` - -None of the entities declared inside a message may have conflicting names. All -of the following are prohibited: - -``` -message MyMessage { - string foo = 1; - message foo {} -} - -message MyMessage { - string foo = 1; - oneof foo { - string bar = 2; - } -} - -message MyMessage { - string foo = 1; - extend Extendable { - string foo = 2; - } -} - -message MyMessage { - string foo = 1; - enum E { - foo = 0; - } -} -``` - -### Extend - -If a message in the same or imported .proto file has reserved a range for -extensions, the message can be extended. - -``` -extend = "extend" messageType "{" {field | group} "}" -``` - -Example: - -```proto -extend Foo { - int32 bar = 126; -} -``` - -### Service definition {#service_definition} - -``` -service = "service" serviceName "{" { option | rpc | emptyStatement } "}" -rpc = "rpc" rpcName "(" [ "stream" ] messageType ")" "returns" "(" [ "stream" ] -messageType ")" (( "{" { option | emptyStatement } "}" ) | ";" ) -``` - -Example: - -```proto -service SearchService { - rpc Search (SearchRequest) returns (SearchResponse); -} -``` - -## Proto file {#proto_file} - -``` -proto = [syntax] { import | package | option | topLevelDef | emptyStatement } -topLevelDef = message | enum | extend | service -``` - -An example .proto file: - -```proto -edition = "2024"; -import public "other.proto"; -import option "custom_option.proto"; -option java_package = "com.example.foo"; -enum EnumAllowingAlias { - option allow_alias = true; - EAA_UNSPECIFIED = 0; - EAA_STARTED = 1; - EAA_RUNNING = 1; - EAA_FINISHED = 2 [(custom_option) = "hello world"]; -} -message Outer { - option (my_option).a = true; - message Inner { // Level 2 - int64 ival = 1 [features.field_presence = LEGACY_REQUIRED]; - } - repeated Inner inner_message = 2; - EnumAllowingAlias enum_field = 3; - map my_map = 4; - extensions 20 to 30; - reserved reserved_field; -} -message Foo { - message GroupMessage { - bool a = 1; - } - GroupMessage groupmessage = [features.message_encoding = DELIMITED]; -} -``` diff --git a/content/reference/protobuf/google.protobuf.md b/content/reference/protobuf/google.protobuf.md deleted file mode 100644 index ffac4498c..000000000 --- a/content/reference/protobuf/google.protobuf.md +++ /dev/null @@ -1,1515 +0,0 @@ -+++ -title = "Protocol Buffers Well-Known Types" -weight = 830 -linkTitle = "Well-Known Types" -description = "API documentation for the google.protobuf package." -type = "docs" -+++ - -## Index - -- [`Any`](#any) (message) -- [`Api`](#api) (message) -- [`BoolValue`](#bool-value) (message) -- [`BytesValue`](#bytes-value) (message) -- [`DoubleValue`](#double-value) (message) -- [`Duration`](#duration) (message) -- [`Empty`](#empty) (message) -- [`Enum`](#enum) (message) -- [`EnumValue`](#enum-value) (message) -- [`Field`](#field) (message) -- [`Field.Cardinality`](#field-cardinality) (enum) -- [`Field.Kind`](#field-kind) (enum) -- [`FieldMask`](#field-mask) (message) -- [`FloatValue`](#float-value) (message) -- [`Int32Value`](#int32-value) (message) -- [`Int64Value`](#int64-value) (message) -- [`ListValue`](#list-value) (message) -- [`Method`](#method) (message) -- [`Mixin`](#mixin) (message) -- [`NullValue`](#null-value) (enum) -- [`Option`](#option) (message) -- [`SourceContext`](#source-context) (message) -- [`StringValue`](#string-value) (message) -- [`Struct`](#struct) (message) -- [`Syntax`](#syntax) (enum) -- [`Timestamp`](#timestamp) (message) -- [`Type`](#type) (message) -- [`UInt32Value`](#uint32-value) (message) -- [`UInt64Value`](#uint64-value) (message) -- [`Value`](#value) (message) - -Well-Known Types that end in "`Value`" are wrapper messages for other types, -such as `BoolValue` and `EnumValue`. These are now obsolete. The only reasons to -use wrappers today would be: - -* Wire compatibility with messages that already use them. -* If you want to put a scalar value into an `Any` message. - -In most cases, there are better options: - -* For new messages, it's better to use regular explicit-presence fields - (`optional` in proto2/proto3, regular field in edition >= 2023). -* Extensions are generally a better option than `Any` fields. - -## Any {#any} - -`Any` contains an arbitrary serialized message along with a URL that describes -the type of the serialized message. - -#### JSON {#json} - -The JSON representation of an `Any` value uses the regular representation of the -deserialized, embedded message, with an additional field `@type` which contains -the type URL. Example: - -```proto -package google.profile; -message Person { - string first_name = 1; - string last_name = 2; -} -``` - -```json -{ - "@type": "type.googleapis.com/google.profile.Person", - "firstName": , - "lastName": -} -``` - -If the embedded message type is well-known and has a custom JSON representation, -that representation will be embedded adding a field `value` which holds the -custom JSON in addition to the `@type` field. Example (for message -`google.protobuf.Duration`): - -```json -{ - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "1.212s" -} -``` - - - - - - - - - - - - - - - - - - - - - -
Field nameTypeDescription
type_urlstring

A URL/resource name whose content describes the type of the serialized message.

For URLs which use the schema http, https, or no schema, the following restrictions and interpretations apply:

-
    -
  • If no schema is provided, https is assumed.
  • -
  • The last segment of the URL's path must represent the fully qualified name of the type (as in path/google.protobuf.Duration).
  • -
  • An HTTP GET on the URL must yield a google.protobuf.Type value in binary format, or produce an error.
  • -
  • Applications are allowed to cache lookup results based on the URL, or have them precompiled into a binary to avoid any lookup. Therefore, binary compatibility needs to be preserved on changes to types. (Use versioned type names to manage breaking changes.)
  • -

Schemas other than http, https (or the empty schema) might be used with implementation specific semantics.

valuebytesMust be valid serialized data of the above specified type.
- -## Api {#api} - -Api is a light-weight descriptor for a protocol buffer service. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Field nameTypeDescription
namestring - The fully qualified name of this api, including package name followed by - the api's simple name. -
methods - Method - The methods of this api, in unspecified order.
options -Option - Any metadata attached to the API.
versionstring -

- A version string for this api. If specified, must have the form - major-version.minor-version, as in 1.10. If - the minor version is omitted, it defaults to zero. If the entire - version field is empty, the major version is derived from the package - name, as outlined below. If the field is not empty, the version in the - package name will be verified to be consistent with what is provided - here. -

-

- The versioning schema uses - semantic versioning where the major - version number indicates a breaking change and the minor version an - additive, non-breaking change. Both version numbers are signals to - users what to expect from different versions, and should be carefully - chosen based on the product plan. -

-

- The major version is also reflected in the package name of the API, - which must end in v<major-version>, as in - google.feature.v1. For major versions 0 and 1, the suffix - can be omitted. Zero major versions must only be used for - experimental, none-GA apis. -

-
source_context - SourceContext - - Source context for the protocol buffer service represented by this - message. -
mixins - Mixin - - Included APIs. See - Mixin. -
syntax - Syntax - The source syntax of the service.
- -## BoolValue {#bool-value} - -Wrapper message for `bool`. - -The JSON representation for `BoolValue` is JSON `true` and `false`. - - - - - - - - - - - - - - - - -
Field nameTypeDescription
valueboolThe bool value.
- -## BytesValue {#bytes-value} - -Wrapper message for `bytes`. - -The JSON representation for `BytesValue` is JSON string. - - - - - - - - - - - - - - - - -
Field nameTypeDescription
valuebytesThe bytes value.
- -## DoubleValue {#double-value} - -Wrapper message for `double`. - -The JSON representation for `DoubleValue` is JSON number. - - - - - - - - - - - - - - - - -
Field nameTypeDescription
valuedoubleThe double value.
- -## Duration {#duration} - -A Duration represents a signed, fixed-length span of time represented as a count -of seconds and fractions of seconds at nanosecond resolution. It is independent -of any calendar and concepts like \"day\" or \"month\". It is related to -Timestamp in that the difference between two Timestamp values is a Duration and -it can be added or subtracted from a Timestamp. Range is approximately +-10,000 -years. - -Example 1: Compute Duration from two Timestamps in pseudo code. - -```c -Timestamp start = ...; -Timestamp end = ...; -Duration duration = ...; - -duration.seconds = end.seconds - start.seconds; -duration.nanos = end.nanos - start.nanos; - -if (duration.seconds < 0 && duration.nanos > 0) { - duration.seconds += 1; - duration.nanos -= 1000000000; -} else if (duration.seconds > 0 && duration.nanos < 0) { - duration.seconds -= 1; - duration.nanos += 1000000000; -} -``` - -Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. - -```c -Timestamp start = ...; -Duration duration = ...; -Timestamp end = ...; - -end.seconds = start.seconds + duration.seconds; -end.nanos = start.nanos + duration.nanos; - -if (end.nanos < 0) { - end.seconds -= 1; - end.nanos += 1000000000; -} else if (end.nanos >= 1000000000) { - end.seconds += 1; - end.nanos -= 1000000000; -} -``` - -The JSON representation for `Duration` is a `String` that ends in `s` to -indicate seconds and is preceded by the number of seconds, with nanoseconds -expressed as fractional seconds. - - - - - - - - - - - - - - - - - - - - - -
Field nameTypeDescription
secondsint64 - Signed seconds of the span of time. Must be from -315,576,000,000 to - +315,576,000,000 inclusive. -
nanosint32 - Signed fractions of a second at nanosecond resolution of the span of - time. Durations less than one second are represented with a 0 - seconds field and a positive or negative - nanos field. For durations of one second or more, a - non-zero value for the nanos field must be of the same sign - as the seconds field. Must be from -999,999,999 to - +999,999,999 inclusive. -
- -## Empty {#empty} - -A generic empty message that you can re-use to avoid defining duplicated empty -messages in your APIs. A typical example is to use it as the request or the -response type of an API method. For instance: - -```proto -service Foo { - rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); -} -``` - -The JSON representation for `Empty` is empty JSON object `{}`. - -## Enum {#enum} - -Enum type definition - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Field nameTypeDescription
namestringEnum type name.
enumvalue - EnumValue - Enum value definitions.
options - Option - Protocol buffer options.
source_context - SourceContext - The source context.
syntax - Syntax - The source syntax.
editionstring - The source edition if syntax is SYNTAX_EDITIONS.
- -## EnumValue {#enum-value} - -Enum value definition. - - - - - - - - - - - - - - - - - - - - - - - - - - -
Field nameTypeDescription
namestringEnum value name.
numberint32Enum value number.
options - Option - Protocol buffer options.
- -## Field {#field} - -A single field of a message type. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Field nameTypeDescription
kind - Kind - The field type.
cardinality - Cardinality - The field cardinality.
numberint32The field number.
namestringThe field name.
type_urlstring - The field type URL, without the scheme, for message or enumeration - types. Example: - "type.googleapis.com/google.protobuf.Timestamp". -
oneof_indexint32 - The index of the field type in Type.oneofs, for message or - enumeration types. The first type has index 1; zero means the type is - not in the list. -
packedboolWhether to use alternative packed wire representation.
options - Option - The protocol buffer options.
json_namestringThe field JSON name.
default_valuestring - The string value of the default value of this field. Proto2 syntax only. -
- -## Cardinality {#field-cardinality} - -Whether a field is optional, required, or repeated. - - - - - - - - - - - - - - - - - - - - - - - - - - -
Enum valueDescription
CARDINALITY_UNKNOWNFor fields with unknown cardinality.
CARDINALITY_OPTIONALFor optional fields.
CARDINALITY_REQUIREDFor required fields. Proto2 syntax only.
CARDINALITY_REPEATEDFor repeated fields.
- -## Kind {#field-kind} - -Basic field types. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Enum valueDescription
TYPE_UNKNOWNField type unknown.
TYPE_DOUBLEField type double.
TYPE_FLOATField type float.
TYPE_INT64Field type int64.
TYPE_UINT64Field type uint64.
TYPE_INT32Field type int32.
TYPE_FIXED64Field type fixed64.
TYPE_FIXED32Field type fixed32.
TYPE_BOOLField type bool.
TYPE_STRINGField type string.
TYPE_GROUPField type group. Proto2 syntax only, and deprecated.
TYPE_MESSAGEField type message.
TYPE_BYTESField type bytes.
TYPE_UINT32Field type uint32.
TYPE_ENUMField type enum.
TYPE_SFIXED32Field type sfixed32.
TYPE_SFIXED64Field type sfixed64.
TYPE_SINT32Field type sint32.
TYPE_SINT64Field type sint64.
- -## FieldMask {#field-mask} - -`FieldMask` represents a set of symbolic field paths, for example: - -```proto -paths: "f.a" -paths: "f.b.d" -``` - -Here `f` represents a field in some root message, `a` and `b` fields in the -message found in `f`, and `d` a field found in the message in `f.b`. - -Field masks are used to specify a subset of fields that should be returned by a -get operation (a *projection*), or modified by an update operation. Field masks -also have a custom JSON encoding (see below). - -#### Field Masks in Projections {#field-masks-projections} - -When a `FieldMask` specifies a *projection*, the API will filter the response -message (or sub-message) to contain only those fields specified in the mask. For -example, consider this \"pre-masking\" response message: - -```proto -f { - a : 22 - b { - d : 1 - x : 2 - } - y : 13 -} -z: 8 -``` - -After applying the mask in the previous example, the API response will not -contain specific values for fields x, y, or z (their value will be set to the -default, and omitted in proto text output): - -```proto -f { - a : 22 - b { - d : 1 - } -} -``` - -A repeated field is not allowed except at the last position of a field mask. - -If a `FieldMask` object is not present in a get operation, the operation applies -to all fields (as if a FieldMask of all fields had been specified). - -Note that a field mask does not necessarily apply to the top-level response -message. In case of a REST get operation, the field mask applies directly to the -response, but in case of a REST list operation, the mask instead applies to each -individual message in the returned resource list. In case of a REST custom -method, other definitions may be used. Where the mask applies will be clearly -documented together with its declaration in the API. In any case, the effect on -the returned resource/resources is required behavior for APIs. - -#### Field Masks in Update Operations {#field-masks-updates} - -A field mask in update operations specifies which fields of the targeted -resource are going to be updated. The API is required to only change the values -of the fields as specified in the mask and leave the others untouched. If a -resource is passed in to describe the updated values, the API ignores the values -of all fields not covered by the mask. - -In order to reset a field's value to the default, the field must be in the mask -and set to the default value in the provided resource. Hence, in order to reset -all fields of a resource, provide a default instance of the resource and set all -fields in the mask, or do not provide a mask as described below. - -If a field mask is not present on update, the operation applies to all fields -(as if a field mask of all fields has been specified). Note that in the presence -of schema evolution, this may mean that fields the client does not know and has -therefore not filled into the request will be reset to their default. If this is -unwanted behavior, a specific service may require a client to always specify a -field mask, producing an error if not. - -As with get operations, the location of the resource which describes the updated -values in the request message depends on the operation kind. In any case, the -effect of the field mask is required to be honored by the API. - -##### Considerations for HTTP REST {#http-rest} - -The HTTP kind of an update operation which uses a field mask must be set to -PATCH instead of PUT in order to satisfy HTTP semantics (PUT must only be used -for full updates). - -#### JSON Encoding of Field Masks {#json-encoding-field-masks} - -In JSON, a field mask is encoded as a single string where paths are separated by -a comma. Fields name in each path are converted to/from lower-camel naming -conventions. - -As an example, consider the following message declarations: - -```proto -message Profile { - User user = 1; - Photo photo = 2; -} -message User { - string display_name = 1; - string address = 2; -} -``` - -In proto a field mask for `Profile` may look as such: - -```proto -mask { - paths: "user.display_name" - paths: "photo" -} -``` - -In JSON, the same mask is represented as below: - -```json -{ - mask: "user.displayName,photo" -} -``` - - - - - - - - - - - - - - - - -
Field nameTypeDescription
pathsstringThe set of field mask paths.
- -## FloatValue {#float-value} - -Wrapper message for `float`. - -The JSON representation for `FloatValue` is JSON number. - - - - - - - - - - - - - - - - -
Field nameTypeDescription
valuefloatThe float value.
- -## Int32Value {#int32-value} - -Wrapper message for `int32`. - -The JSON representation for `Int32Value` is JSON number. - - - - - - - - - - - - - - - - -
Field nameTypeDescription
valueint32The int32 value.
- -## Int64Value {#int64-value} - -Wrapper message for `int64`. - -The JSON representation for `Int64Value` is JSON string. - - - - - - - - - - - - - - - - -
Field nameTypeDescription
valueint64The int64 value.
- -## ListValue {#list-value} - -`ListValue` is a wrapper around a repeated field of values. - -The JSON representation for `ListValue` is JSON array. - - - - - - - - - - - - - - - - -
Field nameTypeDescription
values - Value - Repeated field of dynamically typed values.
- -## Method {#method} - -Method represents a method of an api. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Field nameTypeDescription
namestringThe simple name of this method.
request_type_urlstringA URL of the input message type.
request_streamingboolIf true, the request is streamed.
response_type_urlstringThe URL of the output message type.
response_streamingboolIf true, the response is streamed.
options - Option - Any metadata attached to the method.
syntax - Syntax - The source syntax of this method.
- -## Mixin {#mixin} - -Declares an API to be included in this API. The including API must redeclare all -the methods from the included API, but documentation and options are inherited -as follows: - -- If after comment and whitespace stripping, the documentation string of the - redeclared method is empty, it will be inherited from the original method. - -- Each annotation belonging to the service config (http, visibility) which is - not set in the redeclared method will be inherited. - -- If an http annotation is inherited, the path pattern will be modified as - follows. Any version prefix will be replaced by the version of the including - API plus the `root` path if specified. - -Example of a simple mixin: - -```proto -package google.acl.v1; -service AccessControl { - // Get the underlying ACL object. - rpc GetAcl(GetAclRequest) returns (Acl) { - option (google.api.http).get = "/v1/{resource=**}:getAcl"; - } -} - -package google.storage.v2; -service Storage { - // rpc GetAcl(GetAclRequest) returns (Acl); - - // Get a data record. - rpc GetData(GetDataRequest) returns (Data) { - option (google.api.http).get = "/v2/{resource=**}"; - } -} -``` - -Example of a mixin configuration: - -``` -apis: -- name: google.storage.v2.Storage - mixins: - - name: google.acl.v1.AccessControl -``` - -The mixin construct implies that all methods in `AccessControl` are also -declared with same name and request/response types in `Storage`. A documentation -generator or annotation processor will see the effective `Storage.GetAcl` method -after inheriting documentation and annotations as follows: - -```proto -service Storage { - // Get the underlying ACL object. - rpc GetAcl(GetAclRequest) returns (Acl) { - option (google.api.http).get = "/v2/{resource=**}:getAcl"; - } - ... -} -``` - -Note how the version in the path pattern changed from `v1` to `v2`. - -If the `root` field in the mixin is specified, it should be a relative path -under which inherited HTTP paths are placed. Example: - -``` -apis: -- name: google.storage.v2.Storage - mixins: - - name: google.acl.v1.AccessControl - root: acls -``` - -This implies the following inherited HTTP annotation: - -```proto -service Storage { - // Get the underlying ACL object. - rpc GetAcl(GetAclRequest) returns (Acl) { - option (google.api.http).get = "/v2/acls/{resource=**}:getAcl"; - } - ... -} -``` - - - - - - - - - - - - - - - - - - - - - -
Field nameTypeDescription
namestringThe fully qualified name of the API which is included.
rootstring - If non-empty specifies a path under which inherited HTTP paths are - rooted. -
- -## NullValue {#null-value} - -`NullValue` is a singleton enumeration to represent the null value for the -`Value` type union. - -The JSON representation for `NullValue` is JSON `null`. - - - - - - - - - - - - - - -
Enum valueDescription
NULL_VALUENull value.
- -## Option {#option} - -A protocol buffer option, which can be attached to a message, field, -enumeration, etc. - - - - - - - - - - - - - - - - - - - - - -
Field nameTypeDescription
namestring - The option's name. For example, "java_package". -
value - Any - - The option's value. For example, - "com.google.protobuf". -
- -## SourceContext {#source-context} - -`SourceContext` represents information about the source of a protobuf element, -like the file in which it is defined. - - - - - - - - - - - - - - - - -
Field nameTypeDescription
file_namestring - The path-qualified name of the .proto file that contained the associated - protobuf element. For example: - "google/protobuf/source.proto". -
- -## StringValue {#string-value} - -Wrapper message for `string`. - -The JSON representation for `StringValue` is JSON string. - - - - - - - - - - - - - - - - -
Field nameTypeDescription
valuestringThe string value.
- -## Struct {#struct} - -`Struct` represents a structured data value, consisting of fields which map to -dynamically typed values. In some languages, `Struct` might be supported by a -native representation. For example, in scripting languages like JS a struct is -represented as an object. The details of that representation are described -together with the proto support for the language. - -The JSON representation for `Struct` is JSON object. - - - - - - - - - - - - - - - - -
Field nameTypeDescription
fields - map<string, Value> - Map of dynamically typed values.
- -## Syntax {#syntax} - -The syntax in which a protocol buffer element is defined. - - - - - - - - - - - - - - - - - - - - - - -
Enum valueDescription
SYNTAX_PROTO2Syntax proto2.
SYNTAX_PROTO3Syntax proto3.
SYNTAX_EDITIONSSyntax uses the edition construct.
- -## Timestamp {#timestamp} - -A Timestamp represents a point in time independent of any time zone or calendar, -represented as seconds and fractions of seconds at nanosecond resolution in UTC -Epoch time. It is encoded using the Proleptic Gregorian Calendar which extends -the Gregorian calendar backwards to year one. It is encoded assuming all minutes -are 60 seconds long, i.e. leap seconds are "smeared" so that no leap second -table is needed for interpretation. Range is from 0001-01-01T00:00:00Z to -9999-12-31T23:59:59.999999999Z. By restricting to that range, we ensure that we -can convert to and from RFC 3339 date strings. See -. - -The Timestamp type is encoded as a string in the RFC 3339 format: -"`{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z`", where `{year}` is -always expressed using four digits while `{month}`, `{day}`, `{hour}`, `{min}`, -and `{sec}` are zero-padded to two digits each. The fractional seconds, which -can go up to 9 digits (that is, up to 1 nanosecond resolution), are optional. -The "Z" suffix indicates the timezone ("UTC"); the timezone is required. A -proto3 JSON serializer should always use UTC (as indicated by "Z") when printing -the Timestamp type and a proto3 JSON parser should be able to accept both UTC -and other timezones (as indicated by an offset). - -Example 1: Compute Timestamp from POSIX `time()`. - -```cpp -Timestamp timestamp; -timestamp.set_seconds(time(NULL)); -timestamp.set_nanos(0); -``` - -Example 2: Compute Timestamp from POSIX `gettimeofday()`. - -```cpp -struct timeval tv; -gettimeofday(&tv, NULL); - -Timestamp timestamp; -timestamp.set_seconds(tv.tv_sec); -timestamp.set_nanos(tv.tv_usec * 1000); -``` - -Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. - -```cpp -FILETIME ft; -GetSystemTimeAsFileTime(&ft); -UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; - -// A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z -// is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. -Timestamp timestamp; -timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); -timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); -``` - -Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. - -```java -long millis = System.currentTimeMillis(); - -Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) - .setNanos((int) ((millis % 1000) * 1000000)).build(); -``` - -Example 5: Compute Timestamp from current time in Python. - -```py -now = time.time() -seconds = int(now) -nanos = int((now - seconds) * 10**9) -timestamp = Timestamp(seconds=seconds, nanos=nanos) -``` - - - - - - - - - - - - - - - - - - - - - -
Field nameTypeDescription
secondsint64 - Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. - Must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive. -
nanosint32 - Non-negative fractions of a second at nanosecond resolution. Negative - second values with fractions must still have non-negative nanos values - that count forward in time. Must be from 0 to 999,999,999 inclusive. -
- -## Type {#type} - -A protocol buffer message type. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Field nameTypeDescription
namestringThe fully qualified message name.
fields - Field - The list of fields.
oneofsstring - The list of types appearing in oneof definitions in this - type. -
options - Option - The protocol buffer options.
source_context - SourceContext - The source context.
syntax - Syntax - The source syntax.
- -## UInt32Value {#uint32-value} - -Wrapper message for `uint32`. - -The JSON representation for `UInt32Value` is JSON number. - - - - - - - - - - - - - - - - -
Field nameTypeDescription
valueuint32The uint32 value.
- -## UInt64Value {#uint64-value} - -Wrapper message for `uint64`. - -The JSON representation for `UInt64Value` is JSON string. - - - - - - - - - - - - - - - - -
Field nameTypeDescription
valueuint64The uint64 value.
- -## Value {#value} - -`Value` represents a dynamically typed value which can be either null, a number, -a string, a boolean, a recursive struct value, or a list of values. A producer -of value is expected to set one of that variants, absence of any variant -indicates an error. - -The JSON representation for `Value` is JSON value. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Field nameTypeDescription
Union field, only one of the following:
null_value - NullValue - Represents a null value.
number_valuedouble - Represents a double value. Note that attempting to serialize NaN or - Infinity results in error. (We can't serialize these as string "NaN" or - "Infinity" values like we do for regular fields, because they would - parse as string_value, not number_value). -
string_valuestringRepresents a string value.
bool_valueboolRepresents a boolean value.
struct_value - Struct - Represents a structured value.
list_value - ListValue - Represents a repeated Value.
diff --git a/content/reference/protobuf/mime-types.md b/content/reference/protobuf/mime-types.md deleted file mode 100644 index b290d4a19..000000000 --- a/content/reference/protobuf/mime-types.md +++ /dev/null @@ -1,50 +0,0 @@ -+++ -title = "Protocol Buffer MIME Types" -weight = 830 -linkTitle = "MIME Types" -description = "Standard MIME types for Protobuf Serializations." -type = "docs" -+++ - -All Protobuf documents should have the MIME type `application` and the subtype -`protobuf`, with the suffix `+json` for -JSON -encodings according to -[the standard](https://datatracker.ietf.org/doc/draft-murray-dispatch-mime-protobuf/), -followed by the following parameters: - -- `encoding` should be set only to `binary`, - or `json`, denoting those respective - formats. - + With subtype `protobuf+json`, `encoding` has the default `json` and - cannot be set to `binary`. With subtype `protobuf` (without `+json`), - `encoding` has the default `binary` and cannot be set to - `json`. - + Use `+json` for JSON even in HTTP responses that use parser - breakers as a CORB mitigation. -- Set `charset` to `utf-8` for all JSONor Text Format encodings, and never set - it for binary encodings. - + If `charset` is unspecified it is assumed to be UTF-8. It is preferable - to always specify a `charset` as that may prevent certain attack vectors - when protos are used in HTTP responses. -- Protobuf reserves the `version` parameter for potential future versioning of - our wire formats. Do not set it until a wire format is versioned. - -So the standard MIME types for common protobuf encodings are: - -- `application/protobuf` for serialized binary protos. -- `application/protobuf+json; charset=utf-8` for JSON format protos. - -Services that read Protobuf should also handle `application/json`, which may be -used to encode JSON format protos. - -Parsers must fail if MIME parameters (`encoding`, `charset`, or `version`) have -unknown or illegal values. - -When binary protos are transacted over HTTP, Protobuf strongly recommends -Base64-encoding them and setting `X-Content-Type-Options: nosniff` to prevent -XSS, as it is possible for a Protobuf to parse as active content. - -It is acceptable to pass additional parameters to these MIME types if desired, -such as a type URL which indicates the content schema; but the MIME type -parameters ***must not*** include encoding options. diff --git a/content/reference/protobuf/proto2-spec.md b/content/reference/protobuf/proto2-spec.md deleted file mode 100644 index 7325c46a7..000000000 --- a/content/reference/protobuf/proto2-spec.md +++ /dev/null @@ -1,452 +0,0 @@ -+++ -title = "Protocol Buffers Language Specification (Proto2 Syntax)" -weight = 800 -linkTitle = "Language Specification (Proto2 Syntax)" -description = "Language specification reference for the proto2 syntax and its relationship to Protobuf Editions." -type = "docs" -+++ - -The syntax is specified using -[Extended Backus-Naur Form (EBNF)](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form): - -``` -| alternation -() grouping -[] option (zero or one time) -{} repetition (any number of times) -``` - -For more information about using proto2, see the -[language guide](/programming-guides/proto2). - -## Lexical Elements {#lexical_elements} - -### Letters and Digits {#letters_and_digits} - -``` -letter = "A" ... "Z" | "a" ... "z" -capitalLetter = "A" ... "Z" -decimalDigit = "0" ... "9" -octalDigit = "0" ... "7" -hexDigit = "0" ... "9" | "A" ... "F" | "a" ... "f" -``` - -### Identifiers - -``` -ident = letter { letter | decimalDigit | "_" } -fullIdent = ident { "." ident } -messageName = ident -enumName = ident -fieldName = ident -oneofName = ident -mapName = ident -serviceName = ident -rpcName = ident -streamName = ident -messageType = [ "." ] { ident "." } messageName -enumType = [ "." ] { ident "." } enumName -groupName = capitalLetter { letter | decimalDigit | "_" } -``` - -### Integer Literals {#integer_literals} - -``` -intLit = decimalLit | octalLit | hexLit -decimalLit = [-] ( "1" ... "9" ) { decimalDigit } -octalLit = [-] "0" { octalDigit } -hexLit = [-] "0" ( "x" | "X" ) hexDigit { hexDigit } -``` - -### Floating-point Literals - -``` -floatLit = [-] ( decimals "." [ decimals ] [ exponent ] | decimals exponent | "."decimals [ exponent ] ) | "inf" | "nan" -decimals = [-] decimalDigit { decimalDigit } -exponent = ( "e" | "E" ) [ "+" | "-" ] decimals -``` - -### Boolean - -``` -boolLit = "true" | "false" -``` - -### String Literals {#string_literals} - -``` -strLit = strLitSingle { strLitSingle } -strLitSingle = ( "'" { charValue } "'" ) | ( '"' { charValue } '"' ) -charValue = hexEscape | octEscape | charEscape | unicodeEscape | unicodeLongEscape | /[^\0\n\\]/ -hexEscape = '\' ( "x" | "X" ) hexDigit [ hexDigit ] -octEscape = '\' octalDigit [ octalDigit [ octalDigit ] ] -charEscape = '\' ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | '\' | "'" | '"' ) -unicodeEscape = '\' "u" hexDigit hexDigit hexDigit hexDigit -unicodeLongEscape = '\' "U" ( "000" hexDigit hexDigit hexDigit hexDigit hexDigit | - "0010" hexDigit hexDigit hexDigit hexDigit -``` - -### EmptyStatement - -``` -emptyStatement = ";" -``` - -### Constant - -``` -constant = fullIdent | ( [ "-" | "+" ] intLit ) | ( [ "-" | "+" ] floatLit ) | - strLit | boolLit | MessageValue -``` - -`MessageValue` is defined in the -[Text Format Language Specification](/reference/protobuf/textformat-spec#fields). - -## Syntax - -The syntax statement is used to define the protobuf version. If `syntax` is -omitted, the protocol compiler will use `proto2`. For the sake of clarity, it's -recommended to always explicitly include a `syntax` statement in your `.proto` -files. - -``` -syntax = "syntax" "=" ("'" "proto2" "'" | '"' "proto2" '"') ";" -``` - -## Import Statement {#import_statement} - -The import statement is used to import another .proto's definitions. - -``` -import = "import" [ "weak" | "public" ] strLit ";" -``` - -Example: - -```proto -import public "other.proto"; -``` - -## Package - -The package specifier can be used to prevent name clashes between protocol -message types. - -``` -package = "package" fullIdent ";" -``` - -Example: - -```proto -package foo.bar; -``` - -## Option - -Options can be used in proto files, messages, enums and services. An option can -be a protobuf defined option or a custom option. For more information, see -[Options](/programming-guides/proto2#options) in the -language guide. - -``` -option = "option" optionName "=" constant ";" -optionName = ( ident | bracedFullIdent ) { "." ( ident | bracedFullIdent ) } -bracedFullIdent = "(" ["."] fullIdent ")" -``` - -For examples: - -```proto -option java_package = "com.example.foo"; -``` - -## Fields - -Fields are the basic elements of a protocol buffer message. Fields can be normal -fields, group fields, oneof fields, or map fields. A field has a type, name, and -field number. In proto2, fields also have a label (`required`, `optional`, or -`repeated`). - -``` -label = "required" | "optional" | "repeated" -type = "double" | "float" | "int32" | "int64" | "uint32" | "uint64" - | "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64" - | "bool" | "string" | "bytes" | messageType | enumType -fieldNumber = intLit; -``` - -### Normal field {#normal_field} - -Each field has a type, name and field number. It may have field options. Note -that labels are optional only for oneof fields. - -``` -field = [ label ] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";" -fieldOptions = fieldOption { "," fieldOption } -fieldOption = optionName "=" constant -``` - -Examples: - -```proto -optional foo.bar nested_message = 2; -repeated int32 samples = 4 [packed=true]; -``` - -### Group field {#group_field} - -**Note that this feature is deprecated and should not be used when creating new -message types. Use nested message types instead.** - -Groups are one way to nest information in message definitions. The group name -must begin with capital letter. - -``` -group = label "group" groupName "=" fieldNumber messageBody -``` - -Example: - -```proto -repeated group Result = 1 { - required string url = 1; - optional string title = 2; - repeated string snippets = 3; -} -``` - -### Oneof and oneof field {#oneof_and_oneof_field} - -A oneof consists of oneof fields and a oneof name. Oneof fields do not have -labels. - -``` -oneof = "oneof" oneofName "{" { option | oneofField } "}" -oneofField = type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";" -``` - -Example: - -```proto -oneof foo { - string name = 4; - SubMessage sub_message = 9; -} -``` - -### Map field {#map_field} - -A map field has a key type, value type, name, and field number. The key type can -be any integral or string type. Note, the key type may not be an enum. - -``` -mapField = "map" "<" keyType "," type ">" mapName "=" fieldNumber [ "[" fieldOptions "]" ] ";" -keyType = "int32" | "int64" | "uint32" | "uint64" | "sint32" | "sint64" | - "fixed32" | "fixed64" | "sfixed32" | "sfixed64" | "bool" | "string" -``` - -Example: - -```proto -map projects = 3; -``` - -## Extensions and Reserved {#extensions_and_reserved} - -Extensions and reserved are message elements that declare a range of field -numbers or field names. - -### Extensions - -Extensions declare that a range of field numbers in a message are available for -third-party extensions. Other people can declare new fields for your message -type with those numeric tags in their own .proto files without having to edit -the original file. - -``` -extensions = "extensions" ranges ";" -ranges = range { "," range } -range = intLit [ "to" ( intLit | "max" ) ] -``` - -Examples: - -```proto -extensions 100 to 199; -extensions 4, 20 to max; -``` - -For more on this topic, see -[Extension Declarations](/programming-guides/extension_declarations). - -### Reserved - -Reserved declares a range of field numbers or field names in a message that can -not be used. - -``` -reserved = "reserved" ( ranges | strFieldNames ) ";" -strFieldNames = strFieldName { "," strFieldName } -strFieldName = "'" fieldName "'" | '"' fieldName '"' -``` - -Examples: - -```proto -reserved 2, 15, 9 to 11; -reserved "foo", "bar"; -``` - -## Top Level definitions {#top_level_definitions} - -### Enum definition {#enum_definition} - -The enum definition consists of a name and an enum body. The enum body can have -options, enum fields, and reserved statements. - -``` -enum = "enum" enumName enumBody -enumBody = "{" { option | enumField | emptyStatement | reserved } "}" -enumField = ident "=" [ "-" ] intLit [ "[" enumValueOption { "," enumValueOption } "]" ]";" -enumValueOption = optionName "=" constant -``` - -Example: - -```proto -enum EnumAllowingAlias { - option allow_alias = true; - EAA_UNSPECIFIED = 0; - EAA_STARTED = 1; - EAA_RUNNING = 2 [(custom_option) = "hello world"]; -} -``` - -### Message definition {#message_definition} - -A message consists of a message name and a message body. The message body can -have fields, nested enum definitions, nested message definitions, extend -statements, extensions, groups, options, oneofs, map fields, and reserved -statements. A message cannot contain two fields with the same name in the same -message schema. - -``` -message = "message" messageName messageBody -messageBody = "{" { field | enum | message | extend | extensions | group | -option | oneof | mapField | reserved | emptyStatement } "}" -``` - -Example: - -```proto -message Outer { - option (my_option).a = true; - message Inner { // Level 2 - required int64 ival = 1; - } - map my_map = 2; - extensions 20 to 30; -} -``` - -None of the entities declared inside a message may have conflicting names. All -of the following are prohibited: - -``` -message MyMessage { - optional string foo = 1; - message foo {} -} - -message MyMessage { - optional string foo = 1; - oneof foo { - string bar = 2; - } -} - -message MyMessage { - optional string foo = 1; - extend Extendable { - optional string foo = 2; - } -} - -message MyMessage { - optional string foo = 1; - enum E { - foo = 0; - } -} -``` - -### Extend - -If a message in the same or imported .proto file has reserved a range for -extensions, the message can be extended. - -``` -extend = "extend" messageType "{" {field | group} "}" -``` - -Example: - -```proto -extend Foo { - optional int32 bar = 126; -} -``` - -### Service definition {#service_definition} - -``` -service = "service" serviceName "{" { option | rpc | emptyStatement } "}" -rpc = "rpc" rpcName "(" [ "stream" ] messageType ")" "returns" "(" [ "stream" ] -messageType ")" (( "{" { option | emptyStatement } "}" ) | ";" ) -``` - -Example: - -```proto -service SearchService { - rpc Search (SearchRequest) returns (SearchResponse); -} -``` - -## Proto file {#proto_file} - -``` -proto = [syntax] { import | package | option | topLevelDef | emptyStatement } -topLevelDef = message | enum | extend | service -``` - -An example `.proto` file: - -```proto -syntax = "proto2"; -import public "other.proto"; -option java_package = "com.example.foo"; -enum EnumAllowingAlias { - option allow_alias = true; - EAA_UNSPECIFIED = 0; - EAA_STARTED = 1; - EAA_RUNNING = 1; - EAA_FINISHED = 2 [(custom_option) = "hello world"]; -} -message Outer { - option (my_option).a = true; - message Inner { // Level 2 - required int64 ival = 1; - } - repeated Inner inner_message = 2; - optional EnumAllowingAlias enum_field = 3; - map my_map = 4; - extensions 20 to 30; -} -message Foo { - optional group GroupMessage = 1 { - optional bool a = 1; - } -} -``` diff --git a/content/reference/protobuf/proto3-spec.md b/content/reference/protobuf/proto3-spec.md deleted file mode 100644 index d4ad6dd62..000000000 --- a/content/reference/protobuf/proto3-spec.md +++ /dev/null @@ -1,368 +0,0 @@ -+++ -title = "Protocol Buffers Language Specification (Proto3)" -weight = 810 -linkTitle = "Language Specification (Proto3)" -description = "Language specification reference for the Protocol Buffers language (Proto3)." -type = "docs" -+++ - -The syntax is specified using -[Extended Backus-Naur Form (EBNF)](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form): - -``` -| alternation -() grouping -[] option (zero or one time) -{} repetition (any number of times) -``` - -For more information about using proto3, see the -[language guide](/programming-guides/proto3). - -## Lexical Elements {#lexical_elements} - -### Letters and Digits {#letters_and_digits} - -``` -letter = "A" ... "Z" | "a" ... "z" -decimalDigit = "0" ... "9" -octalDigit = "0" ... "7" -hexDigit = "0" ... "9" | "A" ... "F" | "a" ... "f" -``` - -### Identifiers - -``` -ident = letter { letter | decimalDigit | "_" } -fullIdent = ident { "." ident } -messageName = ident -enumName = ident -fieldName = ident -oneofName = ident -mapName = ident -serviceName = ident -rpcName = ident -messageType = [ "." ] { ident "." } messageName -enumType = [ "." ] { ident "." } enumName -``` - -### Integer Literals {#integer_literals} - -``` -intLit = decimalLit | octalLit | hexLit -decimalLit = [-] ( "1" ... "9" ) { decimalDigit } -octalLit = [-] "0" { octalDigit } -hexLit = [-] "0" ( "x" | "X" ) hexDigit { hexDigit } -``` - -### Floating-point Literals - -``` -floatLit = [-] ( decimals "." [ decimals ] [ exponent ] | decimals exponent | "."decimals [ exponent ] ) | "inf" | "nan" -decimals = [-] decimalDigit { decimalDigit } -exponent = ( "e" | "E" ) [ "+" | "-" ] decimals -``` - -### Boolean - -``` -boolLit = "true" | "false" -``` - -### String Literals {#string_literals} - -``` -strLit = strLitSingle { strLitSingle } -strLitSingle = ( "'" { charValue } "'" ) | ( '"' { charValue } '"' ) -charValue = hexEscape | octEscape | charEscape | unicodeEscape | unicodeLongEscape | /[^\0\n\\]/ -hexEscape = '\' ( "x" | "X" ) hexDigit [ hexDigit ] -octEscape = '\' octalDigit [ octalDigit [ octalDigit ] ] -charEscape = '\' ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | '\' | "'" | '"' ) -unicodeEscape = '\' "u" hexDigit hexDigit hexDigit hexDigit -unicodeLongEscape = '\' "U" ( "000" hexDigit hexDigit hexDigit hexDigit hexDigit | - "0010" hexDigit hexDigit hexDigit hexDigit -``` - -### EmptyStatement - -``` -emptyStatement = ";" -``` - -### Constant - -``` -constant = fullIdent | ( [ "-" | "+" ] intLit ) | ( [ "-" | "+" ] floatLit ) | - strLit | boolLit | MessageValue -``` - -`MessageValue` is defined in the -[Text Format Language Specification](/reference/protobuf/textformat-spec#fields). - -## Syntax - -The syntax statement is used to define the protobuf version. - -``` -syntax = "syntax" "=" ("'" "proto3" "'" | '"' "proto3" '"') ";" -``` - -Example: - -```proto -syntax = "proto3"; -``` - -## Import Statement {#import_statement} - -The import statement is used to import another .proto's definitions. - -``` -import = "import" [ "weak" | "public" ] strLit ";" -``` - -Example: - -```proto -import public "other.proto"; -``` - -## Package - -The package specifier can be used to prevent name clashes between protocol -message types. - -``` -package = "package" fullIdent ";" -``` - -Example: - -```proto -package foo.bar; -``` - -## Option - -Options can be used in proto files, messages, enums and services. An option can -be a protobuf defined option or a custom option. For more information, see -[Options](/programming-guides/proto3#options) in the -language guide. - -``` -option = "option" optionName "=" constant ";" -optionName = ( ident | bracedFullIdent ) { "." ( ident | bracedFullIdent ) } -bracedFullIdent = "(" ["."] fullIdent ")" -optionNamePart = { ident | "(" ["."] fullIdent ")" } -``` - -Example: - -```proto -option java_package = "com.example.foo"; -``` - -## Fields - -Fields are the basic elements of a protocol buffer message. Fields can be normal -fields, oneof fields, or map fields. A field has a type and field number. - -``` -type = "double" | "float" | "int32" | "int64" | "uint32" | "uint64" - | "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64" - | "bool" | "string" | "bytes" | messageType | enumType -fieldNumber = intLit; -``` - -### Normal Field {#normal_field} - -Each field has type, name and field number. It may have field options. - -``` -field = [ "repeated" | "optional" ] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";" -fieldOptions = fieldOption { "," fieldOption } -fieldOption = optionName "=" constant -``` - -Examples: - -```proto -foo.Bar nested_message = 2; -repeated int32 samples = 4 [packed=true]; -``` - -### Oneof and Oneof Field {#oneof_and_oneof_field} - -A oneof consists of oneof fields and a oneof name. - -``` -oneof = "oneof" oneofName "{" { option | oneofField } "}" -oneofField = type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";" -``` - -Example: - -```proto -oneof foo { - string name = 4; - SubMessage sub_message = 9; -} -``` - -### Map Field {#map_field} - -A map field has a key type, value type, name, and field number. The key type can -be any integral or string type. - -``` -mapField = "map" "<" keyType "," type ">" mapName "=" fieldNumber [ "[" fieldOptions "]" ] ";" -keyType = "int32" | "int64" | "uint32" | "uint64" | "sint32" | "sint64" | - "fixed32" | "fixed64" | "sfixed32" | "sfixed64" | "bool" | "string" -``` - -Example: - -```proto -map projects = 3; -``` - -## Reserved - -Reserved statements declare a range of field numbers or field names that cannot -be used in this message. - -``` -reserved = "reserved" ( ranges | strFieldNames ) ";" -ranges = range { "," range } -range = intLit [ "to" ( intLit | "max" ) ] -strFieldNames = strFieldName { "," strFieldName } -strFieldName = "'" fieldName "'" | '"' fieldName '"' -``` - -Examples: - -```proto -reserved 2, 15, 9 to 11; -reserved "foo", "bar"; -``` - -## Top Level Definitions {#top_level_definitions} - -### Enum Definition {#enum_definition} - -The enum definition consists of a name and an enum body. The enum body can have -options, enum fields, and reserved statements. - -``` -enum = "enum" enumName enumBody -enumBody = "{" { option | enumField | emptyStatement | reserved } "}" -enumField = ident "=" [ "-" ] intLit [ "[" enumValueOption { "," enumValueOption } "]" ]";" -enumValueOption = optionName "=" constant -``` - -Example: - -```proto -enum EnumAllowingAlias { - option allow_alias = true; - EAA_UNSPECIFIED = 0; - EAA_STARTED = 1; - EAA_RUNNING = 2 [(custom_option) = "hello world"]; -} -``` - -### Message Definition {#message_definition} - -A message consists of a message name and a message body. The message body can -have fields, nested enum definitions, nested message definitions, options, -oneofs, map fields, and reserved statements. A message cannot contain two fields -with the same name in the same message schema. - -``` -message = "message" messageName messageBody -messageBody = "{" { field | enum | message | option | oneof | mapField | -reserved | emptyStatement } "}" -``` - -Example: - -```proto -message Outer { - option (my_option).a = true; - message Inner { // Level 2 - int64 ival = 1; - } - map my_map = 2; -} -``` - -None of the entities declared inside a message may have conflicting names. All -of the following are prohibited: - -``` -message MyMessage { - optional string foo = 1; - message foo {} -} - -message MyMessage { - optional string foo = 1; - oneof foo { - string bar = 2; - } -} - -message MyMessage { - optional string foo = 1; - enum E { - foo = 0; - } -} -``` - -### Service Definition {#service_definition} - -``` -service = "service" serviceName "{" { option | rpc | emptyStatement } "}" -rpc = "rpc" rpcName "(" [ "stream" ] messageType ")" "returns" "(" [ "stream" ] -messageType ")" (( "{" {option | emptyStatement } "}" ) | ";") -``` - -Example: - -```proto -service SearchService { - rpc Search (SearchRequest) returns (SearchResponse); -} -``` - -## Proto File {#proto_file} - -``` -proto = [syntax] { import | package | option | topLevelDef | emptyStatement } -topLevelDef = message | enum | service -``` - -An example .proto file: - -```proto -syntax = "proto3"; -import public "other.proto"; -option java_package = "com.example.foo"; -enum EnumAllowingAlias { - option allow_alias = true; - EAA_UNSPECIFIED = 0; - EAA_STARTED = 1; - EAA_RUNNING = 1; - EAA_FINISHED = 2 [(custom_option) = "hello world"]; -} -message Outer { - option (my_option).a = true; - message Inner { // Level 2 - int64 ival = 1; - } - repeated Inner inner_message = 2; - EnumAllowingAlias enum_field = 3; - map my_map = 4; -} -``` diff --git a/content/reference/protobuf/textformat-spec.md b/content/reference/protobuf/textformat-spec.md deleted file mode 100644 index 0ff0cc29c..000000000 --- a/content/reference/protobuf/textformat-spec.md +++ /dev/null @@ -1,768 +0,0 @@ -+++ -title = "Text Format Language Specification" -weight = 820 -description = "The protocol buffer Text Format Language specifies a syntax for representation of protobuf data in text form, which is often useful for configurations or tests." -type = "docs" -+++ - -This format is distinct from the format of text -within a `.proto` schema, for example. This document contains reference -documentation using the syntax specified in -[ISO/IEC 14977 EBNF](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form). - -{{% alert title="Note" color="note" %}} -This is a draft spec originally reverse-engineered from the C++ text format -[implementation](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/text_format.cc) -It has evolved and may change further based on discussion and review. While an -effort has been made to keep text formats consistent across supported languages, -incompatibilities are likely to exist. {{% /alert %}} - -## Example {#example} - -```textproto -convolution_benchmark { - label: "NHWC_128x20x20x56x160" - input { - dimension: [128, 56, 20, 20] - data_type: DATA_HALF - format: TENSOR_NHWC - } -} -``` - -## Parsing Overview {#parsing} - -The language elements in this spec are split into lexical and syntactic -categories. Lexical elements must match the input text exactly as described, but -syntactic elements may be separated by optional `WHITESPACE` and `COMMENT` -tokens. - -For example, a signed floating point value comprises two syntactic elements: the -sign (`-`) and the `FLOAT` literal. Optional whitespace and comments may exist -between the sign and the number, but not within the number. Example: - -```textproto -value: -2.0 # Valid: no additional whitespace. -value: - 2.0 # Valid: whitespace between '-' and '2.0'. -value: - - # comment - 2.0 # Valid: whitespace and comments between '-' and '2.0'. -value: 2 . 0 # Invalid: the floating point period is part of the lexical - # element, so no additional whitespace is allowed. -``` - -There is one edge case that requires special attention: a number token (`FLOAT`, -`DEC_INT`, `OCT_INT`, or `HEX_INT`) may not be immediately followed by an -`IDENT` token. Example: - -```textproto -foo: 10 bar: 20 # Valid: whitespace separates '10' and 'bar' -foo: 10,bar: 20 # Valid: ',' separates '10' and 'bar' -foo: 10[com.foo.ext]: 20 # Valid: '10' is followed immediately by '[', which is - # not an identifier. -foo: 10bar: 20 # Invalid: no space between '10' and identifier 'bar'. -``` - -## Lexical Elements {#lexical} - -The lexical elements described below fall into two categories: uppercase primary -elements and lowercase fragments. Only primary elements are included in the -output stream of tokens used during syntactic analysis; fragments exist only to -simplify construction of primary elements. - -When parsing input text, the longest matching primary element wins. Example: - -```textproto -value: 10 # '10' is parsed as a DEC_INT token. -value: 10f # '10f' is parsed as a FLOAT token, despite containing '10' which - # would also match DEC_INT. In this case, FLOAT matches a longer - # subsequence of the input. -``` - -### Characters {#characters} - -``` -char = ? Any non-NUL unicode character ? ; -newline = ? ASCII #10 (line feed) ? ; - -letter = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" - | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" - | "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" - | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" - | "_" ; - -oct = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" ; -dec = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; -hex = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" - | "A" | "B" | "C" | "D" | "E" | "F" - | "a" | "b" | "c" | "d" | "e" | "f" ; -``` - -A limited set of URL characters following -[RFC 3986: Uniform Resource Identifier (URI)](https://www.rfc-editor.org/rfc/rfc3986#appendix-A): - -``` -url_unreserved = letter | dec | "-" | "." | "~" | "_" -url_sub_delim = "!" | "$" | "&" | "(" | ")" - | "*" | "+" | "," | ";" | "=" -url_pct_encoded = "%" hex hex -url_char = url_unreserved | url_sub_delim | url_pct_encoded -``` - -### Whitespace and Comments {#whitespace} - -``` -COMMENT = "#", { char - newline }, [ newline ] ; -WHITESPACE = " " - | newline - | ? ASCII #9 (horizontal tab) ? - | ? ASCII #11 (vertical tab) ? - | ? ASCII #12 (form feed) ? - | ? ASCII #13 (carriage return) ? ; -``` - -### Identifiers {#identifiers} - -``` -IDENT = letter, { letter | dec } ; -``` - -### Numeric Literals {#numeric} - -``` -dec_lit = "0" - | ( dec - "0" ), { dec } ; -float_lit = ".", dec, { dec }, [ exp ] - | dec_lit, ".", { dec }, [ exp ] - | dec_lit, exp ; -exp = ( "E" | "e" ), [ "+" | "-" ], dec, { dec } ; - -DEC_INT = dec_lit -OCT_INT = "0", oct, { oct } ; -HEX_INT = "0", ( "X" | "x" ), hex, { hex } ; -FLOAT = float_lit, [ "F" | "f" ] - | dec_lit, ( "F" | "f" ) ; -``` - -Decimal integers can be cast as floating-point values by using the `F` and `f` -suffixes. Example: - -```textproto -foo: 10 # This is an integer value. -foo: 10f # This is a floating-point value. -foo: 1.0f # Also optional for floating-point literals. -``` - -### String Literals {#string} - -``` -STRING = single_string | double_string ; -single_string = "'", { escape | char - "'" - newline - "\" }, "'" ; -double_string = '"', { escape | char - '"' - newline - "\" }, '"' ; - -escape = "\a" (* ASCII #7 (bell) *) - | "\b" (* ASCII #8 (backspace) *) - | "\f" (* ASCII #12 (form feed) *) - | "\n" (* ASCII #10 (line feed) *) - | "\r" (* ASCII #13 (carriage return) *) - | "\t" (* ASCII #9 (horizontal tab) *) - | "\v" (* ASCII #11 (vertical tab) *) - | "\?" (* ASCII #63 (question mark) *) - | "\\" (* ASCII #92 (backslash) *) - | "\'" (* ASCII #39 (apostrophe) *) - | '\"' (* ASCII #34 (quote) *) - | "\", oct, [ oct, [ oct ] ] (* octal escaped byte value *) - | "\x", hex, [ hex ] (* hexadecimal escaped byte value *) - | "\u", hex, hex, hex, hex (* Unicode code point up to 0xffff *) - | "\U000", - hex, hex, hex, hex, hex (* Unicode code point up to 0xfffff *) - | "\U0010", - hex, hex, hex, hex ; (* Unicode code point between 0x100000 and 0x10ffff *) -``` - -Octal escape sequences consume up to three octal digits. Additional digits are -passed through without escaping. For example, when unescaping the input `\1234`, -the parser consumes three octal digits (123) to unescape the byte value 0x53 -(ASCII 'S', 83 in decimal) and the subsequent '4' passes through as the byte -value 0x34 (ASCII '4'). To ensure correct parsing, express octal escape -sequences with 3 octal digits, using leading zeros as needed, such as: `\000`, -`\001`, `\063`, `\377`. Fewer than three digits are consumed when a non-numeric -character follows the numeric characters, such as `\5Hello`. - -Hexadecimal escape sequences consume up to two hexadecimal digits. For example, -when unescaping `\x213`, the parser consumes only the first two digits (21) to -unescape the byte value 0x21 (ASCII '!'). To ensure correct parsing, express -hexadecimal escape sequences with 2 hexadecimal digits, using leading zeros as -needed, such as: `\x00`, `\x01`, `\xFF`. Fewer than two digits are consumed when -a non-hexadecimal character follows the numeric character, such as `\xFHello` or -`\x3world`. - -Use byte-wise escaping only for fields with type `bytes`. While it is possible -to use byte-wise escaping in fields with type `string`, those escape sequences -are required to form valid UTF-8 sequences. Using byte-wise escaping to express -UTF-8 sequences is error-prone. Prefer unicode escape sequences for unprintable -characters and line-breaking characters in literals for `string`-type fields. - -Longer strings can be broken into several quoted strings on successive lines. -For example: - -```proto - quote: - "When we got into office, the thing that surprised me most was to find " - "that things were just as bad as we'd been saying they were.\n\n" - " -- John F. Kennedy" -``` - -Unicode code points are interpreted per -[Unicode 13 Table A-1 Extended BNF](https://www.unicode.org/versions/Unicode13.0.0/appA.pdf#page=5) -and are encoded as UTF-8. - -{{% alert title="Warning" color="warning" %}} The -C++ implementation currently interprets escaped high-surrogate code points as -UTF-16 code units, and expects a `\uHHHH` low-surrogate code point to -immediately follow, without any split across separate quoted strings. In -addition, unpaired surrogates will be rendered directly into also-invalid UTF-8. -These are both non-conforming behaviors[^surrogates] and should not be relied -on. {{% /alert %}} - -[^surrogates]: See Unicode 13 - [§3.8 Surrogates](https://www.unicode.org/versions/Unicode13.0.0/ch03.pdf#page=48), - [§3.2 Conformance Requirements, C1](https://www.unicode.org/versions/Unicode13.0.0/ch03.pdf#page=8) - and - [§3.9 Unicode Encoding Forms, D92](https://www.unicode.org/versions/Unicode13.0.0/ch03.pdf#page=54). - -## Syntax Elements {#syntax} - -### Message {#message} - -A message is a collection of fields. A text format file is a single Message. - -``` -Message = { Field } ; -``` - -### Literals {#literals} - -Field literal values can be numbers, strings, or identifiers such as `true` or -enum values. - -``` -String = STRING, { STRING } ; -Float = [ "-" ], FLOAT ; -Identifier = IDENT ; -SignedIdentifier = "-", IDENT ; (* For example, "-inf" *) -DecSignedInteger = "-", DEC_INT ; -OctSignedInteger = "-", OCT_INT ; -HexSignedInteger = "-", HEX_INT ; -DecUnsignedInteger = DEC_INT ; -OctUnsignedInteger = OCT_INT ; -HexUnsignedInteger = HEX_INT ; -``` - -A single string value can comprise multiple quoted parts separated by optional -whitespace. Example: - -```textproto -a_string: "first part" 'second part' - "third part" -no_whitespace: "first""second"'third''fourth' -``` - -### Field Names {#field-names} - -Fields that are part of the containing message use simple `Identifiers` as -names. -[`Extension`](/programming-guides/proto2#extensions) and -[`Any`](/programming-guides/proto3#any) field names are -wrapped in square brackets and fully-qualified. `Any` field names are URI suffix -references, meaning that they are prefixed with a qualifying authority and an -optional path, such as `type.googleapis.com/`. - -``` -FieldName = ExtensionName | AnyName | IDENT ; -ExtensionName = "[", TypeName, "]" ; -AnyName = "[", UrlPrefix, "/", TypeName, "]" ; -TypeName = IDENT, { ".", IDENT } ; -UrlPrefix = url_char, { url_char | "/" } ; -``` - -Text format serializers should not write any whitespace characters or comments -between the brackets of an `ExtensionName` or `AnyName`. Parsers should skip any -whitespace characters and comments between the brackets of an `ExtensionName` or -`AnyName`. This includes whitespace and comments which split the name into -multiple segments. - -Regular fields and extension fields can have scalar or message values. `Any` -fields are always messages. Example: - -```textproto -reg_scalar: 10 -reg_message { foo: "bar" } - -[com.foo.ext.scalar]​: 10 -[com.foo.ext.message] { foo: "bar" } - -any_value { - [type.googleapis.com/com.foo.any] { foo: "bar" } -} -``` - -#### Unknown Fields {#unknown-fields} - -Text format parsers cannot support unknown fields represented as raw field -numbers in place of field names because three of the six wire types are -represented in the same way in textformat. Some text-format serializer -implementations encode unknown fields with a format that uses a field number and -a numeric representation of the value, but this is inherently lossy because the -wire-type information is ignored. For comparison, wire-format is non-lossy -because it includes the wire-type in each field tag as `(field_number << 3) | -wire_type`. For more information on encoding, see the -[Encoding](/programming-guides/encoding.md) topic. - -Without information about the field type from the message schema, the value -cannot be correctly encoded into a wire-format proto message. - -### Fields {#fields} - -Field values can be literals (strings, numbers, or identifiers), or nested -messages. - -``` -Field = ScalarField | MessageField ; -MessageField = FieldName, [ ":" ], ( MessageValue | MessageList ) [ ";" | "," ]; -ScalarField = FieldName, ":", ( ScalarValue | ScalarList ) [ ";" | "," ]; -MessageList = "[", [ MessageValue, { ",", MessageValue } ], "]" ; -ScalarList = "[", [ ScalarValue, { ",", ScalarValue } ], "]" ; -MessageValue = "{", Message, "}" | "<", Message, ">" ; -ScalarValue = String - | Float - | Identifier - | SignedIdentifier - | DecSignedInteger - | OctSignedInteger - | HexSignedInteger - | DecUnsignedInteger - | OctUnsignedInteger - | HexUnsignedInteger ; -``` - -The `:` delimiter between the field name and value is required for scalar fields -but optional for message fields (including lists). Example: - -```textproto -scalar: 10 # Valid -scalar 10 # Invalid -scalars: [1, 2, 3] # Valid -scalars [1, 2, 3] # Invalid -message: {} # Valid -message {} # Valid -messages: [{}, {}] # Valid -messages [{}, {}] # Valid -``` - -Values of message fields can be surrounded by curly brackets -or angle brackets: - -```textproto -message: { foo: "bar" } -message: < foo: "bar" > -``` - -Fields marked `repeated` can have multiple values specified by repeating the -field, using the special `[]` list syntax, or some combination of both. The -order of values is maintained. Example: - -```textproto -repeated_field: 1 -repeated_field: 2 -repeated_field: [3, 4, 5] -repeated_field: 6 -repeated_field: [7, 8, 9] -``` - -is equivalent to: - -```textproto -repeated_field: [1, 2, 3, 4, 5, 6, 7, 8, 9] -``` - -Non-`repeated` fields cannot use the list syntax. For example, `[0]` is not -valid for `optional` or `required` fields. Fields marked `optional` can be -omitted or specified once. Fields marked `required` must be specified exactly -once. `required` is a legacy feature of proto2 and is not available in proto3. -Backward compatibility is available for messages in Editions using -[`features.field_presence = LEGACY_REQUIRED`](/editions/features#field_presence). - -Fields not specified in the associated *.proto* message are not allowed unless -the field name is present in the message's `reserved` field list. `reserved` -fields, if present in any form (scalar, list, message), are simply ignored by -text format. - -## Value Types {#value} - -When a field's associated *.proto* value type is known, the following value -descriptions and constraints apply. For the purposes of this section, we declare -the following container elements: - -``` -signedInteger = DecSignedInteger | OctSignedInteger | HexSignedInteger ; -unsignedInteger = DecUnsignedInteger | OctUnsignedInteger | HexUnsignedInteger ; -integer = signedInteger | unsignedInteger ; -``` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
.proto TypeValues
- float, double - - A Float, DecSignedInteger, or - DecUnsignedInteger element, or an Identifier - or SignedIdentifier element whose IDENT - portion is equal to "inf", "infinity", or - "nan" (case-insensitive). Overflows are treated as infinity or - -infinity. Octal and hexadecimal values are not valid. -

- Note: "nan" should be interpreted as Quiet NaN -

-
- int32, sint32, sfixed32 - - Any of the integer elements in the range - -0x80000000 to 0x7FFFFFFF. -
- int64, sint64, sfixed64 - - Any of the integer elements in the range - -0x8000000000000000 to 0x7FFFFFFFFFFFFFFF. -
- uint32, fixed32 - - Any of the unsignedInteger elements in the range - 0 to 0xFFFFFFFF. Note that signed values - (-0) are not valid. -
- uint64, fixed64 - - Any of the unsignedInteger elements in the range - 0 to 0xFFFFFFFFFFFFFFFF. Note that signed - values (-0) are not valid. -
- string - - A String element containing valid UTF-8 data. Any escape - sequences must form valid UTF-8 byte sequences when unescaped. -
- bytes - - A String element, possibly including invalid UTF-8 escape - sequences. -
- bool - - An Identifier element or any of the - unsignedInteger elements matching one of the following - values.
- True values: "True", "true", - "t", 1
- False values: "False", "false", - "f", 0
- Any unsigned integer representation of 0 or 1 - is permitted: 00, 0x0, 01, - 0x1, etc. -
- enum values - - An Identifier element containing an enum value name, or any - of the integer elements in the range - -0x80000000 to 0x7FFFFFFF containing an enum - value number. It is not valid to specify a name that is not a - member of the field's enum type definition. Depending on - the particular protobuf runtime implementation, it may or may not be - valid to specify a number that is not a member of the field's - enum type definition. Text format processors not tied to a - particular runtime implementation (such as IDE support) may choose to - issue a warning when a provided number value is not a valid member. Note - that certain names that are valid keywords in other contexts, such as - "true" or "infinity", are also valid enum value names. -
- message values - - A MessageValue element. -
- -## Extension Fields {#extension} - -Extension fields are specified using their qualified names. Example: - -```textproto -local_field: 10 -[com.example.ext_field]​: 20 -``` - -Extension fields are generally defined in other *.proto* files. The text format -language does not provide a mechanism for specifying the locations of files that -define extension fields; instead, the parser must have prior knowledge of their -locations. - -## `Any` Fields {#any} - -Text format supports an expanded form of the -[`google.protobuf.Any`](/programming-guides/proto3#any) -well-known type using a special syntax resembling extension fields. Example: - -```textproto -local_field: 10 - -# An Any value using regular fields. -any_value { - type_url: "type.googleapis.com/com.example.SomeType" - value: "\x0a\x05hello" # serialized bytes of com.example.SomeType -} - -# The same value using Any expansion -any_value { - [type.googleapis.com/com.example.SomeType] { - field1: "hello" - } -} -``` - -In this example, `any_value` is a field of type `google.protobuf.Any`, and it -stores a serialized `com.example.SomeType` message containing `field1: hello`. - -## `group` Fields {#group} - -In text format, a `group` field uses a normal `MessageValue` element as its -value, but is specified using the capitalized group name rather than the -implicit lower-cased field name. Example: - -```proto -// proto2 -message MessageWithGroup { - optional group MyGroup = 1 { - optional int32 my_value = 1; - } -} -``` - -With the above *.proto* definition, the following text format is a valid -`MessageWithGroup`: - -```textproto -MyGroup { - my_value: 1 -} -``` - -Similar to Message fields, the `:` delimiter between the group name and value is -optional. - -This functionality is included in Editions for backward-compatibility. Normally -`DELIMITED` fields will serialize like normal messages. The following shows the -behavior with Editions: - -```proto -edition = "2024"; - -message Parent { - message GroupLike { - int32 foo = 1; - } - GroupLike grouplike = 1 [features.message_encoding = DELIMITED]; -} -``` - -The content of that *.proto* file will be serialized like a proto2 group: - -```proto -GroupLike { - foo: 2; -} -``` - -## `map` Fields {#map} - -Text format does not provide a custom syntax for specifying map field entries. -When a `map` field is defined in a *.proto* file, an implicit `Entry` message is -defined containing `key` and `value` fields. Map fields are always repeated, -accepting multiple key/value entries. Example: - -```proto -// Editions -edition = "2024"; - -message MessageWithMap { - map my_map = 1; -} -``` - -With the above *.proto* definition, the following text format is a valid -`MessageWithMap`: - -```textproto -my_map { key: "entry1" value: 1 } -my_map { key: "entry2" value: 2 } - -# You can also use the list syntax -my_map: [ - { key: "entry3" value: 3 }, - { key: "entry4" value: 4 } -] -``` - -Both the `key` and `value` fields are optional and default to the zero value of -their respective types if unspecified. If a key is duplicated, only the -last-specified value will be retained in a parsed map. - -The order of maps is not maintained in textprotos. - -## `oneof` Fields {#oneof} - -While there is no special syntax related to `oneof` fields in text format, only -one `oneof` member may be specified at a time. Specifying multiple members -concurrently is not valid. Example: - -```proto -// Editions -edition = "2024"; - -message OneofExample { - message MessageWithOneof { - string not_part_of_oneof = 1; - oneof Example { - string first_oneof_field = 2; - string second_oneof_field = 3; - } - } - repeated MessageWithOneof message = 1; -} -``` - -The above *.proto* definition results in the following text format behavior: - -```textproto -# Valid: only one field from the Example oneof is set. -message { - not_part_of_oneof: "always valid" - first_oneof_field: "valid by itself" -} - -# Valid: the other oneof field is set. -message { - not_part_of_oneof: "always valid" - second_oneof_field: "valid by itself" -} - -# Invalid: multiple fields from the Example oneof are set. -message { - not_part_of_oneof: "always valid" - first_oneof_field: "not valid" - second_oneof_field: "not valid" -} -``` - -## Text Format Files {#text-format-files} - -A text format file uses the `.txtpb` filename suffix and contains a single -`Message`. Text format files are UTF-8 encoded. An example textproto file is -provided below. - -{{% alert title="Important" color="warning" %}} -`.txtpb` is the canonical text format file extension and should be preferred to -the alternatives. This suffix is preferred for its brevity and consistency with -the official wire-format file extension `.binpb`. The legacy canonical extension -`.textproto` still has widespread usage and tooling -support. Some tooling also -supports the legacy extensions `.textpb` and `.pbtxt`. All other extensions -besides the above are **strongly** discouraged; in particular, extensions such -as `.protoascii` wrongly imply that text format is ascii-only, and others like -`.pb.txt` are not recognized by common tooling. -{{% /alert %}} - -```textproto -# This is an example of Protocol Buffer's text format. -# Unlike .proto files, only shell-style line comments are supported. - -name: "John Smith" - -pet { - kind: DOG - name: "Fluffy" - tail_wagginess: 0.65f -} - -pet < - kind: LIZARD - name: "Lizzy" - legs: 4 -> - -string_value_with_escape: "valid \n escape" -repeated_values: [ "one", "two", "three" ] -``` - -### Header {#header} - -The header comments `proto-file` and `proto-message` inform developer tools of -the schema, so they may provide various features. - -```textproto -# proto-file: some/proto/my_file.proto -# proto-message: MyMessage -``` - -## Working with the Format Programmatically - -Due to how individual Protocol Buffer implementations emit -neither a consistent nor canonical text format, -tools or libraries that modify TextProto files or emit TextProto output must -explicitly use -https://github.com/protocolbuffers/txtpbfmt -to format their output. diff --git a/content/reference/python/_index.md b/content/reference/python/_index.md deleted file mode 100644 index f5db62f67..000000000 --- a/content/reference/python/_index.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "Python Reference" -weight = 740 -linkTitle = "Python" -description = "Reference documentation for working with protocol buffer classes in Python." -type = "docs" -+++ diff --git a/content/reference/python/api-docs-link.md b/content/reference/python/api-docs-link.md deleted file mode 100644 index 87bf404a7..000000000 --- a/content/reference/python/api-docs-link.md +++ /dev/null @@ -1,8 +0,0 @@ - - ---- -title: "Python API" -manualLink: "https://googleapis.dev/python/protobuf/latest/" -manualLinkTarget: "_blank" -weight: 760 ---- \ No newline at end of file diff --git a/content/reference/python/python-comparison.md b/content/reference/python/python-comparison.md deleted file mode 100644 index 48c66f774..000000000 --- a/content/reference/python/python-comparison.md +++ /dev/null @@ -1,89 +0,0 @@ -+++ -title = "Python Comparison" -weight = 751 -linkTitle = "Python Comparison" -description = "Describes how Python compares objects." -type = "docs" -+++ - -Because of how proto data is serialized, you cannot rely on the wire -representation of a proto message instance to determine if its content is the -same as another instance. A subset of the ways that a wire-format proto message -instance can vary include the following: - -* The protobuf schema changes in certain ways. -* A map field stores its values in a different order. -* The binary is built with different flags (such as opt vs. debug). -* The protobuf library is updated. - -Because of these ways that serialized data can vary, determining equality -involves other methods. - -## Comparison Methods {#methods} - -You can compare protocol buffer messages for equality using the standard Python -`==` operator. Comparing two objects using the `==` operator compares with -`message.ListFields()`. When testing, you can use `self.assertEqual(msg1, -msg2)`. - -Two messages are considered equal if they have the same type and all of their -corresponding fields are equal. The inequality operator `!=` is the exact -inverse of `==`. - -Message equality is recursive: for two messages to be equal, any nested messages -must also be equal. - -## Field Equality and Presence - -The equality check for fields is value-based. For fields with -[explicit presence](#singular-explicit), the presence of a field is also taken -into account. - -A field that is explicitly set to its default value is **not** considered equal -to a field that is unset. - -For example, consider the following message which has an explicit presence -field: - -```proto -edition = "2023"; -message MyMessage { - int32 value = 1; // 'explicit' presence by default in Editions -} -``` - -If you create two instances, one where `value` is unset and one where `value` is -explicitly set to `0`, they will not be equal: - -```python -msg1 = MyMessage() -msg2 = MyMessage() -msg2.value = 0 - -assert not msg1.HasField("value") -assert msg2.HasField("value") -assert msg1 != msg2 -``` - -This same principle applies to sub-message fields: an unset sub-message is not -equal to a sub-message that is present but empty (a default instance of the -sub-message class). - -For fields with [implicit presence](#singular-implicit), since presence cannot -be tracked, the field is always compared by its value against the corresponding -field in the other message. - -This behavior, where presence is part of the equality check, is different from -how some other languages or protobuf libraries might handle equality, where -unset fields and fields set to their default value are sometimes treated as -equivalent (often for wire-format compatibility). In Python, `==` performs a -stricter check. - -## Other Field Types {#other-types} - -* **Repeated fields** are equal if they have the same number of elements and - each corresponding element is equal. The order of elements matters. -* **Map fields** are equal if they have the same set of key-value pairs. The - order of pairs does not matter. -* **Floating-point fields** (`float` and `double`) are compared by value. Be - aware of the usual caveats with floating-point comparisons. diff --git a/content/reference/python/python-generated.md b/content/reference/python/python-generated.md deleted file mode 100644 index c16ba75e8..000000000 --- a/content/reference/python/python-generated.md +++ /dev/null @@ -1,1106 +0,0 @@ -+++ -title = "Python Generated Code Guide" -weight = 750 -linkTitle = "Generated Code Guide" -description = "Describes exactly what Python definitions the protocol buffer compiler generates for any given protocol definition." -type = "docs" -+++ - -Any -differences between proto2, proto3, and Editions generated code are -highlighted - note that these differences are in the generated code as described -in this document, not the base message classes/interfaces, which are the same -across all versions. You should read the -[proto2 language guide](/programming-guides/proto2), -[proto3 language guide](/programming-guides/proto3), -and/or [Editions guide](/programming-guides/editions) -before reading this document. - -The Python Protocol Buffers implementation is a little different from C++ and -Java. In Python, the compiler only outputs code to build descriptors for the -generated classes, and a -[Python metaclass](https://docs.python.org/2.7/reference/datamodel#metaclasses) -does the real work. This document describes what you get *after* the metaclass -has been applied. - -## Compiler Invocation {#invocation} - -The protocol buffer compiler produces Python output when invoked with the -`--python_out=` command-line flag. The parameter to the `--python_out=` option -is the directory where you want the compiler to write your Python output. The -compiler creates a `.py` file for each `.proto` file input. The names of the -output files are computed by taking the name of the `.proto` file and making two -changes: - -- The extension (`.proto`) is replaced with `_pb2.py`. -- The proto path (specified with the `--proto_path=` or `-I` command-line - flag) is replaced with the output path (specified with the `--python_out=` - flag). - -So, for example, let's say you invoke the compiler as follows: - -```shell -protoc --proto_path=src --python_out=build/gen src/foo.proto src/bar/baz.proto -``` - -The compiler will read the files `src/foo.proto` and `src/bar/baz.proto` and -produce two output files: `build/gen/foo_pb2.py` and `build/gen/bar/baz_pb2.py`. -The compiler will automatically create the directory `build/gen/bar` if -necessary, but it will *not* create `build` or `build/gen`; they must already -exist. - -Protoc can generate Python stubs (`.pyi`) using the `--pyi_out` parameter. - -Note that if the `.proto` file or its path contains any characters which cannot -be used in Python module names (for example, hyphens), they will be replaced -with underscores. So, the file `foo-bar.proto` becomes the Python file -`foo_bar_pb2.py`. - -{{% alert title="Tip" color="note" %}} When -outputting Python code, the protocol buffer compiler's ability to output -directly to ZIP archives is particularly convenient, as the Python interpreter -is able to read directly from these archives if placed in the `PYTHONPATH`. To -output to a ZIP file, simply provide an output location ending in `.zip`. -{{% /alert %}} - -{{% alert title="Note" color="note" %}} -The number 2 in the extension `_pb2.py` designates version 2 of Protocol -Buffers. Version 1 was used primarily inside Google, though you might be able to -find parts of it included in other Python code that was released before Protocol -Buffers. Since version 2 of Python Protocol Buffers has a completely different -interface, and since Python does not have compile-time type checking to catch -mistakes, we chose to make the version number be a prominent part of generated -Python file names. Currently proto2, proto3, and Editions all use `_pb2.py` for -their generated files. {{% /alert %}} - -## Packages {#package} - -The Python code generated by the protocol buffer compiler is completely -unaffected by the package name defined in the `.proto` file. Instead, Python -packages are identified by directory structure. - -## Messages {#message} - -Given a simple message declaration: - -```proto -message Foo {} -``` - -The protocol buffer compiler generates a class called `Foo`, which subclasses -[`google.protobuf.Message`](https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message). -The class is a concrete class; no abstract methods are left unimplemented. -Unlike C++ and Java, Python generated code is unaffected by the `optimize_for` -option in the `.proto` file; in effect, all Python code is optimized for code -size. - -If the message's name is a Python keyword, then its class will only be -accessible via `getattr()`, as described in the -[Names that conflict with Python keywords](#keyword-conflicts) section. - -You should *not* create your own `Foo` subclasses. Generated classes are not -designed for subclassing and may lead to \"fragile base class\" problems. -Besides, implementation inheritance is bad design. - -Python message classes have no particular public members other than those -defined by the `Message` interface and those generated for nested fields, -messages, and enum types (described below). `Message` provides methods you can -use to check, manipulate, read, or write the entire message, including parsing -from and serializing to binary strings. In addition to these methods, the `Foo` -class defines the following static methods: - -- `FromString(s)`: Returns a new message instance deserialized from the given - string. - -Note that you can also use the -[`text_format`](https://googleapis.dev/python/protobuf/latest/google/protobuf/text_format.html) -module to work with protocol messages in text format: for example, the `Merge()` -method lets you merge an ASCII representation of a message into an existing -message. - -### Nested Types {#nested-types} - -A message can be declared inside another message. For example: - -```proto -message Foo { - message Bar {} -} -``` - -In this case, the `Bar` class is declared as a static member of `Foo`, so you -can refer to it as `Foo.Bar`. - -## Well-known Types {#wkt} - -Protocol buffers provides a number of -[well-known types](/reference/protobuf/google.protobuf) -that you can use in your .proto files along with your own message types. Some -WKT messages have special methods in addition to the usual protocol buffer -message methods, as they subclass both -[`google.protobuf.Message`](https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message) -and a WKT class. - -### Any {#any} - -For Any messages, you can call `Pack()` to pack a specified message into the -current Any message, or `Unpack()` to unpack the current Any message into a -specified message. For example: - -```python -any_message.Pack(message) -any_message.Unpack(message) -``` - -`Unpack()` also checks the descriptor of the passed-in message object against -the stored one and returns `False` if they don't match and does not attempt any -unpacking; `True` otherwise. - -You can also call the `Is()` method to check if the Any message represents the -given protocol buffer type. For example: - -```python -assert any_message.Is(message.DESCRIPTOR) -``` - -Use the `TypeName()` method to retrieve the protobuf type name of an inner -message. - -### Timestamp {#timestamp} - -Timestamp messages can be converted to/from RFC 3339 date string format (JSON -string) using the `ToJsonString()`/`FromJsonString()` methods. For example: - -```python -timestamp_message.FromJsonString("1970-01-01T00:00:00Z") -assert timestamp_message.ToJsonString() == "1970-01-01T00:00:00Z" -``` - -You can also call `GetCurrentTime()` to fill the Timestamp message with current -time: - -```python -timestamp_message.GetCurrentTime() -``` - -To convert between other time units since epoch, you can call `ToNanoseconds(), -FromNanoseconds(), ToMicroseconds(), FromMicroseconds(), ToMilliseconds(), -FromMilliseconds(), ToSeconds()`, or `FromSeconds()`. The generated code also -has `ToDatetime()` and `FromDatetime()` methods to convert between Python -datetime objects and Timestamps. For example: - -```python -timestamp_message.FromMicroseconds(-1) -assert timestamp_message.ToMicroseconds() == -1 -dt = datetime(2016, 1, 1) -timestamp_message.FromDatetime(dt) -self.assertEqual(dt, timestamp_message.ToDatetime()) -``` - -### Duration {#duration} - -Duration messages have the same methods as Timestamp to convert between JSON -string and other time units. To convert between timedelta and Duration, you can -call `ToTimedelta()` or `FromTimedelta`. For example: - -```python -duration_message.FromNanoseconds(1999999999) -td = duration_message.ToTimedelta() -assert td.seconds == 1 -assert td.microseconds == 999999 -``` - -### FieldMask {#fieldmask} - -FieldMask messages can be converted to/from JSON string using the -`ToJsonString()`/`FromJsonString()` methods. In addition, a FieldMask message -has the following methods: - -- `IsValidForDescriptor(message_descriptor)`: Checks whether the FieldMask is - valid for Message Descriptor. -- `AllFieldsFromDescriptor(message_descriptor)`: Gets all direct fields of - Message Descriptor to FieldMask. -- `CanonicalFormFromMask(mask)`: Converts a FieldMask to the canonical form. -- `Union(mask1, mask2)`: Merges two FieldMasks into this FieldMask. -- `Intersect(mask1, mask2)`: Intersects two FieldMasks into this FieldMask. -- `MergeMessage(source, destination, replace_message_field=False, - replace_repeated_field=False)`: Merges fields specified in FieldMask from - source to destination. - -### Struct {#struct} - -Struct messages let you get and set the items directly. For example: - -```python -struct_message["key1"] = 5 -struct_message["key2"] = "abc" -struct_message["key3"] = True -``` - -To get or create a list/struct, you can call -`get_or_create_list()`/`get_or_create_struct()`. For example: - -```python -struct.get_or_create_struct("key4")["subkey"] = 11.0 -struct.get_or_create_list("key5") -``` - -### ListValue {#listvalue} - -A ListValue message acts like a Python sequence that lets you do the following: - -```python -list_value = struct_message.get_or_create_list("key") -list_value.extend([6, "seven", True, None]) -list_value.append(False) -assert len(list_value) == 5 -assert list_value[0] == 6 -assert list_value[1] == "seven" -assert list_value[2] == True -assert list_value[3] == None -assert list_Value[4] == False -``` - -To add a ListValue/Struct, call `add_list()`/`add_struct()`. For example: - -```python -list_value.add_struct()["key"] = 1 -list_value.add_list().extend([1, "two", True]) -``` - -## Fields {#fields} - -For each field in a message type, the corresponding class has a property with -the same name as the field. How you can manipulate the property depends on its -type. - -As well as a property, the compiler generates an integer constant for each field -containing its field number. The constant name is the field name converted to -upper-case followed by `_FIELD_NUMBER`. For example, given the field `int32 -foo_bar = 5;`, the compiler will generate the constant `FOO_BAR_FIELD_NUMBER = -5`. - -If the field's name is a Python keyword, then its property will only be -accessible via `getattr()` and `setattr()`, as described in the -[Names that conflict with Python keywords](#keyword-conflicts) section. - -Protocol buffers defines two modes of field presence: `explicit` and `implicit`. -Each of these is described in the following sections. - -### Singular Fields with Explicit Presence {#singular-explicit} - -Singular fields with `explicit` presence are always able to differentiate -between the field being unset and the field being set to its default value. - -If you have a singular field `foo` of any non-message type, you can manipulate -the field `foo` as if it were a regular field. For example, if `foo`'s type is -`int32`, you can say: - -```python -message.foo = 123 -print(message.foo) -``` - -Note that setting `foo` to a value of the wrong type will raise a `TypeError`. - -If `foo` is read when it is not set, its value is the default value for that -field. To check if `foo` is set, or to clear the value of `foo`, you must call -the `HasField()` or `ClearField()` methods of the -[`Message`](https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message) -interface. For example: - -```python -assert not message.HasField("foo") -message.foo = 123 -assert message.HasField("foo") -message.ClearField("foo") -assert not message.HasField("foo") -``` - -In Editions, fields have `explicit` presence by default. The following is an -example of an `explicit` field in an Editions `.proto` file: - -```proto -edition = "2023"; -message MyMessage { - int32 foo = 1; -} -``` - -### Singular Fields with Implicit Presence {#singular-implicit} - -Singular fields with `implicit` presence do not have a `HasField()` method. An -`implicit` field is always "set" and reading the field will always return a -value. Reading an `implicit` field that has not been assigned a value will -return the default value for that type. - -If you have a singular field `foo` of any non-message type, you can manipulate -the field `foo` as if it were a regular field. For example, if `foo`'s type is -`int32`, you can say: - -```python -message.foo = 123 -print(message.foo) -``` - -Note that setting `foo` to a value of the wrong type will raise a `TypeError`. - -If `foo` is read when it is not set, its value is the default value for that -field. To clear the value of `foo` and reset it to the default value for its -type, you call the `ClearField()` method of the -[`Message`](https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message) -interface. For example: - -```python -message.foo = 123 -message.ClearField("foo") -``` - -### Singular Message Fields {#embedded_message} - -Message types work slightly differently. You cannot assign a value to an -embedded message field. Instead, assigning a value to any field within the child -message implies setting the message field in the parent. Submessages always have -[explicit presence](#fields-with-explicit-presence), so you can also use the -parent message's `HasField()` method to check if a message type field value has -been set. - -So, for example, let's say you have the following `.proto` definition: - -```proto -edition = "2023"; -message Foo { - Bar bar = 1; -} -message Bar { - int32 i = 1; -} -``` - -You *cannot* do the following: - -```python -foo = Foo() -foo.bar = Bar() # WRONG! -``` - -Instead, to set `bar`, you simply assign a value directly to a field within -`bar`, and - presto! - `foo` has a `bar` field: - -```python -foo = Foo() -assert not foo.HasField("bar") -foo.bar.i = 1 -assert foo.HasField("bar") -assert foo.bar.i == 1 -foo.ClearField("bar") -assert not foo.HasField("bar") -assert foo.bar.i == 0 # Default value -``` - -Similarly, you can set `bar` using the -[`Message`](https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message) -interface's `CopyFrom()` method. This copies all the values from another message -of the same type as `bar`. - -```python -foo.bar.CopyFrom(baz) -``` - -Note that simply reading a field inside `bar` does *not* set the field: - -```python -foo = Foo() -assert not foo.HasField("bar") -print(foo.bar.i) # Print i's default value -assert not foo.HasField("bar") -``` - -If you need the \"has\" bit on a message that does not have any fields you can -or want to set, you may use the `SetInParent()` method. - -```python -foo = Foo() -assert not foo.HasField("bar") -foo.bar.SetInParent() # Set Foo.bar to a default Bar message -assert foo.HasField("bar") -``` - -### Repeated Fields {#repeated-fields} - -There are three types of repeated fields: scalar, enum, and message. Map fields -and oneof fields cannot be repeated. - -### Repeated Scalar and Enum Fields {#repeated-scalar} - -Repeated fields are represented as an object that acts like a Python sequence. -As with embedded messages, you cannot assign the field directly, but you can -manipulate it. For example, given this message definition: - -```proto -message Foo { - repeated int32 nums = 1; -} -``` - -You can do the following: - -```python -foo = Foo() -foo.nums.append(15) # Appends one value -foo.nums.extend([32, 47]) # Appends an entire list - -assert len(foo.nums) == 3 -assert foo.nums[0] == 15 -assert foo.nums[1] == 32 -assert foo.nums == [15, 32, 47] - -foo.nums[:] = [33, 48] # Assigns an entire list -assert foo.nums == [33, 48] - -foo.nums[1] = 56 # Reassigns a value -assert foo.nums[1] == 56 -for i in foo.nums: # Loops and print - print(i) -del foo.nums[:] # Clears list (works just like in a Python list) -``` - -The `ClearField()` method of the -[`Message`](https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message) -interface works in addition to using Python `del`. - -When using the index to retrieve a value, you can use negative numbers, such as -using `-1` to retrieve the last element in the list. If your index goes out of -bounds, you'll get an `IndexError: list index out of range`. - -### Repeated Message Fields {#repeated-message-fields} - -Repeated message fields work similar to repeated scalar fields. However, the -corresponding Python object also has an `add()` method that creates a new -message object, appends it to the list, and returns it for the caller to fill -in. Also, the object's `append()` method makes a **copy** of the given message -and appends that copy to the list. This is done so that messages are always -owned by the parent message to avoid circular references and other confusion -that can happen when a mutable data structure has multiple owners. Similarly, -the object's `extend()` method appends an entire list of messages, but makes a -**copy** of every message in the list. - -For example, given this message definition: - -```proto -edition = "2023"; -message Foo { - repeated Bar bars = 1; -} -message Bar { - int32 i = 1; - int32 j = 2; -} -``` - -You can do the following: - -```python -foo = Foo() -bar = foo.bars.add() # Adds a Bar then modify -bar.i = 15 -foo.bars.add().i = 32 # Adds and modify at the same time -new_bar = Bar() -new_bar.i = 40 -another_bar = Bar() -another_bar.i = 57 -foo.bars.append(new_bar) # Uses append() to copy -foo.bars.extend([another_bar]) # Uses extend() to copy - -assert len(foo.bars) == 4 -assert foo.bars[0].i == 15 -assert foo.bars[1].i == 32 -assert foo.bars[2].i == 40 -assert foo.bars[2] == new_bar # The appended message is equal, -assert foo.bars[2] is not new_bar # but it is a copy! -assert foo.bars[3].i == 57 -assert foo.bars[3] == another_bar # The extended message is equal, -assert foo.bars[3] is not another_bar # but it is a copy! - -foo.bars[1].i = 56 # Modifies a single element -assert foo.bars[1].i == 56 -for bar in foo.bars: # Loops and print - print(bar.i) -del foo.bars[:] # Clears list - -# add() also forwards keyword arguments to the concrete class. -# For example, you can do: - -foo.bars.add(i=12, j=13) - -# Initializers forward keyword arguments to a concrete class too. -# For example: - -foo = Foo( # Creates Foo - bars=[ # with its field bars set to a list - Bar(i=15, j=17), # where each list member is also initialized during creation. - Bar(i=32), - Bar(i=47, j=77), - ] -) - -assert len(foo.bars) == 3 -assert foo.bars[0].i == 15 -assert foo.bars[0].j == 17 -assert foo.bars[1].i == 32 -assert foo.bars[2].i == 47 -assert foo.bars[2].j == 77 -``` - -Unlike repeated scalar fields, repeated message fields **don't** support item -assignment (i.e. -[`__setitem__`](https://docs.python.org/3/reference/datamodel#object.__setitem__)). -For example: - -```python -foo = Foo() -foo.bars.add(i=3) -# WRONG! -foo.bars[0] = Bar(i=15) # Raises an exception -# WRONG! -foo.bars[:] = [Bar(i=15), Bar(i=17)] # Also raises an exception -# WRONG! -# AttributeError: Cannot delete field attribute -del foo.bars -# RIGHT -del foo.bars[:] -foo.bars.extend([Bar(i=15), Bar(i=17)]) -``` - -### Groups (proto2) {#groups-proto2} - -**Note that groups are deprecated and should not be used when creating new -message types -- use nested message types (proto2, proto3) or -[delimited fields](/editions/features#message_encoding) -(editions) instead.** - -A group combines a nested message type and a field into a single declaration, -and uses a different -[wire format](/programming-guides/encoding) for the -message. The generated message has the same name as the group. The generated -field's name is the **lowercased** name of the group. - -For example, except for wire format, the following two message definitions are -equivalent: - -```proto -// Version 1: Using groups -message SearchResponse { - repeated group SearchResult = 1 { - optional string url = 1; - } -} -// Version 2: Not using groups -message SearchResponse { - message SearchResult { - optional string url = 1; - } - repeated SearchResult searchresult = 1; -} -``` - -A group is either `required`, `optional`, or `repeated`. A required or optional -group is manipulated using the same API as a regular singular message field. A -repeated group is manipulated using the same API as a regular repeated message -field. - -For example, given the above `SearchResponse` definition, you can do the -following: - -```python -resp = SearchResponse() -resp.searchresult.add(url="https://blog.google") -assert resp.searchresult[0].url == "https://blog.google" -assert resp.searchresult[0] == SearchResponse.SearchResult(url="https://blog.google") -``` - -### Map Fields {#map-fields} - -Given this message definition: - -```proto -message MyMessage { - map mapfield = 1; -} -``` - -The generated Python API for the map field is just like a Python `dict`: - -```python -# Assign value to map -m.mapfield[5] = 10 - -# Read value from map -m.mapfield[5] - -# Iterate over map keys -for key in m.mapfield: - print(key) - print(m.mapfield[key]) - -# Test whether key is in map: -if 5 in m.mapfield: - print(“Found!”) - -# Delete key from map. -del m.mapfield[key] -``` - -As with [embedded message fields](#embedded_message), messages cannot be -directly assigned into a map value. Instead, to add a message as a map value you -reference an [undefined key](#undefined), which constructs and returns a new -submessage: - -```python -m.message_map[key].submessage_field = 10 -``` - -You can find out more about undefined keys in the next section. - -#### Referencing undefined keys {#undefined} - -The semantics of Protocol Buffer maps behave slightly differently to Python -`dict`s when it comes to undefined keys. In a regular Python `dict`, referencing -an undefined key raises a KeyError exception: - -```python ->>> x = {} ->>> x[5] -Traceback (most recent call last): - File "", line 1, in -KeyError: 5 -``` - -However, in Protocol Buffers maps, referencing an undefined key creates the key -in the map with a zero/false/empty value. This behavior is more like the Python -standard library `defaultdict`. - -```python ->>> dict(m.mapfield) -{} ->>> m.mapfield[5] -0 ->>> dict(m.mapfield) -{5: 0} -``` - -This behavior is especially convenient for maps with message type values, -because you can directly update the fields of the returned message. - -```python ->>> m.message_map[5].foo = 3 -``` - -Note that even if you don't assign any values to message fields, the submessage -is still created in the map: - -```python ->>> m.message_map[10] - ->>> dict(m.message_map) -{10: } -``` - -This is **different** from regular [embedded message fields](#embedded_message), -where the message itself is only created once you assign a value to one of its -fields. - -As it may not be immediately obvious to anyone reading your code that -`m.message_map[10]` alone, for example, may create a submessage, we also provide -a `get_or_create()` method that does the same thing but whose name makes the -possible message creation more explicit: - -```python -# Equivalent to: -# m.message_map[10] -# but more explicit that the statement might be creating a new -# empty message in the map. -m.message_map.get_or_create(10) -``` - -### Memory management {#clearing-fields} - -Note that clearing a field (via `ClearField`, `Clear`, `del` (for lists) or -`ClearExtension`) doesn't necessarily reclaim memory. It just resets the object -to look as if things are unset, but the subobjects *may* continue to exist. For -example, clearing a repeated field sets its size to 0, but does not relinquish -its capacity (analogous to calling `.clear()` on a `std::vector` in C++). - -There are various ways in which to ensure the memory is freed up. One method is -to make a copy of the proto after clearing the fields, as the unused memory is -not copied over: - -```python -# Assuming 'my_proto' has a memory-intensive field 'big_field' -# Clears the field. Memory might still be reserved. -my_proto.ClearField('big_field') - -# Copy to a new instance. This allocates only necessary memory. -compact_proto = my_proto_pb2.MyProto() -compact_proto.CopyFrom(my_proto) - -# Once all references to the initial proto are gone, it is garbage collected. -my_proto = compact_proto -``` - -## Enumerations {#enum} - -In Python, enums are just integers. A set of integral constants are defined -corresponding to the enum's defined values. For example, given: - -```proto -message Foo { - enum SomeEnum { - VALUE_A = 0; - VALUE_B = 5; - VALUE_C = 1234; - } - SomeEnum bar = 1; -} -``` - -The constants `VALUE_A`, `VALUE_B`, and `VALUE_C` are defined with values 0, 5, -and 1234, respectively. You can access `SomeEnum` if desired. If an enum is -defined in the outer scope, the values are module constants; if it is defined -within a message (like above), they become static members of that message class. - -For example, you can access the values in the three following ways for the -following enum in a proto: - -```proto -enum SomeEnum { - VALUE_A = 0; - VALUE_B = 5; - VALUE_C = 1234; -} -``` - -```python -value_a = myproto_pb2.SomeEnum.VALUE_A -# or -myproto_pb2.VALUE_A -# or -myproto_pb2.SomeEnum.Value('VALUE_A') -``` - -An enum field works just like a scalar field. - -```python -foo = Foo() -foo.bar = Foo.VALUE_A -assert foo.bar == 0 -assert foo.bar == Foo.VALUE_A -``` - -If the enum's name (or an enum value) is a Python keyword, then its object (or -the enum value's property) will only be accessible via `getattr()`, as described -in the [Names that conflict with Python keywords](#keyword-conflicts) section. - -With proto2, enums are closed, and with proto3, enums are open. In Editions, the -`enum_type` feature determines the behavior of an enum. - -- `OPEN` enums can have any `int32` value, even if it is not specified in the - enum definition. This is the default in Editions. -- `CLOSED` enums cannot contain a numeric value other than those defined for - the enum type. If you assign a value that is not in the enum, the generated - code will throw an exception. This is equivalent to the behavior of enums in - proto2. - -Enums have a number of utility methods for getting field names from values and -vice versa, lists of fields, and so on - these are defined in -[`enum_type_wrapper.EnumTypeWrapper`](https://github.com/protocolbuffers/protobuf/blob/master/python/google/protobuf/internal/enum_type_wrapper.py) -(the base class for generated enum classes). So, for example, if you have the -following standalone enum in `myproto.proto`: - -```proto -enum SomeEnum { - VALUE_A = 0; - VALUE_B = 5; - VALUE_C = 1234; -} -``` - -...you can do this: - -```python -self.assertEqual('VALUE_A', myproto_pb2.SomeEnum.Name(myproto_pb2.VALUE_A)) -self.assertEqual(5, myproto_pb2.SomeEnum.Value('VALUE_B')) -``` - -For an enum declared within a protocol message, such as Foo above, the syntax is -similar: - -```python -self.assertEqual('VALUE_A', myproto_pb2.Foo.SomeEnum.Name(myproto_pb2.Foo.VALUE_A)) -self.assertEqual(5, myproto_pb2.Foo.SomeEnum.Value('VALUE_B')) -``` - -If multiple enum constants have the same value (aliases), the first constant -defined is returned. - -```proto -enum SomeEnum { - option allow_alias = true; - VALUE_A = 0; - VALUE_B = 5; - VALUE_C = 1234; - VALUE_B_ALIAS = 5; -} -``` - -In the above example, `myproto_pb2.SomeEnum.Name(5)` returns `"VALUE_B"`. - -## Oneof {#oneof} - -Given a message with a oneof: - -```proto -message Foo { - oneof test_oneof { - string name = 1; - int32 serial_number = 2; - } -} -``` - -The Python class corresponding to `Foo` will have properties called `name` and -`serial_number` just like regular [fields](#fields). However, unlike regular -fields, at most one of the fields in a oneof can be set at a time, which is -ensured by the runtime. For example: - -```python -message = Foo() -message.name = "Bender" -assert message.HasField("name") -message.serial_number = 2716057 -assert message.HasField("serial_number") -assert not message.HasField("name") -``` - -The message class also has a `WhichOneof` method that lets you find out which -field (if any) in the oneof has been set. This method returns the name of the -field that is set, or `None` if nothing has been set: - -```python -assert message.WhichOneof("test_oneof") is None -message.name = "Bender" -assert message.WhichOneof("test_oneof") == "name" -``` - -`HasField` and `ClearField` also accept oneof names in addition to field names: - -```python -assert not message.HasField("test_oneof") -message.name = "Bender" -assert message.HasField("test_oneof") -message.serial_number = 2716057 -assert message.HasField("test_oneof") -message.ClearField("test_oneof") -assert not message.HasField("test_oneof") -assert not message.HasField("serial_number") -``` - -Note that calling `ClearField` on a oneof just clears the currently set field. - -## Names that conflict with Python keywords {#keyword-conflicts} - -If the name of a message, field, enum, or enum value is a -[Python keyword](https://docs.python.org/3/reference/lexical_analysis#keywords), -then the name of its corresponding class or property will be the same, but -you'll only be able to access it using Python's -[`getattr()`](https://docs.python.org/3/library/functions#getattr) and -[`setattr()`](https://docs.python.org/3/library/functions#setattr) built-in -functions, and not via Python's normal attribute reference syntax (i.e. the dot -operator). - -For example, if you have the following `.proto` definition: - -```proto -message Baz { - optional int32 from = 1 - repeated int32 in = 2; -} -``` - -You would access those fields like this: - -```python -baz = Baz() -setattr(baz, "from", 99) -assert getattr(baz, "from") == 99 -getattr(baz, "in").append(42) -assert getattr(baz, "in") == [42] -``` - -By contrast, trying to use `obj.attr` syntax to access these fields results in -Python raising syntax errors when parsing your code: - -```python -# WRONG! -baz.in # SyntaxError: invalid syntax -baz.from # SyntaxError: invalid syntax -``` - -## Extensions {#extension} - -Given a proto2 or editions message with an extension range: - -```proto -edition = "2023"; -message Foo { - extensions 100 to 199; -} -``` - -The Python class corresponding to `Foo` will have a member called `Extensions`, -which is a dictionary mapping extension identifiers to their current values. - -Given an extension definition: - -```proto -extend Foo { - int32 bar = 123; -} -``` - -The protocol buffer compiler generates an \"extension identifier\" called `bar`. -The identifier acts as a key to the `Extensions` dictionary. The result of -looking up a value in this dictionary is exactly the same as if you accessed a -normal field of the same type. So, given the above example, you could do: - -```python -foo = Foo() -foo.Extensions[proto_file_pb2.bar] = 2 -assert foo.Extensions[proto_file_pb2.bar] == 2 -``` - -Note that you need to specify the extension identifier constant, not just a -string name: this is because it's possible for multiple extensions with the same -name to be specified in different scopes. - -Analogous to normal fields, `Extensions[...]` returns a message object for -singular messages and a sequence for repeated fields. - -The -[`Message`](https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message) -interface's `HasField()` and `ClearField()` methods do not work with extensions; -you must use `HasExtension()` and `ClearExtension()` instead. To use the -`HasExtension()` and `ClearExtension()` methods, pass in the `field_descriptor` -for the extension you are checking for the existence of. - -## Services {#service} - -If the `.proto` file contains the following line: - -```proto -option py_generic_services = true; -``` - -Then the protocol buffer compiler will generate code based on the service -definitions found in the file as described in this section. However, the -generated code may be undesirable as it is not tied to any particular RPC -system, and thus requires more levels of indirection that code tailored to one -system. If you do NOT want this code to be generated, add this line to the file: - -```proto -option py_generic_services = false; -``` - -If neither of the above lines are given, the option defaults to `false`, as -generic services are deprecated. (Note that prior to 2.4.0, the option defaults -to `true`) - -RPC systems based on `.proto`-language service definitions should provide -[plugins](/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb) -to generate code appropriate for the system. These plugins are likely to require -that abstract services are disabled, so that they can generate their own classes -of the same names. - -The remainder of this section describes what the protocol buffer compiler -generates when abstract services are enabled. - -### Interface {#interface} - -Given a service definition: - -```proto -service Foo { - rpc Bar(FooRequest) returns(FooResponse); -} -``` - -The protocol buffer compiler will generate a class `Foo` to represent this -service. `Foo` will have a method for each method defined in the service -definition. In this case, the method `Bar` is defined as: - -```python -def Bar(self, rpc_controller, request, done) -``` - -The parameters are equivalent to the parameters of -[`Service.CallMethod()`](https://googleapis.dev/python/protobuf/latest/google/protobuf/service.html#google.protobuf.service.Service.CallMethod), -except that the `method_descriptor` argument is implied. - -These generated methods are intended to be overridden by subclasses. The default -implementations simply call -[`controller.SetFailed()`](https://googleapis.dev/python/protobuf/latest/google/protobuf/service.html#google.protobuf.service.RpcController.SetFailed) -with an error message indicating that the method is unimplemented, then invoke -the `done` callback. When implementing your own service, you must subclass this -generated service and implement its methods as appropriate. - -`Foo` subclasses the `Service` interface. The protocol buffer compiler -automatically generates implementations of the methods of `Service` as follows: - -- `GetDescriptor`: Returns the service's - [`ServiceDescriptor`](https://googleapis.dev/python/protobuf/latest/google/protobuf/descriptor.html#google.protobuf.descriptor.ServiceDescriptor). -- `CallMethod`: Determines which method is being called based on the provided - method descriptor and calls it directly. -- `GetRequestClass` and `GetResponseClass`: Returns the class of the request - or response of the correct type for the given method. - -### Stub {#stub} - -The protocol buffer compiler also generates a \"stub\" implementation of every -service interface, which is used by clients wishing to send requests to servers -implementing the service. For the `Foo` service (above), the stub implementation -`Foo_Stub` will be defined. - -`Foo_Stub` is a subclass of `Foo`. Its constructor takes an -[`RpcChannel`](https://googleapis.dev/python/protobuf/latest/google/protobuf/service.html#google.protobuf.service.RpcChannel) -as a parameter. The stub then implements each of the service's methods by -calling the channel's `CallMethod()` method. - -The Protocol Buffer library does not include an RPC implementation. However, it -includes all of the tools you need to hook up a generated service class to any -arbitrary RPC implementation of your choice. You need only provide -implementations of `RpcChannel` and -[`RpcController`](https://googleapis.dev/python/protobuf/latest/google/protobuf/service.html#google.protobuf.service.RpcController). - -## Plugin Insertion Points {#plugins} - -[Code generator plugins](/reference/cpp/api-docs/google.protobuf.compiler.plugin) -which want to extend the output of the Python code generator may insert code of -the following types using the given insertion point names. - -- `imports`: Import statements. -- `module_scope`: Top-level declarations. - -{{% alert title="Warning" color="warning" %}} Do not -generate code which relies on private class members declared by the standard -code generator, as these implementation details may change in future versions of -Protocol Buffers. {{% /alert %}} - -## Sharing Messages Between Python and C++ {#sharing-messages} - -Prior to the 4.21.0 version of the Protobuf Python API, Python apps could share -messages with C++ using a native extension. Starting in the 4.21.0 API version, -sharing messages between Python and C++ is not supported by the default install. -To enable this capability when working with the 4.x and later versions of the -Protobuf Python API, define the environment variable, -`PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp`, and ensure that the Python/C++ -extension is installed. diff --git a/content/reference/ruby/_index.md b/content/reference/ruby/_index.md deleted file mode 100644 index 65d4ca27c..000000000 --- a/content/reference/ruby/_index.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "Ruby Reference" -weight = 770 -linkTitle = "Ruby" -description = "Reference documentation for working with protocol buffer classes in Ruby." -type = "docs" -+++ diff --git a/content/reference/ruby/ruby-generated.md b/content/reference/ruby/ruby-generated.md deleted file mode 100644 index bef60f3af..000000000 --- a/content/reference/ruby/ruby-generated.md +++ /dev/null @@ -1,449 +0,0 @@ -+++ -title = "Ruby Generated Code Guide" -weight = 780 -linkTitle = "Generated Code Guide" -description = "Describes the API of message objects that the protocol buffer compiler generates for any given protocol definition." -type = "docs" -+++ - -You should -read the language guides for -[proto2](/programming-guides/proto2), -[proto3](/programming-guides/proto3), or -[editions](/programming-guides/editions) before reading -this document. - -## Compiler Invocation {#invocation} - -The protocol buffer compiler produces Ruby output when invoked with the -`--ruby_out=` command-line flag. The parameter to the `--ruby_out=` option is -the directory where you want the compiler to write your Ruby output. The -compiler creates a `.rb` file for each `.proto` file input. The names of the -output files are computed by taking the name of the `.proto` file and making two -changes: - -- The extension (`.proto`) is replaced with `_pb.rb`. -- The proto path (specified with the `--proto_path=` or `-I` command-line - flag) is replaced with the output path (specified with the `--ruby_out=` - flag). - -So, for example, let's say you invoke the compiler as follows: - -```shell -protoc --proto_path=src --ruby_out=build/gen src/foo.proto src/bar/baz.proto -``` - -The compiler will read the files `src/foo.proto` and `src/bar/baz.proto` and -produce two output files: `build/gen/foo_pb.rb` and `build/gen/bar/baz_pb.rb`. -The compiler will automatically create the directory `build/gen/bar` if -necessary, but it will *not* create `build` or `build/gen`; they must already -exist. - -## Packages {#package} - -The package name defined in the `.proto` file is used to generate a module -structure for the generated messages. Given a file like: - -```proto -package foo_bar.baz; - -message MyMessage {} -``` - -The protocol compiler generates an output message with the name -`FooBar::Baz::MyMessage`. - -However, if the `.proto` file contains the `ruby_package` option, like this: - -```proto -option ruby_package = "Foo::Bar"; -``` - -then the generated output will give precedence to the `ruby_package` option -instead and generate `Foo::Bar::MyMessage`. - -## Messages {#message} - -Given a simple message declaration: - -```proto -message Foo {} -``` - -The protocol buffer compiler generates a class called `Foo`. The generated class -derives from the Ruby `Object` class (protos have no common base class). Unlike -C++ and Java, Ruby generated code is unaffected by the `optimize_for` option in -the `.proto` file; in effect, all Ruby code is optimized for code size. - -You should *not* create your own `Foo` subclasses. Generated classes are not -designed for subclassing and may lead to \"fragile base class\" problems. - -Ruby message classes define accessors for each field, and also provide the -following standard methods: - -- `Message#dup`, `Message#clone`: Performs a shallow copy of this message and - returns the new copy. -- `Message#==`: Performs a deep equality comparison between two messages. -- `Message#hash`: Computes a shallow hash of the message's value. -- `Message#to_hash`, `Message#to_h`: Converts the object to a ruby `Hash` - object. Only the top-level message is converted. -- `Message#inspect`: Returns a human-readable string representing this - message. -- `Message#[]`, `Message#[]=`: Gets or sets a field by string name. In the - future this will probably also be used to get/set extensions. - -The message classes also define the following methods as static. (In general we -prefer static methods, since regular methods can conflict with field names you -defined in your .proto file.) - -- `Message.decode(str)`: Decodes a binary protobuf for this message and - returns it in a new instance. -- `Message.encode(proto)`: Serializes a message object of this class to a - binary string. -- `Message.decode_json(str)`: Decodes a JSON text string for this message and - returns it in a new instance. -- `Message.encode_json(proto)`: Serializes a message object of this class to a - JSON text string. -- `Message.descriptor`: Returns the `Google::Protobuf::Descriptor` object for - this message. - -When you create a message, you can conveniently initialize fields in the -constructor. Here is an example of constructing and using a message: - -```ruby -message = MyMessage.new(int_field: 1, - string_field: "String", - repeated_int_field: [1, 2, 3, 4], - submessage_field: MyMessage::SubMessage.new(foo: 42)) -serialized = MyMessage.encode(message) - -message2 = MyMessage.decode(serialized) -raise unless message2.int_field == 1 -``` - -### Nested Types - -A message can be declared inside another message. For example: - -```proto -message Foo { - message Bar { } -} -``` - -In this case, the `Bar` class is declared as a class inside of `Foo`, so you can -refer to it as `Foo::Bar`. - -## Fields - -For each field in a message type, there are accessor methods to set and get the -field. So given a field `foo` you can write: - -```ruby -message.foo = get_value() -print message.foo -``` - -Whenever you set a field, the value is type-checked against the declared type of -that field. If the value is of the wrong type (or out of range), an exception -will be raised. - -### Singular Fields - -For singular primitive fields (numbers, strings, and boolean), the value you -assign to the field should be of the correct type and must be in the appropriate -range: - -- **Number types**: the value should be a `Fixnum`, `Bignum`, or `Float`. The - value you assign must be exactly representable in the target type. So - assigning `1.0` to an int32 field is ok, but assigning `1.2` is not. -- **Boolean fields**: the value must be `true` or `false`. No other values - will implicitly convert to true/false. -- **Bytes fields**: the assigned value must be a `String` object. The protobuf - library will duplicate the string, convert it to ASCII-8BIT encoding, and - freeze it. -- **String fields**: the assigned value must be a `String` object. The - protobuf library will duplicate the string, convert it to UTF-8 encoding, - and freeze it. - -No automatic `#to_s`, `#to_i`, etc. calls will happen to perform automatic -conversion. You should convert values yourself first, if necessary. - -#### Checking Presence - -Explicit field presence is determined by the `field_presence` feature (in -editions), the `optional` keyword (in proto2/proto3), and the field type -(message and oneof fields always have explicit presence). When a field has -presence, you can check whether the field is set on a message by calling a -generated `has_...?` method. Setting any value—even the default -value—marks the field as present. Fields can be cleared by calling a -different generated `clear_...` method. - -For example, for a message `MyMessage` with an int32 field `foo`: - -```proto -message MyMessage { - int32 foo = 1; -} -``` - -The presence of `foo` can be checked as follows: - -```ruby -m = MyMessage.new -raise if m.has_foo? -m.foo = 0 -raise unless m.has_foo? -m.clear_foo -raise if m.has_foo? -``` - -### Singular Message Fields {#embedded_message} - -Submessage fields always have presence, regardless of whether they're marked as -`optional`. Unset submessage fields return `nil`, so you can always tell if the -message was explicitly set or not. To clear a submessage field, set its value -explicitly to `nil`. - -```ruby -if message.submessage_field.nil? - puts "Submessage field is unset." -else - message.submessage_field = nil - puts "Cleared submessage field." -end -``` - -In addition to comparing and assigning `nil`, generated messages have `has_...` -and `clear_...` methods, which behave the same as for basic types: - -```ruby -if !message.has_submessage_field? - puts "Submessage field is unset." -else - message.clear_submessage_field - raise if message.has_submessage_field? - puts "Cleared submessage field." -end -``` - -When you assign a submessage, it must be a generated message object of the -correct type. - -It is possible to create message cycles when you assign submessages. For -example: - -```proto -// foo.proto -message RecursiveMessage { - RecursiveMessage submessage = 1; -} - -# test.rb -require 'foo' - -message = RecursiveMessage.new -message.submessage = message -``` - -If you try to serialize this, the library will detect the cycle and fail to -serialize. - -### Repeated Fields - -Repeated fields are represented using a custom class -`Google::Protobuf::RepeatedField`. This class acts like a Ruby `Array` and mixes -in `Enumerable`. Unlike a regular Ruby array, `RepeatedField` is constructed -with a specific type and expects all of the array members to have the correct -type. The types and ranges are checked just like message fields. - -```ruby -int_repeatedfield = Google::Protobuf::RepeatedField.new(:int32, [1, 2, 3]) - -raise unless !int_repeatedfield.empty? - -# Raises TypeError. -int_repeatedfield[2] = "not an int32" - -# Raises RangeError -int_repeatedfield[2] = 2**33 - -message.int32_repeated_field = int_repeatedfield - -# This isn't allowed; the regular Ruby array doesn't enforce types like we need. -message.int32_repeated_field = [1, 2, 3, 4] - -# This is fine, since the elements are copied into the type-safe array. -message.int32_repeated_field += [1, 2, 3, 4] - -# The elements can be cleared without reassigning. -int_repeatedfield.clear -raise unless int_repeatedfield.empty? -``` - -For repeated fields that contain messages, the constructor for -`Google::Protobuf::RepeatedField` supports a variant with three arguments: -`:message`, the class of the submessage, and the values to set: - -```ruby -first_message = MySubMessage.new(foo: 42) -second_message = MySubMessage.new(foo: 79) - -repeated_field = Google::Protobuf::RepeatedField.new( - :message, - MySubMessage, - [first_message, second_message] -) -message.sub_message_repeated_field = repeated_field -``` - -The `RepeatedField` type supports all of the same methods as a regular Ruby -`Array`. You can convert it to a regular Ruby Array with `repeated_field.to_a`. - -Unlike singular fields, `has_...?` methods are never generated for repeated -fields. - -### Map Fields - -Map fields are represented using a special class that acts like a Ruby `Hash` -(`Google::Protobuf::Map`). Unlike a regular Ruby hash, `Map` is constructed with -a specific type for the key and value and expects all of the map's keys and -values to have the correct type. The types and ranges are checked just like -message fields and `RepeatedField` elements. - -```ruby -int_string_map = Google::Protobuf::Map.new(:int32, :string) - -# Returns nil; items is not in the map. -print int_string_map[5] - -# Raises TypeError, value should be a string -int_string_map[11] = 200 - -# Ok. -int_string_map[123] = "abc" - -message.int32_string_map_field = int_string_map -``` - -## Enumerations {#enum} - -Since Ruby does not have native enums, we create a module for each enum with -constants to define the values. Given the `.proto` file: - -```proto -message Foo { - enum SomeEnum { - VALUE_A = 0; - VALUE_B = 5; - VALUE_C = 1234; - } - SomeEnum bar = 1; -} -``` - -You can refer to enum values like so: - -```ruby -print Foo::SomeEnum::VALUE_A # => 0 -message.bar = Foo::SomeEnum::VALUE_A -``` - -You may assign either a number or a symbol to an enum field. When reading the -value back, it will be a symbol if the enum value is known, or a number if it is -not. - -With `OPEN` enums, which proto3 uses, any integer value can be assigned to the -enum, even if that value is not defined in the enum. - -```ruby -message.bar = 0 -puts message.bar.inspect # => :VALUE_A -message.bar = :VALUE_B -puts message.bar.inspect # => :VALUE_B -message.bar = 999 -puts message.bar.inspect # => 999 - -# Raises: RangeError: Unknown symbol value for enum field. -message.bar = :UNDEFINED_VALUE - -# Switching on an enum value is convenient. -case message.bar -when :VALUE_A - # ... -when :VALUE_B - # ... -when :VALUE_C - # ... -else - # ... -end -``` - -An enum module also defines the following utility methods: - -- `Foo::SomeEnum.lookup(number)`: Looks up the given number and returns its - name, or `nil` if none was found. If more than one name has this number, - returns the first that was defined. -- `Foo::SomeEnum.resolve(symbol)`: Returns the number for this enum name, or - `nil` if none was found. -- `Foo::SomeEnum.descriptor`: Returns the descriptor for this enum. - -## Oneof - -Given a message with a oneof: - -```proto -message Foo { - oneof test_oneof { - string name = 1; - int32 serial_number = 2; - } -} -``` - -The Ruby class corresponding to `Foo` will have members called `name` and -`serial_number` with accessor methods just like regular [fields](#fields). -However, unlike regular fields, at most one of the fields in a oneof can be set -at a time, so setting one field will clear the others. - -```ruby -message = Foo.new - -# Fields have their defaults. -raise unless message.name == "" -raise unless message.serial_number == 0 -raise unless message.test_oneof == nil - -message.name = "Bender" -raise unless message.name == "Bender" -raise unless message.serial_number == 0 -raise unless message.test_oneof == :name - -# Setting serial_number clears name. -message.serial_number = 2716057 -raise unless message.name == "" -raise unless message.test_oneof == :serial_number - -# Setting serial_number to nil clears the oneof. -message.serial_number = nil -raise unless message.test_oneof == nil -``` - -For proto2 messages, oneof members have individual `has_...?` methods as well: - -```ruby -message = Foo.new - -raise unless !message.has_test_oneof? -raise unless !message.has_name? -raise unless !message.has_serial_number? -raise unless !message.has_test_oneof? - -message.name = "Bender" -raise unless message.has_test_oneof? -raise unless message.has_name? -raise unless !message.has_serial_number? -raise unless !message.has_test_oneof? - -``` diff --git a/content/reference/rust/_index.md b/content/reference/rust/_index.md deleted file mode 100644 index 0520ea568..000000000 --- a/content/reference/rust/_index.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "Rust Reference" -weight = 781 -linkTitle = "Rust" -description = "Reference documentation for working with protocol buffer classes in Rust." -type = "docs" -+++ diff --git a/content/reference/rust/building-rust-protos.md b/content/reference/rust/building-rust-protos.md deleted file mode 100644 index 8ec52118e..000000000 --- a/content/reference/rust/building-rust-protos.md +++ /dev/null @@ -1,73 +0,0 @@ -+++ -title = "Building Rust Protos" -weight = 784 -linkTitle = "Building Rust Protos" -description = "Describes how to build Rust protos using Cargo or Bazel." -type = "docs" -+++ - -## Cargo - -See the -[protobuf-example](https://docs.rs/crate/protobuf-example/latest/source/) crate -for an example of how to set up your build. - -## Bazel - -The process of building a Rust library for a Protobuf definition is similar to -other programming languages: - -1. Use the language-agnostic `proto_library` rule: - - ```build - proto_library( - name = "person_proto", - srcs = ["person.proto"], - ) - ``` - -2. Create a Rust library: - - ```build {highlight="lines:1,8-11"} - load("//third_party/protobuf/rust:defs.bzl", "rust_proto_library") - - proto_library( - name = "person_proto", - srcs = ["person.proto"], - ) - - rust_proto_library( - name = "person_rust_proto", - deps = [":person_proto"], - ) - ``` - -3. Use the library by including it in a Rust binary: - - ```build {highlight="lines:1,14-20"} - load("//devtools/rust/build_defs:rules.bzl", "rust_binary") - load("//third_party/protobuf/rust:defs.bzl", "rust_proto_library") - - proto_library( - name = "person_proto", - srcs = ["person.proto"], - ) - - rust_proto_library( - name = "person_rust_proto", - deps = [":person_proto"], - ) - - rust_binary( - name = "greet", - srcs = ["greet.rs"], - deps = [ - ":person_rust_proto", - ], - ) - ``` - -{{% alert title="Note" color="note" %}} Don't use -`rust_upb_proto_library` or `rust_cc_proto_library` directly. -`rust_proto_library` checks the global build flag to choose the appropriate -backend for you. {{% /alert %}} diff --git a/content/reference/rust/rust-design-decisions.md b/content/reference/rust/rust-design-decisions.md deleted file mode 100644 index abb5f8ff3..000000000 --- a/content/reference/rust/rust-design-decisions.md +++ /dev/null @@ -1,201 +0,0 @@ -+++ -title = "Rust Proto Design Decisions" -weight = 785 -linkTitle = "Design Decisions" -description = "Explains some of the design choices that the Rust Proto implementation makes." -type = "docs" -+++ - -As with any library, Rust Protobuf is designed considering the needs of both -Google's first-party usage of Rust as well that of external users. Choosing a -path in that design space means that some choices made will not be optimal for -some users in some cases, even if it is the right choice for the implementation -overall. - -This page covers some of the larger design decisions that the Rust Protobuf -implementation makes and the considerations which led to those decisions. - -## Designed to Be ‘Backed’ by Other Protobuf Implementations, Including C++ Protobuf {#backed-by-cpp} - -Protobuf Rust is not a pure Rust implementation of protobuf, but a safe Rust API -implemented on top of existing protobuf implementations, or as we call these -implementations: kernels. - -The biggest factor that goes into this decision was to enable zero-cost of -adding Rust to a preexisting binary which already uses non-Rust Protobuf. By -enabling the implementation to be ABI-compatible with the C++ Protobuf generated -code, it is possible to share Protobuf messages across the language boundary -(FFI) as plain pointers, avoiding the need to serialize in one language, pass -the byte array across the boundary, and deserialize in the other language. This -also reduces binary size for these use cases by avoiding having redundant schema -information embedded in the binary for the same messages for each language. - -Google sees Rust as an opportunity to incrementally get memory safety to key -portions of preexisting brownfield C++ servers; the cost of serialization at the -language boundaries would prevent adoption of Rust to replace C++ in many of -these important and performance-sensitive cases. If we pursued a greenfield Rust -Protobuf implementation that did not have this support, it would end up blocking -Rust adoption and require that these important cases stay on C++ instead. - -Protobuf Rust currently supports three kernels: - -* C++ kernel - the generated code is backed by C++ Protocol Buffers (the - "full" implementation, typically used for servers). This kernel offers - in-memory interoperability with C++ code that uses the C++ runtime. This is - the default for servers within Google. -* C++ Lite kernel - the generated code is backed by C++ Lite Protocol Buffers - (typically used for mobile). This kernel offers in-memory interoperability - with C++ code that uses the C++ Lite runtime. This is the default for - for mobile apps within Google. -* upb kernel - the generated code is backed by - [upb](https://github.com/protocolbuffers/protobuf/tree/main/upb), - a highly performant and small-binary-size Protobuf library written in C. upb - is designed to be used as an implementation detail by Protobuf runtimes in - other languages. This is the default in open source builds where we expect - static linking with code already using C++ Protobuf to be more rare. - -Rust Protobuf is designed to support multiple alternate implementations -(including multiple different memory layouts) while exposing exactly the same -API, allowing for the same application code to be recompiled targeting being -backed by a different implementation. This design constraint significantly -influences our public API decisions, including the types used on getters -(discussed later in this document). - -### No Pure Rust Kernel {#no-pure-rust} - -Given that we designed the API to be implementable by multiple backing -implementations, a natural question is why the only supported kernels are -written in the memory unsafe languages of C and C++ today. - -While Rust being a memory-safe language can significantly reduce exposure to -critical security issues, no language is immune to security issues. The Protobuf -implementations that we support as kernels have been scrutinized and fuzzed to -the extent that Google is comfortable using those implementations to perform -unsandboxed parsing of untrusted inputs in our own servers and apps. - -A greenfield binary parser written in Rust at this time would be understood to -be much more likely to contain critical vulnerabilities than our preexisting C++ -Protobuf or upb parsers, which have been extensively fuzzed, tested, and -reviewed. - -There are legitimate arguments for supporting a pure Rust kernel implementation -long-term, including the ability for developers to avoid needing to have Clang -available to compile C code at build time. - -We expect that Google will support a pure Rust implementation with the same -exposed API at some later date, but we have no concrete roadmap for it at this -time. A second official Rust Protobuf implementation that has a 'better' API by -avoiding the constraints that come from being backed by C++ Proto and upb is not -planned, as we wouldn't want to fragment Google's own Protobuf usage. - -## View/Mut Proxy Types {#view-mut-proxy-types} - -The Rust Proto API is designed with opaque "Proxy" types. For a `.proto` file -that defines `message SomeMsg {}`, we generate the Rust types `SomeMsg`, -`SomeMsgView<'_>` and `SomeMsgMut<'_>`. The simple rule of thumb is that we -expect the View and Mut types to stand in for `&SomeMsg` and `&mut SomeMsg` in -all usages by default, while still getting all of the borrow checking/Send/etc. -behavior that you would expect from those types. - -### Another Lens to Understand These Types {#another-lens} - -To better understand the nuances of these types, it may be useful to think of -these types as follows: - -```rust -struct SomeMsg(Box); -struct SomeMsgView<'a>(&'a cpp::SomeMsg); -struct SomeMsgMut<'a>(&'a mut cpp::SomeMsg); -``` - -Under this lens you can see that: - -- Given a `&SomeMsg` it is possible to get a `SomeMsgView` (similar to how - given a `&Box` you can get a `&T`) -- Given a `SomeMsgView` it in *not* possible to get a `&SomeMsg` (similar to - how given a `&T` you couldn't get a `&Box`). - -Just like with the `&Box` example, this means that on function arguments, it is -generally better to default to use `SomeMsgView<'a>` rather than a `&'a -SomeMsg`, as it will allow a superset of callers to use the function. - -### Why {#why} - -There are two main reasons for this design: to unlock possible optimization -benefits, and as an inherent outcome of the kernel design. - -#### Optimization Opportunity Benefit {#optimization} - -Protobuf being such a core and widespread technology makes it unusually both -prone to all possible observable behaviors being depended on by someone, as well -as relatively small optimizations having unusually major net impact at scale. We -have found that more opaqueness of types gives unusually high amount of -leverage: they permit us to be more deliberate about exactly what behaviors are -exposed, and give us more room to optimize the implementation. - -A `SomeMsgMut<'_>` provides those opportunities where a `&mut SomeMsg` would -not: namely that we can construct them lazily and with an implementation detail -which is not the same as the owned message representation. It also inherently -allows us to control certain behaviors that we couldn't otherwise limit or -control: for example, any `&mut` can be used with `std::mem::swap()`, which is a -behavior that would place strong limits on what invariants you are able to -maintain between a parent and child struct if `&mut SomeChild` is given to -callers. - -#### Inherent to Kernel Design {#kernel-design} - -The other reason for the proxy types is more of an inherent limitation to our -kernel design; when you have a `&T` there must be a real Rust `T` type in memory -somewhere. - -Our C++ kernel design allows you to parse a message which contains nested -messages, and create only a small Rust stack-allocated object to representing -the root message, with all other memory being stored on the C++ Heap. When you -later access a child message, there will be no already-allocated Rust object -which corresponds to that child, and so there's no Rust instance to borrow at -that moment. - -By using proxy types, we're able to on-demand create the Rust proxy types that -semantically acting as borrows, without there being any eagerly allocated Rust -memory for those instances ahead of time. - -## Non-Std Types {#non-std} - -### Simple Types Which May Have a Directly Corresponding Std Type {#corresponding-std} - -In some cases the Rust Protobuf API may choose to create our own types where a -corresponding std type exists with the same name, where the current -implementation may even simply wrap the std type, for example -`protobuf::UTF8Error`. - -Using these types rather than std types gives us more flexibility in optimizing -the implementation in the future. While our current implementation uses the Rust -std UTF-8 validation today, by creating our own `protobuf::Utf8Error` type it -enables us to change the implementation to use the highly optimized C++ -implementation of UTF-8 validation that we use from C++ Protobuf which is faster -than Rust's std UTF-8 validation. - -### ProtoString {#proto-string} - -Rust's `str` and `std::string::String` types maintain a strict invariant that -they only contain valid UTF-8, but C++'s `std::string` type does not enforce any -such guarantee. `string` typed Protobuf fields are intended to only ever contain -valid UTF-8, and C++ Protobuf does use a correct and highly optimized UTF8 -validator. However, C++ Protobuf's API surface is not set up to strictly enforce -as a runtime invariant that its `string` fields always contain valid UTF-8, -instead, in some cases it allows setting of non-UTF8 data into a `string` field -and validation will only occur at a later time when serialization is happening. - -To enable integrating Rust into preexisting codebases that use C++ Protobuf -while allowing for zero-cost boundary crossings with no risk of undefined -behavior in Rust, we unfortunately have to avoid the `str`/`String` types for -`string` field getters. Instead, the types `ProtoStr` and `ProtoString` are -used, which are equivalent types, except that they may contain invalid UTF-8 in -rare situations. Those types let the application code choose if they wish to -perform the validation on-demand to observe the fields as a `Result<&str>`, or -operate on the raw bytes to avoid any runtime validation. All of the setter -paths are still designed to allow you to pass `&str` or `String` types. - -We are aware that vocabulary types like `str` are very important to idiomatic -usage, and intend to keep an eye on if this decision is the right one as usage -details of Rust evolves. diff --git a/content/reference/rust/rust-generated.md b/content/reference/rust/rust-generated.md deleted file mode 100644 index 0fde6d870..000000000 --- a/content/reference/rust/rust-generated.md +++ /dev/null @@ -1,744 +0,0 @@ -+++ -title = "Rust Generated Code Guide" -weight = 782 -linkTitle = "Generated Code Guide" -description = "Describes the API of message objects that the protocol buffer compiler generates for any given protocol definition." -type = "docs" -+++ - -This page describes exactly what Rust code the protocol buffer compiler -generates for any given protocol definition. - -This document covers how the protocol buffer compiler generates Rust code for -proto2, proto3, and protobuf editions. Any differences between proto2, proto3, -and editions generated code are highlighted. You should read the -[proto2 language guide](/programming-guides/proto2), -[proto3 language guide](/programming-guides/proto3), or -[editions guide](/programming-guides/editions) before -reading this document. - -## Protobuf Rust {#rust} - -Protobuf Rust is an implementation of protocol buffers designed to be able to -sit on top of other existing protocol buffer implementations that we refer to as -'kernels'. - -The decision to support multiple non-Rust kernels has significantly influenced -our public API, including the choice to use custom types like `ProtoStr` over -Rust std types like `str`. See -[Rust Proto Design Decisions](/reference/rust/rust-design-decisions) -for more on this topic. - -## Packages {#packages} - -Unlike in most other languages, the `package` declarations in the `.proto` files -are not used in Rust codegen. - -When `rust_proto_library` is used, the library will correspond to one crate. The -name of the target is used as the crate name. Choose your library name -correspondingly. - -When using Cargo, we recommend you `include!` the `generated.rs` entry point in -a mod of an appropriate name, as in our -[Example Crate](https://docs.rs/crate/protobuf-example). - -## Messages {#messages} - -Given the message declaration: - -```proto -message Foo {} -``` - -The compiler generates a struct named `Foo`. The `Foo` struct defines the -following associated functions and methods: - -### Associated Functions - -* `fn new() -> Self`: Creates a new instance of `Foo`. - -### Traits - -For a number of reasons, including gencode size, name collision problems, and -gencode stability, most common functionality on messages is implemented on -traits instead of as inherent implementations. - -Most users should import our prelude, which only includes traits and our -`proto!` macro and no other types (`use protobuf::prelude::*`). If you would -rather avoid preludes, you can always import the specific traits as needed (see -the - -[documentation here](https://docs.rs/protobuf/4.33.5-release/protobuf/trait.Message.html) -for the names and definitions of the traits if you want to import them -directly). - -* `fn parse(data: &[u8]) -> Result`: Parses a new instance - of a message. -* `fn parse_dont_enforce_required(data: &[u8]) -> Result`: - Same as `parse` but does not fail on missing proto2 `required` fields. -* `fn clear(&mut self)`: Clears message. -* `fn clear_and_parse(&mut self, data: &[u8]) -> Result<(), ParseError>`: - Clearing and parsing into an existing instance. -* `fn clear_and_parse_dont_enforce_required(&mut self, data: &[u8]) -> - Result<(), ParseError>`: Same as `parse` but does not fail on missing proto2 - `required` fields. -* `fn serialize(&self) -> Result, SerializeError>`: Serializes the - message to Protobuf wire format. Serialization can fail but rarely will. - Failure reasons include if the representation exceeds the maximum encoded - message size (must be less than 2 GiB), and `required` fields (proto2) that - are unset. -* `fn take_from(&mut self, other)`: Moves `other` into `self`, discarding any - previous state that `self` contained. -* `fn copy_from(&mut self, other)`: Copies `other` into `self`, discarding any - previous state that `self` contained. `other` is unmodified. -* `fn merge_from(&mut self, other)`: Merges `other` into `self`. -* `fn as_view(&self) -> FooView<'_>`: Returns an immutable handle (view) to - `Foo`. This is further covered in the section on proxy types. -* `fn as_mut(&mut self) -> FooMut<'_>`: Returns a mutable handle (mut) to - `Foo`. This is further covered in the section on proxy types. - -`Foo` additionally implements the following std traits: - -* `std::fmt::Debug` -* `std::default::Default` -* `std::clone::Clone` -* `std::marker::Send` -* `std::marker::Sync` - -### Fluently Create New Instances {#proto-macro} - -The API design of setters follows our established Protobuf idioms, but the -verbosity when constructing new instances is a mild pain point in certain other -languages. To mitigate this, we offer a `proto!` macro, which can be used to -more-succinctly/fluently create new instances. - -For example, instead of writing this: - -``` -let mut msg = SomeMsg::new(); -msg.set_x(1); -msg.set_y("hello"); -msg.some_submessage_mut().set_z(42); -``` - -This macro can be used to write it as follows: - -``` -let msg = proto!(SomeMsg { - x: 1, - y: "hello", - some_submsg: SomeSubmsg { - z: 42 - } -}); -``` - -### Message Proxy Types {#message-proxy-types} - -For a number of technical reasons, we have chosen to avoid using native Rust -references (`&T` and `&mut T`) in certain cases. Instead, we need to express -these concepts using types - `View`s and `Mut`s. These situations are shared and -mutable references to: - -* Messages -* Repeated fields -* Map fields - -For example, the compiler emits structs `FooView<'a>` and `FooMut<'msg>` -alongside `Foo`. These types are used in place of `&Foo` and `&mut Foo`, and -they behave the same as native Rust references in terms of borrow checker -behavior. Just like native borrows, Views are `Copy` and the borrow checker will -enforce that you can either have any number of Views or at most one Mut live at -a given time. - -For the purposes of this documentation, we focus on describing all methods -emitted for the owned message type (`Foo`). A subset of these functions with -`&self` receiver will also be included on the `FooView<'msg>`. A subset of these -functions with either `&self` or `&mut self` will also be included on the -`FooMut<'msg>`. - -To create an owned message type from a View / Mut type call `to_owned()`, which -creates a deep copy. - -See the corresponding section in our -[design decisions](/reference/rust/rust-design-decisions#view-mut-proxy-types) -documentation for more discussion about why this choice was made. - -## Nested Types {#nested-types} - -Given the message declaration: - -```proto -message Foo { - message Bar { - enum Baz { ... } - } -} -``` - -In addition to the struct named `Foo`, a module named `foo` is created to -contain the struct for `Bar`. And similarly a nested module named `bar` to -contain the deeply nested enum `Baz`: - -```rs -pub struct Foo {} - -pub mod foo { - pub struct Bar {} - pub mod bar { - pub struct Baz { ... } - } -} -``` - -## Fields {#fields} - -In addition to the methods described in the previous section, the protocol -buffer compiler generates a set of accessor methods for each field defined -within the message in the `.proto` file. - -Following Rust style, the methods are in lower-case/snake-case, such as -`has_foo()` and `clear_foo()`. Note that the capitalization of the field name -portion of the accessor maintains the style from the original .proto file, which -in turn should be lower-case/snake-case per the -[.proto file style guide](/programming-guides/style). - -### Fields with Explicit Presence {#explicit-presence} - -Explicit presence means that a field distinguishes between the default value and -no value set. In proto2, `optional` fields have explicit presence. In proto3, -only message fields and `oneof` or `optional` fields have explicit presence. -Presence is set using the -[`features.field_presence`](/editions/features#field_presence) -option in editions. - -#### Numeric Fields {#numeric-fields} - -For this field definition: - -```proto -int32 foo = 1; -``` - -The compiler generates the following accessor methods: - -* `fn has_foo(&self) -> bool`: Returns `true` if the field is set. -* `fn foo(&self) -> i32`: Returns the current value of the field. If the field - is not set, it returns the default value. -* `fn foo_opt(&self) -> protobuf::Optional`: Returns an optional with the - variant `Set(value)` if the field is set or `Unset(default value)` if it's - unset. See - [`Optional` rustdoc](https://docs.rs/protobuf/4.33.5-release/protobuf/enum.Optional.html) -* `fn set_foo(&mut self, val: i32)`: Sets the value of the field. After - calling this, `has_foo()` will return `true` and `foo()` will return - `value`. -* `fn clear_foo(&mut self)`: Clears the value of the field. After calling - this, `has_foo()` will return `false` and `foo()` will return the default - value. - -For other numeric field types (including `bool`), `int32` is replaced with the -corresponding Rust type according to the -[scalar value types table](/programming-guides/proto3#scalar). - -#### String and Bytes Fields {#string-byte-fields} - -For these field definitions: - -```proto -string foo = 1; -bytes foo = 1; -``` - -The compiler generates the following accessor methods: - -* `fn has_foo(&self) -> bool`: Returns `true` if the field is set. -* `fn foo(&self) -> &protobuf::ProtoStr`: Returns the current value of the - field. If the field is not set, it returns the default value. See - [`ProtoStr` rustdoc](https://docs.rs/protobuf/4.33.5-release/protobuf/struct.ProtoStr.html). -* `fn foo_opt(&self) -> protobuf::Optional<&ProtoStr>`: Returns an optional - with the variant `Set(value)` if the field is set or `Unset(default value)` - if it's unset. -* `fn set_foo(&mut self, val: impl IntoProxied)`: Sets the value - of the field. `&str`, `String`, `&ProtoStr` and `ProtoString` all - implelement `IntoProxied` and can be passed to this method. -* `fn clear_foo(&mut self)`: Clears the value of the field. After calling - this, `has_foo()` will return `false` and `foo()` will return the default - value. - -For fields of type `bytes` the compiler will generate the `ProtoBytes` type -instead. - -#### Enum Fields {#enum-fields} - -Given this enum definition in any proto syntax version: - -```proto -enum Bar { - BAR_UNSPECIFIED = 0; - BAR_VALUE = 1; - BAR_OTHER_VALUE = 2; -} -``` - -The compiler generates a struct where each variant is an associated constant: - -```rust -#[derive(Clone, Copy, PartialEq, Eq, Hash)] -#[repr(transparent)] -pub struct Bar(i32); - -impl Bar { - pub const Unspecified: Bar = Bar(0); - pub const Value: Bar = Bar(1); - pub const OtherValue: Bar = Bar(2); -} -``` - -For this field definition: - -```proto -Bar foo = 1; -``` - -The compiler generates the following accessor methods: - -* `fn has_foo(&self) -> bool`: Returns `true` if the field is set. -* `fn foo(&self) -> Bar`: Returns the current value of the field. If the field - is not set, it returns the default value. -* `fn foo_opt(&self) -> Optional`: Returns an optional with the variant - `Set(value)` if the field is set or `Unset(default value)` if it's unset. -* `fn set_foo(&mut self, val: Bar)`: Sets the value of the field. After - calling this, `has_foo()` will return `true` and `foo()` will return - `value`. -* `fn clear_foo(&mut self)`: Clears the value of the field. After calling - this, `has_foo()` will return false and `foo()` will return the default - value. - -#### Embedded Message Fields {#embedded-message-fields} - -Given the message type `Bar` from any proto syntax version: - -```proto -message Bar {} -``` - -For any of these field definitions: - -```proto - -message MyMessage { - Bar foo = 1; -} -``` - -The compiler will generate the following accessor methods: - -* `fn foo(&self) -> BarView<'_>`: Returns a view of the current value of the - field. If the field is not set it returns an empty message. -* `fn foo_mut(&mut self) -> BarMut<'_>`: Returns a mutable handle to the - current value of the field. Sets the field if it is not set. After calling - this method, `has_foo()` returns true. -* `fn foo_opt(&self) -> protobuf::Optional`: If the field is set, - returns the variant `Set` with its `value`. Else returns the variant `Unset` - with the default value. -* `fn set_foo(&mut self, value: impl protobuf::IntoProxied)`: Sets the - field to `value`. After calling this method, `has_foo()` returns `true`. -* `fn has_foo(&self) -> bool`: Returns `true` if the field is set. -* `fn clear_foo(&mut self)`: Clears the field. After calling this method - `has_foo()` returns `false`. - -### Fields with Implicit Presence (proto3 and Editions) {#implicit-presence} - -Implicit presence means that a field does not distinguish between the default -value and no value set. In proto3, fields have implicit presence by default. In -editions, you can declare a field with implicit presence by setting the -`field_presence` feature to `IMPLICIT`. - -#### Numeric Fields {#implicit-numeric-fields} - -For these field definitions: - -```proto -// proto3 -int32 foo = 1; - -// editions -message MyMessage { - int32 foo = 1 [features.field_presence = IMPLICIT]; -} -``` - -The compiler generates the following accessor methods: - -* `fn foo(&self) -> i32`: Returns the current value of the field. If the field - is not set, it returns `0`. -* `fn set_foo(&mut self, val: i32)`: Sets the value of the field. - -For other numeric field types (including `bool`), `int32` is replaced with the -corresponding Rust type according to the -[scalar value types table](/programming-guides/proto3#scalar). - -#### String and Bytes Fields {#implicit-string-byte-fields} - -For these field definitions: - -```proto -// proto3 -string foo = 1; -bytes foo = 1; - -// editions -string foo = 1 [features.field_presence = IMPLICIT]; -bytes bar = 2 [features.field_presence = IMPLICIT]; -``` - -The compiler will generate the following accessor methods: - -* `fn foo(&self) -> &ProtoStr`: Returns the current value of the field. If the - field is not set, returns the empty string/empty bytes. See - [`ProtoStr` rustdoc](https://docs.rs/protobuf/4.33.5-release/protobuf/struct.ProtoStr.html). -* `fn set_foo(&mut self, value: IntoProxied)`: Sets the field to - `value`. - -For fields of type `bytes` the compiler will generate the `ProtoBytes` type -instead. - -### Singular String and Bytes Fields with Cord Support {#singular-string-bytes} - -`[ctype = CORD]` enables bytes and strings to be stored as an -[absl::Cord](https://github.com/abseil/abseil-cpp/blob/master/absl/strings/cord.h) -in C++ Protobufs. `absl::Cord` currently does not have an equivalent type in -Rust . Protobuf Rust uses an enum to represent a cord -field: - -```proto -enum ProtoStringCow<'a> { - Owned(ProtoString), - Borrowed(&'a ProtoStr) -} -``` - -In the common case, for small strings, an `absl::Cord` stores its data as a -contiguous string. In this case cord accessors return -`ProtoStringCow::Borrowed`. If the underlying `absl::Cord` is non-contiguous, -the accessor copies the data from the cord into an owned `ProtoString` and -returns `ProtoStringCow::Owned`. The `ProtoStringCow` implements -`Deref`. - -For any of these field definitions: - -```proto -optional string foo = 1 [ctype = CORD]; -string foo = 1 [ctype = CORD]; -optional bytes foo = 1 [ctype = CORD]; -bytes foo = 1 [ctype = CORD]; -``` - -The compiler generates the following accessor methods: - -* `fn my_field(&self) -> ProtoStringCow<'_>`: Returns the current value of the - field. If the field is not set, returns the empty string/empty bytes. -* `fn set_my_field(&mut self, value: IntoProxied)`: Sets the - field to `value`. After calling this function `foo()` returns `value` and - `has_foo()` returns `true`. -* `fn has_foo(&self) -> bool`: Returns `true` if the field is set. -* `fn clear_foo(&mut self)`: Clears the value of the field. After calling - this, `has_foo()` returns `false` and `foo()` returns the default value. - Cords have not been implemented yet. - -For fields of type `bytes` the compiler generates the `ProtoBytesCow` type -instead. - -The compiler generates the following accessor methods: - -* `fn foo(&self) -> &ProtoStr`: Returns the current value of the field. If the - field is not set, returns the empty string/empty bytes. -* `fn set_foo(&mut self, value: impl IntoProxied)`: Sets the - field to `value`. - -#### Enum Fields {#implicit-presence-enum} - -Given the enum type: - -```proto -enum Bar { - BAR_UNSPECIFIED = 0; - BAR_VALUE = 1; - BAR_OTHER_VALUE = 2; -} -``` - -The compiler generates a struct where each variant is an associated constant: - -```rust -#[derive(Clone, Copy, PartialEq, Eq, Hash)] -#[repr(transparent)] -pub struct Bar(i32); - -impl Bar { - pub const Unspecified: Bar = Bar(0); - pub const Value: Bar = Bar(1); - pub const OtherValue: Bar = Bar(2); -} -``` - -For these field definitions: - -```proto -// proto3 -Bar foo = 1; - -// editions -message MyMessage { - Bar foo = 1 [features.field_presence = IMPLICIT]; -} -``` - -The compiler will generate the following accessor methods: - -* `fn foo(&self) -> Bar`: Returns the current value of the field. If the field - is not set, it returns the default value. -* `fn set_foo(&mut self, value: Bar)`: Sets the value of the field. After - calling this, `has_foo()` will return `true` and `foo()` will return - `value`. - -### Repeated Fields {#repeated-fields} - -For any repeated field definition the compiler will generate the same three -accessor methods that deviate only in the field type. - -In editions, you can control the wire format encoding of repeated primitive -fields using the -[`repeated_field_encoding`](/editions/features#repeated_field_encoding) -feature. - -```proto -// proto2 -repeated int32 foo = 1; // EXPANDED by default - -// proto3 -repeated int32 foo = 1; // PACKED by default - -// editions -repeated int32 foo = 1 [features.repeated_field_encoding = PACKED]; -repeated int32 bar = 2 [features.repeated_field_encoding = EXPANDED]; -``` - -Given any of the above field definitions, the compiler generates the following -accessor methods: - -* `fn foo(&self) -> RepeatedView<'_, i32>`: Returns a view of the underlying - repeated field. See - [`RepeatedView` rustdoc](https://docs.rs/protobuf/4.33.5-release/protobuf/struct.RepeatedView.html). -* `fn foo_mut(&mut self) -> RepeatedMut<'_, i32>`: Returns a mutable handle to - the underlying repeated field. See - [`RepeatedMut` rustdoc](https://docs.rs/protobuf/4.33.5-release/protobuf/struct.RepeatedMut.html). -* `fn set_foo(&mut self, src: impl IntoProxied>)`: Sets the - underlying repeated field to a new repeated field provided in `src`. Accepts - a `RepeatedView`, `RepeatedMut` or `Repeated`. See - [`Repeated` rustdoc](https://docs.rs/protobuf/4.33.5-release/protobuf/struct.Repeated.html). - -For different field types only the respective generic types of the -`RepeatedView`, `RepeatedMut` and `Repeated` types will change. For example, -given a field of type `string` the `foo()` accessor would return a -`RepeatedView<'_, ProtoString>`. - -### Map Fields {#map} - -For this map field definition: - -```proto -map weight = 1; -``` - -The compiler will generate the following 3 accessor methods: - -* `fn weight(&self) -> protobuf::MapView<'_, i32, i32>`: Returns an immutable - view of the underlying map. See - [`MapView` rustdoc](https://docs.rs/protobuf/4.33.5-release/protobuf/struct.MapView.html). -* `fn weight_mut(&mut self) -> protobuf::MapMut<'_, i32, i32>`: Returns a - mutable handle to the underlying map. See - [`MapMut` rustdoc](https://docs.rs/protobuf/4.33.5-release/protobuf/struct.MapView.html). -* `fn set_weight(&mut self, src: protobuf::IntoProxied>)`: Sets - the underlying map to `src`. Accepts a `MapView`, `MapMut` or `Map`. See - [`Map` rustdoc](https://docs.rs/protobuf/4.33.5-release/protobuf/struct.Map.html). - -For different field types only the respective generic types of the `MapView`, -`MapMut` and `Map` types will change. For example, given a field of type -`string` the `foo()` accessor would return a `MapView<'_, int32, ProtoString>`. - -## Any {#any} - -Any is not special-cased by Rust Protobuf at this time; it will behave as though -it was a simple message with this definition: - -```proto -message Any { - string type_url = 1; - bytes value = 2; -} -``` - -## Oneof {#oneof} - -Given a oneof definition like this: - -```proto -oneof example_name { - int32 foo_int = 4; - string foo_string = 9; - ... -} -``` - -The compiler will generate accessors (getters, setters, hazzers) for every field -as if the same field was declared as an `optional` field outside of the oneof. -So you can work with oneof fields like regular fields, but setting one will -clear the other fields in the oneof block. In addition, the following types are -emitted for the `oneof` block: - -```rust - #[non_exhaustive] - #[derive(Debug, Clone, Copy)] - - pub enum ExampleNameOneof<'msg> { - FooInt(i32) = 4, - FooString(&'msg protobuf::ProtoStr) = 9, - not_set(std::marker::PhantomData<&'msg ()>) = 0 - } -``` - -```rust - #[derive(Debug, Copy, Clone, PartialEq, Eq)] - - pub enum ExampleNameCase { - FooInt = 4, - FooString = 9, - not_set = 0 - } -``` - -Additionally, it will generate the two accessors: - -* `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 - indicating which field is set. Returns `not_set` if no field is set. - -## Enumerations {#enumerations} - -Given an enum definition like: - -```proto -enum FooBar { - FOO_BAR_UNKNOWN = 0; - FOO_BAR_A = 1; - FOO_B = 5; - VALUE_C = 1234; -} -``` - -The compiler will generate: - -```rust - #[derive(Clone, Copy, PartialEq, Eq, Hash)] - #[repr(transparent)] - pub struct FooBar(i32); - - impl FooBar { - pub const Unknown: FooBar = FooBar(0); - pub const A: FooBar = FooBar(1); - pub const FooB: FooBar = FooBar(5); - pub const ValueC: FooBar = FooBar(1234); - } -``` - -Note that for values with a prefix that matches the enum, the prefix will be -stripped; this is done to improve ergonomics. Enum values are commonly prefixed -with the enum name to avoid name collisions between sibling enums (which follow -the semantics of C++ enums where the values are not scoped by their containing -enum). Since the generated Rust consts are scoped within the `impl`, the -additional prefix, which is beneficial to add in .proto files, would be -redundant in Rust. - -## Extensions {#extensions} - -Protobuf Rust supports extensions for proto2 messages. Extensions are accessed -via generated `ExtensionId` constants. - -Given a message with extensions defined: - -```proto -package xyz; -message Foo { - extensions 100 to 199; -} - -extend Foo { - optional int32 i32_ext = 100; - repeated int32 repeated_i32_ext = 101; -} -``` - -The compiler generates constants of type `proto::ExtensionId` named `I32_EXT` -and `REPEATED_I32_EXT`, which you can use to read and write the extensions on -the `Foo` type. - -### Accessing Extensions {#accessing-exts} - -The `ExtensionId` type provides methods to interact with extensions on a -message. These methods work with owned messages, views, and muts. - -* `fn has(&self, msg: impl AsView) -> bool`: Returns `true` if the - extension is set on the message. (Not available for repeated extensions, by - design). -* `fn get(&self, msg: impl AsView) -> View<'_, E>`: Returns the - value of the extension. If not set, returns the default value. For repeated - fields, returns a `RepeatedView`. -* `fn set(&self, msg: impl AsMut, value: impl IntoProxied)`: - Sets the value of the extension. -* `fn clear(&self, msg: impl AsMut)`: Clears the extension from - the message. -* `fn get_mut(&self, msg: impl AsMut) -> Mut<'_, E>`: Returns a - mutable handle to the extension. For messages and repeated fields, this will - create the field if it doesn't exist. - -### Example Usage {#ext-example} - -```rust -use protobuf::prelude::*; - -let mut foo = xyz::Foo::new(); - -// Check and set scalar extension -assert!(!xyz::INT32_EXT.has(&foo)); -xyz::INT32_EXT.set(&mut foo, 42); -assert!(xyz::INT32_EXT.has(&foo)); -assert_eq!(xyz::INT32_EXT.get(&foo), 42); - -// Clear scalar extension -xyz::INT32_EXT.clear(&mut foo); -assert!(!xyz::INT32_EXT.has(&foo)); - -// Working with repeated extensions -{ - let mut rep_mut = xyz::REPEATED_INT32_EXT.get_mut(&mut foo); - rep_mut.push(1); - rep_mut.push(2); -} -assert_eq!(xyz::REPEATED_INT32_EXT.get(&foo).len(), 2); -assert_eq!(xyz::REPEATED_INT32_EXT.get(&foo).get(0), Some(1)); -``` - -## Arena Allocation {#arena} - -A Rust API for arena allocated messages has not yet been implemented. - -Internally, Protobuf Rust on upb kernel uses arenas, but on C++ kernels it -doesn't. However, references (both const and mutable) to messages that were -arena allocated in C++ can be safely passed to Rust to be accessed or mutated. - -## Services {#services} - -A Rust API for services has not yet been implemented. diff --git a/content/reference/rust/rust-redaction.md b/content/reference/rust/rust-redaction.md deleted file mode 100644 index a7100f053..000000000 --- a/content/reference/rust/rust-redaction.md +++ /dev/null @@ -1,23 +0,0 @@ -+++ -title = "Redaction in Rust" -weight = 783 -linkTitle = "Redaction in Rust" -description = "Describes redaction in Rust." -type = "docs" -+++ - - - -Use the standard `fmt::Debug` ("`{:?}`" in format strings) on Protobuf messages -for human-readable strings for logging, error messages, exceptions, and similar -use cases. The output of this debug info is not intended to be machine-readable -(unlike `TextFormat` and `JSON` which are -[not be used for debug output](/best-practices/dos-donts#text-format-interchange)). - -Using `fmt::Debug` enables redaction of some sensitive fields. - -Note that under upb kernel this redaction is not yet implemented, but is -expected to be added. diff --git a/content/search.md b/content/search.md deleted file mode 100644 index d9a4d5bee..000000000 --- a/content/search.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Search Results -layout: search ---- \ No newline at end of file diff --git a/content/support/_index.md b/content/support/_index.md deleted file mode 100644 index 1436c98d0..000000000 --- a/content/support/_index.md +++ /dev/null @@ -1,11 +0,0 @@ -+++ -title = "Support" -weight = 900 -description = "Resources to support using Protocol Buffers." -type = "docs" -+++ - -This section of the documentation contains topics related to the support that -the Protocol Buffers team provides to developers, including the timeframes for -support for each version of a language library and migration guides to help you -keep up with major version bumps. diff --git a/content/support/cross-version-runtime-guarantee.md b/content/support/cross-version-runtime-guarantee.md deleted file mode 100644 index 5476db1ed..000000000 --- a/content/support/cross-version-runtime-guarantee.md +++ /dev/null @@ -1,160 +0,0 @@ -+++ -title = "Cross-Version Runtime Guarantee" -weight = 930 -description = "The guarantees that the language has for cross-version runtime compatibility." -type = "docs" -+++ - - - -Protobuf language bindings have two components. The generated code (gencode) and -the runtime libraries that implement common functionality for that generated -code. When these come from different releases of protobuf, we are in a "cross -version runtime" situation. - -We intend to offer the following guarantees across most languages. These are the -default guarantees; however, owners of protobuf code generators and runtimes may -explicitly override them with more specific guarantees for that language. -[C++ and Rust](#cpp) have stricter guarantees than typical, and -[Python](#python) has looser ones. - -Protobuf cross-version usages outside the guarantees are **error-prone and not -supported**. Version skews can lead to *flakes and undefined behaviors* that are -hard to diagnose, even if it can often *seem* to work as long as nothing has -changed in a source-incompatible way. For Protobuf, the proliferation of tools -and services that rely on using unsupported Protobuf language bindings prevents -the protobuf team from updating the protobuf implementation in response to bug -reports or security vulnerabilities. - -## New Gencode + Old Runtime = Never Allowed {#backwards} - -We may add new runtime APIs in any kind of release (Major, Minor, or Patch). -Gencode in that release is allowed to use those new APIs. The consequence is -that gencode should never be paired with a runtime that predates the `protoc` -and plugin that was used to generate those bindings. - -We will add “poison pills” where possible to prevent attempts to pair newer -gencode with an older runtime. - -## Major Versions {#major} - -Protobuf implements sliding window compatibility for major versions. Code -generated for a major version V (full version: V.x.y) will be supported by -protobuf runtimes of major version V and V+1. - -Protobuf will **not** support using gencode from version V with runtime >= -V+2 and will be using a "poison pill" mechanism to fail with a clear error -message when a software assembly attempts to use such a configuration. - -For Example: - -* Java code generated by protobuf version 3.0.0 will work with runtimes 3.0.0 - to 4.x.y but **not** with runtimes 2.0.0 to 2.x.y or runtimes >= 5.0.0. -* Java code generated by protobuf version 4.27.2 will work with runtimes - 4.27.2 to 5.x.y but **not** runtimes 2.0.0 to 4.27.1 or runtimes >= 6.0.0 - -Exceptions may be made in case where compatibility with older gencode *cannot* -be maintained, such as in the case of [security](#exception) fixes requiring -updated gencode. - -**Note:** Poison pills were introduced in the protobuf 26.0 release. Java -gencode older than 4.26.0 may *appear* to work with runtimes that are older than -the gencode. However, the combination of -[newer gencode and older runtime](#backwards) may have serious bugs that do not -manifest until runtime. - -**Note:** [C++ and Rust](#cpp) do not support compatibility windows, and -[Python](#python) supports much longer ones. - -## Minor Versions {#minor} - -Within a single major runtime version, generated code from an older version of -`protoc` will run on a newer runtime. - -**Note:** [C++ and Rust](#cpp) do not support compatibility across minor -versions. - -## Security Exception {#exception} - -We reserve the right to violate the above promises if needed for security -reasons. We expect these exceptions to be rare, but will always prioritize -security above these guarantees. For example, -[the footmitten CVE](https://cve.report/CVE-2022-3510) required paired updates -to both the runtime and the generated code for Java. As a result, code generated -by 3.20.3 (which contained the footmitten fix) would not load with runtime -library 3.21.6 (which predates the footmitten fix), creating the following -compatibility matrix: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Generated Code Version
3.20.23.20.33.21.63.21.7
Runtime
Version
3.20.2Vuln!Broken!!Vuln!!Broken!
3.20.3VulnWorks!Vuln!!Works?!
3.21.6VulnBrokenVuln!Broken!
3.21.7VulnWorksVulnWorks
- -* “Vuln” indicates that the combination will successfully start, but the - security vulnerability still exists. -* “Works” indicates that the combination will successfully start and does not - have the vulnerability. -* “Broken” indicates that the combination will not successfully start. -* **!Bold!** indicates configurations that mix newer gencode with older - runtime and were never intended to work together. - -## No Coexistence of Multiple Major Runtime Versions {#coexist} - -Coexistence of multiple major versions in the same process is **not** supported. - -## C++ and Rust-specific Guarantees {#cpp} - -Protobuf C++ and Rust disclaim all cross-runtime support and require an exact -match between the generated code version and the runtime version at all times. - -Additionally, Protobuf C++ makes no guarantees about ABI stability across any -releases (major, minor, or micro). - -## Python-specific Guarantees {#python} - -Since the 3.20.0 release, the Protobuf Python generated code became a thin -wrapper around an embedded `FileDescriptorProto`. Because these protos are -supported on extremely long timeframes, our usual -[major version compatibility windows](#major) aren't typically necessary. - -Python may break generated code compatibility in specific future major version -releases, but it will be coupled with poison pill warnings and errors in -advance. As of 6.32.0, all generated code since 3.20.0 will be supported until -at least 8.x.y. diff --git a/content/support/debugging-playbook.md b/content/support/debugging-playbook.md deleted file mode 100644 index 1f2a9c8c2..000000000 --- a/content/support/debugging-playbook.md +++ /dev/null @@ -1,45 +0,0 @@ -+++ -title = "Debugging" -weight = 915 -description = "Debugging common issues in Protocol Buffers." -type = "docs" -+++ - -Frequently asked questions and debugging scenarios encountered by protobuf -users. - - - -## Bazel: Resolving Issues with Prebuilt Protoc {#prebuilt-protoc} - -As mentioned in [this news article](/news/2026-01-16), -Bazel 7 and later support builds that use a prebuilt protoc. When everything is -configured correctly, this can save a lot of time building, reduce logging -volume, and eliminate the need for C++ toolchain in non-C++ implementations. - -To prevent protoc compilation from source, add the following to your `.bazelrc` -file: - -```bazel -common --per_file_copt=external/.*protobuf.*@--PROTOBUF_WAS_NOT_SUPPOSED_TO_BE_BUILT -common --host_per_file_copt=external/.*protobuf.*@--PROTOBUF_WAS_NOT_SUPPOSED_TO_BE_BUILT -common --per_file_copt=external/.*grpc.*@--GRPC_WAS_NOT_SUPPOSED_TO_BE_BUILT -common --host_per_file_copt=external/.*grpc.*@--GRPC_WAS_NOT_SUPPOSED_TO_BE_BUILT -``` - -When there are hard-coded references to `@com_google_protobuf//:protoc` that are -reachable by the dependency graph, protoc will force it to be built for those -cases, negating this benefit. To resolve this, you'll need to find where the -dependencies are and request that those rulesets be updated. - -To find where you depend on protoc, use the following command: - -```none -bazel cquery 'somepath("//...", "@com_google_protobuf//:all")' -``` - -**Note:** Prebuilts are only available for our standard set of platforms. Anyone -on a nonstandard platform will have to build protoc from source. diff --git a/content/support/migration.md b/content/support/migration.md deleted file mode 100644 index e571d24ef..000000000 --- a/content/support/migration.md +++ /dev/null @@ -1,1091 +0,0 @@ -+++ -title = "Migration Guide" -weight = 920 -description = "A list of the breaking changes made to versions of the libraries, and how to update your code to accommodate the changes." -aliases = "/programming-guides/migration/" -type = "docs" -+++ - -## Changes in v34.0 {#v34} - -The following is a list of the breaking changes made to versions of the -libraries, and how to update your code to accommodate the changes. - -This covers breaking changes announced in -[News Announcements for v34.x](/news/2025-09-19) and -[Release Notes for v34.0](https://github.com/protocolbuffers/protobuf/releases/tag/v34.0). - -### Changes in C++ {#v34-cpp} - -C++ bumped its major version to 7 with the 7.34.0 release. 6.33 is the final -minor version release on 6.x. - -#### Removal of Future Macros - -The following macros, introduced for staged roll-out of breaking changes, were -removed and their behavior is now the default: - -* `PROTOBUF_FUTURE_RENAME_ADD_UNUSED_IMPORT` -* `PROTOBUF_FUTURE_REMOVE_ADD_IGNORE_CRITERIA` -* `PROTOBUF_FUTURE_STRING_VIEW_DESCRIPTOR_DATABASE` -* `PROTOBUF_FUTURE_NO_RECURSIVE_MESSAGE_COPY` -* `PROTOBUF_FUTURE_REMOVE_REPEATED_PTR_FIELD_ARENA_CONSTRUCTOR` -* `PROTOBUF_FUTURE_REMOVE_MAP_FIELD_ARENA_CONSTRUCTOR` -* `PROTOBUF_FUTURE_REMOVE_REPEATED_FIELD_ARENA_CONSTRUCTOR` - -#### New RepeatedPtrField Layout {#cpp-repeatedptrfield-layout} - -`RepeatedPtrField` were transitioned to a new internal element layout in which -elements are stored in contiguous chunks of preallocated memory, similar to -`std::deque`. This results in some changes to copy/move semantics of some APIs, -and some `UnsafeArena` APIs may become functional equivalents of their -arena-safe counterparts and be deprecated. - -#### MSB Hardening Check on RepeatedField::Get and RepeatedPtrField::Get {#cpp-repeatedfield-get-hardening} - -Protobufs were hardened against OOB errors by adding comprehensive bounds -checking to repeated field accesses. - -#### Remove Arena-enabled constructors from Repeated/Map Fields {#cpp-remove-arena-ctors} - -The `RepeatedField(Arena*)`, `RepeatedPtrField(Arena*)`, and `Map(Arena*)` -constructors were deleted. - -#### Remove Deprecated APIs {#cpp-remove-apis} - -We removed the following public runtime APIs. - -##### AddUnusedImportTrackFile() and ClearUnusedImportTrackFiles() - -**API:** `AddUnusedImportTrackFile()`, `ClearUnusedImportTrackFiles()` - -**Replacement:** `AddDirectInputFile()` and `ClearDirectInputFiles()` - -##### AddIgnoreCriteria from message differencer - -`PROTOBUF_FUTURE_REMOVE_ADD_IGNORE_CRITERIA` was added for the breaking change. -We removed the macro. - -**API:** `AddIgnoreCriteria()` - -**Replacement:** Wrap the raw pointer in a `unique_ptr`. - -##### FieldDescriptor::has_optional_keyword() - -**API:** `FieldDescriptor::has_optional_keyword()` - -**Replacement:** `has_presence()` - -##### FieldDescriptor::label() - -**API:** `FieldDescriptor::label()` - -**Replacement:** `is_repeated()` or `is_required()` - -##### FieldDescriptor::is_optional() - -**API:** `FieldDescriptor::is_optional()` - -**Replacement:** `!is_required() && !is_repeated()` - -##### UseDeprecatedLegacyJsonFieldConflicts() - -**API:** `UseDeprecatedLegacyJsonFieldConflicts()` - -**Replacement:** No replacement. - -#### Stricter Name Length Limits {#cpp-name-limits} - -The protobuf compiler enforces stricter limits on the length of symbol names, -such as field names, to prevent potential issues. If the length of any field -name is > 2^16, it generates an error. - -#### Hide Private Generator Headers in CMake {#cpp-cmake-headers} - -The protoc generator headers are no longer installed by CMake. This should not -affect most users. - -#### [[nodiscard]] on Logically Constant Operations {#cpp-nodiscard} - -`[[nodiscard]]` was added to several logically constant protobuf APIs where -failure to consume the returned value indicates a probable bug. This follows -patterns used commonly in the C++ standard library. - -### Changes in Python {#v34-python} - -Python bumped its major version to 7 with the 7.34.0 release. 6.33 is the final -minor version release on 6.x. - -#### Dropped Python 3.9 Support - -The minimum supported Python version is 3.10. Users should upgrade. - -#### Relax Poison Pill Warnings - -We relaxed the poison pills. No warnings or errors are raised for old generated -files for 7.34.x. - -#### Raise TypeError on Incorrect Conversion to Timestamp or Duration - -We now raise a `TypeError` instead of an `AttributeError` when converting an -incorrect type to a `Timestamp` or `Duration`. - -#### Reject bool to enum and int field - -We now reject setting `enum` or `int` fields with boolean values. The API raises -an error instead of implicitly converting them. - -#### Remove float_precision from json_format - -We removed the deprecated `float_precision` option from the `json_format` -serializer. This option does not exist in other ProtoJSON serializers and has -confusing semantics. - -#### Remove float_format/double_format from text_format - -We removed the deprecated `float_format` and `double_format` options from -`text_format`. These options are not available in other proto text format -serializers. - -#### Removed Deprecated APIs {#v34-php-remove-apis} - -We removed the following public runtime APIs. - -##### FieldDescriptor.label - -**API:** `FieldDescriptor.label` - -**Replacement:** `is_repeated()` or `is_required()` - -### Changes in PHP {#v34-php} - -PHP bumped its major version to 5 with the 5.34.0 release. 4.33 is the final -minor version release on 4.x. - -#### Dropped PHP 8.1 Support - -The minimum supported PHP version is 8.2. Users should upgrade. - -#### Removed Deprecated APIs {#v34-php-remove-apis} - -We removed the following public runtime APIs. - -##### FieldDescriptor getLabel - -**API:** `FieldDescriptor getLabel` - -**Replacement:** `isRepeated()` or `isRequired()` - -##### Google\Protobuf\Field_Kind - -**API:** `Google\Protobuf\Field_Kind` - -**Replacement:** `Google\Protobuf\Field\Kind` - -##### Google\Protobuf\Field_Cardinality - -**API:** `Google\Protobuf\Field_Cardinality` - -**Replacement:** `Google\Protobuf\Field\Cardinality` - -##### Google\Protobuf\Internal\RepeatedField - -**API:** `Google\Protobuf\Internal\RepeatedField` - -**Replacement:** `Google\Protobuf\RepeatedField` - -#### Fix Silent Ignoring of Default Values - -The PHP runtime is fixed to honor default values on scalar fields in proto2 and -editions, instead of silently ignoring them. - -#### Type Checking Alignment - -Type checking for pure-PHP and upb-PHP implementations are aligned. Notably, -pure-PHP now rejects `null` for string fields, matching the behavior of upb-PHP. - -### Changes in Objective-C {#v34-objc} - -Objective-C bumped its major version to 5 with the 5.34.0 release. 4.33 is the -final minor version release on 4.x. - -#### Nullability Annotations - -The nullability annotations for some `GPB*Dictionary` APIs were corrected to -mark when APIs could return `nil`. This results in Swift code getting a Swift -`Optional`. For Objective-C callers, the annotation correction is less likely -to have any impact on the source code. - -#### Removed Deprecated API {#v34-objc-remove-apis} - -We removed the following public runtime APIs. - -##### GPBFieldDescriptor optional - -**API:** -[`GPBFieldDescriptor optional`] - -**Replacement:** `!required && fieldType == GPBFieldTypeSingle` - -### Other Changes {#v34-other} - -#### Dropped Bazel 7 Support - -The minimum supported Bazel version is 8, which changes the default from -WORKSPACE to Bzlmod. Users should upgrade to Bazel 8 or higher and migrate to -Bzlmod. - -#### Bazel: Remove deprecated ProtoInfo.transitive_imports - -The deprecated `transitive_imports` field in `ProtoInfo` was removed. Users -should migrate to `transitive_sources`. - -#### Remove protobuf_allow_msvc flag and continue support Bazel+MSVC - -Due to Bazel’s recent improvements on Windows, we now continue to support -Bazel+MSVC. The `--define=protobuf_allow_msvc` flag was removed. - -## Changes in v30.0 {#v30} - -The following is a list of the breaking changes made to versions of the -libraries, and how to update your code to accommodate the changes. - -This covers breaking changes announced in -[News Announcements for v30.x](/news/v30) and -[Release Notes for v30.0](https://github.com/protocolbuffers/protobuf/releases/tag/v30.0). - -### Changes in C++ {#v30-cpp} - -#### Replaced CMake Submodules with Fetched Deps - -Previously, our default CMake behavior was to use Git submodules to grab pinned -dependencies. Specifying `-Dprotobuf_ABSL_PROVIDER=package` would flip our CMake -configs to look for local installations of Abseil (with similar options for -jsoncpp and gtest). These options no longer exist, and the default behavior is -to first look for installations of all our dependencies, falling back to -fetching pinned versions from GitHub if needed. - -To prevent any fallback fetching (similar to the old `package` behavior), you -can call CMake with: - -```cmake -cmake . -Dprotobuf_LOCAL_DEPENDENCIES_ONLY=ON -``` - -To *always* fetch dependencies from a fixed version (similar to the old default -behavior), you can call CMake with: - -```cmake -cmake . -Dprotobuf_FORCE_FETCH_DEPENDENCIES=ON -``` - -#### string_view return type - -Return types are now `absl::string_view` for the following descriptor APIs, -which opens up memory savings: - -* `MessageLite::GetTypeName` -* `UnknownField::length_delimited` -* Descriptor API name functions, such as `FieldDescriptor::full_name` - -We expect future breaking releases to continue migrating additional APIs to -`absl::string_view`. - -In most cases, you should try to update types to use `absl::string_view` where -safe, or explicitly copy to the original type where needed. You may need to -update callers as well if this is returned in a function. - -If the string returned by the affected API methods is being used as: - - - - - - - - - - - - - - - - - - -
TypeMigration
-

std::string

-
-

Explicitly convert to std::string to preserve the existing behavior.

-

Or, switch to the more performant absl::string_view

-
-

const std::string&

-
-

Migrate to absl::string_view

-

If infeasible (such as due to large number of dependencies), copying to a std::string might be easier.

-
-

const std::string*

-

const char*

-
-

If nullable, migrate to std::optional<absl::string_view>.

-

Otherwise, migrate to absl::string_view.

-

Be careful when calling data() since absl::string_view isn't guaranteed to be null-terminated. -

- -For common containers and other APIs, you may be able to migrate to variants -compatible with `absl::string_view`. Below are some common examples. - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CategoryPre-MigrationMigration
Insertion into std::vector<std::string> -

push_back()

-

push_front()

-

push()

-
-

emplace_back()

-

emplace_front()

-

emplace()

-
Insertion for map or 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...)

-
Lookup for map or sets -

find()

-

count()

-

contains()

-
-

Migrate to Abseil containers.

-

Or, define a transparent comparator.

-

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

-

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

-
String Concatenation -

operator+

-

operator+=

-
-

absl::StrCat()

-

absl::StrAppend()

-

These are recommended for performance reasons anyways. See https://abseil.io/tips/3.

-
- -See also [https://abseil.io/tips/1](https://abseil.io/tips/1) for general tips -around using `absl::string_view`. - -#### Poison MSVC + Bazel - -Bazel users on Windows should switch to using clang-cl by adding the following -to their project, like in this -[example](https://github.com/protocolbuffers/protobuf/commit/117e7bbe74ac7c7faa9b6f44c1b22de366302854#diff-48bcd3965c4a015a8f61ad82b225790209baef37363ee0478519536a620a85e5). - -**.bazelrc** - -```bazel -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 -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** - -```bazel -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** - -For users that need compatibility with Bazel 8 only. - -```bazel -platform( - name = "x64_windows-clang-cl", - constraint_values = [ - "@platforms//cpu:x86_64", - "@platforms//os:windows", - "@bazel_tools//tools/cpp:clang-cl", - ], -) -``` - -For users that need compatibility with Bazel 7 and 8. - -```bazel -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", - ], -) -``` - -Users can also temporarily silence the error by setting the opt-out flag -`--define=protobuf_allow_msvc=true` until the next breaking release. - -Alternatively, users that wish to continue using MSVC may switch to using CMake. -This can be done with -[Visual Studio](https://learn.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio?view=msvc-170), -or by supplying the CMake command-line an MSVC generator. For example: - -```cmake -cmake -G "Visual Studio 17 2022" -A Win64 . -``` - -#### ctype Removed from FieldDescriptor Options {#ctype-removed} - -We stopped exposing the `ctype` from `FieldDescriptor` options. You can use the -`FieldDescriptor::cpp_string_type()` API, added in the -[v28 release](https://github.com/protocolbuffers/protobuf/releases/tag/v28.0), -in its place. - -#### Modified Debug APIs to Redact Sensitive Fields {#debug-redaction} - -The Protobuf C++ debug APIs (including Protobuf AbslStringify, -`proto2::ShortFormat`, `proto2::Utf8Format`, `Message::DebugString`, -`Message::ShortDebugString`, `Message::Utf8DebugString`) changed to redact -sensitive fields annotated by `debug_redact`; the outputs of these APIs contain -a per-process randomized prefix, and are no longer parseable by Protobuf -TextFormat Parsers. Users should adopt the new redacted debug format for most -cases requiring a human-readable output (such as logging), or consider switching -to binary format for serialization and deserialization. Users who need the old -deserializable format can use `TextFormat.printer().printToString(proto)`, but -this does not redact sensitive fields and so should be used with caution. - -Read more about this in the -[news article released December 4, 2024](/news/2024-12-04.md). - -#### Removed Deprecated APIs {#v30-cpp-remove-apis} - -We removed the following public runtime APIs, which have been marked deprecated -(such as `ABSL_DEPRECATED`) for at least one minor or major release and that are -obsolete or replaced. - -**API:** -[`Arena::CreateMessage`](https://github.com/protocolbuffers/protobuf/blob/f4b57b98b08aec8bc52e6a7b762edb7a1b9e8883/src/google/protobuf/arena.h#L179) - -**Replacement:** -[`Arena::Create`](https://github.com/protocolbuffers/protobuf/blob/f4b57b98b08aec8bc52e6a7b762edb7a1b9e8883/src/google/protobuf/arena.h#L191) - -**API:** -[`Arena::GetArena`](https://github.com/protocolbuffers/protobuf/blob/237332ef92daf83a53e76decd6ac43c3fcee782b/src/google/protobuf/arena.h#L346) - -**Replacement:** `value->GetArena()` - -**API:** -[`RepeatedPtrField::ClearedCount`](https://github.com/protocolbuffers/protobuf/blame/f4b57b98b08aec8bc52e6a7b762edb7a1b9e8883/src/google/protobuf/repeated_ptr_field.h#L1157) - -**Replacement:** Migrate to Arenas -([migration guide](https://protobuf.dev/support/migration/#cleared-elements)). - -**API:** -[`JsonOptions`](https://github.com/protocolbuffers/protobuf/blob/f4b57b98b08aec8bc52e6a7b762edb7a1b9e8883/src/google/protobuf/util/json_util.h#L22) - -**Replacement:** `JsonPrintOptions` - -#### Dropped C++14 Support {#drop-cpp-14} - -This release dropped C++ 14 as the minimum supported version and raised it to -17, as per the -[Foundational C++ Support matrix](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md). - -Users should upgrade to C++17. - -#### Introduced ASAN Poisoning After Clearing Oneof Messages on Arena - -This change added a hardening check that affects C++ protobufs using Arenas. -Oneof messages allocated on the protobuf arena are now cleared in debug and -poisoned in ASAN mode. After calling clear, future attempts to use the memory -region will cause a crash in ASAN as a use-after-free error. - -This implementation requires C++17. - -#### Dropped our C++ CocoaPods release - -We dropped our C++ CocoaPods release, which has been broken since v4.x.x. C++ -users should use our -[GitHub release](https://github.com/protocolbuffers/protobuf/releases) directly -instead. - -### Changes in Python {#v30-python} - -Python bumped its major version from 5.29.x to 6.30.x. - -#### Dropped Python 3.8 Support - -The minimum supported Python version is 3.9. Users should upgrade. - -#### Removed bazel/system_python.bzl Alias {#python-remove-alias} - -We removed the legacy `bazel/system_python.bzl` alias. - -Remove direct references to `system_python.bzl` in favor of using -`protobuf_deps.bzl` instead. Use `python/dist/system_python.bzl` where it was -moved -[in v5.27.0](https://github.com/protocolbuffers/protobuf/commit/d7f032ad1596ceeabd45ca1354516c39b97b2551) -if you need a direct reference. - -#### Field Setter Validation Changes {#python-setter-validation} - -Python's and upb's field setters now validate closed enums under edition 2023. -Closed enum fields updated with invalid values generate errors. - -#### Removed Deprecated py_proto_library Macro - -The deprecated internal `py_proto_library` Bazel macro in `protobuf.bzl` was -removed. It was replaced by the official `py_proto_library` which was moved to -protobuf in `bazel/py_proto_library` in v29.x. This implementation was -previously available in `rules_python` prior to v29.x. - -#### Remove Deprecated APIs {#v30-python-remove-apis} - -We removed the following public runtime APIs, which had been marked deprecated -for at least one minor or major release. - -##### Reflection Methods - -**APIs:** -[`reflection.ParseMessage`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/reflection.py#L40), -[`reflection.MakeClass`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/reflection.py#L66) - -**Replacement:** `message_factory.GetMessageClass()` - -##### RPC Service Interfaces - -**APIs:** -[`service.RpcException`](https://github.com/protocolbuffers/protobuf/blob/21c545c8c5cec0b052dc7715b778f0353d37d02c/python/google/protobuf/service.py#L23), -[`service.Service`](https://github.com/protocolbuffers/protobuf/blob/21c545c8c5cec0b052dc7715b778f0353d37d02c/python/google/protobuf/service.py#L28), -[`service.RpcController`](https://github.com/protocolbuffers/protobuf/blob/21c545c8c5cec0b052dc7715b778f0353d37d02c/python/google/protobuf/service.py#L97), -and -[`service.RpcChannel`](https://github.com/protocolbuffers/protobuf/blob/21c545c8c5cec0b052dc7715b778f0353d37d02c/python/google/protobuf/service.py#L180) - -**Replacement:** Starting with version 2.3.0, RPC implementations should not try -to build on these, but should instead provide code generator plugins which -generate code specific to the particular RPC implementation. - -##### MessageFactory and SymbolDatabase Methods - -**APIs:** -[`MessageFactory.GetPrototype`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/message_factory.py#L145), -[`MessageFactory.CreatePrototype`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/message_factory.py#L165), -[`MessageFactory.GetMessages`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/message_factory.py#L185), -[`SymbolDatabase.GetPrototype`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/symbol_database.py#L54), -[`SymbolDatabase.CreatePrototype`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/symbol_database.py#L60), -and -[`SymbolDatabase.GetMessages`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/symbol_database.py#L66) - -**Replacement:** `message_factory.GetMessageClass()` and -`message_factory.GetMessageClassesForFiles()`. - -##### GetDebugString - -**APIs:** -[`GetDebugString`](https://github.com/protocolbuffers/protobuf/blob/7f395af40e86e00b892e812beb67a03564884756/python/google/protobuf/pyext/descriptor.cc#L1510) - -**Replacement:** - -No replacement. It's only in Python C++ which is no longer released. It is not -supported in pure Python or UPB. - -#### Python setdefault Behavior Change for Map Fields - -`setdefault` is similar to `dict` for `ScalarMap`, except that both key and -value must be set. `setdefault` is rejected for `MessageMaps`. - -#### Python Nested Message Class \_\_qualname\_\_ Contains the Outer Message Name - -Python nested message class `__qualname__` now contains the outer message name. -Previously, `__qualname__` had the same result with `__name__` for nested -message, in that the outer message name was not included. - -For example: - -```python -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 -``` - -### Changes in Objective-C {#v30-objc} - -**This is the first breaking release for Objective-C**. - -Objective-C bumped its major version from 3.x.x to 4.30.x. - -#### Overhauled Unknown Field Handling APIs Deprecating Most of the Existing APIs {#objc-field-handling} - -We deprecated `GPBUnknownFieldSet` and replaced it with `GPBUnknownFields`. The -new type preserves the ordering of unknown fields from the original input or API -calls, to ensure any semantic meaning to the ordering is maintained when a -message is written back out. - -As part of this, the `GPBUnknownField` type also has APIs changes, with almost -all of the existing APIs deprecated and new ones added. - -Deprecated property APIs: - -* `varintList` -* `fixed32List` -* `fixed64List` -* `lengthDelimitedList` -* `groupList` - -Deprecated modification APIs: - -* `addVarint:` -* `addFixed32:` -* `addFixed64:` -* `addLengthDelimited:` -* `addGroup:` - -Deprecated initializer `initWithNumber:`. - -New property APIs: - -* `type` -* `varint` -* `fixed32` -* `fixed64` -* `lengthDelimited` -* `group` - -This type models a single field number in its value, rather than *grouping* all -the values for a given field number. The APIs for creating new fields are the -`add*` APIs on the `GPBUnknownFields` class. - -We also deprecated `-[GPBMessage unknownFields]`. In its place, there are new -APIs to extract and update the unknown fields of the message. - -#### Removed Deprecated APIs {#v30-objc-remove-apis} - -We removed the following public runtime APIs, which had been marked deprecated -for at least one minor or major release. - -##### GPBFileDescriptor - -**API:** -[-[`GPBFileDescriptor` syntax]](https://github.com/protocolbuffers/protobuf/blob/44bd65b2d3c0470d91a23cc14df5ffb1ab0af7cd/objectivec/GPBDescriptor.h#L118-L119) - -**Replacement:** Obsolete. - -##### GPBMessage mergeFrom:extensionRegistry - -**API:** -[-[`GPBMessage mergeFrom:extensionRegistry:`]](https://github.com/protocolbuffers/protobuf/blob/44bd65b2d3c0470d91a23cc14df5ffb1ab0af7cd/objectivec/GPBMessage.h#L258-L261) - -**Replacement:** -[-[`GPBMessage mergeFrom:extensionRegistry:error:`]](https://github.com/protocolbuffers/protobuf/blob/44bd65b2d3c0470d91a23cc14df5ffb1ab0af7cd/objectivec/GPBMessage.h#L275-L277) - -##### GPBDuration timeIntervalSince1970 - -**API:** -[-[`GPBDuration timeIntervalSince1970`]](https://github.com/protocolbuffers/protobuf/blob/29fca8a64b62491fb0a2ce61878e70eda88dde98/objectivec/GPBWellKnownTypes.h#L95-L100) - -**Replacement:** -[-[`GPBDuration timeInterval`]](https://github.com/protocolbuffers/protobuf/blob/29fca8a64b62491fb0a2ce61878e70eda88dde98/objectivec/GPBWellKnownTypes.h#L74-L89) - -##### GPBTextFormatForUnknownFieldSet - -**API:** -[`GPBTextFormatForUnknownFieldSet()`](https://github.com/protocolbuffers/protobuf/blob/29fca8a64b62491fb0a2ce61878e70eda88dde98/objectivec/GPBUtilities.h#L32-L43) - -**Replacement:** Obsolete - Use -[`GPBTextFormatForMessage()`](https://github.com/protocolbuffers/protobuf/blob/29fca8a64b62491fb0a2ce61878e70eda88dde98/objectivec/GPBUtilities.h#L20-L30), -which includes any unknown fields. - -##### GPBUnknownFieldSet - -**API:** -[`GPBUnknownFieldSet`](https://github.com/protocolbuffers/protobuf/blob/224573d66a0cc958c76cb43d8b2eb3aa7cdb89f2/objectivec/GPBUnknownFieldSet.h) - -**Replacement:** -[`GPBUnknownFields`](https://github.com/protocolbuffers/protobuf/blob/224573d66a0cc958c76cb43d8b2eb3aa7cdb89f2/objectivec/GPBUnknownFields.h) - -##### GPBMessage unknownFields - -**API:** -[`GPBMessage unknownFields` property](https://github.com/protocolbuffers/protobuf/blob/224573d66a0cc958c76cb43d8b2eb3aa7cdb89f2/objectivec/GPBMessage.h#L73-L76) - -**Replacement:** -[-[`GPBUnknownFields initFromMessage:`]](https://github.com/protocolbuffers/protobuf/blob/224573d66a0cc958c76cb43d8b2eb3aa7cdb89f2/objectivec/GPBUnknownFields.h#L30-L38), -[-[`GPBMessage mergeUnknownFields:extensionRegistry:error:`]](https://github.com/protocolbuffers/protobuf/blob/f26bdff7cc0bb7e8ed88253ba16f81614a26cf16/objectivec/GPBMessage.h#L506-L528), -and -[-[`GPBMessage clearUnknownFields`]](https://github.com/protocolbuffers/protobuf/blob/224573d66a0cc958c76cb43d8b2eb3aa7cdb89f2/objectivec/GPBMessage.h#L497-L504C9) - -#### Removed Deprecated Runtime APIs for Old Gencode {#v30-objc-remove-apis-gencode} - -This release removed deprecated runtime methods that supported the Objective-C -gencode from before the 3.22.x release. The library also issues a log message at -runtime when old generated code is starting up. - -**API:** [`+[GPBFileDescriptor -allocDescriptorForClass:file:fields:fieldCount:storageSize:flags:]`](https://github.com/protocolbuffers/protobuf/blob/1b44ce0feef45a78ba99d09bd2e5ff5052a6541b/objectivec/GPBDescriptor_PackagePrivate.h#L213-L220) - -**Replacement:** Regenerate with a current version of the library. - -**API:** [`+[GPBFileDescriptor -allocDescriptorForClass:rootClass:file:fields:fieldCount:storageSize:flags:]`](https://github.com/protocolbuffers/protobuf/blob/1b44ce0feef45a78ba99d09bd2e5ff5052a6541b/objectivec/GPBDescriptor_PackagePrivate.h#L221-L229) - -**Replacement:** Regenerate with a current version of the library. - -**API:** [`+[GPBEnumDescriptor -allocDescriptorForName:valueNames:values:count:enumVerifier:]`](https://github.com/protocolbuffers/protobuf/blob/1b44ce0feef45a78ba99d09bd2e5ff5052a6541b/objectivec/GPBDescriptor_PackagePrivate.h#L285-L291) - -**Replacement:** Regenerate with a current version of the library. - -**API:** [`+[GPBEnumDescriptor -allocDescriptorForName:valueNames:values:count:enumVerifier:extraTextFormatInfo:]`](https://github.com/protocolbuffers/protobuf/blob/1b44ce0feef45a78ba99d09bd2e5ff5052a6541b/objectivec/GPBDescriptor_PackagePrivate.h#L292-L299) - -**Replacement:** Regenerate with a current version of the library. - -**API:** -[`-[GPBExtensionDescriptor initWithExtensionDescription:]`](https://github.com/protocolbuffers/protobuf/blob/1b44ce0feef45a78ba99d09bd2e5ff5052a6541b/objectivec/GPBDescriptor_PackagePrivate.h#L317-L320) - -**Replacement:** Regenerate with a current version of the library. - -### Other Changes {#v30-other} - -#### Poison Pill Warnings {#poison} - -We updated poison pills to emit warnings for old gencode + new runtime -combinations that work under the new rolling upgrade policy, but will break in -the *next* major bump. For example, Python 4.x.x gencode should work against -5.x.x runtime but warn of upcoming breakage against 6.x.x runtime. - -#### Changes to UTF-8 Enforcement in C# and Ruby {#utf-8-enforcement} - -We included a fix to make UTF-8 enforcement consistent across languages. Users -with bad non-UTF8 data in string fields may see surfaced UTF-8 enforcement -errors earlier. - -#### Ruby and PHP Errors in JSON Parsing - -We fixed non-conformance in JSON parsing of strings in numeric fields per the -[JSON spec](https://protobuf.dev/programming-guides/json/). - -This fix is not accompanied by a major version bump, but Ruby and PHP now raise -errors for non-numeric strings (such as `""`, `"12abc"`, `"abc"`) in numeric -fields. v29.x includes a warning for these error cases. - -## Compiler Changes in v22.0 {#compiler-22} - -### JSON Field Name Conflicts {#json-field-names} - -Source of changes: [PR #11349](https://github.com/protocolbuffers/protobuf/pull/11349), [PR #10750](https://github.com/protocolbuffers/protobuf/pull/10750) - -We've made some subtle changes in how we handle field name conflicts with -respect to JSON mappings. In proto3, we've partially loosened the restrictions -and only give errors when field names produce case-sensitive JSON mappings -(camel case of the original name). We now also check the `json_name` option, and -give errors for case-sensitive conflicts. In proto2, we've tightened -restrictions a bit and will give errors if two `json_name` specifications -conflict. If implicit JSON mappings (camel case) have conflicts, we will give -warnings in proto2. - -We've provided a temporary message/enum option for restoring the legacy -behavior. If renaming the conflicting fields isn't an option you can take -immediately, set the `deprecated_legacy_json_field_conflicts` option on the -specific message/enum. This option will be removed in a future release, but -gives you more time to migrate. - -## C++ API Changes in v22.0 {#cpp-22} - -4.22.0 has breaking changes for C++ runtime and protoc, as -[announced in August](/news/2022-08-03#cpp-changes). - -### Autotools Turndown {#autotools} - -Source of changes: -[PR #10132](https://github.com/protocolbuffers/protobuf/pull/10132) - -In v22.0, we removed all Autotools support from the protobuf compiler and the -C++ runtime. If you're using Autotools to build either of these, you must -migrate to [CMake](http://cmake.org) or [Bazel](http://bazel.build). We have -some -[dedicated instructions](https://github.com/protocolbuffers/protobuf/blob/main/cmake/README.md) -for setting up protobuf with CMake. - -### Abseil Dependency {#abseil} - -Source of changes: -[PR #10416](https://github.com/protocolbuffers/protobuf/pull/10416) - -With v22.0, we've taken on an explicit dependency on -[Abseil](https://github.com/abseil/abseil-cpp). This allowed us to remove most -of our -[stubs](https://github.com/protocolbuffers/protobuf/tree/21.x/src/google/protobuf/stubs), -which were branched from old internal code that later became Abseil. There are a -number of subtle behavior changes, but most should be transparent to users. Some -notable changes include: - -* **string_view** - `absl::string_view` has replaced `const std::string&` in - many of our APIs. This is most-commonly used for input arguments, where - there should be no noticeable change for users. In a few cases (such as - virtual method arguments or return types) users may need to make an explicit - change to use the new signature. - -* **tables** - Instead of STL sets/maps, we now use Abseil's `flat_hash_map`, - `flat_hash_set`, `btree_map`, and `btree_set`. These are more efficient and - allow for [heterogeneous lookup](https://abseil.io/tips/144). This should be - mostly invisible to users, but may cause some subtle behavior changes - related to table ordering. - -* **logging** - Abseil's - [logging library](https://abseil.io/docs/cpp/guides/logging) is very similar - to our old logging code, with just a slightly different spelling (for - example, `ABSL_CHECK` instead of `GOOGLE_CHECK`). The biggest difference is - that it doesn't support exceptions, and will now always crash when `FATAL` - assertions fail. (Previously we had a `PROTOBUF_USE_EXCEPTIONS` flag to - switch to exceptions.) Since these only occur when serious issues are - encountered, we feel unconditional crashing is a suitable response. - - Source of logging changes: [PR #11623](https://github.com/protocolbuffers/protobuf/pull/11623) - -* **Build dependency** - A new build dependency can always cause breakages for - downstream users. We require - [Abseil LTS 20230125](https://github.com/abseil/abseil-cpp/releases/tag/20230125.0) - or later to build. - - * For Bazel builds, Abseil will be automatically downloaded and built at a - pinned LTS release when - [`protobuf_deps`](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_deps.bzl) - is run from your `WORKSPACE`. This should be transparent, but if you - depend on an older version of Abseil, you'll need to upgrade your - dependency. - - * For CMake builds, we will first look for an existing Abseil installation - pulled in by the top-level CMake configuration (see - [instructions](https://github.com/abseil/abseil-cpp/blob/master/CMake/README#traditional-cmake-set-up)). - Otherwise, if `protobuf_ABSL_PROVIDER` is set to `module` (its default) - we will attempt to build and link Abseil from our git - [submodule](https://github.com/protocolbuffers/protobuf/tree/main/third_party). - If `protobuf_ABSL_PROVIDER` is set to `package`, we will look for a - pre-installed system version of Abseil. - -### Changes in GetCurrentTime Method {#getcurrenttime} - -On Windows, `GetCurrentTime()` is the name of a macro provided by the system. -Prior to v22.x, Protobuf incorrectly removed the macro definition for -`GetCurrentTime()`. That made the macro unusable for Windows developers after -including ``. Starting with v22.x, Protobuf preserves -the macro definition. This may break customer code relying on the previous -behavior, such as if they use the expression -[`google::protobuf::util::TimeUtil::GetCurrentTime()`](/reference/cpp/api-docs/google.protobuf.util.time_util#TimeUtil). - -To migrate your app to the new behavior, change your code to do one of the -following: - -* if the `GetCurrent` macro is defined, explicitly undefine the - `GetCurrentTime` macro -* prevent the macro expansion by using - `(google::protobuf::util::TimeUtil::GetCurrentTime)()` or a similar - expression - -#### Example: Undefining the macro - -Use this approach if you don't use the macro from Windows. - -Before: - -```cpp -#include - -void F() { - auto time = google::protobuf::util::TimeUtil::GetCurrentTime(); -} -``` - -After: - -```cpp -#include -#ifdef GetCurrentTime -#undef GetCurrentTime -#endif - -void F() { - auto time = google::protobuf::util::TimeUtil::GetCurrentTime(); -} -``` - -**Example 2: Preventing macro expansion** - -Before: - -```cpp -#include - -void F() { - auto time = google::protobuf::util::TimeUtil::GetCurrentTime(); -} -``` - -After: - -```cpp -#include - -void F() { - auto time = (google::protobuf::util::TimeUtil::GetCurrentTime)(); -} -``` - -## C++20 Support {#cpp20} - -Source of changes: [PR #10796](https://github.com/protocolbuffers/protobuf/pull/10796) - -To support C++20, we've reserved the new -[keywords](https://en.cppreference.com/w/cpp/keyword) in C++ generated protobuf -code. As with other reserved keywords, if you use them for any fields, enums, or -messages, we will add an underscore suffix to make them valid C++. For example, -a `concept` field will generate a `concept_()` getter. In the scenario where you -have existing protos that use these keywords, you'll need to update the C++ code -that references them to add the appropriate underscores. - -### Final Classes {#final-classes} - -Source of changes: [PR #11604](https://github.com/protocolbuffers/protobuf/pull/11604) - -As part of a larger effort to harden assumptions made in the Protobuf library, -we've marked some classes `final` that were never intended to be inherited from. -There are no known use cases for inheriting from these, and doing so would -likely cause problems. There is no mitigation if your code is inheriting from -these classes, but if you think you have some valid reason for the inheritance -you're using, you can -[open an issue](https://github.com/protocolbuffers/protobuf/issues). - -### Container Static Assertions {#container-static-assertions} - -Source of changes: [PR #11550](https://github.com/protocolbuffers/protobuf/pull/11550) - -As part of a larger effort to harden assumptions made in the Protobuf library, -we've added static assertions to the `Map`, `RepeatedField`, and -`RepeatedPtrField` containers. These ensure that you're using these containers -with only expected types, as -[covered in our documentation](https://protobuf.dev/programming-guides/proto/#maps). -If you hit these static assertions, you should migrate your code to use Abseil -or STL containers. `std::vector` is a good drop-in replacement for repeated -field containers, and `std::unordered_map` or `absl::flat_hash_map` for `Map` -(the former gives similar pointer stability, while the latter is more -efficient). - -### Cleared Element Deprecation {#cleared-elements} - -Source of changes: [PR #11588](https://github.com/protocolbuffers/protobuf/pull/11588), [PR #11639](https://github.com/protocolbuffers/protobuf/pull/11639) - -The `RepeatedPtrField` API around "cleared fields" has been deprecated, and will -be fully removed in a later breaking release. This was originally added as an -optimization for reusing elements after they've been cleared, but ended up not -working well. If you're using this API, you should consider migrating to arenas -for better memory reuse. - -### UnsafeArena Deprecation {#unsafe-arena} - -Source of changes: [PR #10325](https://github.com/protocolbuffers/protobuf/pull/10325) - -As part of a larger effort to remove arena-unsafe APIs, we've hidden -`RepeatedField::UnsafeArenaSwap`. This is the only one we've removed so far, but -in later releases we will continue to remove them and provide helpers to handle -efficient borrowing patterns between arenas. Within a single arena (or the -stack/heap), `Swap` is just as efficient as `UnsafeArenaSwap`. The benefit is -that it won't cause invalid memory operations if you accidentally call it across -different arenas. - -### Map Pair Upgrades {#map-pairs} - -Source of changes: [PR #11625](https://github.com/protocolbuffers/protobuf/pull/11625) - -For v22.0 we've started cleaning up the `Map` API to make it more consistent -with Abseil and STL. Notably, we've replaced the `MapPair` class with an alias -to `std::pair`. This should be transparent for most users, but if you were using -the class directly you may need to update your code. - -### New JSON Parser {#json-parser} - -Source of changes: [PR #10729](https://github.com/protocolbuffers/protobuf/pull/10729) - -We have rewritten the C++ JSON parser this release. It should be mostly a hidden -change, but inevitably some undocumented quirks my have changed; test -accordingly. Parsing documents that are not valid RFC-8219 JSON (such as those -that are missing quotes or using non-standard bools) is deprecated and will be -removed in a future release. The serialization order of fields is now guaranteed -to match the field number order, where before it was less deterministic. - -As part of this migration, all of the files under -[util/internal](https://github.com/protocolbuffers/protobuf/tree/21.x/src/google/protobuf/util/internal) -have been deleted. These were used in the old parser, and were never intended to -be used externally. - -### `Arena::Init` {#arena-init} - -Source of changes: [PR #10623](https://github.com/protocolbuffers/protobuf/pull/10623) - -The `Init` method in `Arena` was code that didn't do anything, and has now been -removed. If you were calling this method, you likely meant to call the `Arena` -constructor directly with a set of `ArenaOptions`. You should either delete the -call or migrate to that constructor. - -### ErrorCollector Migration {#error-collector} - -Source of changes: [PR #11555](https://github.com/protocolbuffers/protobuf/pull/11555) - -As part of our Abseil migration, we're moving from `const std::string&` to -`absl::string_view`. For our three error collector classes, this can't be done -without breaking existing code. For v22.0, we've decided to release both -variants, and rename the methods from `AddError` and `AddWarning` to -`RecordError` and `RecordWarning`. The old signature has been marked deprecated, -and will be slightly less efficient (due to string copies), but will otherwise -still work. You should migrate these to the new version, as the `Add*` methods -will be removed in a later breaking release. diff --git a/content/support/version-support.md b/content/support/version-support.md deleted file mode 100644 index 6dea8b257..000000000 --- a/content/support/version-support.md +++ /dev/null @@ -1,743 +0,0 @@ -+++ -title = "Version Support" -weight = 910 -description = "A list of the support windows provided for language implementations." -aliases = "/version-support/" -type = "docs" -+++ - - - -## Currently Supported Release Versions {#currently-supported} - -Language | Active Support | Maintenance Only | Minimum Gencode --------- | -------------- | --------------------- | --------------- -protoc | 34.x | 29.x, 25.x (for Java) | -C++ | 7.34.x | 5.29.x | Exact Match -C# | 3.34.x | | 3.0.0 -Java | 4.34.x | 3.25.x | 3.0.0 -PHP | 5.34.x | | 4.0.0 -Python | 7.34.x | 5.29.x | [3.20.0](https://protobuf.dev/support/cross-version-runtime-guarantee#python) -Ruby | 4.34.x | | 3.0.0 - -### Minimum Supported Gencode {#min-gencode} - -While each language runtime has a minimum supported gencode version, we -recommend regenerating your gencode with every release update. Support for older -generated code exists solely to ensure backwards compatibility for existing -projects, not for new adoption of older gencode versions. - -See -[Cross Version Runtime Guarantee](/support/cross-version-runtime-guarantee) -for more information. - -## Supported Editions {#supported-editions} - -Protobuf release versions are independent of edition "versions" (proto2, proto3, -2023, 2024). All currently supported release versions support all editions. - -The current supported editions are: - -Edition | Released Version | Date Released -------- | ---------------- | ------------- -2024 | 32.0 | 23 May 2025 -2023 | 27.0 | 13 Aug 2024 -proto3 | 3.0 | 2016 -proto2 | 2.0 | 2008 - -## Numbering Scheme {#numbering} - -Version numbers use [SemVer](https://semver.org) conventions. In the version -"3.21.7", "3" is the major version, "21" is the minor version, and "7" is the -patch number. - -Protobuf releases use only a `minor.point` format, for example `29.5`. - -Each language runtime shares this `minor.point` but uses a language-specific -major version. For example, Protobuf release `29.5` corresponds to Java runtime -`4.29.5` and C# runtime `3.29.5`. We recommend using `protoc` `29.5` with Java -`4.29.5` and C# `3.29.5`. - -This scheme unifies release numbers across all languages while decoupling major -version changes. For example, release `30.0` contained breaking changes for -Python but not for Java. Therefore, Python advanced from `5.29.0` to `6.30.0`, -while Java advanced from `4.29.0` to `4.30.0`. - -We introduced this versioning scheme in 2022 with release 21. Previously, all -languages used major version 3. - -## Release Cadence {#cadence} - -Protobuf releases updates quarterly. We target major (breaking) releases for Q1. -Security fixes and other urgent needs will require additional releases. - -Our -[library breaking change policy](https://opensource.google/documentation/policies/library-breaking-change) -defines our support windows. - -Enforcing documented language, tooling, platform, and library support policies -is *not* a breaking change. For example, we might drop support for an -End-of-Life (EOL) language version without bumping the major version. - -## What Changes in a Release? {#changes} - -**The binary wire format never changes.** You can read old binary wire format -data with newer Protobuf versions. You can read new binary wire format data with -older Protobuf versions (as long as the .proto syntax is supported). ProtoJSON -format offers these same stability guarantees. TextProto is intended to be used -for configuration use-cases and should not be used as a wire format between two -servers. - -**The `descriptor.proto` schema can change.** In minor or patch releases, we -might add or deprecate elements (messages, fields, enums, enum values, editions, -or editions [features](/editions/features)). In releases -with breaking changes (major releases), we might remove deprecated elements. - -**The `.proto` language grammar can change with new Editions**. In minor -release, support for a new Edition may be added, which will add language -constructs or deprecate existing behaviors. Adopting a new Edition may require -client code updates. A future release may drop support for an old syntax. -However, we have no current concrete plans to do so. - -**Gencode and runtime APIs can change.** Minor and patch releases include purely -additive or source-compatible updates. You can simply recompile your code. -Releases with breaking changes (major releases) introduce incompatible API -changes that require callsite updates. We minimize these changes. Bug fixes for -undefined behavior do not require a major release. - -**Operating system, programming language, and tooling support can change.** -Minor or patch releases might add or drop support for specific operating -systems, programming languages, or tools. See the -[foundational support matrices](https://github.com/google/oss-policies-info/tree/main) -for supported languages. - -In general: - -* Minor or patch releases include purely additive or source-compatible updates - based on our - [Cross Version Runtime Guarantee](https://protobuf.dev/support/cross-version-runtime-guarantee/#minor). -* Major releases might remove functionality, features, or change APIs in ways - that require updates to callsites. - -## Support Duration {#duration} - -We always support the most recent release. Releasing a new minor version -immediately ends support for the previous minor version. Releasing a major -version ends support for the previous major version four quarters later. - -For example, Protobuf Python 5.26.0 launched in Q1 2024. Therefore, Protobuf -Python 4.25.x support ended in [Q1 2025](#python). - -The following sections detail support timelines for each language. Future plans -appear in *italics* and might change. - -**Legend** - - - - - - - - - - - - - - - - - - -
ActiveMinor and patch releases with new features, compatible changes, and bug fixes.
MaintenancePatch releases with critical bug and security vulnerability fixes.
End of LifeRelease is unsupported. Users should upgrade to a supported release.
FutureProjected release. Shown for planning purposes.
- -## C++ {#cpp} - -**Release Support Dates** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Protobuf C++Release dateEnd of support
3.x25 May 202231 Mar 2024
4.x16 Feb 202331 Mar 2025
5.x13 Mar 202431 Mar 2026
6.x4 Mar 202531 Mar 2027
7.x25 Feb 2026TBD
- -**Release Support Chart** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Protobuf C++protoc23Q223Q323Q424Q124Q224Q324Q425Q125Q225Q325Q426Q1
3.x21.x3.21
4.x22.x-25.x4.234.244.254.25
5.x26.x-29.x5.265.275.285.295.29
6.x30.x-33.x6.306.316.326.336.33
7.x34.x+7.34
- -### C++ Tooling, Platform, and Library Support {#cpp-tooling} - -Protobuf follows the -[Foundational C++ Support Policy](https://opensource.google/documentation/policies/cplusplus-support). -For supported versions, see the -[Foundational C++ Support Matrix](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md). - -## C# {#csharp} - -**Release Support Dates** - - - - - - - - - - - - -
Protobuf C#Release dateEnd of support
3.x25 May 2022TBD
- -**Release Support Chart** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Protobuf C#protoc23Q223Q323Q424Q124Q224Q324Q425Q125Q225Q325Q426Q1
3.x21.x+3.233.243.253.263.273.283.293.303.313.323.333.34
- -### C# Platform and Library Support {#csharp-support} - -Protobuf is committed to following the platform and library support policy -described in -[.NET Support Policy](https://opensource.google/documentation/policies/dotnet-support). -For specific versions supported, see -[Foundational .NET Support Matrix](https://github.com/google/oss-policies-info/blob/main/foundational-dotnet-support-matrix.md). - -## Java {#java} - -**Release Support Dates** - - - - - - - - - - - - - - - - - - - - - - -
Protobuf JavaRelease dateEnd of support
3.x25 May 202231 Mar 2027*
4.x13 Mar 202431 Mar 2028
5.xQ1 2027*31 Mar 2029
- -**Release Support Chart** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Protobuf Javaprotoc23Q223Q323Q424Q124Q224Q324Q425Q125Q225Q325Q426Q1
3.x21.x-25.x3.233.243.253.25
4.x26.x+4.264.274.284.294.304.314.324.334.34
- -{{% alert title="Note" color="note" %}} -The maintenance support window for the Protobuf Java 3.x release line is 36 -months instead of the typical 12 -months.{{% /alert %}} - -### Java Platform and Library Support {#java-support} - -Protobuf follows the -[Java Support Policy](https://cloud.google.com/java/docs/supported-java-versions). -For supported versions, see the -[Foundational Java Support Matrix](https://github.com/google/oss-policies-info/blob/main/foundational-java-support-matrix.md). - -On Android, Protobuf supports the minimum SDK version defined by -[Google Play services](https://developers.google.com/android/guides/setup) or -the default in -[Jetpack](https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/docs/api_guidelines/modules#module-minsdkversion). -We support whichever version is lower. - -## PHP {#php} - -**Release Support Dates** - - - - - - - - - - - - - - - - - - - - - - -
Protobuf PHPRelease dateEnd of support
3.x25 May 202231 Mar 2025
4.x13 Mar 202431 Mar 2026
5.x25 Feb 2026TBD
- -**Release Support Chart** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Protobuf PHPprotoc23Q223Q323Q424Q124Q224Q324Q425Q125Q225Q325Q426Q1
3.x21.x-25.x3.233.243.253.25
4.x26.x - 33.x4.264.274.284.294.304.314.324.334.33
5.x34.x+5.34
- -### PHP Platform and Library Support {#php-support} - -Protobuf follows the -[PHP Support Policy](https://cloud.google.com/php/getting-started/supported-php-versions). -For supported versions, see the -[Foundational PHP Support Matrix](https://github.com/google/oss-policies-info/blob/main/foundational-php-support-matrix.md). - -## Python {#python} - -**Release Support Dates** - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Protobuf PythonRelease dateEnd of support
4.x25 May 202231 Mar 2025
5.x13 Mar 202431 Mar 2026
6.x4 Mar 202531 Mar 2027
7.x25 Feb 2026TBD
- -**Release Support Chart** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Protobuf Pythonprotoc23Q223Q323Q424Q124Q224Q324Q425Q125Q225Q325Q426Q1
4.x21.x-25.x4.234.244.254.25
5.x26.x-29.x5.265.275.285.295.29
6.x30.x-33.x6.306.316.326.336.33
7.x34.x+7.34
- -### Python Platform and Library Support {#python-support} - -Protobuf follows the -[Python Support Policy](https://cloud.google.com/python/docs/supported-python-versions). -For supported versions, see the -[Foundational Python Support Matrix](https://github.com/google/oss-policies-info/blob/main/foundational-python-support-matrix.md). - -## Ruby {#ruby} - -**Release Support Dates** - - - - - - - - - - - - - - - - - -
Protobuf RubyRelease dateEnd of support
3.x25 May 202231 Mar 2025
4.x13 Mar 2024TBD
- -**Release Support Chart** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Protobuf Rubyprotoc23Q223Q323Q424Q124Q224Q324Q425Q125Q225Q325Q426Q1
3.x21.x-25.x3.233.243.253.25
4.x26.x+4.264.274.284.294.304.314.324.334.34
- -### Ruby Platform and Library Support {#ruby-support} - -Protobuf follows the -[Ruby Support Policy](https://cloud.google.com/ruby/getting-started/supported-ruby-versions). -For supported versions, see the -[Foundational Ruby Support Matrix](https://github.com/google/oss-policies-info/blob/main/foundational-ruby-support-matrix.md). - -We do not officially support JRuby. However, we provide unofficial, best-effort -support for the latest JRuby version. This targets compatibility with our -minimum supported Ruby version. diff --git a/css/prism.css b/css/prism.css new file mode 100644 index 000000000..716b70d6c --- /dev/null +++ b/css/prism.css @@ -0,0 +1,4 @@ +/* PrismJS 1.28.0 +https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+bash+c+csharp+cpp+go+java+markdown+python+scss+sql+toml+yaml&plugins=toolbar+copy-to-clipboard */ +code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help} +div.code-toolbar{position:relative}div.code-toolbar>.toolbar{position:absolute;z-index:10;top:.3em;right:.2em;transition:opacity .3s ease-in-out;opacity:0}div.code-toolbar:hover>.toolbar{opacity:1}div.code-toolbar:focus-within>.toolbar{opacity:1}div.code-toolbar>.toolbar>.toolbar-item{display:inline-block}div.code-toolbar>.toolbar>.toolbar-item>a{cursor:pointer}div.code-toolbar>.toolbar>.toolbar-item>button{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}div.code-toolbar>.toolbar>.toolbar-item>a,div.code-toolbar>.toolbar>.toolbar-item>button,div.code-toolbar>.toolbar>.toolbar-item>span{color:#bbb;font-size:.8em;padding:0 .5em;background:#f5f2f0;background:rgba(224,224,224,.2);box-shadow:0 2px 0 0 rgba(0,0,0,.2);border-radius:.5em}div.code-toolbar>.toolbar>.toolbar-item>a:focus,div.code-toolbar>.toolbar>.toolbar-item>a:hover,div.code-toolbar>.toolbar>.toolbar-item>button:focus,div.code-toolbar>.toolbar>.toolbar-item>button:hover,div.code-toolbar>.toolbar>.toolbar-item>span:focus,div.code-toolbar>.toolbar>.toolbar-item>span:hover{color:inherit;text-decoration:none} diff --git a/design-decisions/index.html b/design-decisions/index.html new file mode 100644 index 000000000..c892160ba --- /dev/null +++ b/design-decisions/index.html @@ -0,0 +1,11 @@ +Protobuf Team Design Decisions | Protocol Buffers Documentation +

Protobuf Team Design Decisions

Covers the design decisions the Protobuf team has made

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 newline at end of file diff --git a/design-decisions/index.xml b/design-decisions/index.xml new file mode 100644 index 000000000..f6e1676d4 --- /dev/null +++ b/design-decisions/index.xml @@ -0,0 +1,2 @@ +Protobuf Team Design Decisions on Protocol Buffers Documentationhttps://protobuf.dev/design-decisions/Recent content in Protobuf Team Design Decisions on Protocol Buffers DocumentationHugoenNo Nullable Setters/Getters Supporthttps://protobuf.dev/design-decisions/nullable-getters-setters/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/design-decisions/nullable-getters-setters/We have heard feedback that some folks would like protobuf to support nullable getters/setters in their null-friendly language of choice (particularly Kotlin, C#, and Rust). While this does seem to be a helpful feature for folks using those languages, the design choice has tradeoffs which have led to the Protobuf team choosing not to implement them. +Explicit presence is not a concept that directly maps to the traditional notion of nullability. \ No newline at end of file diff --git a/design-decisions/nullable-getters-setters/index.html b/design-decisions/nullable-getters-setters/index.html new file mode 100644 index 000000000..564e1ba66 --- /dev/null +++ b/design-decisions/nullable-getters-setters/index.html @@ -0,0 +1,60 @@ +No Nullable Setters/Getters Support | Protocol Buffers Documentation +

No Nullable Setters/Getters Support

Covers why Protobuf doesn’t support nullable setters and getters

We have heard feedback that some folks would like protobuf to support nullable +getters/setters in their null-friendly language of choice (particularly Kotlin, +C#, and Rust). While this does seem to be a helpful feature for folks using +those languages, the design choice has tradeoffs which have led to the Protobuf +team choosing not to implement them.

Explicit presence is not a concept that directly maps to the traditional notion +of nullability. It is subtle, but explicit presence philosophy is closer to “the +fields are not nullable, but you can detect if the field was explicitly assigned +a value or not. Normal access will see some default value if it is not assigned, +but you can check if the field was actively written to or not, when needed.”

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:

message Msg { Child child = 1; }
+message Child { Grandchild grandchild = 1; }
+message Grandchild { int32 foo = 1 [default = 72]; }
+

and corresponding Kotlin getters:

// With our API where getters are always non-nullable:
+msg.child.grandchild.foo == 72
+
+// With nullable submessages the ?. operator fails to get the default value:
+msg?.child?.grandchild?.foo == null
+
+// Or verbosely duplicating the default value at the usage site:
+(msg?.child?.grandchild?.foo ?: 72)
+

and corresponding Rust getters:

// With our API:
+msg.child().grandchild().foo()   // == 72
+
+// Where every getter is an Option<T>, verbose and no default observed
+msg.child().map(|c| c.grandchild()).map(|gc| gc.foo()) // == Option::None
+
+// For the rare situations where code may want to observe both the presence and
+// value of a field, the _opt() accessor which returns a custom Optional type
+// can also be used here (the Optional type is similar to Option except can also
+// be aware of the default value):
+msg.child().grandchild().foo_opt() // Optional::Unset(72)
+

If a nullable getter existed, it would necessarily ignore the user-specified +defaults (to return null instead) which would lead to surprising and +inconsistent behavior. If users of nullable getters want to access the default +value of the field, they would have to write their own custom handling to use +the default if null is returned, which removes the supposed benefit of +cleaner/easier code with null getters.

Similarly, we do not provide nullable setters as the behavior would be +unintuitive. Performing a set and then get would not always give the same value +back, and calling a set would only sometimes affect the has-bit for the field.

Note that message-typed fields are always explicit presence fields (with +hazzers). Proto3 defaults to scalar fields having implicit presence (without +hazzers) unless they are explicitly marked optional, while Proto2 does not +support implicit presence. With +Editions, explicit +presence is the default behavior unless an implicit presence feature is used. +With the forward expectation that almost all fields will have explicit presence, +the ergonomic concerns that come with nullable getters are expected to be more +of a concern than they may have been for Proto3 users.

Due to these issues, nullable setters/getters would radically change the way +default values can be used. While we understand the possible utility, we have +decided it’s not worth the inconsistencies and difficulty it introduces.

\ No newline at end of file diff --git a/downloads/index.html b/downloads/index.html new file mode 100644 index 000000000..d15d243a1 --- /dev/null +++ b/downloads/index.html @@ -0,0 +1,11 @@ +Downloads | Protocol Buffers Documentation +

Downloads

The downloads page for protocol buffers.

Release Packages

Latest Version

The latest release of Protocol Buffers can be found on the +release page.

Old Versions

Older versions are available in our historical releases +on GitHub.

Source Code

GitHub Repository

Protocol Buffers source code is hosted on +GitHub.

\ No newline at end of file diff --git a/editions/features/index.html b/editions/features/index.html new file mode 100644 index 000000000..ff86afdce --- /dev/null +++ b/editions/features/index.html @@ -0,0 +1,512 @@ +Feature Settings for Editions | Protocol Buffers Documentation +

Feature Settings for Editions

Protobuf Editions features and how they affect protobuf behavior.

This topic provides an overview of the features that are included in the +released edition versions. Subsequent editions’ features will be added to this +topic. We announce new editions in +the News section.

Before configuring feature settings in your new schema definition content, make +sure you understand why you are using them. Avoid +cargo-culting with +features.

Prototiller

Prototiller is a command-line tool that updates proto schema configuration files +between syntax versions and editions. It hasn’t been released yet, but is +referenced throughout this topic.

Features

The following sections include all of the behaviors that are configurable using +features in editions. Preserving proto2 or proto3 Behavior shows +how to override the default behaviors so that your proto definition files act +like proto2 or proto3 files. For more information on how editions and features +work together to set behavior, see +Protobuf Editions Overview.

Feature settings apply at different levels:

File-level: These settings apply to all elements (messages, fields, enums, +and so on) that don’t have an overriding setting.

Non-nested: Messages, enums, and services can override settings made at the +file level. They apply to everything within them (message fields, enum values) +that aren’t overridden, but don’t apply to other parallel messages and enums.

Nested: Oneofs, messages, and enums can override settings from the message +they’re nested in.

Lowest-level: Fields, extensions, enum values, extension ranges, and methods +are the lowest level at which you can override settings.

Each of the following sections has a comment that states what scope the feature +can be applied to. The following sample shows a mock feature applied to each +scope:

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 this example, the setting “GRAULT" in the lowest-level scope feature +definition overrides the non-nested-scope “QUUX” setting. And within the +Garply message, “WALDO” overrides “QUUX.”

features.default_symbol_visibility

This feature enables setting the default visibility for messages and enums, +making them available or unavailable when imported by other protos. Use of this +feature will reduce dead symbols in order to create smaller binaries.

In addition to setting the defaults for the entire file, you can use the local +and export keywords to set per-field behavior. Read more about this at +export / local Keywords.

Values available:

  • EXPORT_ALL: This is the default prior to Edition 2024. All messages and +enums are exported by default.
  • EXPORT_TOP_LEVEL: All top-level symbols default to export; nested default +to local.
  • LOCAL_ALL: All symbols default to local.
  • STRICT: All symbols local by default. Nested types cannot be exported, +except for a special-case caveat for message { enum {} reserved 0 to max; }. This will become the default in a future edition.

Applicable to the following scope: file

Added in: Edition 2024

Default behavior per syntax/edition:

Syntax/editionDefault
2024EXPORT_TOP_LEVEL
2023EXPORT_ALL
proto3EXPORT_ALL
proto2EXPORT_ALL

Note: Feature settings on different schema elements +have different scopes.

The following sample shows how you can apply the feature to elements in your +proto schema definition files:

// 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

Introduced in Edition 2024, this feature enables strict naming style enforcement +as defined in +the style guide to ensure +protos are round-trippable by default with a feature value to opt-out to use

Values available:

  • STYLE2024: Enforces strict adherence to the style guide for naming.
  • STYLE_LEGACY: Applies the pre-Edition 2024 level of style guide +enforcement.

Applicable to the following scopes: file, extension range, message, field, +oneof, enum, enum value, service, method

Added in: Edition 2024

Default behavior per syntax/edition:

Syntax/editionDefault
2024STYLE2024
2023STYLE_LEGACY
proto3STYLE_LEGACY
proto2STYLE_LEGACY

Note: Feature settings on different schema elements +have different scopes.

The following code sample shows an Edition 2023 file:

Edition 2023 defaults to STYLE_LEGACY, so a non-conformant field name is fine:

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

Edition 2024 defaults to STYLE2024, so an override is needed to keep the +non-conformant field name:

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

This feature sets the behavior for how enum values that aren’t contained within +the defined set are handled. See +Enum Behavior for more +information on open and closed enums.

This feature doesn’t impact proto3 files, so this section doesn’t have a before +and after of a proto3 file.

Values available:

  • CLOSED: Closed enums store enum values that are out of range in the +unknown field set.
  • OPEN: Open enums parse out of range values into their fields directly.

Applicable to the following scopes: file, enum

Added in: Edition 2023

Default behavior per syntax/edition:

Syntax/editionDefault
2024OPEN
2023OPEN
proto3OPEN
proto2CLOSED

Note: Feature settings on different schema elements +have different scopes.

The following code sample shows a proto2 file:

syntax = "proto2";
+
+enum Foo {
+  A = 2;
+  B = 4;
+  C = 6;
+}
+

After running Prototiller, the equivalent code might look like +this:

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

This feature sets the behavior for tracking field presence, or the notion of +whether a protobuf field has a value.

Values available:

  • LEGACY_REQUIRED: The field is required for parsing and serialization. +Any explicitly-set value is +serialized onto the wire (even if it is the same as the default value).
  • EXPLICIT: The field has explicit presence tracking. Any explicitly-set +value is serialized onto the wire (even if it is the same as the default +value). For singular primitive fields, has_* functions are generated for +fields set to EXPLICIT.
  • IMPLICIT: The field has no presence tracking. The default value is not +serialized onto the wire (even if it is explicitly set). has_* functions +are not generated for fields set to IMPLICIT.

Applicable to the following scopes: file, field

Added in: Edition 2023

Default behavior per syntax/edition:

Syntax/editionDefault
2024EXPLICIT
2023EXPLICIT
proto3IMPLICIT*
proto2EXPLICIT

* proto3 is IMPLICIT unless the field has the optional label, in which case +it behaves like EXPLICIT. See +Presence in Proto3 APIs +for more information.

Note: Feature settings on different schema elements +have different scopes.

The following code sample shows a proto2 file:

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

After running Prototiller, the equivalent code might look like this:

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

The following shows a proto3 file:

syntax = "proto3";
+
+message Bar {
+  int32 x = 1;
+  optional int32 y = 2;
+  repeated int32 z = 3;
+}
+

After running Prototiller, the equivalent code might look like this:

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

Note that the required and optional labels no longer exist in Editions, as +the corresponding behavior is set explicitly with the field_presence feature.

features.json_format

This feature sets the behavior for JSON parsing and serialization.

This feature doesn’t impact proto3 files, so this section doesn’t have a before +and after of a proto3 file. Editions behavior matches the behavior in proto3.

Values available:

  • ALLOW: A runtime must allow JSON parsing and serialization. Checks are +applied at the proto level to make sure that there is a well-defined mapping +to JSON.
  • LEGACY_BEST_EFFORT: A runtime does the best it can to parse and serialize +JSON. Certain protos are allowed that can result in unspecified behavior at +runtime (such as many:1 or 1:many mappings).

Applicable to the following scopes: file, message, enum

Added in: Edition 2023

Default behavior per syntax/edition:

Syntax/editionDefault
2024ALLOW
2023ALLOW
proto3ALLOW
proto2LEGACY_BEST_EFFORT

Note: Feature settings on different schema elements +have different scopes.

The following code sample shows a proto2 file:

syntax = "proto2";
+
+message Foo {
+  // Warning only
+  string bar = 1;
+  string bar_ = 2;
+}
+

After running Prototiller, the equivalent code might look like this:

edition = "2024";
+option features.json_format = LEGACY_BEST_EFFORT;
+
+message Foo {
+  string bar = 1;
+  string bar_ = 2;
+}
+

features.message_encoding

This feature sets the behavior for encoding fields when serializing.

This feature doesn’t impact proto3 files, so this section doesn’t have a before +and after of a proto3 file.

Depending on the language, fields that are “group-like” may have some unexpected +capitalization in generated code and in text-format, in order to provide +backwards compatibility with proto2. Message fields are “group-like” if all of +the following conditions are met:

  • Has DELIMITED message encoding specified
  • Message type is defined in the same scope as the field
  • Field name is exactly the lowercased type name

Values available:

  • LENGTH_PREFIXED: Fields are encoded using the LEN wire type described in +Message Structure.
  • DELIMITED: Message-typed fields are encoded as +groups.

Applicable to the following scopes: file, field

Added in: Edition 2023

Default behavior per syntax/edition:

Syntax/editionDefault
2024LENGTH_PREFIXED
2023LENGTH_PREFIXED
proto3LENGTH_PREFIXED
proto2LENGTH_PREFIXED

Note: Feature settings on different schema elements +have different scopes.

The following code sample shows a proto2 file:

syntax = "proto2";
+
+message Foo {
+  group Bar = 1 {
+    optional int32 x = 1;
+    repeated int32 y = 2;
+  }
+}
+

After running Prototiller, the equivalent code might look like this:

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

features.repeated_field_encoding

This feature is what the proto2/proto3 +packed option +for repeated fields has been migrated to in Editions.

Values available:

  • PACKED: Repeated fields of a primitive type are encoded as a single LEN +record that contains each element concatenated.
  • EXPANDED: Repeated fields are each encoded with the field number for +each value.

Applicable to the following scopes: file, field

Added in: Edition 2023

Default behavior per syntax/edition:

Syntax/editionDefault
2024PACKED
2023PACKED
proto3PACKED
proto2EXPANDED

Note: Feature settings on different schema elements +have different scopes.

The following code sample shows a proto2 file:

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

After running Prototiller, the equivalent code might look like this:

edition = "2024";
+option features.repeated_field_encoding = EXPANDED;
+
+message Foo {
+  repeated int32 bar = 6 [features.repeated_field_encoding=PACKED];
+  repeated int32 baz = 7;
+}
+

The following shows a proto3 file:

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

After running Prototiller, the equivalent code might look like this:

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

features.utf8_validation

This feature sets how strings are validated. It applies to all languages except +where there’s a language-specific utf8_validation feature that overrides it. +See features.(pb.java).utf8_validation for the +Java-language-specific feature.

This feature doesn’t impact proto3 files, so this section doesn’t have a before +and after of a proto3 file.

Values available:

  • VERIFY: The runtime should verify UTF-8. This is the default proto3 +behavior.
  • NONE: The field behaves like an unverified bytes field on the wire. +Parsers may handle this type of field in an unpredictable way, such as +replacing invalid characters. This is the default proto2 behavior.

Applicable to the following scopes: file, field

Added in: Edition 2023

Default behavior per syntax/edition:

Syntax/editionDefault
2024VERIFY
2023VERIFY
proto3VERIFY
proto2NONE

Note: Feature settings on different schema elements +have different scopes.

The following code sample shows a proto2 file:

syntax = "proto2";
+
+message MyMessage {
+  string foo = 1;
+}
+

After running Prototiller, the equivalent code might look like this:

edition = "2024";
+
+message MyMessage {
+  string foo = 1 [features.utf8_validation = NONE];
+}
+

Language-specific Features

Some features apply to specific languages, and not to the same protos in other +languages. Using these features requires you to import the corresponding +*_features.proto file from the language’s runtime. The examples in the following +sections show these imports.

features.(pb.go).api_level

Languages: Go

The api_level feature enables you to select which API version the Go protobuf +plugin should generate code for. The Opaque API is the latest version of the +Protocol Buffers implementation for the Go programming language. The previous +version is now called Open Struct API. See the +Go Protobuf: Releasing the Opaque API +blog post for an introduction.

Values available:

  • API_OPEN: The Open Struct API generates struct types that are open to +direct access.
  • API_HYBRID: Hybrid is a step between Open and Opaque: The Hybrid API also +includes accessor methods (so you can update your code), but still exports +the struct fields as before. There is no performance difference; this API +level only helps with the migration.
  • API_OPAQUE: With the Opaque API, the struct fields are hidden and can no +longer be directly accessed. Instead, the new accessor methods allow for +getting, setting, or clearing a field.

Applicable to the following scopes: message, file

Added in: Edition 2023

Default behavior per syntax/edition:

Syntax/editionDefault
2023API_OPEN
2024API_OPAQUE

Note: Feature settings on different schema elements +have different scopes.

You can set the api_level feature starting in edition 2023:

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

See also: +Opaque API: Migration

features.(pb.cpp).enum_name_uses_string_view

Languages: C++

Before Edition 2024, all generated enum types provide the following function to +obtain the label out of an enum value, which has some overhead to construct the +std::string instances at runtime:

const std::string& Foo_Name(int);
+

The default feature value in Edition 2024 changes this signature to return +absl::string_view to allow for better storage decoupling and potential +memory/CPU savings. If you aren’t ready to migrate, yet, you can override this +to set it back to its previous behavior. See +string_view return type +in the migration guide for more on this topic.

Values available:

  • true: The enum uses string_view for its values.
  • false: The enum uses std::string for its values.

Applicable to the following scopes: file, enum

Added in: Edition 2024

Default behavior per syntax/edition:

Syntax/editionDefault
2024true
2023false
proto3false
proto2false

Note: Feature settings on different schema elements +have different scopes.

features.(pb.java).large_enum

Languages: Java

This language-specific feature enables you to adopt new functionality that +handles large enums in Java without causing compiler errors. Note that this +feature replicates enum-like behavior but has some notable differences. For +example, switch statements are not supported.

Values available:

  • true: Java enums will use the new functionality.
  • false: Java enums will continue to use Java enums.

Applicable to the following scopes: file, enum

Added in: Edition 2024

Default behavior per syntax/edition:

Syntax/editionDefault
2024false
2023false
proto3false
proto2false

Note: Feature settings on different schema elements +have different scopes.

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

Languages: C++, Java

This feature determines whether a field with an open enum type should be behave +as if it was a closed enum. This allows editions to reproduce +non-conformant behavior in +Java and C++ from proto2 and proto3.

This feature doesn’t impact proto3 files, and so this section doesn’t have a +before and after of a proto3 file.

Values available:

  • true: Treats the enum as closed regardless of enum_type.
  • false: Respect whatever is set in the enum_type.

Applicable to the following scopes: file, field

Added in: Edition 2023

Default behavior per syntax/edition:

Syntax/editionDefault
2024false
2023false
proto3false
proto2true

Note: Feature settings on different schema elements +have different scopes.

The following code sample shows a proto2 file:

syntax = "proto2";
+
+import "myproject/proto3file.proto";
+
+message Msg {
+  myproject.proto3file.Proto3Enum name = 1;
+}
+

After running Prototiller, the equivalent code might look like this:

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

Languages: Java

This feature controls whether the Java generator will nest the generated class +in the Java generated file class. Setting this option to NO is the equivalent +of setting java_multiple_files = true in proto2/proto3/edition 2023.

The default outer classname is also updated to always be the camel-cased .proto +filename suffixed with Proto by default (for example, foo/bar_baz.proto +becomes BarBazProto). You can still override this using the +java_outer_classname file option and replace the pre-Edition 2024 default of +BarBaz or BarBazOuterClass depending on the presence of conflicts.

Values available:

  • NO: Do not nest the generated class in the file class.
  • YES: Nest the generated class in the file class.
  • Legacy: Nesting behavior controlled by java_multiple_files option (see +go/java-proto-names#immutable-api-message-names).

Applicable to the following scopes: message, enum, service

Added in: Edition 2024

Default behavior per syntax/edition:

Syntax/editionDefault
2024NO
2023Legacy
proto3Legacy
proto2Legacy

Note: Feature settings on different schema elements +have different scopes.

features.(pb.cpp).string_type

Languages: C++

This feature determines how generated code should treat string fields. This +replaces the ctype option from proto2 and proto3, and offers a new +string_type feature. In Edition 2023, you can specify either ctype or +string_type on a field, but not both. In Edition 2024, the ctype option is +removed.

Values available:

  • VIEW: Generates string_view accessors for the field.
  • CORD: Generates Cord accessors for the field. Not supported on extension +fields.
  • STRING: Generates string accessors for the field.

Applicable to the following scopes: file, field

Added in: Edition 2023

Default behavior per syntax/edition:

Syntax/editionDefault
2024VIEW
2023STRING
proto3STRING
proto2STRING

Note: Feature settings on different schema elements +have different scopes.

The following code sample shows a proto2 file:

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

After running Prototiller, the equivalent code might look like this:

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

The following shows a proto3 file:

syntax = "proto3"
+
+message Foo {
+  string bar = 6;
+  string baz = 7 [ctype = CORD];
+}
+

After running Prototiller, the equivalent code might look like this:

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

Languages: Java

This language-specific feature enables you to override the file-level settings +at the field level for Java only.

This feature doesn’t impact proto3 files, and so this section doesn’t have a +before and after of a proto3 file.

Values available:

  • DEFAULT: The behavior matches that set by +features.utf8_validation.
  • VERIFY: Overrides the file-level features.utf8_validation setting to +force it to VERIFY for Java only.

Applicable to the following scopes: file, field

Added in: Edition 2023

Default behavior per syntax/edition:

Syntax/editionDefault
2024DEFAULT
2023DEFAULT
proto3DEFAULT
proto2DEFAULT

Note: Feature settings on different schema elements +have different scopes.

The following code sample shows a proto2 file:

syntax = "proto2";
+
+option java_string_check_utf8=true;
+
+message MyMessage {
+  string foo = 1;
+  string bar = 2;
+}
+

After running Prototiller, the equivalent code might look like this:

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

Languages: Go

Enum values are not scoped by their containing enum name, so +prefixing every value with the enum name is recommended:

edition = "2024";
+
+enum Strip {
+  STRIP_ZERO = 0;
+  STRIP_ONE = 1;
+}
+

However, the generated Go code will now contain two prefixes!

type Strip int32
+
+const (
+    Strip_STRIP_ZERO Strip = 0
+    Strip_STRIP_ONE  Strip = 1
+)
+

The language-specific strip_enum_prefix feature determines whether the Go code +generator strips the repetitive prefix or not.

Values available:

  • STRIP_ENUM_PREFIX_KEEP: Keep the name as-is, even if repetitive.
  • STRIP_ENUM_PREFIX_GENERATE_BOTH: Generate both, a full name and a stripped +name (to help with migrating your Go code).
  • STRIP_ENUM_PREFIX_STRIP: Strip the enum name prefix from enum value names.

Applicable to the following scopes: file, enum, enum value

Added in: Edition 2024

Default behavior per syntax/edition:

Syntax/editionDefault
2024STRIP_ENUM_PREFIX_KEEP

Note: Feature settings on different schema elements +have different scopes.

You can set the strip_enum_prefix feature in edition 2024 (or newer) .proto +files:

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

The generated Go code will now strip the STRIP prefix:

type Strip int32
+
+const (
+    Strip_ZERO Strip = 0
+    Strip_ONE  Strip = 1
+)
+

Preserving proto2 or proto3 Behavior in Edition 2023

You may want to move to the editions format but not deal with updates to the way +that generated code behaves yet. This section shows the changes that the +Prototiller tool makes to your .proto files to make edition-2023-based protos +behave like a proto2 or proto3 file.

After these changes are made at the file level, you get the proto2 or proto3 +defaults. You can override at lower levels (message level, field level) to +consider additional behavior differences (such as +required, proto3 optional) or if you want your definition to only be +mostly like proto2 or proto3.

We recommend using Prototiller unless you have a specific reason not to. To +manually apply all of these instead of using Prototiller, add the content from +the following sections to the top of your .proto file.

Proto2 Behavior

The following shows the settings to replicate proto2 behavior with 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 Behavior

The following shows the settings to replicate proto3 behavior with 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 to 2024

The following shows the settings to replicate Edition 2023 behavior with 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;
+}
+

Caveats and Exceptions

This section shows the changes that you’ll need to make manually if you choose +not to use Prototiller.

Setting the file-level defaults shown in the previous section sets the default +behaviors in most cases, but there are a few exceptions.

Edition 2023 and later

  • optional: Remove all instances of the optional label and change the +features.field_presence to EXPLICIT if the file +default is IMPLICIT.
  • required: Remove all instances of the required label and add the +features.field_presence=LEGACY_REQUIRED option at the +field level.
  • groups: Unwrap the groups into a separate message and add the +features.message_encoding = DELIMITED option at the field level. See +features.message_encoding for more on this.
  • java_string_check_utf8: Remove this file option and replace it with the +features.(pb.java).utf8_validation. You’ll need +to import Java features, as covered in +Language-specific Features.
  • packed: For proto2 files converted to editions format, remove the packed +field option and add [features.repeated_field_encoding=PACKED] at the +field level when you don’t want the EXPANDED behavior that you set in +Proto2 Behavior. For proto3 files converted to editions +format, add [features.repeated_field_encoding=EXPANDED] at the field level +when you don’t want the default proto3 behavior.

Edition 2024 and later

\ No newline at end of file diff --git a/editions/implementation/index.html b/editions/implementation/index.html new file mode 100644 index 000000000..0fb625476 --- /dev/null +++ b/editions/implementation/index.html @@ -0,0 +1,262 @@ +Implementing Editions Support | Protocol Buffers Documentation +

Implementing Editions Support

Instructions for implementing Editions support in runtimes and plugins.

This topic explains how to implement editions in new runtimes and generators.

Overview

Edition 2023

The first edition released is Edition 2023, which is designed to unify proto2 +and proto3 syntax. The features we’ve added to cover the difference in behaviors +are detailed in +Feature Settings for Editions.

Feature Definition

In addition to supporting editions and the global features we’ve defined, you +may want to define your own features to leverage the infrastructure. This will +allow you to define arbitrary features that can be used by your generators and +runtimes to gate new behaviors. The first step is to claim an extension number +for the FeatureSet message in descriptor.proto above 9999. You can send a +pull-request to us in GitHub, and it will be included in our next release (see, +for example, #15439).

Once you have your extension number, you can create your features proto (similar +to +cpp_features.proto). +These will typically look something like:

edition = "2023";
+
+package foo;
+
+import "google/protobuf/descriptor.proto";
+
+extend google.protobuf.FeatureSet {
+  MyFeatures features = <extension #>;
+}
+
+message MyFeatures {
+  enum FeatureValue {
+    FEATURE_VALUE_UNKNOWN = 0;
+    VALUE1 = 1;
+    VALUE2 = 2;
+  }
+
+  FeatureValue feature_value = 1 [
+    targets = TARGET_TYPE_FIELD,
+    targets = TARGET_TYPE_FILE,
+    feature_support = {
+      edition_introduced: EDITION_2023,
+      edition_deprecated: EDITION_2024,
+      deprecation_warning: "Feature will be removed in 2025",
+      edition_removed: EDITION_2025,
+    },
+    edition_defaults = { edition: EDITION_LEGACY, value: "VALUE1" },
+    edition_defaults = { edition: EDITION_2024, value: "VALUE2" }
+  ];
+}
+

Here we’ve defined a new enum feature foo.feature_value (currently only +boolean and enum types are supported). In addition to defining the values it can +take, you also need to specify how it can be used:

  • Targets - specifies the type of proto descriptors this feature can be +attached to. This controls where users can explicitly specify the feature. +Every type must be explicitly listed.
  • Feature support - specifies the lifetime of this feature relative to +edition. You must specify the edition it was introduced in, and it will not +be allowed before then. You can optionally deprecate or remove the feature +in later editions.
  • Edition defaults - specifies any changes to the default value of the +feature. This must cover every supported edition, but you can leave out any +edition where the default didn’t change. Note that EDITION_PROTO2 and +EDITION_PROTO3 can be specified here to provide defaults for the “legacy” +editions (see Legacy Editions).

What is a Feature?

Features are designed to provide a mechanism for ratcheting down bad behavior +over time, on edition boundaries. While the timeline for actually removing a +feature may be years (or decades) in the future, the desired goal of any feature +should be eventual removal. When a bad behavior is identified, you can introduce +a new feature that guards the fix. In the next edition (or possibly later), you +would flip the default value while still allowing users to retain their old +behavior when upgrading. At some point in the future you would mark the feature +deprecated, which would trigger a custom warning to any users overriding it. In +a later edition, you would then mark it removed, preventing users from +overriding it anymore (but the default value would still apply). Until support +for that last edition is dropped in a breaking release, the feature will remain +usable for protos stuck on older editions, giving them time to migrate.

Flags that control optional behaviors you have no intention of removing are +better implemented as +custom options. +This is related to the reason we’ve restricted features to be either boolean or +enum types. Any behavior controlled by a (relatively) unbounded number of values +probably isn’t a good fit for the editions framework, since it’s not realistic +to eventually turn down that many different behaviors.

One caveat to this is behaviors related to wire boundaries. Using +language-specific features to control serialization or parsing behavior can be +dangerous, since any other language could be on the other side. Wire-format +changes should always be controlled by global features in descriptor.proto, +which can be respected by every runtime uniformly.

Generators

Generators written in C++ get a lot for free, because they use the C++ runtime. +They don’t need to handle Feature Resolution themselves, +and if they need any feature extensions they can register them in +GetFeatureExtensions in their CodeGenerator. They can generally use +GetResolvedSourceFeatures for access to resolved features for a descriptor in +codegen and GetUnresolvedSourceFeatures for access to their own unresolved +features.

Plugins written in the same language as the runtime they generate code for may +need some custom bootstrapping for their feature definitions.

Explicit Support

Generators must specify exactly which editions they support. This allows you to +safely add support for an edition after it’s been released, on your own +schedule. Protoc will reject any editions protos sent to generators that don’t +include FEATURE_SUPPORTS_EDITIONS in the supported_features field of their +CodeGeneratorResponse. Additionally, we have minimum_edition and +maximum_edition fields for specifying your precise support window. Once you’ve +defined all of the code and feature changes for a new edition, you can bump +maximum_edition to advertise this support.

Codegen Tests

We have a set of codegen tests that can be used to lock down that Edition 2023 +produces no unexpected functional changes. These have been very useful in +languages like C++ and Java, where a significant amount of the functionality is +in gencode. On the other hand, in languages like Python, where the gencode is +basically just a collection of serialized descriptors, these are not quite as +useful.

This infrastructure is not reusable yet, but is planned to be in a future +release. At that point you will be able to use them to verify that migrating to +editions doesn’t have any unexpected codegen changes.

Runtimes

Runtimes without reflection or dynamic messages should not need to do anything +to implement Editions. All of that logic should be handled by the code +generator.

Languages with reflection but without dynamic messages need resolved +features, but may optionally choose to handle it in their generator only. This +can be done by passing both resolved and unresolved feature sets to the runtime +during codegen. This avoids re-implementing +Feature Resolution in the runtime with the main downside +being efficiency, since it will create a unique feature set for every +descriptor.

Languages with dynamic messages must fully implement Editions, because they need +to be able to build descriptors at runtime.

Syntax Reflection

The first step in implementing Editions in a runtime with reflection is to +remove all direct checks of the syntax keyword. All of these should be moved +to finer-grained feature helpers, which can continue to use syntax if +necessary.

The following feature helpers should be implemented on descriptors, with +language-appropriate naming:

  • FieldDescriptor::has_presence - Whether or not a field has explicit +presence
    • Repeated fields never have presence
    • Message, extension, and oneof fields always have explicit presence
    • Everything else has presence iff field_presence is not IMPLICIT
  • FieldDescriptor::is_required - Whether or not a field is required
  • FieldDescriptor::requires_utf8_validation - Whether or not a field should +be checked for utf8 validity
  • FieldDescriptor::is_packed - Whether or not a repeated field has packed +encoding
  • FieldDescriptor::is_delimited - Whether or not a message field has +delimited encoding
  • EnumDescriptor::is_closed - Whether or not a field is closed

Downstream users should migrate to these new helpers instead of using syntax +directly. The following class of existing descriptor APIs should ideally be +deprecated and eventually removed, since they leak syntax information:

  • FileDescriptor syntax
  • Proto3 optional APIs
    • FieldDescriptor::has_optional_keyword
    • OneofDescriptor::is_synthetic
    • Descriptor::*real_oneof* - should be renamed to just “oneof” and the +existing “oneof” helpers should be removed, since they leak information +about synthetic oneofs (which don’t exist in editions).
  • Group type
    • The TYPE_GROUP enum value should be removed, replaced with the +is_delimited helper.
  • Required label
    • The LABEL_REQUIRED enum value should be removed, replaced with the +is_required helper.

There are many classes of user code where these checks exist but aren’t +hostile to editions. For example, code that needs to handle proto3 optional +specially because of its synthetic oneof implementation won’t be hostile to +editions as long as the polarity is something like syntax == "proto3" (rather +than checking syntax != "proto2").

If it’s not possible to remove these APIs entirely, they should be deprecated +and discouraged.

Feature Visibility

As discussed in +editions-feature-visibility, +feature protos should remain an internal detail of any Protobuf implementation. +The behaviors they control should be exposed via descriptor methods, but the +protos themselves should not. Notably, this means that any options that are +exposed to the users need to have their features fields stripped out.

The one case where we permit features to leak out is when serializing +descriptors. The resulting descriptor protos should be a faithful representation +of the original proto files, and should contain unresolved features inside of +the options.

Legacy Editions

As discussed more in +legacy-syntax-editions, +a great way to get early coverage of your editions implementation is to unify +proto2, proto3, and editions. This effectively migrates proto2 and proto3 to +editions under the hood, and makes all of the helpers implemented in +Syntax Reflection use features exclusively (instead of +branching on syntax). This can be done by inserting a feature inference phase +into Feature Resolution, where various aspects of the +proto file can inform what features are appropriate. These features can then be +merged into the parent’s features to get the resolved feature set.

While we provide reasonable defaults for proto2/proto3 already, for edition 2023 +the following additional inferences are required:

  • required - we infer LEGACY_REQUIRED presence when a field has +LABEL_REQUIRED
  • groups - we infer DELIMITED message encoding when a field has TYPE_GROUP
  • packed - we infer PACKED encoding when the packed option is true
  • expanded - we infer EXPANDED encoding when a proto3 field has packed +explicitly set to false

Conformance Tests

Editions-specific conformance tests have been added, but need to be opted-in to. +A --maximum_edition 2023 flag can be passed to the runner to enable these. You +will need to configure your testee binary to handle the following new message +types:

  • protobuf_test_messages.editions.proto2.TestAllTypesProto2 - Identical to +the old proto2 message, but transformed to edition 2023
  • protobuf_test_messages.editions.proto3.TestAllTypesProto3 - Identical to +the old proto3 message, but transformed to edition 2023
  • protobuf_test_messages.editions.TestAllTypesEdition2023 - Used to cover +edition-2023-specific test cases

Feature Resolution

Editions use lexical scoping to define features, meaning that any non-C++ code +that needs to implement editions support will need to reimplement our feature +resolution algorithm. However, the bulk of the work is handled by protoc +itself, which can be configured to output an intermediate FeatureSetDefaults +message. This message contains a “compilation” of a set of feature definition +files, laying out the default feature values in every edition.

For example, the feature definition above would compile to the following +defaults between proto2 and edition 2025 (in text-format notation):

defaults {
+  edition: EDITION_PROTO2
+  overridable_features { [foo.features] {} }
+  fixed_features {
+    // Global feature defaults…
+    [foo.features] { feature_value: VALUE1 }
+  }
+}
+defaults {
+  edition: EDITION_PROTO3
+  overridable_features { [foo.features] {} }
+  fixed_features {
+    // Global feature defaults…
+    [foo.features] { feature_value: VALUE1 }
+  }
+}
+defaults {
+  edition: EDITION_2023
+  overridable_features {
+    // Global feature defaults…
+    [foo.features] { feature_value: VALUE1 }
+  }
+}
+defaults {
+  edition: EDITION_2024
+  overridable_features {
+    // Global feature defaults…
+    [foo.features] { feature_value: VALUE2 }
+  }
+}
+defaults {
+  edition: EDITION_2025
+  overridable_features {
+    // Global feature defaults…
+  }
+  fixed_features { [foo.features] { feature_value: VALUE2 } }
+}
+minimum_edition: EDITION_PROTO2
+maximum_edition: EDITION_2025
+

Global feature defaults are left out for compactness, but they would also be +present. This object contains an ordered list of every edition with a unique set +of defaults (some editions may end up not being present) within the specified +range. Each set of defaults is split into overridable and fixed features. +The former are supported features for the edition that can be freely overridden +by users. The fixed features are those which haven’t yet been introduced or have +been removed, and can’t be overridden by users.

We provide a Bazel rule for compiling these intermediate objects:

load("@com_google_protobuf//editions:defaults.bzl", "compile_edition_defaults")
+
+compile_edition_defaults(
+    name = "my_defaults",
+    srcs = ["//some/path:lang_features_proto"],
+    maximum_edition = "PROTO2",
+    minimum_edition = "2024",
+)
+

The output FeatureSetDefaults can be embedded into a raw string literal in +whatever language you need to do feature resolution in. We also provide an +embed_edition_defaults macro to do this:

embed_edition_defaults(
+    name = "embed_my_defaults",
+    defaults = ":my_defaults",
+    output = "my_defaults.h",
+    placeholder = "DEFAULTS_DATA",
+    template = "my_defaults.h.template",
+)
+

Alternatively, you can invoke protoc directly (outside of Bazel) to generate +this data:

protoc --edition_defaults_out=defaults.binpb --edition_defaults_minimum=PROTO2 --edition_defaults_maximum=2023 <feature files...>
+

Once the defaults message is hooked up and parsed by your code, feature +resolution for a file descriptor at a given edition follows a simple algorithm:

  1. Validate that the edition is in the appropriate range [minimum_edition, +maximum_edition]
  2. Binary-search the ordered defaults field for the highest entry less than +or equal to the edition
  3. Merge overridable_features into fixed_features from the selected +defaults
  4. Merge any explicit features set on the descriptor (the features field in +the file options)

From there, you can recursively resolve features for all other descriptors:

  1. Initialize to the parent descriptor’s feature set
  2. Merge any explicit features set on the descriptor (the features field in +the options)

For determining the “parent” descriptor, you can reference our +C++ implementation. +This is straightforward in most cases, but extensions are a bit surprising +because their parent is the enclosing scope rather than the extendee. Oneofs +also need to be considered as the parent of their fields.

Conformance Tests

In a future release, we plan to add conformance tests to verify feature +resolution cross-language. Until then, our regular +conformance tests do give partial coverage, and our +example inheritance unit tests +can be ported to provide more comprehensive coverage.

Examples

Below are some real examples of how we implemented editions support in our +runtimes and plugins.

Java

  • #14138 - Bootstrap +compiler with C++ gencode for Java features proto
  • #14377 - Use +features in Java, Kotlin, and Java Lite code generators, including codegen +tests
  • #15210 - Use +features in Java full runtimes covering Java features bootstrap, feature +resolution, and legacy editions, along with unit-tests and conformance +testing

Pure Python

  • #14546 - Setup +codegen tests in advance
  • #14547 - Fully +implements editions in one shot, along with unit-tests and conformance +testing

𝛍pb

  • #14638 - First +pass at editions implementation covering feature resolution and legacy +editions
  • #14667 - Added +more complete handling of field label/type, support for upb’s code +generator, and some tests
  • #14678 - Hooks up +upb to the Python runtime, with more unit tests and conformance tests

Ruby

  • #16132 - Hook up +upb/Java to all four Ruby runtimes for full editions support
\ No newline at end of file diff --git a/editions/index.html b/editions/index.html new file mode 100644 index 000000000..d95107af8 --- /dev/null +++ b/editions/index.html @@ -0,0 +1,8 @@ +Protobuf Editions | Protocol Buffers Documentation +

Protobuf Editions

Topics related to the Protobuf Editions functionality.

Protobuf Editions Overview

An overview of the Protobuf Editions functionality.

Feature Settings for Editions

Protobuf Editions features and how they affect protobuf behavior.

Implementing Editions Support

Instructions for implementing Editions support in runtimes and plugins.

\ No newline at end of file diff --git a/editions/index.xml b/editions/index.xml new file mode 100644 index 000000000..86af3e2f2 --- /dev/null +++ b/editions/index.xml @@ -0,0 +1,6 @@ +Protobuf Editions on Protocol Buffers Documentationhttps://protobuf.dev/editions/Recent content in Protobuf Editions on Protocol Buffers DocumentationHugoenProtobuf Editions Overviewhttps://protobuf.dev/editions/overview/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/editions/overview/Protobuf Editions replace the proto2 and proto3 designations that we have used for Protocol Buffers. Instead of adding syntax = &quot;proto2&quot; or syntax = &quot;proto3&quot; at the top of proto definition files, you use an edition number, such as edition = &quot;2024&quot;, to specify the default behaviors your file will have. Editions enable the language to evolve incrementally over time. +Instead of the hardcoded behaviors that older versions have had, editions represent a collection of features with a default value (behavior) per feature.Feature Settings for Editionshttps://protobuf.dev/editions/features/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/editions/features/This topic provides an overview of the features that are included in the released edition versions. Subsequent editions&rsquo; features will be added to this topic. We announce new editions in the News section. +Before configuring feature settings in your new schema definition content, make sure you understand why you are using them. Avoid cargo-culting with features. +Prototiller Prototiller is a command-line tool that updates proto schema configuration files between syntax versions and editions.Implementing Editions Supporthttps://protobuf.dev/editions/implementation/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/editions/implementation/This topic explains how to implement editions in new runtimes and generators. +Overview Edition 2023 The first edition released is Edition 2023, which is designed to unify proto2 and proto3 syntax. The features we’ve added to cover the difference in behaviors are detailed in Feature Settings for Editions. +Feature Definition In addition to supporting editions and the global features we&rsquo;ve defined, you may want to define your own features to leverage the infrastructure. \ No newline at end of file diff --git a/editions/overview/index.html b/editions/overview/index.html new file mode 100644 index 000000000..0a6c85735 --- /dev/null +++ b/editions/overview/index.html @@ -0,0 +1,290 @@ +Protobuf Editions Overview | Protocol Buffers Documentation +

Protobuf Editions Overview

An overview of the Protobuf Editions functionality.

Protobuf Editions replace the proto2 and proto3 designations that we have used +for Protocol Buffers. Instead of adding syntax = "proto2" or syntax = "proto3" at the top of proto definition files, you use an edition number, such +as edition = "2024", to specify the default behaviors your file will have. +Editions enable the language to evolve incrementally over time.

Instead of the hardcoded behaviors that older versions have had, editions +represent a collection of features +with a default value (behavior) per feature. Features are options on a file, +message, field, enum, and so on, that specify the behavior of protoc, the code +generators, and protobuf runtimes. You can explicitly override a behavior at +those different levels (file, message, field, …) when your needs don’t match +the default behavior for the edition you’ve selected. You can also override your +overrides. The section later in this topic on lexical scoping goes +into more detail on that.

NOTE: The latest released edition is 2024.

Lifecycle of a Feature

Editions provide the fundamental increments for the lifecycle of a feature. +Features have an expected lifecycle: introducing +it, changing its default behavior, deprecating it, and then removing it. For +example:

  1. Edition 2031 creates feature.amazing_new_feature with a default value of +false. This value maintains the same behavior as all earlier editions. +That is, it defaults to no impact. Not all new features will default to the +no-op option, but for the sake of this example, amazing_new_feature does.

  2. Developers update their .proto files to edition = "2031".

  3. A later edition, such as edition 2033, switches the default of +feature.amazing_new_feature from false to true. This is the desired +behavior for all protos, and the reason that the protobuf team created the +feature.

    Using the Prototiller tool to migrate earlier versions of proto files to +edition 2033 adds explicit feature.amazing_new_feature = false entries as +needed to continue to retain the previous behavior. Developers remove these +newly-added settings when they want the new behavior to apply to their +.proto files.

  1. At some point, feature.amazing_new_feature is marked deprecated in an +edition and removed in a later one.

    When a feature is removed, the code generators for that behavior and the +runtime libraries that support it may also be removed. The timelines will be +generous, though. Following the example in the earlier steps of the +lifecycle, the deprecation might happen in edition 2034 but not be removed +until edition 2036, roughly two years later. Removing a feature will always +initiate a major version bump.

You will have the full +window of the Google migration plus the deprecation window to upgrade your code.

The preceding lifecycle example used boolean values for the features, but +features may also use enums. For example, features.field_presence has values +LEGACY_REQUIRED, EXPLICIT, and IMPLICIT.

Migrating to Protobuf Editions

Editions won’t break existing binaries and don’t change a message’s binary, +text, or JSON serialization format. Edition 2023 was as minimally disruptive as +possible. It established the baseline and combined proto2 and proto3 definitions +into a new single definition format.

As more editions are released, default behaviors for features may change. You +can have Prototiller do a no-op transformation of your .proto file or you can +choose to accept some or all of the new behaviors. Editions are planned to be +released roughly once a year.

Proto2 to Editions

This section shows a proto2 file, and what it might look like after running the +Prototiller tool to change the definition files to use Protobuf Editions syntax.

Proto2 Syntax

// proto2 file
+syntax = "proto2";
+
+package com.example;
+
+message Player {
+  // in proto2, optional fields have explicit presence
+  optional string name = 1 [default = "N/A"];
+  // proto2 still supports the problematic "required" field rule
+  required int32 id = 2;
+  // in proto2 this is not packed by default
+  repeated int32 scores = 3;
+
+  enum Handed {
+    HANDED_UNSPECIFIED = 0;
+    HANDED_LEFT = 1;
+    HANDED_RIGHT = 2;
+    HANDED_AMBIDEXTROUS = 3;
+  }
+
+  // in proto2 enums are closed
+  optional Handed handed = 4;
+
+  reserved "gender";
+}
+

Editions Syntax

// Edition version of proto2 file
+edition = "2024";
+
+package com.example;
+
+option features.utf8_validation = NONE;
+option features.enforce_naming_style = STYLE_LEGACY;
+option features.default_symbol_visibility = EXPORT_ALL;
+
+// Sets the default behavior for C++ strings
+option features.(pb.cpp).string_type = STRING;
+
+message Player {
+  // fields have explicit presence, so no explicit setting needed
+  string name = 1 [default = "N/A"];
+  // to match the proto2 behavior, LEGACY_REQUIRED is set at the field level
+  int32 id = 2 [features.field_presence = LEGACY_REQUIRED];
+  // to match the proto2 behavior, EXPANDED is set at the field level
+  repeated int32 scores = 3 [features.repeated_field_encoding = EXPANDED];
+
+  export enum Handed {
+    // this overrides the default editions behavior, which is OPEN
+    option features.enum_type = CLOSED;
+    HANDED_UNSPECIFIED = 0;
+    HANDED_LEFT = 1;
+    HANDED_RIGHT = 2;
+    HANDED_AMBIDEXTROUS = 3;
+  }
+
+  Handed handed = 4;
+
+  reserved gender;
+}
+

Proto3 to Editions

This section shows a proto3 file, and what it might look like after running the +Prototiller tool to change the definition files to use Protobuf Editions syntax.

Proto3 Syntax

// proto3 file
+syntax = "proto3";
+
+package com.example;
+
+message Player {
+  // in proto3, optional fields have explicit presence
+  optional string name = 1;
+  // in proto3 no specified field rule defaults to implicit presence
+  int32 id = 2;
+  // in proto3 this is packed by default
+  repeated int32 scores = 3;
+
+  enum Handed {
+    HANDED_UNSPECIFIED = 0;
+    HANDED_LEFT = 1;
+    HANDED_RIGHT = 2;
+    HANDED_AMBIDEXTROUS = 3;
+  }
+
+  // in proto3 enums are open
+  optional Handed handed = 4;
+
+  reserved "gender";
+}
+

Editions Syntax

// Editions version of proto3 file
+edition = "2024";
+
+package com.example;
+
+option features.utf8_validation = NONE;
+option features.enforce_naming_style = STYLE_LEGACY;
+option features.default_symbol_visibility = EXPORT_ALL;
+
+// Sets the default behavior for C++ strings
+option features.(pb.cpp).string_type = STRING;
+
+message Player {
+  // fields have explicit presence, so no explicit setting needed
+  string name = 1 [default = "N/A"];
+  // to match the proto3 behavior, IMPLICIT is set at the field level
+  int32 id = 2 [features.field_presence = IMPLICIT];
+  // PACKED is the default state, and is provided just for illustration
+  repeated int32 scores = 3 [features.repeated_field_encoding = PACKED];
+
+  export enum Handed {
+    HANDED_UNSPECIFIED = 0;
+    HANDED_LEFT = 1;
+    HANDED_RIGHT = 2;
+    HANDED_AMBIDEXTROUS = 3;
+  }
+
+  Handed handed = 4;
+
+  reserved gender;
+}
+

Lexical Scoping

Editions syntax supports lexical scoping, with a per-feature list of allowed +targets. For example, in Edition 2023, features can be specified at only the +file level or the lowest level of granularity. The implementation of lexical +scoping enables you to set the default behavior for a feature across an entire +file, and then override that behavior at the message, field, enum, enum value, +oneof, service, or method level. Settings made at a higher level (file, message) +apply when no setting is made within the same scope (field, enum value). Any +features not explicitly set conform to the behavior defined in the edition +version used for the .proto file.

The following code sample shows some features being set at the file, field, and +enum level.

edition = "2024";
+
+option features.enum_type = CLOSED;
+
+message Person {
+  string name = 1;
+  int32 id = 2 [features.field_presence = IMPLICIT];
+
+  enum Pay_Type {
+    PAY_TYPE_UNSPECIFIED = 1;
+    PAY_TYPE_SALARY = 2;
+    PAY_TYPE_HOURLY = 3;
+  }
+
+  enum Employment {
+    option features.enum_type = OPEN;
+    EMPLOYMENT_UNSPECIFIED = 0;
+    EMPLOYMENT_FULLTIME = 1;
+    EMPLOYMENT_PARTTIME = 2;
+  }
+  Employment employment = 4;
+}
+

In the preceding example, the presence feature is set to IMPLICIT; it would +default to EXPLICIT if it wasn’t set. The Pay_Type enum will be CLOSED, +as it applies the file-level setting. The Employment enum, though, will be +OPEN, as it is set within the enum.

Prototiller

When the Prototiller tool is launched, we will +provide both a migration guide and migration tooling to ease the migration to +and between editions. The tool will enable you to:

  • convert proto2 and proto3 definition files to the new editions syntax, at +scale
  • migrate files from one edition to another
  • manipulate proto files in other ways

Backward Compatibility

We are building Protobuf Editions to be as minimally disruptive as possible. For +example, you can import proto2 and proto3 definitions into editions-based +definition files, and vice versa:

// file myproject/foo.proto
+syntax = "proto2";
+
+enum Employment {
+  EMPLOYMENT_UNSPECIFIED = 0;
+  EMPLOYMENT_FULLTIME = 1;
+  EMPLOYMENT_PARTTIME = 2;
+}
+
// file myproject/edition.proto
+edition = "2024";
+
+import "myproject/foo.proto";
+

While the generated code changes when you move from proto2 or proto3 to +editions, the wire format does not. You’ll still be able to access proto2 and +proto3 data files or file streams using your editions-syntax proto definitions.

Grammar Changes

There are some grammar changes in editions compared to proto2 and proto3.

Syntax Description

Instead of the syntax element, you use an edition element:

syntax = "proto2";
+syntax = "proto3";
+edition = "2028";
+

Reserved Names

You no longer put field names and enum value names in quotation marks when +reserving them:

reserved foo, bar;
+

Group Syntax

Group syntax, available in proto2, is removed in editions. The special +wire-format that groups used is still available by using DELIMITED message +encoding.

Required Label

The required label, available only in proto2, is unavailable in editions. The +underlying functionality is still available +by using features.field_presence=LEGACY_REQUIRED.

import option

Edition 2024 added support for option imports using the syntax import option.

Option imports must come after any other import statements.

Unlike normal import statements, import option only imports custom options +defined in a .proto file, without importing other symbols.

This means that messages and enums are excluded from the option import. In the +following example, the Bar message cannot be used as a field type in +foo.proto, but options with type Bar can still be set.

// bar.proto
+edition = "2024";
+
+import "google/protobuf/descriptor.proto";
+
+message Bar {
+  bool bar = 1;
+}
+
+extend proto2.FileOptions {
+  bool file_opt1 = 5000;
+  Bar file_opt2 = 5001;
+}
+
+// foo.proto:
+edition = "2024";
+
+import option "bar.proto";
+
+option (file_opt1) = true;
+option (file_opt2) = {bar: true};
+
+message Foo {
+  // Bar bar = 1; // This is not allowed
+}
+

Option imports do not require generated code for its symbols and should thus be +provided as option_deps in proto_library instead of deps. This avoids +generating unreachable code.

proto_library(
+  name = "foo",
+  srcs = ["foo.proto"],
+  option_deps = [":custom_option_proto"]
+)
+

Option imports and option_deps are strongly recommended when importing +protobuf language features and other custom options to avoid generating +unnecessary code.

This replaces import weak, which was removed in Edition 2024.

export / local Keywords

export and local keywords were added in Edition 2024 as modifiers for the +symbol visibility of importable symbols, from the default behavior specified by +features.default_symbol_visibility.

This controls which symbols can be imported from other proto files, but does not +affect code-generation.

In Edition 2024, these can be set on all message and enum symbols by +default. However, some values of the default_symbol_visibility feature further +restrict which symbols are exportable.

Example:

// Top-level symbols are exported by default in Edition 2024
+message LocalMessage {
+  int32 baz = 1;
+  // Nested symbols are local by default in Edition 2024; applying the `export`
+  // keyword overrides this
+  export enum ExportedNestedEnum {
+    UNKNOWN_EXPORTED_NESTED_ENUM_VALUE = 0;
+  }
+}
+
+// The `local` keyword overrides the default behavior of exporting messages
+local message AnotherMessage {
+  int32 foo = 1;
+}
+

import weak and Weak Field Option

As of Edition 2024, weak imports are no longer allowed.

If you previously relied on import weak to declare a “weak +dependency”—to import custom options without generated code for C++ and +Go—you should instead migrate to use import option.

See import option +for more details.

ctype Field Option

As of Edition 2024, ctype field option is no longer allowed. Use the +string_type feature instead.

See +features.(pb.cpp).string_type +for more details.

java_multiple_files File Option

As of Edition 2024, the java_multiple_files file option no longer available. +Use the +features.(pb.java).nest_in_file_class +Java feature, instead.

\ No newline at end of file diff --git a/favicons/android-144x144.png b/favicons/android-144x144.png new file mode 100644 index 000000000..8851c09a4 Binary files /dev/null and b/favicons/android-144x144.png differ diff --git a/favicons/android-192x192.png b/favicons/android-192x192.png new file mode 100644 index 000000000..94b2ad2db Binary files /dev/null and b/favicons/android-192x192.png differ diff --git a/favicons/android-36x36.png b/favicons/android-36x36.png new file mode 100644 index 000000000..7ec5cf650 Binary files /dev/null and b/favicons/android-36x36.png differ diff --git a/favicons/android-48x48.png b/favicons/android-48x48.png new file mode 100644 index 000000000..419a445ad Binary files /dev/null and b/favicons/android-48x48.png differ diff --git a/favicons/android-72x72.png b/favicons/android-72x72.png new file mode 100644 index 000000000..230b18fd5 Binary files /dev/null and b/favicons/android-72x72.png differ diff --git a/favicons/android-96x96.png b/favicons/android-96x96.png new file mode 100644 index 000000000..8cc698973 Binary files /dev/null and b/favicons/android-96x96.png differ diff --git a/static/favicons/android-chrome-192x192.png b/favicons/android-chrome-192x192.png similarity index 100% rename from static/favicons/android-chrome-192x192.png rename to favicons/android-chrome-192x192.png diff --git a/static/favicons/android-chrome-512x512.png b/favicons/android-chrome-512x512.png similarity index 100% rename from static/favicons/android-chrome-512x512.png rename to favicons/android-chrome-512x512.png diff --git a/favicons/apple-touch-icon-180x180.png b/favicons/apple-touch-icon-180x180.png new file mode 100644 index 000000000..03d0b5134 Binary files /dev/null and b/favicons/apple-touch-icon-180x180.png differ diff --git a/static/favicons/apple-touch-icon.png b/favicons/apple-touch-icon.png similarity index 100% rename from static/favicons/apple-touch-icon.png rename to favicons/apple-touch-icon.png diff --git a/favicons/favicon-1024.png b/favicons/favicon-1024.png new file mode 100644 index 000000000..920f10720 Binary files /dev/null and b/favicons/favicon-1024.png differ diff --git a/static/favicons/favicon-16x16.png b/favicons/favicon-16x16.png similarity index 100% rename from static/favicons/favicon-16x16.png rename to favicons/favicon-16x16.png diff --git a/favicons/favicon-256.png b/favicons/favicon-256.png new file mode 100644 index 000000000..ebd3f8c98 Binary files /dev/null and b/favicons/favicon-256.png differ diff --git a/static/favicons/favicon-32x32.png b/favicons/favicon-32x32.png similarity index 100% rename from static/favicons/favicon-32x32.png rename to favicons/favicon-32x32.png diff --git a/static/favicons/favicon.ico b/favicons/favicon.ico similarity index 100% rename from static/favicons/favicon.ico rename to favicons/favicon.ico diff --git a/favicons/pwa-192x192.png b/favicons/pwa-192x192.png new file mode 100644 index 000000000..94b2ad2db Binary files /dev/null and b/favicons/pwa-192x192.png differ diff --git a/favicons/pwa-512x512.png b/favicons/pwa-512x512.png new file mode 100644 index 000000000..89258a4e6 Binary files /dev/null and b/favicons/pwa-512x512.png differ diff --git a/favicons/tile150x150.png b/favicons/tile150x150.png new file mode 100644 index 000000000..3d0c7604e Binary files /dev/null and b/favicons/tile150x150.png differ diff --git a/favicons/tile310x150.png b/favicons/tile310x150.png new file mode 100644 index 000000000..ed8904286 Binary files /dev/null and b/favicons/tile310x150.png differ diff --git a/favicons/tile310x310.png b/favicons/tile310x310.png new file mode 100644 index 000000000..67172b306 Binary files /dev/null and b/favicons/tile310x310.png differ diff --git a/favicons/tile70x70.png b/favicons/tile70x70.png new file mode 100644 index 000000000..31413a2be Binary files /dev/null and b/favicons/tile70x70.png differ diff --git a/forum-link/index.html b/forum-link/index.html new file mode 100644 index 000000000..e4df9d9af --- /dev/null +++ b/forum-link/index.html @@ -0,0 +1,4 @@ +Forum | Protocol Buffers Documentation +
\ No newline at end of file diff --git a/getting-started/cpptutorial/index.html b/getting-started/cpptutorial/index.html new file mode 100644 index 000000000..023dbf621 --- /dev/null +++ b/getting-started/cpptutorial/index.html @@ -0,0 +1,439 @@ +Protocol Buffer Basics: C++ | Protocol Buffers Documentation +

Protocol Buffer Basics: C++

A basic C++ programmers introduction to working with protocol buffers.

This tutorial provides a basic C++ programmers introduction to working with +protocol buffers. By walking through creating a simple example application, it +shows you how to

  • Define message formats in a .proto file.
  • Use the protocol buffer compiler.
  • Use the C++ protocol buffer API to write and read messages.

This isn’t a comprehensive guide to using protocol buffers in C++. For more +detailed reference information, see the +Protocol Buffer Language Guide, +the C++ API Reference, the +C++ Generated Code Guide, +and the +Encoding Reference.

The Problem Domain

The example we’re going to use is a very simple “address book” application that +can read and write people’s contact details to and from a file. Each person in +the address book has a name, an ID, an email address, and a contact phone +number.

How do you serialize and retrieve structured data like this? There are a few +ways to solve this problem:

  • The raw in-memory data structures can be sent/saved in binary form. Over +time, this is a fragile approach, as the receiving/reading code must be +compiled with exactly the same memory layout, endianness, etc. Also, as +files accumulate data in the raw format and copies of software that are +wired for that format are spread around, it’s very hard to extend the +format.
  • You can invent an ad-hoc way to encode the data items into a single +string – such as encoding 4 ints as “12:3:-23:67”. This is a simple and +flexible approach, although it does require writing one-off encoding and +parsing code, and the parsing imposes a small run-time cost. This works best +for encoding very simple data.
  • Serialize the data to XML. This approach can be very attractive since XML is +(sort of) human readable and there are binding libraries for lots of +languages. This can be a good choice if you want to share data with other +applications/projects. However, XML is notoriously space intensive, and +encoding/decoding it can impose a huge performance penalty on applications. +Also, navigating an XML DOM tree is considerably more complicated than +navigating simple fields in a class normally would be.

Instead of these options, you can use protocol buffers. Protocol buffers are the +flexible, efficient, automated solution to solve exactly this problem. With +protocol buffers, you write a .proto description of the data structure you +wish to store. From that, the protocol buffer compiler creates a class that +implements automatic encoding and parsing of the protocol buffer data with an +efficient binary format. The generated class provides getters and setters for +the fields that make up a protocol buffer and takes care of the details of +reading and writing the protocol buffer as a unit. Importantly, the protocol +buffer format supports the idea of extending the format over time in such a way +that the code can still read data encoded with the old format.

Where to Find the Example Code

The example code is included in the source code package, under the +“examples” directory.

Defining Your Protocol Format

To create your address book application, you’ll need to start with a .proto +file. The definitions in a .proto file are simple: you add a message for +each data structure you want to serialize, then specify a name and a type for +each field in the message. Here is the .proto file that defines your messages, +addressbook.proto.

edition = "2023";
+
+package tutorial;
+
+message Person {
+  string name = 1;
+  int32 id = 2;
+  string email = 3;
+
+  enum PhoneType {
+    PHONE_TYPE_UNSPECIFIED = 0;
+    PHONE_TYPE_MOBILE = 1;
+    PHONE_TYPE_HOME = 2;
+    PHONE_TYPE_WORK = 3;
+  }
+
+  message PhoneNumber {
+    string number = 1;
+    PhoneType type = 2;
+  }
+
+  repeated PhoneNumber phones = 4;
+}
+
+message AddressBook {
+  repeated Person people = 1;
+}
+

As you can see, the syntax is similar to C++ or Java. Let’s go through each part +of the file and see what it does.

The .proto file starts with an edition declaration. Editions replace the +older syntax = "proto2" and syntax = "proto3" declarations and provide a +more flexible way to evolve the language over time.

Next is a package declaration, which helps to prevent naming conflicts between +different projects. In C++, your generated classes will be placed in a namespace +matching the package name.

Following the package declaration are your message definitions. A message is +just an aggregate containing a set of typed fields. Many standard simple data +types are available as field types, including bool, int32, float, +double, and string. You can also add further structure to your messages by +using other message types as field types – in the above example the Person +message contains PhoneNumber messages, while the AddressBook message +contains Person messages. You can even define message types nested inside +other messages – as you can see, the PhoneNumber type is defined inside +Person. You can also define enum types if you want one of your fields to have +one of a predefined list of values – here you want to specify that a phone +number can be one of several types.

The " = 1", " = 2" markers on each element identify the unique field number that +field uses in the binary encoding. Field numbers 1-15 require one less byte to +encode than higher numbers, so as an optimization you can decide to use those +numbers for the commonly used or repeated elements, leaving field numbers 16 and +higher for less-commonly used elements.

Fields can be one of the following:

  • singular: By default, fields are optional, meaning the field may or may not +be set. If a singular field is not set, a type-specific default is used: +zero for numeric types, the empty string for strings, false for bools, and +the first defined enum value for enums (which must be 0). Note that you +cannot explicitly set a field to singular. This is a description of a +non-repeated field.

  • repeated: The field may be repeated any number of times (including +zero). The order of the repeated values will be preserved. Think of repeated +fields as dynamically sized arrays.

In older versions of protobuf, a required keyword existed, but it has been +found to be brittle and is not supported in modern protobufs (though editions +does have a feature you can use to enable it, for backward compatibility).

You’ll find a complete guide to writing .proto files – including all the +possible field types – in the +Protocol Buffer Language Guide. +Don’t go looking for facilities similar to class inheritance, though – protocol +buffers don’t do that.

Compiling Your Protocol Buffers

Now that you have a .proto, the next thing you need to do is generate the +classes you’ll need to read and write AddressBook (and hence Person and +PhoneNumber) messages. To do this, you need to run the protocol buffer +compiler protoc on your .proto:

  1. If you haven’t installed the compiler, follow the instructions in +Protocol Buffer Compiler Installation.

  2. Now run the compiler, specifying the source directory (where your +application’s source code lives – the current directory is used if you +don’t provide a value), the destination directory (where you want the +generated code to go; often the same as $SRC_DIR), and the path to your +.proto. In this case:

    protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto
    +

    Because you want C++ classes, you use the --cpp_out option – similar +options are provided for other supported languages.

This generates the following files in your specified destination directory:

  • addressbook.pb.h, the header which declares your generated classes.
  • addressbook.pb.cc, which contains the implementation of your classes.

The Protocol Buffer API

Let’s look at some of the generated code and see what classes and functions the +compiler has created for you. If you look in addressbook.pb.h, you can see +that you have a class for each message you specified in addressbook.proto. +Looking closer at the Person class, you can see that the compiler has +generated accessors for each field. For example, for the name, id, email, +and phones fields, you have these methods:

  // name
+  bool has_name() const; // Only for explicit presence
+  void clear_name();
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  ::std::string* mutable_name();
+
+  // id
+  bool has_id() const;
+  void clear_id();
+  int32_t id() const;
+  void set_id(int32_t value);
+
+  // email
+  bool has_email() const;
+  void clear_email();
+  const ::std::string& email() const;
+  void set_email(const ::std::string& value);
+  ::std::string* mutable_email();
+
+  // phones
+  int phones_size() const;
+  void clear_phones();
+  const ::google::protobuf::RepeatedPtrField< ::tutorial::Person_PhoneNumber >& phones() const;
+  ::google::protobuf::RepeatedPtrField< ::tutorial::Person_PhoneNumber >* mutable_phones();
+  const ::tutorial::Person_PhoneNumber& phones(int index) const;
+  ::tutorial::Person_PhoneNumber* mutable_phones(int index);
+  ::tutorial::Person_PhoneNumber* add_phones();
+

As you can see, the getters have exactly the name as the field in lowercase, and +the setter methods begin with set_. There are also has_ methods for singular +fields that have explicit presence tracking, which return true if that field has +been set. Finally, each field has a clear_ method that un-sets the field back +to its default state.

While the numeric id field just has the basic accessor set described above, +the name and email fields have a couple of extra methods because they’re +strings – a mutable_ getter that lets you get a direct pointer to the string, +and an extra setter. Note that you can call mutable_email() even if email is +not already set; it will be initialized to an empty string automatically. If you +had a repeated message field in this example, it would also have a mutable_ +method but not a set_ method.

Repeated fields also have some special methods – if you look at the methods for +the repeated phones field, you’ll see that you can

  • check the repeated field’s _size (in other words, how many phone numbers +are associated with this Person).
  • get a specified phone number using its index.
  • update an existing phone number at the specified index.
  • add another phone number to the message which you can then edit (repeated +scalar types have an add_ that just lets you pass in the new value).

For more information on exactly what members the protocol compiler generates for +any particular field definition, see the +C++ generated code reference.

Enums and Nested Classes

The generated code includes a PhoneType enum that corresponds to your .proto +enum. You can refer to this type as Person::PhoneType and its values as +Person::PHONE_TYPE_MOBILE, Person::PHONE_TYPE_HOME, and +Person::PHONE_TYPE_WORK (the implementation details are a little more +complicated, but you don’t need to understand them to use the enum).

The compiler has also generated a nested class for you called +Person::PhoneNumber. If you look at the code, you can see that the “real” +class is actually called Person_PhoneNumber, but a typedef defined inside +Person allows you to treat it as if it were a nested class. The only case +where this makes a difference is if you want to forward-declare the class in +another file – you cannot forward-declare nested types in C++, but you can +forward-declare Person_PhoneNumber.

Standard Message Methods

Each message class also contains a number of other methods that let you check or +manipulate the entire message, including:

  • bool IsInitialized() const;: checks if all required fields have been set.
  • string DebugString() const;: returns a human-readable representation of +the message, particularly useful for debugging.
  • void CopyFrom(const Person& from);: overwrites the message with the given +message’s values.
  • void Clear();: clears all the elements back to the empty state.

These and the I/O methods described in the following section implement the +Message interface shared by all C++ protocol buffer classes. For more info, +see the +complete API documentation for Message.

Parsing and Serialization

Finally, each protocol buffer class has methods for writing and reading messages +of your chosen type using the protocol buffer +binary format. These +include:

  • bool SerializeToString(string* output) const;: serializes the message and +stores the bytes in the given string. Note that the bytes are binary, not +text; we only use the string class as a convenient container.
  • bool ParseFromString(const string& data);: parses a message from the given +string.
  • bool SerializeToOstream(ostream* output) const;: writes the message to the +given C++ ostream.
  • bool ParseFromIstream(istream* input);: parses a message from the given +C++ istream.

These are just a couple of the options provided for parsing and serialization. +See the +Message API reference +for a complete list.

Writing a Message

Now let’s try using your protocol buffer classes. The first thing you want your +address book application to be able to do is write personal details to your +address book file. To do this, you need to create and populate instances of your +protocol buffer classes and then write them to an output stream.

Here is a program that reads an AddressBook from a file, adds one new Person +to it based on user input, and writes the new AddressBook back out to the file +again. The parts which directly call or reference code generated by the protocol +compiler are highlighted.

#include <iostream>
+#include <fstream>
+#include <string>
+#include "addressbook.pb.h"
+using namespace std;
+
+// This function fills in a Person message based on user input.
+void PromptForAddress(tutorial::Person& person) {
+  cout << "Enter person ID number: ";
+  int id;
+  cin >> id;
+  person.set_id(id);
+  cin.ignore(256, '\n');
+
+  cout << "Enter name: ";
+  getline(cin, *person.mutable_name());
+
+  cout << "Enter email address (blank for none): ";
+  string email;
+  getline(cin, email);
+  if (!email.empty()) {
+    person.set_email(email);
+  }
+
+  while (true) {
+    cout << "Enter a phone number (or leave blank to finish): ";
+    string number;
+    getline(cin, number);
+    if (number.empty()) {
+      break;
+    }
+
+    tutorial::Person::PhoneNumber* phone_number = person.add_phones();
+    phone_number->set_number(number);
+
+    cout << "Is this a mobile, home, or work phone? ";
+    string type;
+    getline(cin, type);
+    if (type == "mobile") {
+      phone_number->set_type(tutorial::Person::PHONE_TYPE_MOBILE);
+    } else if (type == "home") {
+      phone_number->set_type(tutorial::Person::PHONE_TYPE_HOME);
+    } else if (type == "work") {
+      phone_number->set_type(tutorial::Person::PHONE_TYPE_WORK);
+    } else {
+      cout << "Unknown phone type. Using default." << endl;
+    }
+  }
+}
+
+// Main function:  Reads the entire address book from a file,
+//   adds one person based on user input, then writes it back out to the same
+//   file.
+int main(int argc, char* argv[]) {
+  // Verify that the version of the library that we linked against is
+  // compatible with the version of the headers we compiled against.
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  if (argc != 2) {
+    cerr << "Usage:  " << argv[0] << " ADDRESS_BOOK_FILE" << endl;
+    return -1;
+  }
+
+  tutorial::AddressBook address_book;
+
+  {
+    // Read the existing address book.
+    fstream input(argv[1], ios::in | ios::binary);
+    if (!input) {
+      cout << argv[1] << ": File not found.  Creating a new file." << endl;
+    } else if (!address_book.ParseFromIstream(&input)) {
+      cerr << "Failed to parse address book." << endl;
+      return -1;
+    }
+  }
+
+  // Add an address.
+  PromptForAddress(*address_book.add_people());
+
+  {
+    // Write the new address book back to disk.
+    fstream output(argv[1], ios::out | ios::trunc | ios::binary);
+    if (!address_book.SerializeToOstream(&output)) {
+      cerr << "Failed to write address book." << endl;
+      return -1;
+    }
+  }
+
+  // Optional:  Delete all global objects allocated by libprotobuf.
+  google::protobuf::ShutdownProtobufLibrary();
+
+  return 0;
+}
+

Notice the GOOGLE_PROTOBUF_VERIFY_VERSION macro. It is good practice – though +not strictly necessary – to execute this macro before using the C++ Protocol +Buffer library. It verifies that you have not accidentally linked against a +version of the library which is incompatible with the version of the headers you +compiled with. If a version mismatch is detected, the program will abort. Note +that every .pb.cc file automatically invokes this macro on startup.

Also notice the call to ShutdownProtobufLibrary() at the end of the program. +All this does is delete any global objects that were allocated by the Protocol +Buffer library. This is unnecessary for most programs, since the process is just +going to exit anyway and the OS will take care of reclaiming all of its memory. +However, if you use a memory leak checker that requires that every last object +be freed, or if you are writing a library which may be loaded and unloaded +multiple times by a single process, then you may want to force Protocol Buffers +to clean up everything.

Reading a Message

Of course, an address book wouldn’t be much use if you couldn’t get any +information out of it! This example reads the file created by the above example +and prints all the information in it.

#include <iostream>
+#include <fstream>
+#include <string>
+#include "addressbook.pb.h"
+using namespace std;
+
+// Iterates though all people in the AddressBook and prints info about them.
+void ListPeople(const tutorial::AddressBook& address_book) {
+  for (const tutorial::Person& person : address_book.people()) {
+    cout << "Person ID: " << person.id() << endl;
+    cout << "  Name: " << person.name() << endl;
+    if (!person.has_email()) {
+      cout << "  E-mail address: " << person.email() << endl;
+    }
+
+    for (const tutorial::Person::PhoneNumber& phone_number : person.phones()) {
+      switch (phone_number.type()) {
+        case tutorial::Person::PHONE_TYPE_MOBILE:
+          cout << "  Mobile phone #: ";
+          break;
+        case tutorial::Person::PHONE_TYPE_HOME:
+          cout << "  Home phone #: ";
+          break;
+        case tutorial::Person::PHONE_TYPE_WORK:
+          cout << "  Work phone #: ";
+          break;
+        case tutorial::Person::PHONE_TYPE_UNSPECIFIED:
+        default:
+          cout << "  Phone #: ";
+          break;
+      }
+      cout << phone_number.number() << endl;
+    }
+  }
+}
+
+// Main function:  Reads the entire address book from a file and prints all
+//   the information inside.
+int main(int argc, char* argv[]) {
+  // Verify that the version of the library that we linked against is
+  // compatible with the version of the headers we compiled against.
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  if (argc != 2) {
+    cerr << "Usage:  " << argv[0] << " ADDRESS_BOOK_FILE" << endl;
+    return -1;
+  }
+
+  tutorial::AddressBook address_book;
+
+  {
+    // Read the existing address book.
+    fstream input(argv[1], ios::in | ios::binary);
+    if (!address_book.ParseFromIstream(&input)) {
+      cerr << "Failed to parse address book." << endl;
+      return -1;
+    }
+  }
+
+  ListPeople(address_book);
+
+  // Optional:  Delete all global objects allocated by libprotobuf.
+  google::protobuf::ShutdownProtobufLibrary();
+
+  return 0;
+}
+

Extending a Protocol Buffer

Sooner or later after you release the code that uses your protocol buffer, you +will undoubtedly want to “improve” the protocol buffer’s definition. If you want +your new buffers to be backwards-compatible, and your old buffers to be +forward-compatible – and you almost certainly do want this – then there are +some rules you need to follow. In the new version of the protocol buffer:

  • you must not change the field numbers of any existing fields.
  • you may delete singular or repeated fields.
  • you may add new singular or repeated fields but you must use fresh field +numbers (that is, field numbers that were never used in this protocol +buffer, not even by deleted fields).

(There are +some exceptions +to these rules, but they are rarely used.)

If you follow these rules, old code will happily read new messages and simply +ignore any new fields. To the old code, fields that were deleted will simply +have their default value, and deleted repeated fields will be empty. New code +will also transparently read old messages. However, keep in mind that new fields +will not be present in old messages, so you will need to check for their +presence by checking if they have the default value (e.g., an empty string) +before use.

Optimization Tips

The C++ Protocol Buffers library is extremely heavily optimized. However, proper +usage can improve performance even more. Here are some tips for squeezing every +last drop of speed out of the library:

  • Use Arenas for memory allocation. When you create many protocol buffer +messages in a short-lived operation (like parsing a single request), the +system’s memory allocator can become a bottleneck. Arenas are designed to +mitigate this. By using an arena, you can perform many allocations with low +overhead, and a single deallocation for all of them at once. This can +significantly improve performance in message-heavy applications.

    To use arenas, you allocate messages on a google::protobuf::Arena object:

    google::protobuf::Arena arena;
    +tutorial::Person* person = google::protobuf::Arena::Create<tutorial::Person>(&arena);
    +// ... populate person ...
    +

    When the arena object is destroyed, all messages allocated on it are freed. +For more details, see the Arenas guide.

  • Reuse non-arena message objects when possible. Messages try to keep +around any memory they allocate for reuse, even when they are cleared. Thus, +if you are handling many messages with the same type and similar structure +in succession, it is a good idea to reuse the same message object each time +to take load off the memory allocator. However, objects can become bloated +over time, especially if your messages vary in “shape” or if you +occasionally construct a message that is much larger than usual. You should +monitor the sizes of your message objects by calling the SpaceUsed method +and delete them once they get too big.

    Reusing arena messages can lead to unbounded memory growth. Reusing heap +messages is safer. Even with heap message, though, you can still experience +issues with the high water mark of fields. For example, if you see messages:

    a: [1, 2, 3, 4]
    +b: [1]
    +

    and

    a: [1]
    +b: [1, 2, 3, 4]
    +

    and reuse the messages, then both fields will have enough memory for the +largest they have seen. So if each input only had 5 elements, the reused +message will have memory for 8.

  • Your system’s memory allocator may not be well-optimized for allocating lots +of small objects from multiple threads. Try using +Google’s TCMalloc instead.

Advanced Usage

Protocol buffers have uses that go beyond simple accessors and serialization. Be +sure to explore the C++ API reference +to see what else you can do with them.

One key feature provided by protocol message classes is reflection. You can +iterate over the fields of a message and manipulate their values without writing +your code against any specific message type. One very useful way to use +reflection is for converting protocol messages to and from other encodings, such +as XML or JSON. A more advanced use of reflection might be to find differences +between two messages of the same type, or to develop a sort of “regular +expressions for protocol messages” in which you can write expressions that match +certain message contents. If you use your imagination, it’s possible to apply +Protocol Buffers to a much wider range of problems than you might initially +expect!

Reflection is provided by the +Message::Reflection interface.

\ No newline at end of file diff --git a/getting-started/csharptutorial/index.html b/getting-started/csharptutorial/index.html new file mode 100644 index 000000000..2249c7493 --- /dev/null +++ b/getting-started/csharptutorial/index.html @@ -0,0 +1,216 @@ +Protocol Buffer Basics: C# | Protocol Buffers Documentation +

Protocol Buffer Basics: C#

A basic C# programmers introduction to working with protocol buffers.

This tutorial provides a basic C# programmer’s introduction to working with +protocol buffers, using the +proto3 version of the +protocol buffers language. By walking through creating a simple example +application, it shows you how to

  • Define message formats in a .proto file.
  • Use the protocol buffer compiler.
  • Use the C# protocol buffer API to write and read messages.

This isn’t a comprehensive guide to using protocol buffers in C#. For more +detailed reference information, see the +Protocol Buffer Language Guide, +the C# API Reference, the +C# Generated Code Guide, +and the +Encoding Reference.

The Problem Domain

The example we’re going to use is a very simple “address book” application that +can read and write people’s contact details to and from a file. Each person in +the address book has a name, an ID, an email address, and a contact phone +number.

How do you serialize and retrieve structured data like this? There are a few +ways to solve this problem:

  • Use .NET binary serialization with +System.Runtime.Serialization.Formatters.Binary.BinaryFormatter and +associated classes. This ends up being very fragile in the face of changes, +expensive in terms of data size in some cases. It also doesn’t work very +well if you need to share data with applications written for other +platforms.
  • You can invent an ad-hoc way to encode the data items into a single +string – such as encoding 4 ints as “12:3:-23:67”. This is a simple and +flexible approach, although it does require writing one-off encoding and +parsing code, and the parsing imposes a small run-time cost. This works best +for encoding very simple data.
  • Serialize the data to XML. This approach can be very attractive since XML is +(sort of) human readable and there are binding libraries for lots of +languages. This can be a good choice if you want to share data with other +applications/projects. However, XML is notoriously space intensive, and +encoding/decoding it can impose a huge performance penalty on applications. +Also, navigating an XML DOM tree is considerably more complicated than +navigating simple fields in a class normally would be.

Protocol buffers are the flexible, efficient, automated solution to solve +exactly this problem. With protocol buffers, you write a .proto description of +the data structure you wish to store. From that, the protocol buffer compiler +creates a class that implements automatic encoding and parsing of the protocol +buffer data with an efficient binary format. The generated class provides +getters and setters for the fields that make up a protocol buffer and takes care +of the details of reading and writing the protocol buffer as a unit. +Importantly, the protocol buffer format supports the idea of extending the +format over time in such a way that the code can still read data encoded with +the old format.

Where to Find the Example Code

Our example is a command-line application for managing an address book data +file, encoded using protocol buffers. The command AddressBook (see: +Program.cs) +can add a new entry to the data file or parse the data file and print the data +to the console.

You can find the complete example in the +examples directory +and +csharp/src/AddressBook directory +of the GitHub repository.

Defining Your Protocol Format

To create your address book application, you’ll need to start with a .proto +file. The definitions in a .proto file are simple: you add a message for +each data structure you want to serialize, then specify a name and a type for +each field in the message. In our example, the .proto file that defines the +messages is +addressbook.proto.

The .proto file starts with a package declaration, which helps to prevent +naming conflicts between different projects.

syntax = "proto3";
+package tutorial;
+
+import "google/protobuf/timestamp.proto";
+

In C#, your generated classes will be placed in a namespace matching the +package name if csharp_namespace is not specified. In our example, the +csharp_namespace option has been specified to override the default, so the +generated code uses a namespace of Google.Protobuf.Examples.AddressBook +instead of Tutorial.

option csharp_namespace = "Google.Protobuf.Examples.AddressBook";
+

Next, you have your message definitions. A message is just an aggregate +containing a set of typed fields. Many standard simple data types are available +as field types, including bool, int32, float, double, and string. You +can also add further structure to your messages by using other message types as +field types.

message Person {
+  string name = 1;
+  int32 id = 2;  // Unique ID number for this person.
+  string email = 3;
+
+  enum PhoneType {
+    PHONE_TYPE_UNSPECIFIED = 0;
+    PHONE_TYPE_MOBILE = 1;
+    PHONE_TYPE_HOME = 2;
+    PHONE_TYPE_WORK = 3;
+  }
+
+  message PhoneNumber {
+    string number = 1;
+    PhoneType type = 2;
+  }
+
+  repeated PhoneNumber phones = 4;
+
+  google.protobuf.Timestamp last_updated = 5;
+}
+
+// Our address book file is just one of these.
+message AddressBook {
+  repeated Person people = 1;
+}
+

In the above example, the Person message contains PhoneNumber messages, +while the AddressBook message contains Person messages. You can even define +message types nested inside other messages – as you can see, the PhoneNumber +type is defined inside Person. You can also define enum types if you want +one of your fields to have one of a predefined list of values – here you want +to specify that a phone number can be one of PHONE_TYPE_MOBILE, +PHONE_TYPE_HOME, or PHONE_TYPE_WORK.

The " = 1", " = 2" markers on each element identify the unique “tag” that field +uses in the binary encoding. Tag numbers 1-15 require one less byte to encode +than higher numbers, so as an optimization you can decide to use those tags for +the commonly used or repeated elements, leaving tags 16 and higher for +less-commonly used optional elements. Each element in a repeated field requires +re-encoding the tag number, so repeated fields are particularly good candidates +for this optimization.

If a field value isn’t set, a +default value is +used: zero for numeric types, the empty string for strings, false for bools. For +embedded messages, the default value is always the “default instance” or +“prototype” of the message, which has none of its fields set. Calling the +accessor to get the value of a field which has not been explicitly set always +returns that field’s default value.

If a field is repeated, the field may be repeated any number of times +(including zero). The order of the repeated values will be preserved in the +protocol buffer. Think of repeated fields as dynamically sized arrays.

You’ll find a complete guide to writing .proto files – including all the +possible field types – in the +Protocol Buffer Language Guide. +Don’t go looking for facilities similar to class inheritance, though – protocol +buffers don’t do that.

Compiling Your Protocol Buffers

Now that you have a .proto, the next thing you need to do is generate the +classes you’ll need to read and write AddressBook (and hence Person and +PhoneNumber) messages. To do this, you need to run the protocol buffer +compiler protoc on your .proto:

  1. If you haven’t installed the compiler, +download the package and follow the +instructions in the README.

  2. Now run the compiler, specifying the source directory (where your +application’s source code lives – the current directory is used if you +don’t provide a value), the destination directory (where you want the +generated code to go; often the same as $SRC_DIR), and the path to your +.proto. In this case, you would invoke:

    protoc -I=$SRC_DIR --csharp_out=$DST_DIR $SRC_DIR/addressbook.proto
    +

    Because you want C# code, you use the --csharp_out option – similar +options are provided for other supported languages.

This generates Addressbook.cs in your specified destination directory. To +compile this code, you’ll need a project with a reference to the +Google.Protobuf assembly.

The Addressbook Classes

Generating Addressbook.cs gives you five useful types:

  • A static Addressbook class that contains metadata about the protocol +buffer messages.
  • An AddressBook class with a read-only People property.
  • A Person class with properties for Name, Id, Email and Phones.
  • A PhoneNumber class, nested in a static Person.Types class.
  • A PhoneType enum, also nested in Person.Types.

You can read more about the details of exactly what’s generated in the +C# Generated Code guide, +but for the most part you can treat these as perfectly ordinary C# types. One +point to highlight is that any properties corresponding to repeated fields are +read-only. You can add items to the collection or remove items from it, but you +can’t replace it with an entirely separate collection. The collection type for +repeated fields is always RepeatedField<T>. This type is like List<T> but +with a few extra convenience methods, such as an Add overload accepting a +collection of items, for use in collection initializers.

Here’s an example of how you might create an instance of Person:

Person john = new Person
+{
+    Id = 1234,
+    Name = "John Doe",
+    Email = "jdoe@example.com",
+    Phones = { new Person.Types.PhoneNumber { Number = "555-4321", Type = Person.Types.PhoneType.Home } }
+};
+

Note that with C# 6, you can use using static to remove the Person.Types +ugliness:

// Add this to the other using directives
+using static Google.Protobuf.Examples.AddressBook.Person.Types;
+...
+// The earlier Phones assignment can now be simplified to:
+Phones = { new PhoneNumber { Number = "555-4321", Type = PhoneType.HOME } }
+

Parsing and Serialization

The whole purpose of using protocol buffers is to serialize your data so that it +can be parsed elsewhere. Every generated class has a +WriteTo(CodedOutputStream) method, where CodedOutputStream is a class in the +protocol buffer runtime library. However, usually you’ll use one of the +extension methods to write to a regular System.IO.Stream or convert the +message to a byte array or ByteString. These extension messages are in the +Google.Protobuf.MessageExtensions class, so when you want to serialize you’ll +usually want a using directive for the Google.Protobuf namespace. For +example:

using Google.Protobuf;
+...
+Person john = ...; // Code as before
+using (var output = File.Create("john.dat"))
+{
+    john.WriteTo(output);
+}
+

Parsing is also simple. Each generated class has a static Parser property +which returns a MessageParser<T> for that type. That in turn has methods to +parse streams, byte arrays and ByteStrings. So to parse the file we’ve just +created, we can use:

Person john;
+using (var input = File.OpenRead("john.dat"))
+{
+    john = Person.Parser.ParseFrom(input);
+}
+

A full example program to maintain an addressbook (adding new entries and +listing existing ones) using these messages is available +in the Github repository.

Extending a Protocol Buffer

Sooner or later after you release the code that uses your protocol buffer, you +will undoubtedly want to “improve” the protocol buffer’s definition. If you want +your new buffers to be backwards-compatible, and your old buffers to be +forward-compatible – and you almost certainly do want this – then there are +some rules you need to follow. In the new version of the protocol buffer:

  • you must not change the tag numbers of any existing fields.
  • you may delete fields.
  • you may add new fields but you must use fresh tag numbers (i.e. tag +numbers that were never used in this protocol buffer, not even by deleted +fields).

(There are +some exceptions to +these rules, but they are rarely used.)

If you follow these rules, old code will happily read new messages and simply +ignore any new fields. To the old code, singular fields that were deleted will +simply have their default value, and deleted repeated fields will be empty. New +code will also transparently read old messages.

However, keep in mind that new fields will not be present in old messages, so +you will need to do something reasonable with the default value. A type-specific +default value is +used: for strings, the default value is the empty string. For booleans, the +default value is false. For numeric types, the default value is zero.

Reflection

Message descriptors (the information in the .proto file) and instances of +messages can be examined programmatically using the reflection API. This can be +useful when writing generic code such as a different text format or a smart diff +tool. Each generated class has a static Descriptor property, and the +descriptor for any instance can be retrieved using the IMessage.Descriptor +property. As a quick example of how these can be used, here is a short method to +print the top-level fields of any message.

public void PrintMessage(IMessage message)
+{
+    var descriptor = message.Descriptor;
+    foreach (var field in descriptor.Fields.InDeclarationOrder())
+    {
+        Console.WriteLine(
+            "Field {0} ({1}): {2}",
+            field.FieldNumber,
+            field.Name,
+            field.Accessor.GetValue(message);
+    }
+}
+
\ No newline at end of file diff --git a/getting-started/darttutorial/index.html b/getting-started/darttutorial/index.html new file mode 100644 index 000000000..414cf6af1 --- /dev/null +++ b/getting-started/darttutorial/index.html @@ -0,0 +1,269 @@ +Protocol Buffer Basics: Dart | Protocol Buffers Documentation +

Protocol Buffer Basics: Dart

A basic Dart programmers introduction to working with protocol buffers.

This tutorial provides a basic Dart programmer’s introduction to working with +protocol buffers, using the +proto3 version of the +protocol buffers language. By walking through creating a simple example +application, it shows you how to

  • Define message formats in a .proto file.
  • Use the protocol buffer compiler.
  • Use the Dart protocol buffer API to write and read messages.

This isn’t a comprehensive guide to using protocol buffers in Dart . For more +detailed reference information, see the +Protocol Buffer Language Guide, +the +Dart Language Tour, +the Dart API Reference, the +Dart Generated Code Guide, +and the +Encoding Reference.

The Problem Domain

The example we’re going to use is a very simple “address book” application that +can read and write people’s contact details to and from a file. Each person in +the address book has a name, an ID, an email address, and a contact phone +number.

How do you serialize and retrieve structured data like this? There are a few +ways to solve this problem:

  • You can invent an ad-hoc way to encode the data items into a single +string – such as encoding 4 ints as “12:3:-23:67”. This is a simple and +flexible approach, although it does require writing one-off encoding and +parsing code, and the parsing imposes a small run-time cost. This works best +for encoding very simple data.
  • Serialize the data to XML. This approach can be very attractive since XML is +(sort of) human readable and there are binding libraries for lots of +languages. This can be a good choice if you want to share data with other +applications/projects. However, XML is notoriously space intensive, and +encoding/decoding it can impose a huge performance penalty on applications. +Also, navigating an XML DOM tree is considerably more complicated than +navigating simple fields in a class normally would be.

Protocol buffers are the flexible, efficient, automated solution to solve +exactly this problem. With protocol buffers, you write a .proto description of +the data structure you wish to store. From that, the protocol buffer compiler +creates a class that implements automatic encoding and parsing of the protocol +buffer data with an efficient binary format. The generated class provides +getters and setters for the fields that make up a protocol buffer and takes care +of the details of reading and writing the protocol buffer as a unit. +Importantly, the protocol buffer format supports the idea of extending the +format over time in such a way that the code can still read data encoded with +the old format.

Where to Find the Example Code

Our example is a set of command-line applications for managing an address book +data file, encoded using protocol buffers. The command dart add_person.dart +adds a new entry to the data file. The command dart list_people.dart parses +the data file and prints the data to the console.

You can find the complete example in the +examples directory +of the GitHub repository.

Defining Your Protocol Format

To create your address book application, you’ll need to start with a .proto +file. The definitions in a .proto file are simple: you add a message for +each data structure you want to serialize, then specify a name and a type for +each field in the message. In our example, the .proto file that defines the +messages is +addressbook.proto.

The .proto file starts with a package declaration, which helps to prevent +naming conflicts between different projects.

syntax = "proto3";
+package tutorial;
+
+import "google/protobuf/timestamp.proto";
+

Next, you have your message definitions. A message is just an aggregate +containing a set of typed fields. Many standard simple data types are available +as field types, including bool, int32, float, double, and string. You +can also add further structure to your messages by using other message types as +field types.

message Person {
+  string name = 1;
+  int32 id = 2;  // Unique ID number for this person.
+  string email = 3;
+
+  enum PhoneType {
+    PHONE_TYPE_UNSPECIFIED = 0;
+    PHONE_TYPE_MOBILE = 1;
+    PHONE_TYPE_HOME = 2;
+    PHONE_TYPE_WORK = 3;
+  }
+
+  message PhoneNumber {
+    string number = 1;
+    PhoneType type = 2;
+  }
+
+  repeated PhoneNumber phones = 4;
+
+  google.protobuf.Timestamp last_updated = 5;
+}
+
+// Our address book file is just one of these.
+message AddressBook {
+  repeated Person people = 1;
+}
+

In the above example, the Person message contains PhoneNumber messages, +while the AddressBook message contains Person messages. You can even define +message types nested inside other messages – as you can see, the PhoneNumber +type is defined inside Person. You can also define enum types if you want +one of your fields to have one of a predefined list of values – here you want +to specify that a phone number can be one of PHONE_TYPE_MOBILE, +PHONE_TYPE_HOME, or PHONE_TYPE_WORK.

The " = 1", " = 2" markers on each element identify the unique “tag” that field +uses in the binary encoding. Tag numbers 1-15 require one less byte to encode +than higher numbers, so as an optimization you can decide to use those tags for +the commonly used or repeated elements, leaving tags 16 and higher for +less-commonly used optional elements. Each element in a repeated field requires +re-encoding the tag number, so repeated fields are particularly good candidates +for this optimization.

If a field value isn’t set, a +default value is +used: zero for numeric types, the empty string for strings, false for bools. For +embedded messages, the default value is always the “default instance” or +“prototype” of the message, which has none of its fields set. Calling the +accessor to get the value of a field which has not been explicitly set always +returns that field’s default value.

If a field is repeated, the field may be repeated any number of times +(including zero). The order of the repeated values will be preserved in the +protocol buffer. Think of repeated fields as dynamically sized arrays.

You’ll find a complete guide to writing .proto files – including all the +possible field types – in the +Protocol Buffer Language Guide. +Don’t go looking for facilities similar to class inheritance, though – protocol +buffers don’t do that.

Compiling Your Protocol Buffers

Now that you have a .proto, the next thing you need to do is generate the +classes you’ll need to read and write AddressBook (and hence Person and +PhoneNumber) messages. To do this, you need to run the protocol buffer +compiler protoc on your .proto:

  1. If you haven’t installed the compiler, +download the package and follow the +instructions in the README.

  2. Install the Dart Protocol Buffer plugin as described in +its README. +The executable bin/protoc-gen-dart must be in your PATH for the protocol +buffer protoc to find it.

  3. Now run the compiler, specifying the source directory (where your +application’s source code lives – the current directory is used if you +don’t provide a value), the destination directory (where you want the +generated code to go; often the same as $SRC_DIR), and the path to your +.proto. In this case, you would invoke:

    protoc -I=$SRC_DIR --dart_out=$DST_DIR $SRC_DIR/addressbook.proto
    +

    Because you want Dart code, you use the --dart_out option – similar +options are provided for other supported languages.

This generates addressbook.pb.dart in your specified destination directory.

The Protocol Buffer API

Generating addressbook.pb.dart gives you the following useful types:

  • An AddressBook class with a List<Person> get people getter.
  • A Person class with accessor methods for name, id, email and +phones.
  • A Person_PhoneNumber class, with accessor methods for number and type.
  • A Person_PhoneType class with static fields for each value in the +Person.PhoneType enum.

You can read more about the details of exactly what’s generated in the +Dart Generated Code guide.

Writing a Message

Now let’s try using your protocol buffer classes. The first thing you want your +address book application to be able to do is write personal details to your +address book file. To do this, you need to create and populate instances of your +protocol buffer classes and then write them to an output stream.

Here is a program which reads an AddressBook from a file, adds one new +Person to it based on user input, and writes the new AddressBook back out to +the file again. The parts which directly call or reference code generated by the +protocol compiler are highlighted.

import 'dart:io';
+
+import 'dart_tutorial/addressbook.pb.dart';
+
+// This function fills in a Person message based on user input.
+Person promptForAddress() {
+  Person person = Person();
+
+  print('Enter person ID: ');
+  String input = stdin.readLineSync();
+  person.id = int.parse(input);
+
+  print('Enter name');
+  person.name = stdin.readLineSync();
+
+  print('Enter email address (blank for none) : ');
+  String email = stdin.readLineSync();
+  if (email.isNotEmpty) {
+    person.email = email;
+  }
+
+  while (true) {
+    print('Enter a phone number (or leave blank to finish): ');
+    String number = stdin.readLineSync();
+    if (number.isEmpty) break;
+
+    Person_PhoneNumber phoneNumber = Person_PhoneNumber();
+
+    phoneNumber.number = number;
+    print('Is this a mobile, home, or work phone? ');
+
+    String type = stdin.readLineSync();
+    switch (type) {
+      case 'mobile':
+        phoneNumber.type = Person_PhoneType.PHONE_TYPE_MOBILE;
+        break;
+      case 'home':
+        phoneNumber.type = Person_PhoneType.PHONE_TYPE_HOME;
+        break;
+      case 'work':
+        phoneNumber.type = Person_PhoneType.PHONE_TYPE_WORK;
+        break;
+      default:
+        print('Unknown phone type.  Using default.');
+    }
+    person.phones.add(phoneNumber);
+  }
+
+  return person;
+}
+
+// Reads the entire address book from a file, adds one person based
+// on user input, then writes it back out to the same file.
+main(List arguments) {
+  if (arguments.length != 1) {
+    print('Usage: add_person ADDRESS_BOOK_FILE');
+    exit(-1);
+  }
+
+  File file = File(arguments.first);
+  AddressBook addressBook;
+  if (!file.existsSync()) {
+    print('File not found. Creating new file.');
+    addressBook = AddressBook();
+  } else {
+    addressBook = AddressBook.fromBuffer(file.readAsBytesSync());
+  }
+  addressBook.people.add(promptForAddress());
+  file.writeAsBytes(addressBook.writeToBuffer());
+}
+

Reading a Message

Of course, an address book wouldn’t be much use if you couldn’t get any +information out of it! This example reads the file created by the above example +and prints all the information in it.

import 'dart:io';
+
+import 'dart_tutorial/addressbook.pb.dart';
+import 'dart_tutorial/addressbook.pbenum.dart';
+
+// Iterates though all people in the AddressBook and prints info about them.
+void printAddressBook(AddressBook addressBook) {
+  for (Person person in addressBook.people) {
+    print('Person ID: ${ person.id}');
+    print('  Name: ${ person.name}');
+    if (person.hasEmail()) {
+      print('  E-mail address:${ person.email}');
+    }
+
+    for (Person_PhoneNumber phoneNumber in person.phones) {
+      switch (phoneNumber.type) {
+        case Person_PhoneType.PHONE_TYPE_MOBILE:
+          print('   Mobile phone #: ');
+          break;
+        case Person_PhoneType.PHONE_TYPE_HOME:
+          print('   Home phone #: ');
+          break;
+        case Person_PhoneType.PHONE_TYPE_WORK:
+          print('   Work phone #: ');
+          break;
+        default:
+          print('   Unknown phone #: ');
+          break;
+      }
+      print(phoneNumber.number);
+    }
+  }
+}
+
+// Reads the entire address book from a file and prints all
+// the information inside.
+main(List arguments) {
+  if (arguments.length != 1) {
+    print('Usage: list_person ADDRESS_BOOK_FILE');
+    exit(-1);
+  }
+
+  // Read the existing address book.
+  File file = new File(arguments.first);
+ AddressBook addressBook = new AddressBook.fromBuffer(file.readAsBytesSync());
+  printAddressBook(addressBook);
+}
+

Extending a Protocol Buffer

Sooner or later after you release the code that uses your protocol buffer, you +will undoubtedly want to “improve” the protocol buffer’s definition. If you want +your new buffers to be backwards-compatible, and your old buffers to be +forward-compatible – and you almost certainly do want this – then there are +some rules you need to follow. In the new version of the protocol buffer:

  • you must not change the tag numbers of any existing fields.
  • you may delete fields.
  • you may add new fields but you must use fresh tag numbers (i.e. tag +numbers that were never used in this protocol buffer, not even by deleted +fields).

(There are +some exceptions to +these rules, but they are rarely used.)

If you follow these rules, old code will happily read new messages and simply +ignore any new fields. To the old code, singular fields that were deleted will +simply have their default value, and deleted repeated fields will be empty. New +code will also transparently read old messages.

However, keep in mind that new fields will not be present in old messages, so +you will need to do something reasonable with the default value. A type-specific +default value is +used: for strings, the default value is the empty string. For booleans, the +default value is false. For numeric types, the default value is zero.

\ No newline at end of file diff --git a/getting-started/gotutorial/index.html b/getting-started/gotutorial/index.html new file mode 100644 index 000000000..b0b8c176a --- /dev/null +++ b/getting-started/gotutorial/index.html @@ -0,0 +1,193 @@ +Protocol Buffer Basics: Go | Protocol Buffers Documentation +

Protocol Buffer Basics: Go

A basic Go programmers introduction to working with protocol buffers.

This tutorial provides a basic Go programmer’s introduction to working with +protocol buffers, using the +proto3 version of the +protocol buffers language. By walking through creating a simple example +application, it shows you how to

  • Define message formats in a .proto file.
  • Use the protocol buffer compiler.
  • Use the Go protocol buffer API to write and read messages.

This isn’t a comprehensive guide to using protocol buffers in Go. For more +detailed reference information, see the +Protocol Buffer Language Guide, +the Go API Reference, the +Go Generated Code Guide, +and the +Encoding Reference.

The Problem Domain

The example we’re going to use is a very simple “address book” application that +can read and write people’s contact details to and from a file. Each person in +the address book has a name, an ID, an email address, and a contact phone +number.

How do you serialize and retrieve structured data like this? There are a few +ways to solve this problem:

  • Use gobs to serialize Go data structures. +This is a good solution in a Go-specific environment, but it doesn’t work +well if you need to share data with applications written for other +platforms.
  • You can invent an ad-hoc way to encode the data items into a single +string – such as encoding 4 ints as “12:3:-23:67”. This is a simple and +flexible approach, although it does require writing one-off encoding and +parsing code, and the parsing imposes a small run-time cost. This works best +for encoding very simple data.
  • Serialize the data to XML. This approach can be very attractive since XML is +(sort of) human readable and there are binding libraries for lots of +languages. This can be a good choice if you want to share data with other +applications/projects. However, XML is notoriously space intensive, and +encoding/decoding it can impose a huge performance penalty on applications. +Also, navigating an XML DOM tree is considerably more complicated than +navigating simple fields in a class normally would be.

Protocol buffers are the flexible, efficient, automated solution to solve +exactly this problem. With protocol buffers, you write a .proto description of +the data structure you wish to store. From that, the protocol buffer compiler +creates a class that implements automatic encoding and parsing of the protocol +buffer data with an efficient binary format. The generated class provides +getters and setters for the fields that make up a protocol buffer and takes care +of the details of reading and writing the protocol buffer as a unit. +Importantly, the protocol buffer format supports the idea of extending the +format over time in such a way that the code can still read data encoded with +the old format.

Where to Find the Example Code

Our example is a set of command-line applications for managing an address book +data file, encoded using protocol buffers. The command add_person_go adds a +new entry to the data file. The command list_people_go parses the data file +and prints the data to the console.

You can find the complete example in the +examples directory +of the GitHub repository.

Defining Your Protocol Format

To create your address book application, you’ll need to start with a .proto +file. The definitions in a .proto file are simple: you add a message for +each data structure you want to serialize, then specify a name and a type for +each field in the message. In our example, the .proto file that defines the +messages is +addressbook.proto.

The .proto file starts with a package declaration, which helps to prevent +naming conflicts between different projects.

syntax = "proto3";
+package tutorial;
+
+import "google/protobuf/timestamp.proto";
+

The go_package option defines the import path of the package which will +contain all the generated code for this file. The Go package name will be the +last path component of the import path. For example, our example will use a +package name of “tutorialpb”.

option go_package = "github.com/protocolbuffers/protobuf/examples/go/tutorialpb";
+

Next, you have your message definitions. A message is just an aggregate +containing a set of typed fields. Many standard simple data types are available +as field types, including bool, int32, float, double, and string. You +can also add further structure to your messages by using other message types as +field types.

message Person {
+  string name = 1;
+  int32 id = 2;  // Unique ID number for this person.
+  string email = 3;
+
+  message PhoneNumber {
+    string number = 1;
+    PhoneType type = 2;
+  }
+
+  repeated PhoneNumber phones = 4;
+
+  google.protobuf.Timestamp last_updated = 5;
+}
+
+enum PhoneType {
+  PHONE_TYPE_UNSPECIFIED = 0;
+  PHONE_TYPE_MOBILE = 1;
+  PHONE_TYPE_HOME = 2;
+  PHONE_TYPE_WORK = 3;
+}
+
+// Our address book file is just one of these.
+message AddressBook {
+  repeated Person people = 1;
+}
+

In the above example, the Person message contains PhoneNumber messages, +while the AddressBook message contains Person messages. You can even define +message types nested inside other messages – as you can see, the PhoneNumber +type is defined inside Person. You can also define enum types if you want +one of your fields to have one of a predefined list of values – here you want +to specify that a phone number can be one of PHONE_TYPE_MOBILE, +PHONE_TYPE_HOME, or PHONE_TYPE_WORK.

The " = 1", " = 2" markers on each element identify the unique “tag” that field +uses in the binary encoding. Tag numbers 1-15 require one less byte to encode +than higher numbers, so as an optimization you can decide to use those tags for +the commonly used or repeated elements, leaving tags 16 and higher for +less-commonly used optional elements. Each element in a repeated field requires +re-encoding the tag number, so repeated fields are particularly good candidates +for this optimization.

If a field value isn’t set, a +default value is +used: zero for numeric types, the empty string for strings, false for bools. For +embedded messages, the default value is always the “default instance” or +“prototype” of the message, which has none of its fields set. Calling the +accessor to get the value of a field which has not been explicitly set always +returns that field’s default value.

If a field is repeated, the field may be repeated any number of times +(including zero). The order of the repeated values will be preserved in the +protocol buffer. Think of repeated fields as dynamically sized arrays.

You’ll find a complete guide to writing .proto files – including all the +possible field types – in the +Protocol Buffer Language Guide. +Don’t go looking for facilities similar to class inheritance, though – protocol +buffers don’t do that.

Compiling Your Protocol Buffers

Now that you have a .proto, the next thing you need to do is generate the +classes you’ll need to read and write AddressBook (and hence Person and +PhoneNumber) messages. To do this, you need to run the protocol buffer +compiler protoc on your .proto:

  1. If you haven’t installed the compiler, +download the package and follow the +instructions in the README.

  2. Run the following command to install the Go protocol buffers plugin:

    go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
    +

    The compiler plugin protoc-gen-go will be installed in $GOBIN, +defaulting to $GOPATH/bin. It must be in your $PATH for the protocol +compiler protoc to find it.

  3. Now run the compiler, specifying the source directory (where your +application’s source code lives – the current directory is used if you +don’t provide a value), the destination directory (where you want the +generated code to go; often the same as $SRC_DIR), and the path to your +.proto. In this case, you would invoke:

    protoc -I=$SRC_DIR --go_out=$DST_DIR $SRC_DIR/addressbook.proto
    +

    Because you want Go code, you use the --go_out option – similar options +are provided for other supported languages.

This generates +github.com/protocolbuffers/protobuf/examples/go/tutorialpb/addressbook.pb.go +in your specified destination directory.

The Protocol Buffer API

Generating addressbook.pb.go gives you the following useful types:

  • An AddressBook structure with a People field.
  • A Person structure with fields for Name, Id, Email and Phones.
  • A Person_PhoneNumber structure, with fields for Number and Type.
  • The type Person_PhoneType and a value defined for each value in the +Person.PhoneType enum.

You can read more about the details of exactly what’s generated in the +Go Generated Code guide, +but for the most part you can treat these as perfectly ordinary Go types.

Here’s an example from the +list_people command’s unit tests +of how you might create an instance of Person:

p := pb.Person{
+    Id:    1234,
+    Name:  "John Doe",
+    Email: "jdoe@example.com",
+    Phones: []*pb.Person_PhoneNumber{
+        {Number: "555-4321", Type: pb.PhoneType_PHONE_TYPE_HOME},
+    },
+}
+

Writing a Message

The whole purpose of using protocol buffers is to serialize your data so that it +can be parsed elsewhere. In Go, you use the proto library’s +Marshal +function to serialize your protocol buffer data. A pointer to a protocol buffer +message’s struct implements the proto.Message interface. Calling +proto.Marshal returns the protocol buffer, encoded in its wire format. For +example, we use this function in the +add_person command:

book := &pb.AddressBook{}
+// ...
+
+// Write the new address book back to disk.
+out, err := proto.Marshal(book)
+if err != nil {
+    log.Fatalln("Failed to encode address book:", err)
+}
+if err := ioutil.WriteFile(fname, out, 0644); err != nil {
+    log.Fatalln("Failed to write address book:", err)
+}
+

Reading a Message

To parse an encoded message, you use the proto library’s +Unmarshal +function. Calling this parses the data in in as a protocol buffer and places +the result in book. So to parse the file in the +list_people command, +we use:

// Read the existing address book.
+in, err := ioutil.ReadFile(fname)
+if err != nil {
+    log.Fatalln("Error reading file:", err)
+}
+book := &pb.AddressBook{}
+if err := proto.Unmarshal(in, book); err != nil {
+    log.Fatalln("Failed to parse address book:", err)
+}
+

Extending a Protocol Buffer

Sooner or later after you release the code that uses your protocol buffer, you +will undoubtedly want to “improve” the protocol buffer’s definition. If you want +your new buffers to be backwards-compatible, and your old buffers to be +forward-compatible – and you almost certainly do want this – then there are +some rules you need to follow. In the new version of the protocol buffer:

  • you must not change the tag numbers of any existing fields.
  • you may delete fields.
  • you may add new fields but you must use fresh tag numbers (i.e. tag +numbers that were never used in this protocol buffer, not even by deleted +fields).

(There are +some exceptions to +these rules, but they are rarely used.)

If you follow these rules, old code will happily read new messages and simply +ignore any new fields. To the old code, singular fields that were deleted will +simply have their default value, and deleted repeated fields will be empty. New +code will also transparently read old messages.

However, keep in mind that new fields will not be present in old messages, so +you will need to do something reasonable with the default value. A type-specific +default value is +used: for strings, the default value is the empty string. For booleans, the +default value is false. For numeric types, the default value is zero.

\ No newline at end of file diff --git a/getting-started/index.html b/getting-started/index.html new file mode 100644 index 000000000..ce29385bc --- /dev/null +++ b/getting-started/index.html @@ -0,0 +1,10 @@ +Tutorials | Protocol Buffers Documentation +

Tutorials

Each tutorial in this section shows you how to implement a simple application using protocol buffers in your favourite language, introducing you to the language’s protocol buffer API as well as showing you the basics of creating and using .proto files.

The complete sample code for each application is also provided.

The tutorials don’t assume that you know anything about protocol buffers, but do +assume that you are comfortable writing code in your chosen language, including +using file I/O.


Protocol Buffer Basics: C++

A basic C++ programmers introduction to working with protocol buffers.

Protocol Buffer Basics: C#

A basic C# programmers introduction to working with protocol buffers.

Protocol Buffer Basics: Dart

A basic Dart programmers introduction to working with protocol buffers.

Protocol Buffer Basics: Go

A basic Go programmers introduction to working with protocol buffers.

Protocol Buffer Basics: Java

A basic Java programmers introduction to working with protocol buffers.

Protocol Buffer Basics: Kotlin

A basic Kotlin programmers introduction to working with protocol buffers.

Protocol Buffer Basics: Python

A basic Python programmers introduction to working with protocol buffers.

\ No newline at end of file diff --git a/getting-started/index.xml b/getting-started/index.xml new file mode 100644 index 000000000..5c848f9e3 --- /dev/null +++ b/getting-started/index.xml @@ -0,0 +1,8 @@ +Tutorials on Protocol Buffers Documentationhttps://protobuf.dev/getting-started/Recent content in Tutorials on Protocol Buffers DocumentationHugoenProtocol Buffer Basics: C++https://protobuf.dev/getting-started/cpptutorial/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/getting-started/cpptutorial/This tutorial provides a basic C++ programmers introduction to working with protocol buffers. By walking through creating a simple example application, it shows you how to +Define message formats in a .proto file. Use the protocol buffer compiler. Use the C++ protocol buffer API to write and read messages. This isn&rsquo;t a comprehensive guide to using protocol buffers in C++. For more detailed reference information, see the Protocol Buffer Language Guide, the C++ API Reference, the C++ Generated Code Guide, and the Encoding Reference.Protocol Buffer Basics: C#https://protobuf.dev/getting-started/csharptutorial/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/getting-started/csharptutorial/This tutorial provides a basic C# programmer&rsquo;s introduction to working with protocol buffers, using the proto3 version of the protocol buffers language. By walking through creating a simple example application, it shows you how to +Define message formats in a .proto file. Use the protocol buffer compiler. Use the C# protocol buffer API to write and read messages. This isn&rsquo;t a comprehensive guide to using protocol buffers in C#. For more detailed reference information, see the Protocol Buffer Language Guide, the C# API Reference, the C# Generated Code Guide, and the Encoding Reference.Protocol Buffer Basics: Darthttps://protobuf.dev/getting-started/darttutorial/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/getting-started/darttutorial/This tutorial provides a basic Dart programmer&rsquo;s introduction to working with protocol buffers, using the proto3 version of the protocol buffers language. By walking through creating a simple example application, it shows you how to +Define message formats in a .proto file. Use the protocol buffer compiler. Use the Dart protocol buffer API to write and read messages. This isn&rsquo;t a comprehensive guide to using protocol buffers in Dart . For more detailed reference information, see the Protocol Buffer Language Guide, the Dart Language Tour, the Dart API Reference, the Dart Generated Code Guide, and the Encoding Reference.Protocol Buffer Basics: Gohttps://protobuf.dev/getting-started/gotutorial/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/getting-started/gotutorial/This tutorial provides a basic Go programmer&rsquo;s introduction to working with protocol buffers, using the proto3 version of the protocol buffers language. By walking through creating a simple example application, it shows you how to +Define message formats in a .proto file. Use the protocol buffer compiler. Use the Go protocol buffer API to write and read messages. This isn&rsquo;t a comprehensive guide to using protocol buffers in Go. For more detailed reference information, see the Protocol Buffer Language Guide, the Go API Reference, the Go Generated Code Guide, and the Encoding Reference.Protocol Buffer Basics: Javahttps://protobuf.dev/getting-started/javatutorial/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/getting-started/javatutorial/This tutorial provides a basic Java programmer&rsquo;s introduction to working with protocol buffers. By walking through creating a simple example application, it shows you how to +Define message formats in a .proto file. Use the protocol buffer compiler. Use the Java protocol buffer API to write and read messages. This isn&rsquo;t a comprehensive guide to using protocol buffers in Java. For more detailed reference information, see the Protocol Buffer Language Guide (proto2), the Protocol Buffer Language Guide (proto3), the Java API Reference, the Java Generated Code Guide, and the Encoding Reference.Protocol Buffer Basics: Kotlinhttps://protobuf.dev/getting-started/kotlintutorial/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/getting-started/kotlintutorial/This tutorial provides a basic Kotlin programmer&rsquo;s introduction to working with protocol buffers, using the proto3 version of the protocol buffers language. By walking through creating a simple example application, it shows you how to +Define message formats in a .proto file. Use the protocol buffer compiler. Use the Kotlin protocol buffer API to write and read messages. This isn&rsquo;t a comprehensive guide to using protocol buffers in Kotlin. For more detailed reference information, see the Protocol Buffer Language Guide, the Kotlin API Reference, the Kotlin Generated Code Guide, and the Encoding Reference.Protocol Buffer Basics: Pythonhttps://protobuf.dev/getting-started/pythontutorial/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/getting-started/pythontutorial/This tutorial provides a basic Python programmer&rsquo;s introduction to working with protocol buffers. By walking through creating a simple example application, it shows you how to +Define message formats in a .proto file. Use the protocol buffer compiler. Use the Python protocol buffer API to write and read messages. This isn&rsquo;t a comprehensive guide to using protocol buffers in Python. For more detailed reference information, see the Protocol Buffer Language Guide (proto2), the Protocol Buffer Language Guide (proto3), the Python API Reference, the Python Generated Code Guide, and the Encoding Reference. \ No newline at end of file diff --git a/getting-started/javatutorial/index.html b/getting-started/javatutorial/index.html new file mode 100644 index 000000000..0dca8b5a6 --- /dev/null +++ b/getting-started/javatutorial/index.html @@ -0,0 +1,453 @@ +Protocol Buffer Basics: Java | Protocol Buffers Documentation +

Protocol Buffer Basics: Java

A basic Java programmers introduction to working with protocol buffers.

This tutorial provides a basic Java programmer’s introduction to working with +protocol buffers. By walking through creating a simple example application, it +shows you how to

  • Define message formats in a .proto file.
  • Use the protocol buffer compiler.
  • Use the Java protocol buffer API to write and read messages.

This isn’t a comprehensive guide to using protocol buffers in Java. For more +detailed reference information, see the +Protocol Buffer Language Guide (proto2), +the +Protocol Buffer Language Guide (proto3), +the +Java API Reference, +the +Java Generated Code Guide, +and the +Encoding Reference.

The Problem Domain

The example we’re going to use is a very simple “address book” application that +can read and write people’s contact details to and from a file. Each person in +the address book has a name, an ID, an email address, and a contact phone +number.

How do you serialize and retrieve structured data like this? There are a few +ways to solve this problem:

  • Use Java Serialization. This is the default approach since it’s built into +the language, but it has a host of well-known problems (see Effective Java, +by Josh Bloch pp. 213), and also doesn’t work very well if you need to share +data with applications written in C++ or Python.
  • You can invent an ad-hoc way to encode the data items into a single +string – such as encoding 4 ints as “12:3:-23:67”. This is a simple and +flexible approach, although it does require writing one-off encoding and +parsing code, and the parsing imposes a small run-time cost. This works best +for encoding very simple data.
  • Serialize the data to XML. This approach can be very attractive since XML is +(sort of) human readable and there are binding libraries for lots of +languages. This can be a good choice if you want to share data with other +applications/projects. However, XML is notoriously space intensive, and +encoding/decoding it can impose a huge performance penalty on applications. +Also, navigating an XML DOM tree is considerably more complicated than +navigating simple fields in a class normally would be.

Instead of these options, you can use protocol buffers. Protocol buffers are the +flexible, efficient, automated solution to solve exactly this problem. With +protocol buffers, you write a .proto description of the data structure you +wish to store. From that, the protocol buffer compiler creates a class that +implements automatic encoding and parsing of the protocol buffer data with an +efficient binary format. The generated class provides getters and setters for +the fields that make up a protocol buffer and takes care of the details of +reading and writing the protocol buffer as a unit. Importantly, the protocol +buffer format supports the idea of extending the format over time in such a way +that the code can still read data encoded with the old format.

Where to Find the Example Code

The example code is included in the source code package, under the “examples” +directory. Download it here.

Defining Your Protocol Format

To create your address book application, you’ll need to start with a .proto +file. The definitions in a .proto file are simple: you add a message for +each data structure you want to serialize, then specify a name and a type for +each field in the message. Here is the .proto file that defines your messages, +addressbook.proto.

syntax = "proto2";
+
+package tutorial;
+
+option java_multiple_files = true;
+option java_package = "com.example.tutorial.protos";
+option java_outer_classname = "AddressBookProtos";
+
+message Person {
+  optional string name = 1;
+  optional int32 id = 2;
+  optional string email = 3;
+
+  enum PhoneType {
+    PHONE_TYPE_UNSPECIFIED = 0;
+    PHONE_TYPE_MOBILE = 1;
+    PHONE_TYPE_HOME = 2;
+    PHONE_TYPE_WORK = 3;
+  }
+
+  message PhoneNumber {
+    optional string number = 1;
+    optional PhoneType type = 2 [default = PHONE_TYPE_HOME];
+  }
+
+  repeated PhoneNumber phones = 4;
+}
+
+message AddressBook {
+  repeated Person people = 1;
+}
+

As you can see, the syntax is similar to C++ or Java. Let’s go through each part +of the file and see what it does.

The .proto file starts with a package declaration, which helps to prevent +naming conflicts between different projects. In Java, the package name is used +as the Java package unless you have explicitly specified a java_package, as we +have here. Even if you do provide a java_package, you should still define a +normal package as well to avoid name collisions in the Protocol Buffers name +space as well as in non-Java languages.

After the package declaration, you can see three options that are Java-specific: +java_multiple_files, java_package, and java_outer_classname. +java_package specifies in what Java package name your generated classes should +live. If you don’t specify this explicitly, it simply matches the package name +given by the package declaration, but these names usually aren’t appropriate +Java package names (since they usually don’t start with a domain name). The +java_outer_classname option defines the class name of the wrapper class which +will represent this file. If you don’t give a java_outer_classname explicitly, +it will be generated by converting the file name to upper camel case. For +example, “my_proto.proto” would, by default, use “MyProto” as the wrapper class +name. The java_multiple_files = true option enables generating a separate +.java file for each generated class (instead of the legacy behavior of +generating a single .java file for the wrapper class, using the wrapper class +as an outer class, and nesting all the other classes inside the wrapper class).

Next, you have your message definitions. A message is just an aggregate +containing a set of typed fields. Many standard simple data types are available +as field types, including bool, int32, float, double, and string. You +can also add further structure to your messages by using other message types as +field types – in the above example the Person message contains PhoneNumber +messages, while the AddressBook message contains Person messages. You can +even define message types nested inside other messages – as you can see, the +PhoneNumber type is defined inside Person. You can also define enum types +if you want one of your fields to have one of a predefined list of values – +here you want to specify that a phone number can be one of the following phone +types: PHONE_TYPE_MOBILE, PHONE_TYPE_HOME, or PHONE_TYPE_WORK.

The " = 1", " = 2" markers on each element identify the unique “tag” that field +uses in the binary encoding. Tag numbers 1-15 require one less byte to encode +than higher numbers, so as an optimization you can decide to use those tags for +the commonly used or repeated elements, leaving tags 16 and higher for +less-commonly used optional elements. Each element in a repeated field requires +re-encoding the tag number, so repeated fields are particularly good candidates +for this optimization.

Each field must be annotated with one of the following modifiers:

  • optional: the field may or may not be set. If an optional field value +isn’t set, a default value is used. For simple types, you can specify your +own default value, as we’ve done for the phone number type in the example. +Otherwise, a system default is used: zero for numeric types, the empty +string for strings, false for bools. For embedded messages, the default +value is always the “default instance” or “prototype” of the message, which +has none of its fields set. Calling the accessor to get the value of an +optional (or required) field which has not been explicitly set always +returns that field’s default value.
  • repeated: the field may be repeated any number of times (including zero). +The order of the repeated values will be preserved in the protocol buffer. +Think of repeated fields as dynamically sized arrays.
  • required: a value for the field must be provided, otherwise the message +will be considered “uninitialized”. Trying to build an uninitialized message +will throw a RuntimeException. Parsing an uninitialized message will throw +an IOException. Other than this, a required field behaves exactly like an +optional field.

You’ll find a complete guide to writing .proto files – including all the +possible field types – in the +Protocol Buffer Language Guide. +Don’t go looking for facilities similar to class inheritance, though – protocol +buffers don’t do that.

Compiling Your Protocol Buffers

Now that you have a .proto, the next thing you need to do is generate the +classes you’ll need to read and write AddressBook (and hence Person and +PhoneNumber) messages. To do this, you need to run the protocol buffer +compiler protoc on your .proto:

  1. If you haven’t installed the compiler, +download the package and follow the +instructions in the README.

  2. Now run the compiler, specifying the source directory (where your +application’s source code lives – the current directory is used if you +don’t provide a value), the destination directory (where you want the +generated code to go; often the same as $SRC_DIR), and the path to your +.proto. In this case, you…:

    protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/addressbook.proto
    +

    Because you want Java classes, you use the --java_out option – similar +options are provided for other supported languages.

This generates a com/example/tutorial/protos/ subdirectory in your specified +destination directory, containing a few generated .java files.

The Protocol Buffer API

Let’s look at some of the generated code and see what classes and methods the +compiler has created for you. If you look in com/example/tutorial/protos/, you +can see that it contains .java files defining a class for each message you +specified in addressbook.proto. Each class has its own Builder class that +you use to create instances of that class. You can find out more about builders +in the Builders vs. Messages section below.

Both messages and builders have auto-generated accessor methods for each field +of the message; messages have only getters while builders have both getters and +setters. Here are some of the accessors for the Person class (implementations +omitted for brevity):

// required string name = 1;
+public boolean hasName();
+public String getName();
+
+// required int32 id = 2;
+public boolean hasId();
+public int getId();
+
+// optional string email = 3;
+public boolean hasEmail();
+public String getEmail();
+
+// repeated .tutorial.Person.PhoneNumber phones = 4;
+public List<PhoneNumber> getPhonesList();
+public int getPhonesCount();
+public PhoneNumber getPhones(int index);
+

Meanwhile, Person.Builder has the same getters plus setters:

// required string name = 1;
+public boolean hasName();
+public String getName();
+public Builder setName(String value);
+public Builder clearName();
+
+// required int32 id = 2;
+public boolean hasId();
+public int getId();
+public Builder setId(int value);
+public Builder clearId();
+
+// optional string email = 3;
+public boolean hasEmail();
+public String getEmail();
+public Builder setEmail(String value);
+public Builder clearEmail();
+
+// repeated .tutorial.Person.PhoneNumber phones = 4;
+public List<PhoneNumber> getPhonesList();
+public int getPhonesCount();
+public PhoneNumber getPhones(int index);
+public Builder setPhones(int index, PhoneNumber value);
+public Builder addPhones(PhoneNumber value);
+public Builder addAllPhones(Iterable<PhoneNumber> value);
+public Builder clearPhones();
+

As you can see, there are simple JavaBeans-style getters and setters for each +field. There are also has getters for each singular field which return true if +that field has been set. Finally, each field has a clear method that un-sets +the field back to its empty state.

Repeated fields have some extra methods – a Count method (which is just +shorthand for the list’s size), getters and setters which get or set a specific +element of the list by index, an add method which appends a new element to the +list, and an addAll method which adds an entire container full of elements to +the list.

Notice how these accessor methods use camel-case naming, even though the +.proto file uses lowercase-with-underscores. This transformation is done +automatically by the protocol buffer compiler so that the generated classes +match standard Java style conventions. You should always use +lowercase-with-underscores for field names in your .proto files; this ensures +good naming practice in all the generated languages. See the +style guide for more on good +.proto style.

For more information on exactly what members the protocol compiler generates for +any particular field definition, see the +Java generated code reference.

Enums and Nested Classes

The generated code includes a PhoneType Java 5 enum, nested within Person:

public static enum PhoneType {
+  PHONE_TYPE_UNSPECIFIED(0, 0),
+  PHONE_TYPE_MOBILE(1, 1),
+  PHONE_TYPE_HOME(2, 2),
+  PHONE_TYPE_WORK(3, 3),
+  ;
+  ...
+}
+

The nested type Person.PhoneNumber is generated, as you’d expect, as a nested +class within Person.

Builders vs. Messages

The message classes generated by the protocol buffer compiler are all +immutable. Once a message object is constructed, it cannot be modified, just +like a Java String. To construct a message, you must first construct a +builder, set any fields you want to set to your chosen values, then call the +builder’s build() method.

You may have noticed that each method of the builder which modifies the message +returns another builder. The returned object is actually the same builder on +which you called the method. It is returned for convenience so that you can +string several setters together on a single line of code.

Here’s an example of how you would create an instance of Person:

Person john =
+  Person.newBuilder()
+    .setId(1234)
+    .setName("John Doe")
+    .setEmail("jdoe@example.com")
+    .addPhones(
+      Person.PhoneNumber.newBuilder()
+        .setNumber("555-4321")
+        .setType(Person.PhoneType.PHONE_TYPE_HOME)
+        .build());
+    .build();
+

Standard Message Methods

Each message and builder class also contains a number of other methods that let +you check or manipulate the entire message, including:

  • isInitialized(): checks if all the required fields have been set.
  • toString(): returns a human-readable representation of the message, +particularly useful for debugging.
  • mergeFrom(Message other): (builder only) merges the contents of other +into this message, overwriting singular scalar fields, merging composite +fields, and concatenating repeated fields.
  • clear(): (builder only) clears all the fields back to the empty state.

These methods implement the Message and Message.Builder interfaces shared by +all Java messages and builders. For more information, see the +complete API documentation for Message.

Parsing and Serialization

Finally, each protocol buffer class has methods for writing and reading messages +of your chosen type using the protocol buffer +binary format. These +include:

  • byte[] toByteArray();: serializes the message and returns a byte array +containing its raw bytes.
  • static Person parseFrom(byte[] data);: parses a message from the given +byte array.
  • void writeTo(OutputStream output);: serializes the message and writes it +to an OutputStream.
  • static Person parseFrom(InputStream input);: reads and parses a message +from an InputStream.

These are just a couple of the options provided for parsing and serialization. +Again, see the +Message API reference +for a complete list.

Writing a Message

Now let’s try using your protocol buffer classes. The first thing you want your +address book application to be able to do is write personal details to your +address book file. To do this, you need to create and populate instances of your +protocol buffer classes and then write them to an output stream.

Here is a program which reads an AddressBook from a file, adds one new +Person to it based on user input, and writes the new AddressBook back out to +the file again. The parts which directly call or reference code generated by the +protocol compiler are highlighted.

import com.example.tutorial.protos.AddressBook;
+import com.example.tutorial.protos.Person;
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.PrintStream;
+
+class AddPerson {
+  // This function fills in a Person message based on user input.
+  static Person PromptForAddress(BufferedReader stdin,
+                                 PrintStream stdout) throws IOException {
+    Person.Builder person = Person.newBuilder();
+
+    stdout.print("Enter person ID: ");
+    person.setId(Integer.valueOf(stdin.readLine()));
+
+    stdout.print("Enter name: ");
+    person.setName(stdin.readLine());
+
+    stdout.print("Enter email address (blank for none): ");
+    String email = stdin.readLine();
+    if (email.length() > 0) {
+      person.setEmail(email);
+    }
+
+    while (true) {
+      stdout.print("Enter a phone number (or leave blank to finish): ");
+      String number = stdin.readLine();
+      if (number.length() == 0) {
+        break;
+      }
+
+      Person.PhoneNumber.Builder phoneNumber =
+        Person.PhoneNumber.newBuilder().setNumber(number);
+
+      stdout.print("Is this a mobile, home, or work phone? ");
+      String type = stdin.readLine();
+      if (type.equals("mobile")) {
+        phoneNumber.setType(Person.PhoneType.PHONE_TYPE_MOBILE);
+      } else if (type.equals("home")) {
+        phoneNumber.setType(Person.PhoneType.PHONE_TYPE_HOME);
+      } else if (type.equals("work")) {
+        phoneNumber.setType(Person.PhoneType.PHONE_TYPE_WORK);
+      } else {
+        stdout.println("Unknown phone type.  Using default.");
+      }
+
+      person.addPhones(phoneNumber);
+    }
+
+    return person.build();
+  }
+
+  // Main function:  Reads the entire address book from a file,
+  //   adds one person based on user input, then writes it back out to the same
+  //   file.
+  public static void main(String[] args) throws Exception {
+    if (args.length != 1) {
+      System.err.println("Usage:  AddPerson ADDRESS_BOOK_FILE");
+      System.exit(-1);
+    }
+
+    AddressBook.Builder addressBook = AddressBook.newBuilder();
+
+    // Read the existing address book.
+    try {
+      addressBook.mergeFrom(new FileInputStream(args[0]));
+    } catch (FileNotFoundException e) {
+      System.out.println(args[0] + ": File not found.  Creating a new file.");
+    }
+
+    // Add an address.
+    addressBook.addPerson(
+      PromptForAddress(new BufferedReader(new InputStreamReader(System.in)),
+                       System.out));
+
+    // Write the new address book back to disk.
+    FileOutputStream output = new FileOutputStream(args[0]);
+    addressBook.build().writeTo(output);
+    output.close();
+  }
+}
+

Reading a Message

Of course, an address book wouldn’t be much use if you couldn’t get any +information out of it! This example reads the file created by the above example +and prints all the information in it.

import com.example.tutorial.protos.AddressBook;
+import com.example.tutorial.protos.Person;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+
+class ListPeople {
+  // Iterates though all people in the AddressBook and prints info about them.
+  static void Print(AddressBook addressBook) {
+    for (Person person: addressBook.getPeopleList()) {
+      System.out.println("Person ID: " + person.getId());
+      System.out.println("  Name: " + person.getName());
+      if (person.hasEmail()) {
+        System.out.println("  E-mail address: " + person.getEmail());
+      }
+
+      for (Person.PhoneNumber phoneNumber : person.getPhonesList()) {
+        switch (phoneNumber.getType()) {
+          case PHONE_TYPE_MOBILE:
+            System.out.print("  Mobile phone #: ");
+            break;
+          case PHONE_TYPE_HOME:
+            System.out.print("  Home phone #: ");
+            break;
+          case PHONE_TYPE_WORK:
+            System.out.print("  Work phone #: ");
+            break;
+        }
+        System.out.println(phoneNumber.getNumber());
+      }
+    }
+  }
+
+  // Main function:  Reads the entire address book from a file and prints all
+  //   the information inside.
+  public static void main(String[] args) throws Exception {
+    if (args.length != 1) {
+      System.err.println("Usage:  ListPeople ADDRESS_BOOK_FILE");
+      System.exit(-1);
+    }
+
+    // Read the existing address book.
+    AddressBook addressBook =
+      AddressBook.parseFrom(new FileInputStream(args[0]));
+
+    Print(addressBook);
+  }
+}
+

Extending a Protocol Buffer

Sooner or later after you release the code that uses your protocol buffer, you +will undoubtedly want to “improve” the protocol buffer’s definition. If you want +your new buffers to be backwards-compatible, and your old buffers to be +forward-compatible – and you almost certainly do want this – then there are +some rules you need to follow. In the new version of the protocol buffer:

  • you must not change the tag numbers of any existing fields.
  • you must not add or delete any required fields.
  • you may delete optional or repeated fields.
  • you may add new optional or repeated fields but you must use fresh tag +numbers (that is, tag numbers that were never used in this protocol buffer, +not even by deleted fields).

(There are +some exceptions to +these rules, but they are rarely used.)

If you follow these rules, old code will happily read new messages and simply +ignore any new fields. To the old code, optional fields that were deleted will +simply have their default value, and deleted repeated fields will be empty. New +code will also transparently read old messages. However, keep in mind that new +optional fields will not be present in old messages, so you will need to either +check explicitly whether they’re set with has_, or provide a reasonable +default value in your .proto file with [default = value] after the tag +number. If the default value is not specified for an optional element, a +type-specific default value is used instead: for strings, the default value is +the empty string. For booleans, the default value is false. For numeric types, +the default value is zero. Note also that if you added a new repeated field, +your new code will not be able to tell whether it was left empty (by new code) +or never set at all (by old code) since there is no has_ flag for it.

Advanced Usage

Protocol buffers have uses that go beyond simple accessors and serialization. Be +sure to explore the +Java API reference +to see what else you can do with them.

One key feature provided by protocol message classes is reflection. You can +iterate over the fields of a message and manipulate their values without writing +your code against any specific message type. One very useful way to use +reflection is for converting protocol messages to and from other encodings, such +as XML or JSON. A more advanced use of reflection might be to find differences +between two messages of the same type, or to develop a sort of “regular +expressions for protocol messages” in which you can write expressions that match +certain message contents. If you use your imagination, it’s possible to apply +Protocol Buffers to a much wider range of problems than you might initially +expect!

Reflection is provided as part of the +Message +and +Message.Builder +interfaces.

\ No newline at end of file diff --git a/getting-started/kotlintutorial/index.html b/getting-started/kotlintutorial/index.html new file mode 100644 index 000000000..402e57286 --- /dev/null +++ b/getting-started/kotlintutorial/index.html @@ -0,0 +1,254 @@ +Protocol Buffer Basics: Kotlin | Protocol Buffers Documentation +

Protocol Buffer Basics: Kotlin

A basic Kotlin programmers introduction to working with protocol buffers.

This tutorial provides a basic Kotlin programmer’s introduction to working with +protocol buffers, using the +proto3 version of the +protocol buffers language. By walking through creating a simple example +application, it shows you how to

  • Define message formats in a .proto file.
  • Use the protocol buffer compiler.
  • Use the Kotlin protocol buffer API to write and read messages.

This isn’t a comprehensive guide to using protocol buffers in Kotlin. For more +detailed reference information, see the +Protocol Buffer Language Guide, +the Kotlin API Reference, +the +Kotlin Generated Code Guide, +and the +Encoding Reference.

The Problem Domain

The example we’re going to use is a very simple “address book” application that +can read and write people’s contact details to and from a file. Each person in +the address book has a name, an ID, an email address, and a contact phone +number.

How do you serialize and retrieve structured data like this? There are a few +ways to solve this problem:

  • Use kotlinx.serialization. This does not work very well if you need to share +data with applications written in C++ or Python. kotlinx.serialization has a +protobuf mode, +but this does not offer the full features of protocol buffers.
  • You can invent an ad-hoc way to encode the data items into a single +string – such as encoding 4 ints as “12:3:-23:67”. This is a simple and +flexible approach, although it does require writing one-off encoding and +parsing code, and the parsing imposes a small run-time cost. This works best +for encoding very simple data.
  • Serialize the data to XML. This approach can be very attractive since XML is +(sort of) human readable and there are binding libraries for lots of +languages. This can be a good choice if you want to share data with other +applications/projects. However, XML is notoriously space intensive, and +encoding/decoding it can impose a huge performance penalty on applications. +Also, navigating an XML DOM tree is considerably more complicated than +navigating simple fields in a class normally would be.

Protocol buffers are the flexible, efficient, automated solution to solve +exactly this problem. With protocol buffers, you write a .proto description of +the data structure you wish to store. From that, the protocol buffer compiler +creates a class that implements automatic encoding and parsing of the protocol +buffer data with an efficient binary format. The generated class provides +getters and setters for the fields that make up a protocol buffer and takes care +of the details of reading and writing the protocol buffer as a unit. +Importantly, the protocol buffer format supports the idea of extending the +format over time in such a way that the code can still read data encoded with +the old format.

Where to Find the Example Code

Our example is a set of command-line applications for managing an address book +data file, encoded using protocol buffers. The command add_person_kotlin adds +a new entry to the data file. The command list_people_kotlin parses the data +file and prints the data to the console.

You can find the complete example in the +examples directory +of the GitHub repository.

Defining Your Protocol Format

To create your address book application, you’ll need to start with a .proto +file. The definitions in a .proto file are simple: you add a message for +each data structure you want to serialize, then specify a name and a type for +each field in the message. In our example, the .proto file that defines the +messages is +addressbook.proto.

The .proto file starts with a package declaration, which helps to prevent +naming conflicts between different projects.

syntax = "proto3";
+package tutorial;
+
+import "google/protobuf/timestamp.proto";
+

Next, you have your message definitions. A message is just an aggregate +containing a set of typed fields. Many standard simple data types are available +as field types, including bool, int32, float, double, and string. You +can also add further structure to your messages by using other message types as +field types.

message Person {
+  string name = 1;
+  int32 id = 2;  // Unique ID number for this person.
+  string email = 3;
+
+  enum PhoneType {
+    PHONE_TYPE_UNSPECIFIED = 0;
+    PHONE_TYPE_MOBILE = 1;
+    PHONE_TYPE_HOME = 2;
+    PHONE_TYPE_WORK = 3;
+  }
+
+  message PhoneNumber {
+    string number = 1;
+    PhoneType type = 2;
+  }
+
+  repeated PhoneNumber phones = 4;
+
+  google.protobuf.Timestamp last_updated = 5;
+}
+
+// Our address book file is just one of these.
+message AddressBook {
+  repeated Person people = 1;
+}
+

In the above example, the Person message contains PhoneNumber messages, +while the AddressBook message contains Person messages. You can even define +message types nested inside other messages – as you can see, the PhoneNumber +type is defined inside Person. You can also define enum types if you want +one of your fields to have one of a predefined list of values – here you want +to specify that a phone number can be one of PHONE_TYPE_MOBILE, +PHONE_TYPE_HOME, or PHONE_TYPE_WORK.

The " = 1", " = 2" markers on each element identify the unique “tag” that field +uses in the binary encoding. Tag numbers 1-15 require one less byte to encode +than higher numbers, so as an optimization you can decide to use those tags for +the commonly used or repeated elements, leaving tags 16 and higher for +less-commonly used optional elements. Each element in a repeated field requires +re-encoding the tag number, so repeated fields are particularly good candidates +for this optimization.

If a field value isn’t set, a +default value is +used: zero for numeric types, the empty string for strings, false for bools. For +embedded messages, the default value is always the “default instance” or +“prototype” of the message, which has none of its fields set. Calling the +accessor to get the value of a field which has not been explicitly set always +returns that field’s default value.

If a field is repeated, the field may be repeated any number of times +(including zero). The order of the repeated values will be preserved in the +protocol buffer. Think of repeated fields as dynamically sized arrays.

You’ll find a complete guide to writing .proto files – including all the +possible field types – in the +Protocol Buffer Language Guide. +Don’t go looking for facilities similar to class inheritance, though – protocol +buffers don’t do that.

Compiling Your Protocol Buffers

Now that you have a .proto, the next thing you need to do is generate the +classes you’ll need to read and write AddressBook (and hence Person and +PhoneNumber) messages. To do this, you need to run the protocol buffer +compiler protoc on your .proto:

  1. If you haven’t installed the compiler, +download the package and follow the +instructions in the README.

  2. Now run the compiler, specifying the source directory (where your +application’s source code lives – the current directory is used if you +don’t provide a value), the destination directory (where you want the +generated code to go; often the same as $SRC_DIR), and the path to your +.proto. In this case, you would invoke:

    protoc -I=$SRC_DIR --java_out=$DST_DIR --kotlin_out=$DST_DIR $SRC_DIR/addressbook.proto
    +

    Because you want Kotlin code, you use the --kotlin_out option – similar +options are provided for other supported languages.

Note that if you want to generate Kotlin code you must use both --java_out and +--kotlin_out. This generates a com/example/tutorial/protos/ subdirectory in +your specified Java destination directory, containing a few generated .java +files and a com/example/tutorial/protos/ subdirectory in your specified Kotlin +destination directory, containing a few generated .kt files.

The Protocol Buffer API

The protocol buffer compiler for Kotlin generates Kotlin APIs that add to the +existing APIs generated for protocol buffers for Java. This ensures that +codebases written in a mix of Java and Kotlin can interact with the same +protocol buffer message objects without any special handling or conversion.

Protocol buffers for other Kotlin compilation targets, such as JavaScript and +native, are not currently supported.

Compiling addressbook.proto gives you the following APIs in Java:

  • The AddressBook class
    • which, from Kotlin, has the peopleList : List<Person> property
  • The Person class
    • which, from Kotlin, has name, id, email, and phonesList +properties
    • the Person.PhoneNumber nested class with number and type +properties
    • the Person.PhoneType nested enum

but also generates the following Kotlin APIs:

  • The addressBook { ... } and person { ... } factory methods
  • A PersonKt object, with a phoneNumber { ... } factory method

You can read more about the details of exactly what’s generated in the +Kotlin Generated Code guide.

Writing a Message

Now let’s try using your protocol buffer classes. The first thing you want your +address book application to be able to do is write personal details to your +address book file. To do this, you need to create and populate instances of your +protocol buffer classes and then write them to an output stream.

Here is a program which reads an AddressBook from a file, adds one new +Person to it based on user input, and writes the new AddressBook back out to +the file again. The parts which directly call or reference code generated by the +protocol compiler are highlighted.

import com.example.tutorial.Person
+import com.example.tutorial.AddressBook
+import com.example.tutorial.person
+import com.example.tutorial.addressBook
+import com.example.tutorial.PersonKt.phoneNumber
+import java.util.Scanner
+
+// This function fills in a Person message based on user input.
+fun promptPerson(): Person = person {
+  print("Enter person ID: ")
+  id = readLine().toInt()
+
+  print("Enter name: ")
+  name = readLine()
+
+  print("Enter email address (blank for none): ")
+  val email = readLine()
+  if (email.isNotEmpty()) {
+    this.email = email
+  }
+
+  while (true) {
+    print("Enter a phone number (or leave blank to finish): ")
+    val number = readLine()
+    if (number.isEmpty()) break
+
+    print("Is this a mobile, home, or work phone? ")
+    val type = when (readLine()) {
+      "mobile" -> Person.PhoneType.PHONE_TYPE_MOBILE
+      "home" -> Person.PhoneType.PHONE_TYPE_HOME
+      "work" -> Person.PhoneType.PHONE_TYPE_WORK
+      else -> {
+        println("Unknown phone type.  Using home.")
+        Person.PhoneType.PHONE_TYPE_HOME
+      }
+    }
+    phones += phoneNumber {
+      this.number = number
+      this.type = type
+    }
+  }
+}
+
+// Reads the entire address book from a file, adds one person based
+// on user input, then writes it back out to the same file.
+fun main(args: List) {
+  if (arguments.size != 1) {
+    println("Usage: add_person ADDRESS_BOOK_FILE")
+    exitProcess(-1)
+  }
+  val path = Path(arguments.single())
+  val initialAddressBook = if (!path.exists()) {
+    println("File not found. Creating new file.")
+    addressBook {}
+  } else {
+    path.inputStream().use {
+      AddressBook.newBuilder().mergeFrom(it).build()
+    }
+  }
+  path.outputStream().use {
+    initialAddressBook.copy { peopleList += promptPerson() }.writeTo(it)
+  }
+}
+

Reading a Message

Of course, an address book wouldn’t be much use if you couldn’t get any +information out of it! This example reads the file created by the above example +and prints all the information in it.

import com.example.tutorial.Person
+import com.example.tutorial.AddressBook
+
+// Iterates though all people in the AddressBook and prints info about them.
+fun print(addressBook: AddressBook) {
+  for (person in addressBook.peopleList) {
+    println("Person ID: ${person.id}")
+    println("  Name: ${person.name}")
+    if (person.hasEmail()) {
+      println("  Email address: ${person.email}")
+    }
+    for (phoneNumber in person.phonesList) {
+      val modifier = when (phoneNumber.type) {
+        Person.PhoneType.PHONE_TYPE_MOBILE -> "Mobile"
+        Person.PhoneType.PHONE_TYPE_HOME -> "Home"
+        Person.PhoneType.PHONE_TYPE_WORK -> "Work"
+        else -> "Unknown"
+      }
+      println("  $modifier phone #: ${phoneNumber.number}")
+    }
+  }
+}
+
+fun main(args: List) {
+  if (arguments.size != 1) {
+    println("Usage: list_person ADDRESS_BOOK_FILE")
+    exitProcess(-1)
+  }
+  Path(arguments.single()).inputStream().use {
+    print(AddressBook.newBuilder().mergeFrom(it).build())
+  }
+}
+

Extending a Protocol Buffer

Sooner or later after you release the code that uses your protocol buffer, you +will undoubtedly want to “improve” the protocol buffer’s definition. If you want +your new buffers to be backwards-compatible, and your old buffers to be +forward-compatible – and you almost certainly do want this – then there are +some rules you need to follow. In the new version of the protocol buffer:

  • you must not change the tag numbers of any existing fields.
  • you may delete fields.
  • you may add new fields but you must use fresh tag numbers (i.e. tag +numbers that were never used in this protocol buffer, not even by deleted +fields).

(There are +some exceptions to +these rules, but they are rarely used.)

If you follow these rules, old code will happily read new messages and simply +ignore any new fields. To the old code, singular fields that were deleted will +simply have their default value, and deleted repeated fields will be empty. New +code will also transparently read old messages.

However, keep in mind that new fields will not be present in old messages, so +you will need to do something reasonable with the default value. A type-specific +default value is +used: for strings, the default value is the empty string. For booleans, the +default value is false. For numeric types, the default value is zero.

\ No newline at end of file diff --git a/getting-started/pythontutorial/index.html b/getting-started/pythontutorial/index.html new file mode 100644 index 000000000..413321a75 --- /dev/null +++ b/getting-started/pythontutorial/index.html @@ -0,0 +1,348 @@ +Protocol Buffer Basics: Python | Protocol Buffers Documentation +

Protocol Buffer Basics: Python

A basic Python programmers introduction to working with protocol buffers.

This tutorial provides a basic Python programmer’s introduction to working with +protocol buffers. By walking through creating a simple example application, it +shows you how to

  • Define message formats in a .proto file.
  • Use the protocol buffer compiler.
  • Use the Python protocol buffer API to write and read messages.

This isn’t a comprehensive guide to using protocol buffers in Python. For more +detailed reference information, see the +Protocol Buffer Language Guide (proto2), +the +Protocol Buffer Language Guide (proto3), +the Python API Reference, the +Python Generated Code Guide, +and the +Encoding Reference.

The Problem Domain

The example we’re going to use is a very simple “address book” application that +can read and write people’s contact details to and from a file. Each person in +the address book has a name, an ID, an email address, and a contact phone +number.

How do you serialize and retrieve structured data like this? There are a few +ways to solve this problem:

  • Use Python pickling. This is the default approach since it’s built into the +language, but it doesn’t deal well with schema evolution, and also doesn’t +work very well if you need to share data with applications written in C++ or +Java.
  • You can invent an ad-hoc way to encode the data items into a single +string – such as encoding 4 ints as “12:3:-23:67”. This is a simple and +flexible approach, although it does require writing one-off encoding and +parsing code, and the parsing imposes a small run-time cost. This works best +for encoding very simple data.
  • Serialize the data to XML. This approach can be very attractive since XML is +(sort of) human readable and there are binding libraries for lots of +languages. This can be a good choice if you want to share data with other +applications/projects. However, XML is notoriously space intensive, and +encoding/decoding it can impose a huge performance penalty on applications. +Also, navigating an XML DOM tree is considerably more complicated than +navigating simple fields in a class normally would be.

Instead of these options, you can use protocol buffers. Protocol buffers are the +flexible, efficient, automated solution to solve exactly this problem. With +protocol buffers, you write a .proto description of the data structure you +wish to store. From that, the protocol buffer compiler creates a class that +implements automatic encoding and parsing of the protocol buffer data with an +efficient binary format. The generated class provides getters and setters for +the fields that make up a protocol buffer and takes care of the details of +reading and writing the protocol buffer as a unit. Importantly, the protocol +buffer format supports the idea of extending the format over time in such a way +that the code can still read data encoded with the old format.

Where to Find the Example Code

The example code is included in the source code package, under the “examples” +directory. Download it here.

Defining Your Protocol Format

To create your address book application, you’ll need to start with a .proto +file. The definitions in a .proto file are simple: you add a message for +each data structure you want to serialize, then specify a name and a type for +each field in the message. Here is the .proto file that defines your messages, +addressbook.proto.

edition = "2023";
+
+package tutorial;
+
+message Person {
+  string name = 1;
+  int32 id = 2;
+  string email = 3;
+
+  enum PhoneType {
+    PHONE_TYPE_UNSPECIFIED = 0;
+    PHONE_TYPE_MOBILE = 1;
+    PHONE_TYPE_HOME = 2;
+    PHONE_TYPE_WORK = 3;
+  }
+
+  message PhoneNumber {
+    string number = 1;
+    PhoneType type = 2 [default = PHONE_TYPE_HOME];
+  }
+
+  repeated PhoneNumber phones = 4;
+}
+
+message AddressBook {
+  repeated Person people = 1;
+}
+

As you can see, the syntax is similar to C++ or Java. Let’s go through each part +of the file and see what it does.

The .proto file starts with a package declaration, which helps to prevent +naming conflicts between different projects. In Python, packages are normally +determined by directory structure, so the package you define in your .proto +file will have no effect on the generated code. However, you should still +declare one to avoid name collisions in the Protocol Buffers name space as well +as in non-Python languages.

Next, you have your message definitions. A message is just an aggregate +containing a set of typed fields. Many standard simple data types are available +as field types, including bool, int32, float, double, and string. You +can also add further structure to your messages by using other message types as +field types – in the above example the Person message contains PhoneNumber +messages, while the AddressBook message contains Person messages. You can +even define message types nested inside other messages – as you can see, the +PhoneNumber type is defined inside Person. You can also define enum types +if you want one of your fields to have one of a predefined list of values – +here you want to specify that a phone number can be one of the following phone +types: PHONE_TYPE_MOBILE, PHONE_TYPE_HOME, or PHONE_TYPE_WORK.

The " = 1", " = 2" markers on each element identify the unique “tag” that field +uses in the binary encoding. Tag numbers 1-15 require one less byte to encode +than higher numbers, so as an optimization you can decide to use those tags for +the commonly used or repeated elements, leaving tags 16 and higher for +less-commonly used optional elements. Each element in a repeated field requires +re-encoding the tag number, so repeated fields are particularly good candidates +for this optimization.

You’ll find a complete guide to writing .proto files – including all the +possible field types – in the +Protocol Buffer Language Guide. +Don’t go looking for facilities similar to class inheritance, though – protocol +buffers don’t do that.

Compiling Your Protocol Buffers

Now that you have a .proto, the next thing you need to do is generate the +classes you’ll need to read and write AddressBook (and hence Person and +PhoneNumber) messages. To do this, you need to run the protocol buffer +compiler protoc on your .proto:

  1. If you haven’t installed the compiler, +download the package and follow the +instructions in the README.

  2. Now run the compiler, specifying the source directory (where your +application’s source code lives – the current directory is used if you +don’t provide a value), the destination directory (where you want the +generated code to go; often the same as $SRC_DIR), and the path to your +.proto. In this case, you…:

    protoc --proto_path=$SRC_DIR --python_out=$DST_DIR $SRC_DIR/addressbook.proto
    +

    Because you want Python classes, you use the --python_out option – +similar options are provided for other supported languages.

    Protoc is also able to generate python stubs (.pyi) with --pyi_out.

This generates addressbook_pb2.py (or addressbook_pb2.pyi) in your specified +destination directory.

The Protocol Buffer API

Unlike when you generate Java and C++ protocol buffer code, the Python protocol +buffer compiler doesn’t generate your data access code for you directly. Instead +(as you’ll see if you look at addressbook_pb2.py) it generates special +descriptors for all your messages, enums, and fields, and some mysteriously +empty classes, one for each message type:

import google3
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import runtime_version as _runtime_version
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf.internal import builder as _builder
+_runtime_version.ValidateProtobufRuntimeVersion(
+    _runtime_version.Domain.GOOGLE_INTERNAL,
+    0,
+    20240502,
+    0,
+    '',
+    'main.proto'
+)
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nmain.proto\x12\x08tutorial\"\xa3\x02\n\x06Person\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\x05\x12\r\n\x05\x65mail\x18\x03 \x01(\t\x12,\n\x06phones\x18\x04 \x03(\x0b\x32\x1c.tutorial.Person.PhoneNumber\x1aX\n\x0bPhoneNumber\x12\x0e\n\x06number\x18\x01 \x01(\t\x12\x39\n\x04type\x18\x02 \x01(\x0e\x32\x1a.tutorial.Person.PhoneType:\x0fPHONE_TYPE_HOME\"h\n\tPhoneType\x12\x1a\n\x16PHONE_TYPE_UNSPECIFIED\x10\x00\x12\x15\n\x11PHONE_TYPE_MOBILE\x10\x01\x12\x13\n\x0fPHONE_TYPE_HOME\x10\x02\x12\x13\n\x0fPHONE_TYPE_WORK\x10\x03\"/\n\x0b\x41\x64\x64ressBook\x12 \n\x06people\x18\x01 \x03(\x0b\x32\x10.tutorial.Person')
+
+_globals = globals()
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google3.main_pb2', _globals)
+if not _descriptor._USE_C_DESCRIPTORS:
+  DESCRIPTOR._loaded_options = None
+  _globals['_PERSON']._serialized_start=25
+  _globals['_PERSON']._serialized_end=316
+  _globals['_PERSON_PHONENUMBER']._serialized_start=122
+  _globals['_PERSON_PHONENUMBER']._serialized_end=210
+  _globals['_PERSON_PHONETYPE']._serialized_start=212
+  _globals['_PERSON_PHONETYPE']._serialized_end=316
+  _globals['_ADDRESSBOOK']._serialized_start=318
+  _globals['_ADDRESSBOOK']._serialized_end=365
+# @@protoc_insertion_point(module_scope)
+

The important line in each class is __metaclass__ = reflection.GeneratedProtocolMessageType. While the details of how Python +metaclasses work is beyond the scope of this tutorial, you can think of them as +like a template for creating classes. At load time, the +GeneratedProtocolMessageType metaclass uses the specified descriptors to +create all the Python methods you need to work with each message type and adds +them to the relevant classes. You can then use the fully-populated classes in +your code.

The end effect of all this is that you can use the Person class as if it +defined each field of the Message base class as a regular field. For example, +you could write:

import addressbook_pb2
+person = addressbook_pb2.Person()
+person.id = 1234
+person.name = "John Doe"
+person.email = "jdoe@example.com"
+phone = person.phones.add()
+phone.number = "555-4321"
+phone.type = addressbook_pb2.Person.PHONE_TYPE_HOME
+

Note that these assignments are not just adding arbitrary new fields to a +generic Python object. If you were to try to assign a field that isn’t defined +in the .proto file, an AttributeError would be raised. If you assign a field +to a value of the wrong type, a TypeError will be raised. Also, reading the +value of a field before it has been set returns the default value.

person.no_such_field = 1  # raises AttributeError
+person.id = "1234"        # raises TypeError
+

For more information on exactly what members the protocol compiler generates for +any particular field definition, see the +Python generated code reference.

Enums

Enums are expanded by the metaclass into a set of symbolic constants with +integer values. So, for example, the constant +addressbook_pb2.Person.PhoneType.PHONE_TYPE_WORK has the value 2.

Standard Message Methods

Each message class also contains a number of other methods that let you check or +manipulate the entire message, including:

  • IsInitialized(): checks if all the required fields have been set.
  • __str__(): returns a human-readable representation of the message, +particularly useful for debugging. (Usually invoked as str(message) or +print message.)
  • CopyFrom(other_msg): overwrites the message with the given message’s +values.
  • Clear(): clears all the elements back to the empty state.

These methods implement the Message interface. For more information, see the +complete API documentation for Message.

Parsing and Serialization

Finally, each protocol buffer class has methods for writing and reading messages +of your chosen type using the protocol buffer +binary format. These +include:

  • SerializeToString(): serializes the message and returns it as a string. +Note that the bytes are binary, not text; we only use the str type as a +convenient container.
  • ParseFromString(data): parses a message from the given string.

These are just a couple of the options provided for parsing and serialization. +Again, see the +Message API reference +for a complete list.

You can also easily serialize messages to and from JSON. The json_format +module provides helpers for this:

  • MessageToJson(message): serializes the message to a JSON string.
  • Parse(json_string, message): parses a JSON string into the given message.

For example:

from google.protobuf import json_format
+import addressbook_pb2
+
+person = addressbook_pb2.Person()
+person.id = 1234
+person.name = "John Doe"
+person.email = "jdoe@example.com"
+
+# Serialize to JSON
+json_string = json_format.MessageToJson(person)
+
+# Parse from JSON
+new_person = addressbook_pb2.Person()
+json_format.Parse(json_string, new_person)
+

Writing a Message

Now let’s try using your protocol buffer classes. The first thing you want your +address book application to be able to do is write personal details to your +address book file. To do this, you need to create and populate instances of your +protocol buffer classes and then write them to an output stream.

Here is a program which reads an AddressBook from a file, adds one new +Person to it based on user input, and writes the new AddressBook back out to +the file again. The parts which directly call or reference code generated by the +protocol compiler are highlighted.

#!/usr/bin/env python3
+
+import addressbook_pb2
+import sys
+
+# This function fills in a Person message based on user input.
+def PromptForAddress(person):
+  person.id = int(input("Enter person ID number: "))
+  person.name = input("Enter name: ")
+
+  email = input("Enter email address (blank for none): ")
+  if email != "":
+    person.email = email
+
+  while True:
+    number = input("Enter a phone number (or leave blank to finish): ")
+    if number == "":
+      break
+
+    phone_number = person.phones.add()
+    phone_number.number = number
+
+    phone_type = input("Is this a mobile, home, or work phone? ")
+    if phone_type == "mobile":
+      phone_number.type = addressbook_pb2.Person.PhoneType.PHONE_TYPE_MOBILE
+    elif phone_type == "home":
+      phone_number.type = addressbook_pb2.Person.PhoneType.PHONE_TYPE_HOME
+    elif phone_type == "work":
+      phone_number.type = addressbook_pb2.Person.PhoneType.PHONE_TYPE_WORK
+    else:
+      print("Unknown phone type; leaving as default value.")
+
+# Main procedure:  Reads the entire address book from a file,
+#   adds one person based on user input, then writes it back out to the same
+#   file.
+if len(sys.argv) != 2:
+  print("Usage:", sys.argv[0], "ADDRESS_BOOK_FILE")
+  sys.exit(-1)
+
+address_book = addressbook_pb2.AddressBook()
+
+# Read the existing address book.
+try:
+  with open(sys.argv[1], "rb") as f:
+    address_book.ParseFromString(f.read())
+except IOError:
+  print(sys.argv[1] + ": Could not open file.  Creating a new one.")
+
+# Add an address.
+PromptForAddress(address_book.people.add())
+
+# Write the new address book back to disk.
+with open(sys.argv[1], "wb") as f:
+  f.write(address_book.SerializeToString())
+

Reading a Message

Of course, an address book wouldn’t be much use if you couldn’t get any +information out of it! This example reads the file created by the above example +and prints all the information in it.

#!/usr/bin/env python3
+
+import addressbook_pb2
+import sys
+
+# Iterates though all people in the AddressBook and prints info about them.
+def ListPeople(address_book):
+  for person in address_book.people:
+    print("Person ID:", person.id)
+    print("  Name:", person.name)
+    if person.HasField('email'):
+      print("  E-mail address:", person.email)
+
+    for phone_number in person.phones:
+      if phone_number.type == addressbook_pb2.Person.PhoneType.PHONE_TYPE_MOBILE:
+        print("  Mobile phone #: ", end="")
+      elif phone_number.type == addressbook_pb2.Person.PhoneType.PHONE_TYPE_HOME:
+        print("  Home phone #: ", end="")
+      elif phone_number.type == addressbook_pb2.Person.PhoneType.PHONE_TYPE_WORK:
+        print("  Work phone #: ", end="")
+      print(phone_number.number)
+
+# Main procedure:  Reads the entire address book from a file and prints all
+#   the information inside.
+if len(sys.argv) != 2:
+  print("Usage:", sys.argv[0], "ADDRESS_BOOK_FILE")
+  sys.exit(-1)
+
+address_book = addressbook_pb2.AddressBook()
+
+# Read the existing address book.
+with open(sys.argv[1], "rb") as f:
+  address_book.ParseFromString(f.read())
+
+ListPeople(address_book)
+

Extending a Protocol Buffer

Sooner or later after you release the code that uses your protocol buffer, you +will undoubtedly want to “improve” the protocol buffer’s definition. If you want +your new buffers to be backwards-compatible, and your old buffers to be +forward-compatible – and you almost certainly do want this – then there are +some rules you need to follow. In the new version of the protocol buffer:

  • you must not change the tag numbers of any existing fields.
  • you must not add or delete any required fields.
  • you may delete optional or repeated fields.
  • you may add new optional or repeated fields but you must use fresh tag +numbers (that is, tag numbers that were never used in this protocol buffer, +not even by deleted fields).

(There are +some exceptions to +these rules, but they are rarely used.)

If you follow these rules, old code will happily read new messages and simply +ignore any new fields. To the old code, optional fields that were deleted will +simply have their default value, and deleted repeated fields will be empty. New +code will also transparently read old messages. However, keep in mind that new +optional fields will not be present in old messages, so you will need to either +check explicitly whether they’re set with HasField('field_name'), or provide a +reasonable default value in your .proto file with [default = value] after +the tag number. If the default value is not specified for an optional element, a +type-specific default value is used instead: for strings, the default value is +the empty string. For booleans, the default value is false. For numeric types, +the default value is zero. Note also that if you added a new repeated field, +your new code will not be able to tell whether it was left empty (by new code) +or never set at all (by old code) since there is no HasField check for it.

Advanced Usage

Protocol buffers have uses that go beyond simple accessors and serialization. Be +sure to explore the +Python API reference to see +what else you can do with them.

One key feature provided by protocol message classes is reflection. You can +iterate over the fields of a message and manipulate their values without writing +your code against any specific message type. One very useful way to use +reflection is for converting protocol messages to and from other encodings, such +as XML or JSON (see Parsing and Serialization for an +example). A more advanced use of reflection might be to find differences between +two messages of the same type, or to develop a sort of “regular expressions for +protocol messages” in which you can write expressions that match certain message +contents. If you use your imagination, it’s possible to apply Protocol Buffers +to a much wider range of problems than you might initially expect!

Reflection is provided as part of the +Message interface.

\ No newline at end of file diff --git a/go.mod b/go.mod deleted file mode 100644 index 3b0bc6188..000000000 --- a/go.mod +++ /dev/null @@ -1,9 +0,0 @@ -module github.com/google/docsy-example - -go 1.12 - -require ( - github.com/FortAwesome/Font-Awesome v0.0.0-20220831210243-d3a7818c253f // indirect - github.com/google/docsy v0.11.0 // indirect - github.com/twbs/bootstrap v4.6.2+incompatible // indirect -) diff --git a/history/index.html b/history/index.html new file mode 100644 index 000000000..5f53da263 --- /dev/null +++ b/history/index.html @@ -0,0 +1,42 @@ +History | Protocol Buffers Documentation +

History

A brief history behind the creation of protocol buffers.

Understanding +why protobuf was created and the decisions that changed it over time can help +you to better use the features of the tool.

Why Did You Release Protocol Buffers?

There are several reasons that we released Protocol Buffers.

Protocol buffers are used by many projects inside Google. We had other projects +we wanted to release as open source that use protocol buffers, so to do this, we +needed to release protocol buffers first. In fact, bits of the technology had +already found their way into the open; if you dig into the code for Google +AppEngine, you might find some of it.

We wanted to provide public APIs that accept protocol buffers as well as XML, +both because it is more efficient and because we convert that XML to protocol +buffers on our end, anyway.

We thought that people outside Google might find protocol buffers useful. +Getting protocol buffers into a form we were happy to release was a fun side +project.

Why Is the First Release Version 2? What Happened to Version 1?

The initial version of protocol buffers (“Proto1”) was developed starting in +early 2001 and evolved over the course of many years, sprouting new features +whenever someone needed them and was willing to do the work to create them. Like +anything created in such a way, it was a bit of a mess. We came to the +conclusion that it would not be feasible to release the code as it was.

Version 2 (“Proto2”) was a complete rewrite, though it kept most of the design +and used many of the implementation ideas from Proto1. Some features were added, +some removed. Most importantly, though, the code was cleaned up and did not have +any dependencies on Google libraries that were not yet open-sourced.

Why the Name “Protocol Buffers”?

The name originates from the early days of the format, before we had the +protocol buffer compiler to generate classes for us. At the time, there was a +class called ProtocolBuffer that actually acted as a buffer for an individual +method. Users would add tag/value pairs to this buffer individually by calling +methods like AddValue(tag, value). The raw bytes were stored in a buffer that +could then be written out once the message had been constructed.

Since that time, the “buffers” part of the name has lost its meaning, but it is +still the name we use. Today, people usually use the term “protocol message” to +refer to a message in an abstract sense, “protocol buffer” to refer to a +serialized copy of a message, and “protocol message object” to refer to an +in-memory object representing the parsed message.

Does Google Have Any Patents on Protocol Buffers?

Google currently has no issued patents on protocol buffers, and we are happy to +address any concerns around protocol buffers and patents that people may have.

How Do Protocol Buffers Differ from ASN.1, COM, CORBA, and Thrift?

We think all of these systems have strengths and weaknesses. Google relies on +protocol buffers internally and they are a vital component of our success, but +that doesn’t mean they are the ideal solution for every problem. You should +evaluate each alternative in the context of your own project.

It is worth noting, though, that several of these technologies define both an +interchange format and an RPC (remote procedure call) protocol. Protocol buffers +are just an interchange format. They could easily be used for RPC—and, +indeed, they do have limited support for defining RPC services—but they +are not tied to any one RPC implementation or protocol.

\ No newline at end of file diff --git a/content/images/protobuf-editions-lifecycle-short.png b/images/protobuf-editions-lifecycle-short.png similarity index 100% rename from content/images/protobuf-editions-lifecycle-short.png rename to images/protobuf-editions-lifecycle-short.png diff --git a/content/images/protocol-buffers-concepts.png b/images/protocol-buffers-concepts.png similarity index 100% rename from content/images/protocol-buffers-concepts.png rename to images/protocol-buffers-concepts.png diff --git a/content/includes/suppress-nav.css b/includes/suppress-nav.css similarity index 100% rename from content/includes/suppress-nav.css rename to includes/suppress-nav.css diff --git a/content/includes/version-tables.css b/includes/version-tables.css similarity index 100% rename from content/includes/version-tables.css rename to includes/version-tables.css diff --git a/index.html b/index.html new file mode 100644 index 000000000..385d898a5 --- /dev/null +++ b/index.html @@ -0,0 +1,40 @@ +Protocol Buffers Documentation +

Protocol Buffers

Protocol Buffers are language-neutral, platform-neutral extensible mechanisms for serializing structured data.

What Are Protocol Buffers?

Protocol buffers are Google’s language-neutral, platform-neutral, extensible +mechanism for serializing structured data – think XML, but smaller, faster, and +simpler. You define how you want your data to be structured once, then you can +use special generated source code to easily write and read your structured data +to and from a variety of data streams and using a variety of languages.

Pick Your Favorite Language

Protocol buffers support generated code in C++, C#, Dart, Go, Java, +Kotlin, +Objective-C, Python, Rust, and Ruby. With proto3, you can also work with PHP.

Example Implementation

edition = "2024";
+
+message Person {
+  string name = 1;
+  int32 id = 2;
+  string email = 3;
+}
+

Figure 1. A proto definition.

// Java code
+Person john = Person.newBuilder()
+    .setId(1234)
+    .setName("John Doe")
+    .setEmail("jdoe@example.com")
+    .build();
+output = new FileOutputStream(args[0]);
+john.writeTo(output);
+

Figure 2. Using a generated class to persist data.

// C++ code
+Person john;
+fstream input(argv[1],
+    ios::in | ios::binary);
+john.ParseFromIstream(&input);
+id = john.id();
+name = john.name();
+email = john.email();
+

Figure 3. Using a generated class to parse persisted data.

How Do I Start?

  1. Download +and install the protocol buffer compiler.
  2. Read the +overview.
  3. Try the tutorial for your +chosen language.
\ No newline at end of file diff --git a/index.xml b/index.xml new file mode 100644 index 000000000..45b74f797 --- /dev/null +++ b/index.xml @@ -0,0 +1,353 @@ +Protocol Buffers on Protocol Buffers Documentationhttps://protobuf.dev/Recent content in Protocol Buffers on Protocol Buffers DocumentationHugoenOverviewhttps://protobuf.dev/overview/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/overview/It’s like JSON, except it&rsquo;s smaller and faster, and it generates native language bindings. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages. +Protocol buffers are a combination of the definition language (created in .proto files), the code that the proto compiler generates to interface with data, language-specific runtime libraries, the serialization format for data that is written to a file (or sent across a network connection), and the serialized data.Protocol Buffer Compiler Installationhttps://protobuf.dev/installation/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/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) To install the latest release of the protocol compiler from pre-compiled binaries, follow these instructions: +From https://github.com/google/protobuf/releases, manually download the zip file corresponding to your operating system and computer architecture (protoc-&lt;version&gt;-&lt;os&gt;-&lt;arch&gt;.zip), or fetch the file using commands such as the following:Language Guide (editions)https://protobuf.dev/programming-guides/editions/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/editions/This guide describes how to use the protocol buffer language to structure your protocol buffer data, including .proto file syntax and how to generate data access classes from your .proto files. It covers edition 2023 to edition 2024 of the protocol buffers language. For information about how editions differ from proto2 and proto3 conceptually, see Protobuf Editions Overview. +For information on the proto2 syntax, see the Proto2 Language Guide. +For information on proto3 syntax, see the Proto3 Language Guide.Language Guide (proto 2)https://protobuf.dev/programming-guides/proto2/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/proto2/This guide describes how to use the protocol buffer language to structure your protocol buffer data, including .proto file syntax and how to generate data access classes from your .proto files. It covers the proto2 revision of the protocol buffers language. +For information on editions syntax, see the Protobuf Editions Language Guide. +For information on proto3 syntax, see the Proto3 Language Guide. +This is a reference guide – for a step by step example that uses many of the features described in this document, see the tutorial for your chosen language.Language Guide (proto 3)https://protobuf.dev/programming-guides/proto3/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/proto3/This guide describes how to use the protocol buffer language to structure your protocol buffer data, including .proto file syntax and how to generate data access classes from your .proto files. It covers the proto3 revision of the protocol buffers language. +For information on editions syntax, see the Protobuf Editions Language Guide. +For information on the proto2 syntax, see the Proto2 Language Guide. +This is a reference guide – for a step by step example that uses many of the features described in this document, see the tutorial for your chosen language.Protobuf Editions Overviewhttps://protobuf.dev/editions/overview/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/editions/overview/Protobuf Editions replace the proto2 and proto3 designations that we have used for Protocol Buffers. Instead of adding syntax = &quot;proto2&quot; or syntax = &quot;proto3&quot; at the top of proto definition files, you use an edition number, such as edition = &quot;2024&quot;, to specify the default behaviors your file will have. Editions enable the language to evolve incrementally over time. +Instead of the hardcoded behaviors that older versions have had, editions represent a collection of features with a default value (behavior) per feature.Feature Settings for Editionshttps://protobuf.dev/editions/features/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/editions/features/This topic provides an overview of the features that are included in the released edition versions. Subsequent editions&rsquo; features will be added to this topic. We announce new editions in the News section. +Before configuring feature settings in your new schema definition content, make sure you understand why you are using them. Avoid cargo-culting with features. +Prototiller Prototiller is a command-line tool that updates proto schema configuration files between syntax versions and editions.Implementing Editions Supporthttps://protobuf.dev/editions/implementation/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/editions/implementation/This topic explains how to implement editions in new runtimes and generators. +Overview Edition 2023 The first edition released is Edition 2023, which is designed to unify proto2 and proto3 syntax. The features we’ve added to cover the difference in behaviors are detailed in Feature Settings for Editions. +Feature Definition In addition to supporting editions and the global features we&rsquo;ve defined, you may want to define your own features to leverage the infrastructure.Proto Limitshttps://protobuf.dev/programming-guides/proto-limits/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/proto-limits/This topic documents the limits to the number of supported elements (fields, enum values, and so on) in proto schemas. +This information is a collection of discovered limitations by many engineers, but is not exhaustive and may be incorrect/outdated in some areas. As you discover limitations in your work, contribute those to this document to help others. +Number of Fields All messages are limited to 65,535 fields. +Message with only singular proto fields (such as Boolean):Style Guidehttps://protobuf.dev/programming-guides/style/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/style/This document provides a style guide for .proto files. By following these conventions, you&rsquo;ll make your protocol buffer message definitions and their corresponding classes consistent and easy to read. +Enforcement of the following style guidelines is controlled via enforce_naming_style. +Standard File Formatting Keep the line length to 80 characters. Use an indent of 2 spaces. Prefer the use of double quotes for strings. File Structure Files should be named lower_snake_case.proto.Enum Behaviorhttps://protobuf.dev/programming-guides/enum/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/enum/Enums behave differently in different language libraries. This topic covers the different behaviors as well as the plans to move protobufs to a state where they are consistent across all languages. If you&rsquo;re looking for information on how to use enums in general, see the corresponding sections in the proto2, proto3, and editions 2023 language guide topics. +Definitions Enums have two distinct flavors (open and closed). They behave identically except in their handling of unknown values.Encodinghttps://protobuf.dev/programming-guides/encoding/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/encoding/This document describes the protocol buffer wire format, which defines the details of how your message is sent on the wire and how much space it consumes on disk. You probably don&rsquo;t need to understand this to use protocol buffers in your application, but it&rsquo;s useful information for doing optimizations. +If you already know the concepts but want a reference, skip to the Condensed reference card section. +Protoscope is a very simple language for describing snippets of the low-level wire format, which we&rsquo;ll use to provide a visual reference for the encoding of various messages.ProtoJSON Formathttps://protobuf.dev/programming-guides/json/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/json/Protobuf supports a canonical encoding in JSON, making it easier to share data with systems that do not support the standard protobuf binary wire format. +This page specifies the format, but a number of additional edge cases which define a conformant ProtoJSON parser are covered in the Protobuf Conformance Test Suite and are not exhaustively detailed here. +Non-goals of the Format Cannot Represent Some JSON schemas The ProtoJSON format is designed to be a JSON representation of schemas which are expressible in the Protobuf schema language.Techniqueshttps://protobuf.dev/programming-guides/techniques/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/techniques/You can also send design and usage questions to the Protocol Buffers discussion group. +Common Filename Suffixes It is fairly common to write messages to files in several different formats. We recommend using the following file extensions for these files. +Content Extension Text Format .txtpb Wire Format .binpb JSON Format .json For Text Format specifically, .textproto is also fairly common, but we recommend .txtpb for its brevity. +Streaming Multiple Messages If you want to write multiple messages to a single file or stream, it is up to you to keep track of where one message ends and the next begins.Third-Party Add-onshttps://protobuf.dev/programming-guides/addons/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/addons/Many open source projects seek to add useful functionality on top of Protocol Buffers. For a list of links to projects we know about, see the third-party add-ons wiki page.Extension Declarationshttps://protobuf.dev/programming-guides/extension_declarations/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/extension_declarations/Introduction This page describes in detail what extension declarations are, why we need them, and how we use them. +Note Proto3 does not support extensions (except for declaring custom options). Extensions are fully supported in proto2 and editions though. If you need an introduction to extensions, read this extensions guide +Motivation Extension declarations aim to strike a happy medium between regular fields and extensions. Like extensions, they avoid creating a dependency on the message type of the field, which therefore results in a leaner build graph and smaller binaries in environments where unused messages are difficult or impossible to strip.Application Note: Field Presencehttps://protobuf.dev/programming-guides/field_presence/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/field_presence/Background Field presence is the notion of whether a protobuf field has a value. There are two different manifestations of presence for protobufs: implicit presence, where the generated message API stores field values (only), and explicit presence, where the API also stores whether or not a field has been set. +Note We recommend always adding the optional label for proto3 basic types. This provides a smoother path to editions, which uses explicit presence by default.Symbol Visibilityhttps://protobuf.dev/programming-guides/symbol_visibility/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/symbol_visibility/This document describes the terminology and functionality of the symbol visibility system introduced in proto edition = &quot;2024&quot; +Glossary Symbol: Any of message, enum, service or extend &lt;type&gt;, the allowed Top-Level types in a .proto file. Top-Level: A Symbol defined at the root of a .proto file. This includes all service definitions and any message, enum, or extend block not nested in message. Visibility: Property of a Symbol that controls whether it can be imported into another .Proto Serialization Is Not Canonicalhttps://protobuf.dev/programming-guides/serialization-not-canonical/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/serialization-not-canonical/Many people want a serialized proto to canonically represent the contents of that proto. Use cases include: +using a serialized proto as a key in a hash table taking a fingerprint or checksum of a serialized proto comparing serialized payloads as a way of checking message equality Unfortunately, protobuf serialization is not (and cannot be) canonical. There are a few notable exceptions, such as MapReduce, but in general you should generally think of proto serialization as unstable.Deserializing Debug Proto Representationshttps://protobuf.dev/programming-guides/deserialize-debug/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/deserialize-debug/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. +Unlike the Protobuf DebugString output format, the new debugging format automatically redacts sensitive fields by replacing their values with the string &ldquo;[REDACTED]&rdquo; (without the quotation marks).No Nullable Setters/Getters Supporthttps://protobuf.dev/design-decisions/nullable-getters-setters/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/design-decisions/nullable-getters-setters/We have heard feedback that some folks would like protobuf to support nullable getters/setters in their null-friendly language of choice (particularly Kotlin, C#, and Rust). While this does seem to be a helpful feature for folks using those languages, the design choice has tradeoffs which have led to the Protobuf team choosing not to implement them. +Explicit presence is not a concept that directly maps to the traditional notion of nullability.Avoid Cargo Cultinghttps://protobuf.dev/best-practices/no-cargo-cults/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/best-practices/no-cargo-cults/Do not cargo cult settings in proto files. If you are creating a new proto file based on existing schema definitions, don&rsquo;t apply option settings except for those that you understand the need for. +Best Practices Specific to Editions Avoid applying editions features except when they&rsquo;re actually necessary. Features in .proto files signal the use of either experimental future behaviors or deprecated past behaviors. Best practices for the latest edition will always be the default.Proto Best Practiceshttps://protobuf.dev/best-practices/dos-donts/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/best-practices/dos-donts/Clients and servers are never updated at exactly the same time - even when you try to update them at the same time. One or the other may get rolled back. Don’t assume that you can make a breaking change and it&rsquo;ll be okay because the client and server are in sync. +Don&rsquo;t Re-use a Tag Number Never re-use a tag number. It messes up deserialization. Even if you think no one is using the field, don’t re-use a tag number.1-1-1 Best Practicehttps://protobuf.dev/best-practices/1-1-1/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/best-practices/1-1-1/The &ldquo;1-1-1&rdquo; best practice advocates structuring definitions with one top-level entity (message, enum, or extension) per .proto file, corresponding to a single proto_library build rule. This approach promotes small, modular proto definitions. Key benefits include simplified refactoring, potentially improved build times, and smaller binary sizes due to minimized transitive dependencies. +Rationale The 1-1-1 best practice is to keep every proto_library and .proto file as small as is reasonable, with the ideal being:Protocol Buffer Basics: C++https://protobuf.dev/getting-started/cpptutorial/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/getting-started/cpptutorial/This tutorial provides a basic C++ programmers introduction to working with protocol buffers. By walking through creating a simple example application, it shows you how to +Define message formats in a .proto file. Use the protocol buffer compiler. Use the C++ protocol buffer API to write and read messages. This isn&rsquo;t a comprehensive guide to using protocol buffers in C++. For more detailed reference information, see the Protocol Buffer Language Guide, the C++ API Reference, the C++ Generated Code Guide, and the Encoding Reference.Protocol Buffer Basics: C#https://protobuf.dev/getting-started/csharptutorial/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/getting-started/csharptutorial/This tutorial provides a basic C# programmer&rsquo;s introduction to working with protocol buffers, using the proto3 version of the protocol buffers language. By walking through creating a simple example application, it shows you how to +Define message formats in a .proto file. Use the protocol buffer compiler. Use the C# protocol buffer API to write and read messages. This isn&rsquo;t a comprehensive guide to using protocol buffers in C#. For more detailed reference information, see the Protocol Buffer Language Guide, the C# API Reference, the C# Generated Code Guide, and the Encoding Reference.Protocol Buffer Basics: Darthttps://protobuf.dev/getting-started/darttutorial/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/getting-started/darttutorial/This tutorial provides a basic Dart programmer&rsquo;s introduction to working with protocol buffers, using the proto3 version of the protocol buffers language. By walking through creating a simple example application, it shows you how to +Define message formats in a .proto file. Use the protocol buffer compiler. Use the Dart protocol buffer API to write and read messages. This isn&rsquo;t a comprehensive guide to using protocol buffers in Dart . For more detailed reference information, see the Protocol Buffer Language Guide, the Dart Language Tour, the Dart API Reference, the Dart Generated Code Guide, and the Encoding Reference.Protocol Buffer Basics: Gohttps://protobuf.dev/getting-started/gotutorial/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/getting-started/gotutorial/This tutorial provides a basic Go programmer&rsquo;s introduction to working with protocol buffers, using the proto3 version of the protocol buffers language. By walking through creating a simple example application, it shows you how to +Define message formats in a .proto file. Use the protocol buffer compiler. Use the Go protocol buffer API to write and read messages. This isn&rsquo;t a comprehensive guide to using protocol buffers in Go. For more detailed reference information, see the Protocol Buffer Language Guide, the Go API Reference, the Go Generated Code Guide, and the Encoding Reference.Protocol Buffer Basics: Javahttps://protobuf.dev/getting-started/javatutorial/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/getting-started/javatutorial/This tutorial provides a basic Java programmer&rsquo;s introduction to working with protocol buffers. By walking through creating a simple example application, it shows you how to +Define message formats in a .proto file. Use the protocol buffer compiler. Use the Java protocol buffer API to write and read messages. This isn&rsquo;t a comprehensive guide to using protocol buffers in Java. For more detailed reference information, see the Protocol Buffer Language Guide (proto2), the Protocol Buffer Language Guide (proto3), the Java API Reference, the Java Generated Code Guide, and the Encoding Reference.Protocol Buffer Basics: Kotlinhttps://protobuf.dev/getting-started/kotlintutorial/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/getting-started/kotlintutorial/This tutorial provides a basic Kotlin programmer&rsquo;s introduction to working with protocol buffers, using the proto3 version of the protocol buffers language. By walking through creating a simple example application, it shows you how to +Define message formats in a .proto file. Use the protocol buffer compiler. Use the Kotlin protocol buffer API to write and read messages. This isn&rsquo;t a comprehensive guide to using protocol buffers in Kotlin. For more detailed reference information, see the Protocol Buffer Language Guide, the Kotlin API Reference, the Kotlin Generated Code Guide, and the Encoding Reference.Protocol Buffer Basics: Pythonhttps://protobuf.dev/getting-started/pythontutorial/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/getting-started/pythontutorial/This tutorial provides a basic Python programmer&rsquo;s introduction to working with protocol buffers. By walking through creating a simple example application, it shows you how to +Define message formats in a .proto file. Use the protocol buffer compiler. Use the Python protocol buffer API to write and read messages. This isn&rsquo;t a comprehensive guide to using protocol buffers in Python. For more detailed reference information, see the Protocol Buffer Language Guide (proto2), the Protocol Buffer Language Guide (proto3), the Python API Reference, the Python Generated Code Guide, and the Encoding Reference.C++ Generated Code Guidehttps://protobuf.dev/reference/cpp/cpp-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/cpp-generated/Any differences between proto2, proto3, and editions generated code are highlighted. Note that these differences are in the generated code as described in this document, not the base message classes/interfaces, which are the same in all versions. You should read the proto2 language guide, proto3 language guide, or edition 2023 language guide before reading this document. +Compiler Invocation The protocol buffer compiler produces C++ output when invoked with the --cpp_out= command-line flag.String View APIshttps://protobuf.dev/reference/cpp/string-view/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/string-view/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.C++ Arena Allocation Guidehttps://protobuf.dev/reference/cpp/arenas/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/arenas/This page describes exactly what C++ code the protocol buffer compiler generates in addition to the code described in the C++ Generated Code Guide when arena allocation is enabled. It assumes that you are familiar with the material in the language guide and the C++ Generated Code Guide. +Why Use Arena Allocation? Memory allocation and deallocation constitutes a significant fraction of CPU time spent in protocol buffers code. By default, protocol buffers performs heap allocations for each message object, each of its subobjects, and several field types, such as strings.Abseil Supporthttps://protobuf.dev/reference/cpp/abseil/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/abseil/In version 22.x, C++ protobuf added an explicit dependency on Abseil. +Bazel Support If you are using Bazel, to determine the version of Abseil that your protobuf version supports, you can use the bazel mod command: +$ bazel mod deps abseil-cpp --enable_bzlmod &lt;root&gt; (protobuf@30.0-dev) └───abseil-cpp@20240722.0 ├───bazel_skylib@1.7.1 ├───googletest@1.15.2 └───platforms@0.0.10 bazel mod graph produces the full output: +$ bazel mod graph --enable_bzlmod &lt;root&gt; (protobuf@30.0-dev) ├───abseil-cpp@20240722.0 │ ├───bazel_skylib@1.7.1 (*) │ ├───googletest@1.15.2 (*) │ └───platforms@0.C++ APIhttps://protobuf.dev/reference/cpp/api-docs-link/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs-link/C# Generated Code Guidehttps://protobuf.dev/reference/csharp/csharp-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/csharp/csharp-generated/You should read the proto2 language guide, proto3 language guide, or editions language guide before reading this document. +Compiler Invocation The protocol buffer compiler produces C# output when invoked with the --csharp_out command-line flag. The parameter to the --csharp_out option is the directory where you want the compiler to write your C# output, although depending on other options the compiler may create subdirectories of the specified directory. The compiler creates a single source file for each .C# APIhttps://protobuf.dev/reference/csharp/api-docs-link/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/csharp/api-docs-link/Dart Generated Codehttps://protobuf.dev/reference/dart/dart-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/dart/dart-generated/Any differences between proto2, proto3, and editions generated code are highlighted - note that these differences are in the generated code as described in this document, not the base API, which are the same in both versions. You should read the proto2 language guide, proto3 language guide, or editions language guide before reading this document. +Compiler Invocation The protocol buffer compiler requires a plugin to generate Dart code. Installing it following the instructions provides a protoc-gen-dart binary which protoc uses when invoked with the --dart_out command-line flag.Dart APIhttps://protobuf.dev/reference/dart/api-docs-link/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/dart/api-docs-link/Go Generated Code Guide (Open)https://protobuf.dev/reference/go/go-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/go/go-generated/Any differences between proto2, proto3, and editions generated code are highlighted - note that these differences are in the generated code as described in this document, not the base API, which are the same in both versions. You should read the proto2 language guide, proto3 language guide, or editions language guide before reading this document. +Note You are looking at documentation for the old generated code API (Open Struct API). See Go Generated Code (Opaque) for the corresponding documentation of the (new) Opaque API.Go Generated Code Guide (Opaque)https://protobuf.dev/reference/go/go-generated-opaque/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/go/go-generated-opaque/Any differences between proto2 and proto3 generated code are highlighted - note that these differences are in the generated code as described in this document, not the base API, which are the same in both versions. You should read the proto2 language guide and/or the proto3 language guide before reading this document. +Note You are looking at documentation for the Opaque API, which is the current version. If you are working with .Go FAQhttps://protobuf.dev/reference/go/faq/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/go/faq/Versions What&rsquo;s the difference between github.com/golang/protobuf and google.golang.org/protobuf? The github.com/golang/protobuf module is the original Go protocol buffer API. +The google.golang.org/protobuf module is an updated version of this API designed for simplicity, ease of use, and safety. The flagship features of the updated API are support for reflection and a separation of the user-facing API from the underlying implementation. +We recommend that you use google.golang.org/protobuf in new code. +Version v1.4.0 and higher of github.Go Size Semanticshttps://protobuf.dev/reference/go/size/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/go/size/The proto.Size function returns the size in bytes of the wire-format encoding of a proto.Message by traversing all its fields (including submessages). +In particular, it returns the size of how Go Protobuf will encode the message. +A note on Protobuf Editions With Protobuf Editions, .proto files can enable features that change serialization behavior. This can affect the value returned by proto.Size. For example, setting features.field_presence = IMPLICIT will cause scalar fields that are set to their defaults to not be serialized, and therefore don&rsquo;t contribute to the size of the message.Go APIhttps://protobuf.dev/reference/go/api-docs-link/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/go/api-docs-link/Java Generated Code Guidehttps://protobuf.dev/reference/java/java-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/java/java-generated/Any differences between proto2, proto3, and Editions generated code are highlighted—note that these differences are in the generated code as described in this document, not the base message classes/interfaces, which are the same in all versions. You should read the proto2 language guide, proto3 language guide, and/or Editions language guide before reading this document. +Note that no Java protocol buffer methods accept or return nulls unless otherwise specified. +Compiler Invocation The protocol buffer compiler produces Java output when invoked with the --java_out= command-line flag.Go Opaque API Migrationhttps://protobuf.dev/reference/go/opaque-migration/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/go/opaque-migration/The Opaque API is the latest version of the Protocol Buffers implementation for the Go programming language. The old version is now called Open Struct API. See the Go Protobuf: Releasing the Opaque API blog post for an introduction. +The migration to the Opaque API happens incrementally, on a per-proto-message or per-.proto-file basis, by setting the api_level feature to one of its possible values: +API_OPEN selects the Open Struct API. This was backported into edition 2023, so older versions of the Go plugin may not honor it.Java Proto Nameshttps://protobuf.dev/reference/java/java-proto-names/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/java/java-proto-names/This document contains information on what the fully-qualified Java name of a proto is, based on the different proto options. This name corresponds to the package you need to import to use that message. +Recommendation Starting with Edition 2024, best practice is to: +Set option java_package = &quot;com.example.package&quot; Do not set java_outer_classname or features.(pb.java).nest_in_file_class = YES. Starting with Edition 2024, the default behaviors have otherwise been improved so that now the default behavior is considered current best practice.Java APIhttps://protobuf.dev/reference/java/api-docs-link/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/java/api-docs-link/Go Opaque API: Manual Migrationhttps://protobuf.dev/reference/go/opaque-migration-manual/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/go/opaque-migration-manual/The Opaque API is the latest version of the Protocol Buffers implementation for the Go programming language. The old version is now called Open Struct API. See the Go Protobuf: Releasing the Opaque API blog post for an introduction. +This is a user guide for migrating Go Protobuf usages from the older Open Struct API to the new Opaque API. +Warning You are looking at the manual migration guide. Typically you’re better off using the open2opaque tool to automate the migration.Go Opaque API FAQhttps://protobuf.dev/reference/go/opaque-faq/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/go/opaque-faq/The Opaque API is the latest version of the Protocol Buffers implementation for the Go programming language. The old version is now called Open Struct API. See the Go Protobuf: The new Opaque API blog post for an introduction. +This FAQ answers common questions about the new API and the migration process. +Which API Should I Use When Creating a New .proto File? We recommend you select the Opaque API for new development.Kotlin Generated Code Guidehttps://protobuf.dev/reference/kotlin/kotlin-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/kotlin/kotlin-generated/Any differences between proto2, proto3, and editions generated code are highlighted—note that these differences are in the generated code as described in this document, not the base message classes/interfaces, which are the same in both versions. You should read the proto2 language guide, proto3 language guide, and/or the Editions guide before reading this document. +Compiler Invocation The protocol buffer compiler produces Kotlin code that builds on top of Java code. As a result, it must be invoked with two command-line flags, --java_out= and --kotlin_out=.Objective-C Generated Code Guidehttps://protobuf.dev/reference/objective-c/objective-c-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/objective-c/objective-c-generated/Any differences between proto2, proto3, and Editions generated code are highlighted. You should read the proto2 language guide and/or proto3 language guide and/or the Editions guide before reading this document. +Compiler invocation The protocol buffer compiler produces Objective-C output when invoked with the --objc_out= command-line flag. The parameter to the --objc_out= option is the directory where you want the compiler to write your Objective-C output. The compiler creates a header file and an implementation file for each .PHP Generated Code Guidehttps://protobuf.dev/reference/php/php-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/php/php-generated/You should read the proto3 language guide or Editions language guide before reading this document. Note that the protocol buffer compiler currently only supports proto3 and editions code generation for PHP. +Compiler Invocation The protocol buffer compiler produces PHP output when invoked with the --php_out= command-line flag. The parameter to the --php_out= option is the directory where you want the compiler to write your PHP output. In order to conform to PSR-4, the compiler creates a sub-directory corresponding to the package defined in the proto file.PHP APIhttps://protobuf.dev/reference/php/api-docs-link/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/php/api-docs-link/Python Generated Code Guidehttps://protobuf.dev/reference/python/python-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/python/python-generated/Any differences between proto2, proto3, and Editions generated code are highlighted - note that these differences are in the generated code as described in this document, not the base message classes/interfaces, which are the same across all versions. You should read the proto2 language guide, proto3 language guide, and/or Editions guide before reading this document. +The Python Protocol Buffers implementation is a little different from C++ and Java. In Python, the compiler only outputs code to build descriptors for the generated classes, and a Python metaclass does the real work.Python Comparisonhttps://protobuf.dev/reference/python/python-comparison/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/python/python-comparison/Because of how proto data is serialized, you cannot rely on the wire representation of a proto message instance to determine if its content is the same as another instance. A subset of the ways that a wire-format proto message instance can vary include the following: +The protobuf schema changes in certain ways. A map field stores its values in a different order. The binary is built with different flags (such as opt vs.Python APIhttps://protobuf.dev/reference/python/api-docs-link/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/python/api-docs-link/Ruby Generated Code Guidehttps://protobuf.dev/reference/ruby/ruby-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/ruby/ruby-generated/You should read the language guides for proto2, proto3, or editions before reading this document. +Compiler Invocation The protocol buffer compiler produces Ruby output when invoked with the --ruby_out= command-line flag. The parameter to the --ruby_out= option is the directory where you want the compiler to write your Ruby output. The compiler creates a .rb file for each .proto file input. The names of the output files are computed by taking the name of the .Rust Generated Code Guidehttps://protobuf.dev/reference/rust/rust-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/rust/rust-generated/This page describes exactly what Rust code the protocol buffer compiler generates for any given protocol definition. +This document covers how the protocol buffer compiler generates Rust code for proto2, proto3, and protobuf editions. Any differences between proto2, proto3, and editions generated code are highlighted. You should read the proto2 language guide, proto3 language guide, or editions guide before reading this document. +Protobuf Rust Protobuf Rust is an implementation of protocol buffers designed to be able to sit on top of other existing protocol buffer implementations that we refer to as &lsquo;kernels&rsquo;.Redaction in Rusthttps://protobuf.dev/reference/rust/rust-redaction/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/rust/rust-redaction/Use the standard fmt::Debug (&quot;{:?}&quot; in format strings) on Protobuf messages for human-readable strings for logging, error messages, exceptions, and similar use cases. The output of this debug info is not intended to be machine-readable (unlike TextFormat and JSON which are not be used for debug output). +Using fmt::Debug enables redaction of some sensitive fields. +Note that under upb kernel this redaction is not yet implemented, but is expected to be added.Building Rust Protoshttps://protobuf.dev/reference/rust/building-rust-protos/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/rust/building-rust-protos/Cargo See the protobuf-example crate for an example of how to set up your build. +Bazel The process of building a Rust library for a Protobuf definition is similar to other programming languages: +Use the language-agnostic proto_library rule: +proto_library( name = &#34;person_proto&#34;, srcs = [&#34;person.proto&#34;], ) Create a Rust library: +load(&#34;//third_party/protobuf/rust:defs.bzl&#34;, &#34;rust_proto_library&#34;) proto_library( name = &#34;person_proto&#34;, srcs = [&#34;person.proto&#34;], ) rust_proto_library( name = &#34;person_rust_proto&#34;, deps = [&#34;:person_proto&#34;], ) Use the library by including it in a Rust binary:Rust Proto Design Decisionshttps://protobuf.dev/reference/rust/rust-design-decisions/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/rust/rust-design-decisions/As with any library, Rust Protobuf is designed considering the needs of both Google&rsquo;s first-party usage of Rust as well that of external users. Choosing a path in that design space means that some choices made will not be optimal for some users in some cases, even if it is the right choice for the implementation overall. +This page covers some of the larger design decisions that the Rust Protobuf implementation makes and the considerations which led to those decisions.Protocol Buffers Edition 2023 Language Specificationhttps://protobuf.dev/reference/protobuf/edition-2023-spec/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/protobuf/edition-2023-spec/The syntax is specified using Extended Backus-Naur Form (EBNF): +| alternation () grouping [] option (zero or one time) {} repetition (any number of times) Lexical Elements Letters and Digits letter = &#34;A&#34; ... &#34;Z&#34; | &#34;a&#34; ... &#34;z&#34; capitalLetter = &#34;A&#34; ... &#34;Z&#34; decimalDigit = &#34;0&#34; ... &#34;9&#34; octalDigit = &#34;0&#34; ... &#34;7&#34; hexDigit = &#34;0&#34; ... &#34;9&#34; | &#34;A&#34; ... &#34;F&#34; | &#34;a&#34; ... &#34;f&#34; Identifiers ident = letter { letter | decimalDigit | &#34;_&#34; } fullIdent = ident { &#34;.Protocol Buffers Language Specification (Proto2 Syntax)https://protobuf.dev/reference/protobuf/proto2-spec/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/protobuf/proto2-spec/The syntax is specified using Extended Backus-Naur Form (EBNF): +| alternation () grouping [] option (zero or one time) {} repetition (any number of times) For more information about using proto2, see the language guide. +Lexical Elements Letters and Digits letter = &#34;A&#34; ... &#34;Z&#34; | &#34;a&#34; ... &#34;z&#34; capitalLetter = &#34;A&#34; ... &#34;Z&#34; decimalDigit = &#34;0&#34; ... &#34;9&#34; octalDigit = &#34;0&#34; ... &#34;7&#34; hexDigit = &#34;0&#34; ... &#34;9&#34; | &#34;A&#34; .Protocol Buffers Edition 2024 Language Specificationhttps://protobuf.dev/reference/protobuf/edition-2024-spec/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/protobuf/edition-2024-spec/The syntax is specified using Extended Backus-Naur Form (EBNF): +| alternation () grouping [] option (zero or one time) {} repetition (any number of times) Lexical Elements Letters and Digits letter = &#34;A&#34; ... &#34;Z&#34; | &#34;a&#34; ... &#34;z&#34; capitalLetter = &#34;A&#34; ... &#34;Z&#34; decimalDigit = &#34;0&#34; ... &#34;9&#34; octalDigit = &#34;0&#34; ... &#34;7&#34; hexDigit = &#34;0&#34; ... &#34;9&#34; | &#34;A&#34; ... &#34;F&#34; | &#34;a&#34; ... &#34;f&#34; Identifiers ident = letter { letter | decimalDigit | &#34;_&#34; } fullIdent = ident { &#34;.Protocol Buffers Language Specification (Proto3)https://protobuf.dev/reference/protobuf/proto3-spec/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/protobuf/proto3-spec/The syntax is specified using Extended Backus-Naur Form (EBNF): +| alternation () grouping [] option (zero or one time) {} repetition (any number of times) For more information about using proto3, see the language guide. +Lexical Elements Letters and Digits letter = &#34;A&#34; ... &#34;Z&#34; | &#34;a&#34; ... &#34;z&#34; decimalDigit = &#34;0&#34; ... &#34;9&#34; octalDigit = &#34;0&#34; ... &#34;7&#34; hexDigit = &#34;0&#34; ... &#34;9&#34; | &#34;A&#34; ... &#34;F&#34; | &#34;a&#34; .Text Format Language Specificationhttps://protobuf.dev/reference/protobuf/textformat-spec/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/protobuf/textformat-spec/This format is distinct from the format of text within a .proto schema, for example. This document contains reference documentation using the syntax specified in ISO/IEC 14977 EBNF. +Note This is a draft spec originally reverse-engineered from the C++ text format implementation It has evolved and may change further based on discussion and review. While an effort has been made to keep text formats consistent across supported languages, incompatibilities are likely to exist.Protocol Buffer MIME Typeshttps://protobuf.dev/reference/protobuf/mime-types/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/protobuf/mime-types/All Protobuf documents should have the MIME type application and the subtype protobuf, with the suffix +json for JSON encodings according to the standard, followed by the following parameters: +encoding should be set only to binary, or json, denoting those respective formats. With subtype protobuf+json, encoding has the default json and cannot be set to binary. With subtype protobuf (without +json), encoding has the default binary and cannot be set to json.Protocol Buffers Well-Known Typeshttps://protobuf.dev/reference/protobuf/google.protobuf/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/protobuf/google.protobuf/Index Any (message) Api (message) BoolValue (message) BytesValue (message) DoubleValue (message) Duration (message) Empty (message) Enum (message) EnumValue (message) Field (message) Field.Cardinality (enum) Field.Kind (enum) FieldMask (message) FloatValue (message) Int32Value (message) Int64Value (message) ListValue (message) Method (message) Mixin (message) NullValue (enum) Option (message) SourceContext (message) StringValue (message) Struct (message) Syntax (enum) Timestamp (message) Type (message) UInt32Value (message) UInt64Value (message) Value (message) Well-Known Types that end in &ldquo;Value&rdquo; are wrapper messages for other types, such as BoolValue and EnumValue.Other Languageshttps://protobuf.dev/reference/other/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/other/While the current release includes compilers and APIs for C++, Java, Go, Ruby, C#, and Python, the compiler code is designed so that it&rsquo;s easy to add support for other languages. There are several ongoing projects to add new language implementations to Protocol Buffers, including C, Haskell, Perl, Rust, and more. +For a list of links to projects we know about, see the third-party add-ons wiki page. +Compiler Plugins protoc, the Protocol Buffers Compiler, can be extended to support new languages via plugins.Version Supporthttps://protobuf.dev/support/version-support/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/support/version-support/Currently Supported Release Versions Language Active Support Maintenance Only Minimum Gencode protoc 34.x 29.x, 25.x (for Java) C++ 7.34.x 5.29.x Exact Match C# 3.34.x 3.0.0 Java 4.34.x 3.25.x 3.0.0 PHP 5.34.x 4.0.0 Python 7.34.x 5.29.x 3.20.0 Ruby 4.34.x 3.0.0 Minimum Supported Gencode While each language runtime has a minimum supported gencode version, we recommend regenerating your gencode with every release update. Support for older generated code exists solely to ensure backwards compatibility for existing projects, not for new adoption of older gencode versions.Debugginghttps://protobuf.dev/support/debugging-playbook/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/support/debugging-playbook/Frequently asked questions and debugging scenarios encountered by protobuf users. +Bazel: Resolving Issues with Prebuilt Protoc As mentioned in this news article, Bazel 7 and later support builds that use a prebuilt protoc. When everything is configured correctly, this can save a lot of time building, reduce logging volume, and eliminate the need for C++ toolchain in non-C++ implementations. +To prevent protoc compilation from source, add the following to your .Migration Guidehttps://protobuf.dev/support/migration/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/support/migration/Changes in v34.0 The following is a list of the breaking changes made to versions of the libraries, and how to update your code to accommodate the changes. +This covers breaking changes announced in News Announcements for v34.x and Release Notes for v34.0. +Changes in C++ C++ bumped its major version to 7 with the 7.34.0 release. 6.33 is the final minor version release on 6.x. +Removal of Future Macros The following macros, introduced for staged roll-out of breaking changes, were removed and their behavior is now the default:Cross-Version Runtime Guaranteehttps://protobuf.dev/support/cross-version-runtime-guarantee/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/support/cross-version-runtime-guarantee/Protobuf language bindings have two components. The generated code (gencode) and the runtime libraries that implement common functionality for that generated code. When these come from different releases of protobuf, we are in a &ldquo;cross version runtime&rdquo; situation. +We intend to offer the following guarantees across most languages. These are the default guarantees; however, owners of protobuf code generators and runtimes may explicitly override them with more specific guarantees for that language.Downloadshttps://protobuf.dev/downloads/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/downloads/Release Packages Latest Version The latest release of Protocol Buffers can be found on the release page. +Old Versions Older versions are available in our historical releases on GitHub. +Source Code GitHub Repository Protocol Buffers source code is hosted on GitHub.Historyhttps://protobuf.dev/history/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/history/Understanding why protobuf was created and the decisions that changed it over time can help you to better use the features of the tool. +Why Did You Release Protocol Buffers? There are several reasons that we released Protocol Buffers. +Protocol buffers are used by many projects inside Google. We had other projects we wanted to release as open source that use protocol buffers, so to do this, we needed to release protocol buffers first.Forumhttps://protobuf.dev/forum-link/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/forum-link/<link>https://protobuf.dev/navbar/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/navbar/</guid><description> Home Programming Guides Codelab Reference</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/-dsl-list/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/-dsl-list/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslList/DslList +DslList [JVM] Content fun &lt;E&gt; DslList(delegate: List&lt;E&gt;)</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/equals/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/equals/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslList/equals +equals [JVM] Content open operator override fun equals(other: Any?): Boolean</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/hash-code/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/hash-code/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslList/hashCode +hashCode [JVM] Content open override fun hashCode(): Int</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/iterator/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/iterator/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslList/iterator +iterator [JVM] Content open operator override fun iterator(): Iterator&lt;E&gt;</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/list-iterator/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/list-iterator/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslList/listIterator +listIterator [JVM] Content open override fun listIterator(): ListIterator&lt;E&gt; open override fun listIterator(index: Int): ListIterator&lt;E&gt;</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/to-string/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/to-string/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslList/toString +toString [JVM] Content open override fun toString(): String</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/-dsl-map/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/-dsl-map/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/DslMap +DslMap [JVM] Content fun &lt;K, V&gt; DslMap(delegate: Map&lt;K, V&gt;)</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/entries/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/entries/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/entries +entries [JVM] Content open override val entries: Set&lt;Map.Entry&lt;K, V&raquo;</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/equals/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/equals/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/equals +equals [JVM] Content open operator override fun equals(other: Any?): Boolean</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/hash-code/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/hash-code/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/hashCode +hashCode [JVM] Content open override fun hashCode(): Int</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/keys/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/keys/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/keys +keys [JVM] Content open override val keys: Set&lt;K&gt;</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/to-string/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/to-string/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/toString +toString [JVM] Content open override fun toString(): String</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/values/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/values/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/values +values [JVM] Content open override val values: Collection&lt;V&gt;</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/-extension-list/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/-extension-list/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/ExtensionList +ExtensionList [JVM] Content fun &lt;E, M : MessageLite&gt; ExtensionList(extension: ExtensionLite&lt;M, List&lt;E&raquo;, delegate: List&lt;E&gt;)</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/equals/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/equals/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/equals +equals [JVM] Content open operator override fun equals(other: Any?): Boolean</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/extension/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/extension/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/extension +extension [JVM] Content val extension: ExtensionLite&lt;M, List&lt;E&raquo;</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/hash-code/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/hash-code/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/hashCode +hashCode [JVM] Content open override fun hashCode(): Int</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/iterator/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/iterator/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/iterator +iterator [JVM] Content open operator override fun iterator(): Iterator&lt;E&gt;</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/list-iterator/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/list-iterator/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/listIterator +listIterator [JVM] Content open override fun listIterator(): ListIterator&lt;E&gt; open override fun listIterator(index: Int): ListIterator&lt;E&gt;</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/to-string/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/to-string/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/toString +toString [JVM] Content open override fun toString(): String</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/-only-for-use-by-generated-proto-code/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/-only-for-use-by-generated-proto-code/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/OnlyForUseByGeneratedProtoCode/OnlyForUseByGeneratedProtoCode +OnlyForUseByGeneratedProtoCode [JVM] Content fun OnlyForUseByGeneratedProtoCode()</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/-proto-dsl-marker/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/-proto-dsl-marker/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/ProtoDslMarker/ProtoDslMarker +ProtoDslMarker [JVM] Content fun ProtoDslMarker()</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/contains/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/contains/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/contains +contains [JVM] Content operator fun &lt;M : GeneratedMessageV3.ExtendableMessage&lt;M&gt;, MorBT : GeneratedMessageV3.ExtendableMessageOrBuilder&lt;M&raquo; MorBT.contains(extension: ExtensionLite&lt;M, *&gt;): Boolean +Returns true if the specified extension is set on this builder.</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/get/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/get/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/get +get [JVM] Content operator fun ByteString.get(index: Int): Byte +Gets the byte at index. +[JVM] Content operator fun &lt;M : GeneratedMessageV3.ExtendableMessage&lt;M&gt;, MorBT : GeneratedMessageV3.ExtendableMessageOrBuilder&lt;M&gt;, T : Any&gt; MorBT.get(extension: ExtensionLite&lt;M, T&gt;): T +Gets the current value of the proto extension.</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/is-a/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/is-a/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/isA +isA [JVM] Content inline fun &lt;T : Message&gt; Any.isA(): Boolean +Returns true if this com.google.protobuf.Any contains a message of type T.</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/plus/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/plus/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/plus +plus [JVM] Content operator fun ByteString.plus(other: ByteString): ByteString \ +Concatenates the given ByteString to this one.</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/set/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/set/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/set +set [JVM] Content operator fun &lt;M : GeneratedMessageV3.ExtendableMessage&lt;M&gt;, B : GeneratedMessageV3.ExtendableBuilder&lt;M, B&gt;, T : Any&gt; B.set(extension: ExtensionLite&lt;M, T&gt;, value: T) +Sets the current value of the proto extension in this builder.</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string-utf8/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string-utf8/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/toByteStringUtf8 +toByteStringUtf8 [JVM] Content fun String.toByteStringUtf8(): ByteString +Encodes this String into a sequence of UTF-8 bytes and returns the result as a ByteString.</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/toByteString +toByteString [JVM] Content fun ByteArray.toByteString(): ByteString +Returns a copy of this ByteArray as an immutable ByteString. +[JVM] Content fun ByteBuffer.toByteString(): ByteString +Copies the remaining bytes from this ByteBuffer to a ByteString.</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/unpack/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/unpack/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/unpack +unpack [JVM] Content inline fun &lt;T : Message&gt; Any.unpack(): T +Returns the message of type T encoded in this com.google.protobuf.Any. +Throws | | &mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;- | &mdash; InvalidProtocolBufferException | if this com.google.protobuf.Any does not contain a T message.</description></item><item><title>Changes announced April 11, 2023https://protobuf.dev/news/2023-04-11/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-04-11/Syntax Reflection Deprecation v23 will deprecate the ability to check syntax version using reflection. The deprecation will be included as warnings at build time. The capability will be removed in a future release. +Adding support for ctype=CORD in C++ v23 will add ctype=CORD support for singular bytes fields, including oneof fields, to specify that data should be stored using absl::cord instead of string. Support may be added in future releases for singular string field types and for repeated string and byte fields if there is enough interest from the open source community.Changes announced April 20, 2023https://protobuf.dev/news/2023-04-20/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-04-20/Changes to Ruby Generator This GitHub PR, which will appear in the 23.x release, changes the Ruby code generator to emit a serialized proto instead of the DSL. +It removes the DSL from the code generator in anticipation of splitting the DSL out into a separate package. +Given a .proto file like: +syntax = &#34;proto3&#34;; package pkg; message TestMessage { optional int32 i32 = 1; optional TestMessage msg = 2; } Generated code before:Changes announced April 28, 2023https://protobuf.dev/news/2023-04-28/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-04-28/Stricter validation for json_name v24 will forbid zero unicode code points (\u0000) in the json_name field option. Going forward, any valid Unicode characters will be accepted in json_name, except \u0000. \0 characters will still be allowed to be used as values. +Previously, the proto compiler allowed \0 characters in the json_name field option, but support for this was inconsistent across languages and implementations. To help prevent interoperability problems relating to mishandling of keys containing a \0 character, we are clarifying the spec to say that \0 is not allowed in json_name, and will be rejected by the compiler.Changes Announced on August 15, 2023https://protobuf.dev/news/2023-08-15/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-08-15/Python Breaking Change In v25 message.UnknownFields() will be deprecated in pure Python and C++ extensions. It will be removed in v26. Use the new UnknownFieldSet(message) support in unknown_fields.py as a replacement.Changes announced August 3, 2022https://protobuf.dev/news/2022-08-03/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2022-08-03/This topic covers two areas: general platform support changes, and C++-specific changes that are being considered for the 22.x release line. +Platform Support Changes We&rsquo;ve added guidance about the platforms that we support in this section of the documentation. The section currently covers C++ and PHP, but may be expanded with information about other platforms in the future. +Official C++ Support Matrix With the policy, mentioned earlier in this announcement, of using Google&rsquo;s official foundational C++ support policy, our C++ compiler and toolchain support matrix will change.Changes Announced on August 9, 2023https://protobuf.dev/news/2023-08-09/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-08-09/.NET support policy The Protobuf team supports .NET in two ways: +Generation of C# code by protoc The Google.Protobuf NuGet package, which provides runtime support for the generated code, as well as reflection and other facilities The support policy for these has previously been unclear, particularly in terms of which .NET runtimes are supported. From August 2023 onwards, support will be provided in accordance with the Google Open Source support policy for .arena.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.arena/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.arena/#include &lt;google/protobuf/arena.h&gt; +namespace google::protobuf +This file defines an Arena allocator for better allocation performance. Classes in this fileArenaOptionsArenaOptions provides optional additional parameters to arena construction that control its block-allocation behavior. ArenaArena allocator. Arena::InternalHelperArena::is_arena_constructableHelper typetraits that indicates support for arenas in a type T at compile time. Arena::is_destructor_skippablestruct ArenaOptions#include &lt;google/protobuf/arena.h&gt; +namespace google::protobuf +ArenaOptions provides optional additional parameters to arena construction that control its block-allocation behavior. Memberssize_tstart_block_sizeThis defines the size of the first block requested from the system malloc.common.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.common/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.common/#include &lt;google/protobuf/stubs/common.h&gt; +namespace google::protobuf +Contains basic types and utilities used by the rest of the library. Classes in this filecode_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.code_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.code_generator/#include &lt;google/protobuf/compiler/code_generator.h&gt; +namespace google::protobuf::compiler +Defines the abstract interface implemented by each of the language-specific code generators. Classes in this fileCodeGeneratorThe abstract interface to a class which generates code implementing a particular proto file in a particular language. GeneratorContextCodeGenerators generate one or more files in a given directory. File MembersThese definitions are not part of any class.typedefGeneratorContext OutputDirectoryThe type GeneratorContext was once called OutputDirectory. more...voidParseGeneratorParameter(const std::string &amp; , std::vector&lt; std::pair&lt; std::string, std::string &gt; &gt; * )Several code generators treat the parameter argument as holding a list of options separated by commas.command_line_interface.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.command_line_interface/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.command_line_interface/#include &lt;google/protobuf/compiler/command_line_interface.h&gt; +namespace google::protobuf::compiler +Implements the Protocol Compiler front-end such that it may be reused by custom compilers written to support other languages. Classes in this fileCommandLineInterfaceThis class implements the command-line interface to the protocol compiler. class CommandLineInterface#include &lt;google/protobuf/compiler/command_line_interface.h&gt; +namespace google::protobuf::compiler +This class implements the command-line interface to the protocol compiler. It is designed to make it very easy to create a custom protocol compiler supporting the languages of your choice.cpp_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.cpp_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.cpp_generator/#include &lt;google/protobuf/compiler/cpp/cpp_generator.h&gt; +namespace google::protobuf::compiler::cpp +Generates C++ code for a given .proto file. Classes in this fileCppGeneratorCodeGenerator implementation which generates a C++ source file and header. class CppGenerator: public CodeGenerator#include &lt;google/protobuf/compiler/cpp/cpp_generator.h&gt; +namespace google::protobuf::compiler::cpp +CodeGenerator implementation which generates a C++ source file and header. If you create your own protocol compiler binary and you want it to support C++ output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.csharp_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.csharp_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.csharp_generator/#include &lt;google/protobuf/compiler/csharp/csharp_generator.h&gt; +namespace google::protobuf::compiler::csharp +Generates C# code for a given .proto file. Classes in this fileGeneratorCodeGenerator implementation which generates a C# source file and header. class Generator: public CodeGenerator#include &lt;google/protobuf/compiler/csharp/csharp_generator.h&gt; +namespace google::protobuf::compiler::csharp +CodeGenerator implementation which generates a C# source file and header. If you create your own protocol compiler binary and you want it to support C# output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.csharp_names.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.csharp_names/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.csharp_names/#include &lt;google/protobuf/compiler/csharp/csharp_names.h&gt; +namespace google::protobuf::compiler::csharp +Provides a mechanism for mapping a descriptor to the fully-qualified name of the corresponding C# class. Classes in this fileFile MembersThese definitions are not part of any class.std::stringGetFileNamespace(const FileDescriptor * descriptor)Requires: more...std::stringGetClassName(const Descriptor * descriptor)Requires: more...std::stringGetReflectionClassName(const FileDescriptor * descriptor)Requires: more...std::stringGetOutputFile(const FileDescriptor * descriptor, const std::string file_extension, const bool generate_directories, const std::string base_namespace, std::string * error)Generates output file name for given file descriptor. more... std::string csharp::GetFileNamespace( +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const FileDescriptor * descriptor)Requires: descriptor !importer.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.importer/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.importer/#include &lt;google/protobuf/compiler/importer.h&gt; +namespace google::protobuf::compiler +This file is the public interface to the .proto file parser. Classes in this fileSourceTreeDescriptorDatabaseAn implementation of DescriptorDatabase which loads files from a SourceTree and parses them. ImporterSimple interface for parsing .proto files. MultiFileErrorCollectorIf the importer encounters problems while trying to import the proto files, it reports them to a MultiFileErrorCollector. SourceTreeAbstract interface which represents a directory tree containing proto files. DiskSourceTreeAn implementation of SourceTree which loads files from locations on disk.java_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.java_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.java_generator/#include &lt;google/protobuf/compiler/java/java_generator.h&gt; +namespace google::protobuf::compiler::java +Generates Java code for a given .proto file. Classes in this fileJavaGeneratorCodeGenerator implementation which generates Java code. class JavaGenerator: public CodeGenerator#include &lt;google/protobuf/compiler/java/java_generator.h&gt; +namespace google::protobuf::compiler::java +CodeGenerator implementation which generates Java code. If you create your own protocol compiler binary and you want it to support Java output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function. MembersJavaGenerator()~JavaGenerator()implements CodeGeneratorvirtual boolGenerate(const FileDescriptor * file, const std::string &amp; parameter, GeneratorContext * generator_context, std::string * error) constGenerates code for the given proto file, generating one or more files in the given output directory.java_names.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.java_names/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.java_names/#include &lt;google/protobuf/compiler/java/java_names.h&gt; +namespace google::protobuf::compiler::java +Provides a mechanism for mapping a descriptor to the fully-qualified name of the corresponding Java class. Classes in this fileFile MembersThese definitions are not part of any class.std::stringClassName(const Descriptor * descriptor)Requires: more...std::stringClassName(const EnumDescriptor * descriptor)Requires: more...std::stringClassName(const FileDescriptor * descriptor)Requires: more...std::stringClassName(const ServiceDescriptor * descriptor)Requires: more...std::stringFileJavaPackage(const FileDescriptor * descriptor)Requires: more...std::stringCapitalizedFieldName(const FieldDescriptor * descriptor)Requires: more... std::string java::ClassName( +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const Descriptor * descriptor)Requires: descriptor != NULL Returns: The fully-qualified Java class name.javanano_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.javanano_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.javanano_generator/#include &lt;google/protobuf/compiler/javanano/javanano_generator.h&gt; +namespace google::protobuf::compiler::javanano +Generates Java nano code for a given .proto file. Classes in this fileJavaNanoGeneratorCodeGenerator implementation which generates Java nano code. class JavaNanoGenerator: public CodeGenerator#include &lt;google/protobuf/compiler/javanano/javanano_generator.h&gt; +namespace google::protobuf::compiler::javanano +CodeGenerator implementation which generates Java nano code. If you create your own protocol compiler binary and you want it to support Java output for the nano runtime, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.js_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.js_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.js_generator/#include &lt;google/protobuf/compiler/js/js_generator.h&gt; +namespace google::protobuf::compiler::js +Generates JavaScript code for a given .proto file. Classes in this fileGeneratorOptionsGeneratorCodeGenerator implementation which generates a JavaScript source file and header. struct GeneratorOptions#include &lt;google/protobuf/compiler/js/js_generator.h&gt; +namespace google::protobuf::compiler::js +MembersenumImportStyleWhat style of imports should be used. more...enumOutputMode more...std::stringoutput_dirOutput path. std::stringnamespace_prefixNamespace prefix. boolbinaryEnable binary-format support? enum google::protobuf::compiler::js::GeneratorOptions::ImportStyleimport_stylebooladd_require_for_enumsAdd a goog.requires() call for each enum type used. more...booltestonlySet this as a test-only module via goog.setTestOnly();. std::stringlibraryCreate a library with name &lt;name&gt;_lib.js rather than a separate .objectivec_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.objectivec_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.objectivec_generator/#include &lt;google/protobuf/compiler/objectivec/objectivec_generator.h&gt; +namespace google::protobuf::compiler::objectivec +Generates ObjectiveC code for a given .proto file. Classes in this fileObjectiveCGeneratorCodeGenerator implementation which generates a ObjectiveC source file and header. class ObjectiveCGenerator: public CodeGenerator#include &lt;google/protobuf/compiler/objectivec/objectivec_generator.h&gt; +namespace google::protobuf::compiler::objectivec +CodeGenerator implementation which generates a ObjectiveC source file and header. If you create your own protocol compiler binary and you want it to support ObjectiveC output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.objectivec_helpers.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.objectivec_helpers/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.objectivec_helpers/#include &lt;google/protobuf/compiler/objectivec/objectivec_helpers.h&gt; +namespace google::protobuf::compiler::objectivec +Helper functions for generating ObjectiveC code. Classes in this fileOptionsGenerator options (see objectivec_generator.cc for a description of each): TextFormatDecodeDataGenerate decode data needed for ObjC's GPBDecodeTextFormatName() to transform the input into the expected output. LineConsumerHelper for parsing simple files. ImportWriterHelper class for parsing framework import mappings and generating import statements. File MembersThese definitions are not part of any class.enumObjectiveCType more...enumFlagType more...const char *constProtobufLibraryFrameworkNameThe name the commonly used by the library when built as a framework.parser.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.parser/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.parser/#include &lt;google/protobuf/compiler/parser.h&gt; +namespace google::protobuf::compiler +Implements parsing of .proto files to FileDescriptorProtos. Classes in this fileParserImplements parsing of protocol definitions (such as .proto files). SourceLocationTableA table mapping (descriptor, ErrorLocation) pairs &ndash; as reported by DescriptorPool when validating descriptors &ndash; to line and column numbers within the original source code. class Parser#include &lt;google/protobuf/compiler/parser.h&gt; +namespace google::protobuf::compiler +Implements parsing of protocol definitions (such as .proto files). Note that most users will be more interested in the Importer class.plugin.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.plugin/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.plugin/#include &lt;google/protobuf/compiler/plugin.h&gt; +namespace google::protobuf::compiler +Front-end for protoc code generator plugins written in C++. To implement a protoc plugin in C++, simply write an implementation of CodeGenerator, then create a main() function like: int main(int argc, char* argv[]) { MyCodeGenerator generator; return google::protobuf::compiler::PluginMain(argc, argv, &amp;generator); } You must link your plugin against libprotobuf and libprotoc. +The core part of PluginMain is to invoke the given CodeGenerator on a CodeGeneratorRequest to generate a CodeGeneratorResponse.plugin.pb.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb/#include &lt;google/protobuf/compiler/plugin.pb.h&gt; +namespace google::protobuf::compiler +API for protoc plugins. +This file defines a set of protocol message classes which make up the API to protoc code generator plugins. Plugins written in C++ should probably build on the API in plugin.h instead of dealing with the protobuf-level API, but plugins in other languages will need to deal with the raw messages as defined below. +The protocol compiler currently doesn't support auto-generated documentation, hence this page contains no descriptions.python_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.python_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.python_generator/#include &lt;google/protobuf/compiler/python/python_generator.h&gt; +namespace google::protobuf::compiler::python +Generates Python code for a given .proto file. Classes in this fileGeneratorCodeGenerator implementation for generated Python protocol buffer classes. class Generator: public CodeGenerator#include &lt;google/protobuf/compiler/python/python_generator.h&gt; +namespace google::protobuf::compiler::python +CodeGenerator implementation for generated Python protocol buffer classes. If you create your own protocol compiler binary and you want it to support Python output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.ruby_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.ruby_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.ruby_generator/#include &lt;google/protobuf/compiler/ruby/ruby_generator.h&gt; +namespace google::protobuf::compiler::ruby +Generates Ruby code for a given .proto file. Classes in this fileGeneratorCodeGenerator implementation for generated Ruby protocol buffer classes. class Generator: public CodeGenerator#include &lt;google/protobuf/compiler/ruby/ruby_generator.h&gt; +namespace google::protobuf::compiler::ruby +CodeGenerator implementation for generated Ruby protocol buffer classes. If you create your own protocol compiler binary and you want it to support Ruby output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.descriptor.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.descriptor/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.descriptor/#include &lt;google/protobuf/descriptor.h&gt; +namespace google::protobuf +This file contains classes which describe a type of protocol message. You can use a message's descriptor to learn at runtime what fields it contains and what the types of those fields are. The Message interface also allows you to dynamically access and modify individual fields by passing the FieldDescriptor of the field you are interested in. +Most users will not care about descriptors, because they will write code specific to certain protocol types and will simply use the classes generated by the protocol compiler directly.descriptor.pb.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.descriptor.pb/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.descriptor.pb/#include &lt;google/protobuf/descriptor.pb.h&gt; +namespace google::protobuf +Protocol buffer representations of descriptors. +This file defines a set of protocol message classes which represent the same information represented by the classes defined in descriptor.h. You can convert a FileDescriptorProto to a FileDescriptor using the DescriptorPool class. Thus, the classes in this file allow protocol type definitions to be communicated efficiently between processes. +The protocol compiler currently doesn't support auto-generated documentation, hence this page contains no descriptions.descriptor_database.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.descriptor_database/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.descriptor_database/#include &lt;google/protobuf/descriptor_database.h&gt; +namespace google::protobuf +Interface for manipulating databases of descriptors. Classes in this fileDescriptorDatabaseAbstract interface for a database of descriptors. SimpleDescriptorDatabaseA DescriptorDatabase into which you can insert files manually. EncodedDescriptorDatabaseVery similar to SimpleDescriptorDatabase, but stores all the descriptors as raw bytes and generally tries to use as little memory as possible. DescriptorPoolDatabaseA DescriptorDatabase that fetches files from a given pool. MergedDescriptorDatabaseA DescriptorDatabase that wraps two or more others. class DescriptorDatabase#include &lt;google/protobuf/descriptor_database.dynamic_message.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.dynamic_message/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.dynamic_message/#include &lt;google/protobuf/dynamic_message.h&gt; +namespace google::protobuf +Defines an implementation of Message which can emulate types which are not known at compile-time. Classes in this fileDynamicMessageFactoryConstructs implementations of Message which can emulate types which are not known at compile-time. DynamicMapSorterHelper for computing a sorted list of map entries via reflection. class DynamicMessageFactory: public MessageFactory#include &lt;google/protobuf/dynamic_message.h&gt; +namespace google::protobuf +Constructs implementations of Message which can emulate types which are not known at compile-time. Sometimes you want to be able to manipulate protocol types that you don't know about at compile time.coded_stream.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.coded_stream/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.coded_stream/#include &lt;google/protobuf/io/coded_stream.h&gt; +namespace google::protobuf::io +This file contains the CodedInputStream and CodedOutputStream classes, which wrap a ZeroCopyInputStream or ZeroCopyOutputStream, respectively, and allow you to read or write individual pieces of data in various formats. In particular, these implement the varint encoding for integers, a simple variable-length encoding in which smaller numbers take fewer bytes. +Typically these classes will only be used internally by the protocol buffer library in order to encode and decode protocol buffers.gzip_stream.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.gzip_stream/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.gzip_stream/#include &lt;google/protobuf/io/gzip_stream.h&gt; +namespace google::protobuf::io +This file contains the definition for classes GzipInputStream and GzipOutputStream. GzipInputStream decompresses data from an underlying ZeroCopyInputStream and provides the decompressed data as a ZeroCopyInputStream. +GzipOutputStream is an ZeroCopyOutputStream that compresses data to an underlying ZeroCopyOutputStream. Classes in this fileGzipInputStreamA ZeroCopyInputStream that reads compressed data through zlib. GzipOutputStreamGzipOutputStream::Optionsclass GzipInputStream: public ZeroCopyInputStream#include &lt;google/protobuf/io/gzip_stream.h&gt; +namespace google::protobuf::io +A ZeroCopyInputStream that reads compressed data through zlib. MembersenumFormatFormat key for constructor. more.printer.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.printer/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.printer/#include &lt;google/protobuf/io/printer.h&gt; +namespace google::protobuf::io +Utility class for writing text to a ZeroCopyOutputStream. Classes in this fileAnnotationCollectorRecords annotations about a Printer's output. AnnotationProtoCollectorRecords annotations about a Printer's output to the given protocol buffer, assuming that the buffer has an ::Annotation message exposing path, source_file, begin and end fields. Printerclass AnnotationCollector#include &lt;google/protobuf/io/printer.h&gt; +namespace google::protobuf::io +Records annotations about a Printer's output. Known subclasses: +AnnotationProtoCollector< AnnotationProto >Memberstypedefstd::pair&lt; std::pair&lt; size_t, size_t &gt;, std::string &gt; AnnotationAnnotation is a offset range and a payload pair.tokenizer.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.tokenizer/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.tokenizer/#include &lt;google/protobuf/io/tokenizer.h&gt; +namespace google::protobuf::io +Class for parsing tokenized text from a ZeroCopyInputStream. Classes in this fileErrorCollectorAbstract interface for an object which collects the errors that occur during parsing. TokenizerThis class converts a stream of raw text into a stream of tokens for the protocol definition parser to parse. Tokenizer::TokenStructure representing a token read from the token stream. File MembersThese definitions are not part of any class.typedefint ColumnNumberBy "column number", the proto compiler refers to a count of the number of bytes before a given byte, except that a tab character advances to the next multiple of 8 bytes.zero_copy_stream.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream/#include &lt;google/protobuf/io/zero_copy_stream.h&gt; +namespace google::protobuf::io +This file contains the ZeroCopyInputStream and ZeroCopyOutputStream interfaces, which represent abstract I/O streams to and from which protocol buffers can be read and written. For a few simple implementations of these interfaces, see zero_copy_stream_impl.h. +These interfaces are different from classic I/O streams in that they try to minimize the amount of data copying that needs to be done. To accomplish this, responsibility for allocating buffers is moved to the stream object, rather than being the responsibility of the caller.zero_copy_stream_impl.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl/#include &lt;google/protobuf/io/zero_copy_stream_impl.h&gt; +namespace google::protobuf::io +This file contains common implementations of the interfaces defined in zero_copy_stream.h which are only included in the full (non-lite) protobuf library. These implementations include Unix file descriptors and C++ iostreams. See also: zero_copy_stream_impl_lite.h Classes in this fileFileInputStreamA ZeroCopyInputStream which reads from a file descriptor. FileOutputStreamA ZeroCopyOutputStream which writes to a file descriptor. IstreamInputStreamA ZeroCopyInputStream which reads from a C++ istream. OstreamOutputStreamA ZeroCopyOutputStream which writes to a C++ ostream.zero_copy_stream_iml_lite.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl_lite/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl_lite/#include &lt;google/protobuf/io/zero_copy_stream_impl_lite.h&gt; +namespace google::protobuf::io +This file contains common implementations of the interfaces defined in zero_copy_stream.h which are included in the "lite" protobuf library. These implementations cover I/O on raw arrays and strings, as well as adaptors which make it easy to implement streams based on traditional streams. Of course, many users will probably want to write their own implementations of these interfaces specific to the particular I/O abstractions they prefer to use, but these should cover the most common cases.map.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.map/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.map/#include &lt;google/protobuf/map.h&gt; +namespace google::protobuf +This file defines the map container and its helpers to support protobuf maps. The Map and MapIterator types are provided by this header file. Please avoid using other types defined here, unless they are public types within Map or MapIterator, such as Map::value_type. Classes in this fileMapPairThis is the class for Map's internal value_type. MapMap is an associative container type used to store protobuf map fields. Map::const_iteratorIterators.message.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.message/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.message/#include &lt;google/protobuf/message.h&gt; +namespace google::protobuf +Defines Message, the abstract interface implemented by non-lite protocol message objects. Although it's possible to implement this interface manually, most users will use the protocol compiler to generate implementations. +Example usage: +Say you have a message defined as: +message Foo { optional string text = 1; repeated int32 numbers = 2; } Then, if you used the protocol compiler to generate a class from the above definition, you could use it like so:message_lite.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.message_lite/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.message_lite/#include &lt;google/protobuf/message_lite.h&gt; +namespace google::protobuf +Defines MessageLite, the abstract interface implemented by all (lite and non-lite) protocol message objects. Classes in this fileMessageLiteInterface to light weight protocol messages. File MembersThese definitions are not part of any class.voidShutdownProtobufLibrary()Shut down the entire protocol buffers library, deleting all static-duration objects allocated by the library or by generated .pb.cc files. more... void protobuf::ShutdownProtobufLibrary()Shut down the entire protocol buffers library, deleting all static-duration objects allocated by the library or by generated .repeated_field.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.repeated_field/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.repeated_field/#include &lt;google/protobuf/repeated_field.h&gt; +namespace google::protobuf +RepeatedField and RepeatedPtrField are used by generated protocol message classes to manipulate repeated fields. These classes are very similar to STL's vector, but include a number of optimizations found to be useful specifically in the case of Protocol Buffers. RepeatedPtrField is particularly different from STL vector as it manages ownership of the pointers that it contains. +Typically, clients should not need to access RepeatedField objects directly, but should instead use the accessor functions generated automatically by the protocol compiler.service.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.service/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.service/#include &lt;google/protobuf/service.h&gt; +namespace google::protobuf +DEPRECATED: This module declares the abstract interfaces underlying proto2 RPC services. These are intended to be independent of any particular RPC implementation, so that proto2 services can be used on top of a variety of implementations. Starting with version 2.3.0, RPC implementations should not try to build on these, but should instead provide code generator plugins which generate code specific to the particular RPC implementation. This way the generated code can be more appropriate for the implementation in use and can avoid unnecessary layers of indirection.text_format.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.text_format/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.text_format/#include &lt;google/protobuf/text_format.h&gt; +namespace google::protobuf +Utilities for printing and parsing protocol messages in a human-readable, text-based format. Classes in this fileTextFormatThis class implements protocol buffer text format, colloquially known as text proto. TextFormat::BaseTextGeneratorTextFormat::FastFieldValuePrinterThe default printer that converts scalar values from fields into their string representation. TextFormat::FieldValuePrinterDeprecated: please use FastFieldValuePrinter instead. TextFormat::FinderInterface that Printers or Parsers can use to find extensions, or types referenced in Any messages. TextFormat::MessagePrinterTextFormat::ParseInfoTreeData structure which is populated with the locations of each field value parsed from the text.unknown_field_set.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.unknown_field_set/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.unknown_field_set/#include &lt;google/protobuf/unknown_field_set.h&gt; +namespace google::protobuf +Contains classes used to keep track of unrecognized fields seen while parsing a protocol message. Classes in this fileUnknownFieldSetAn UnknownFieldSet contains fields that were encountered while parsing a message but were not defined by its type. UnknownFieldRepresents one field in an UnknownFieldSet. UnknownField::LengthDelimitedclass UnknownFieldSet#include &lt;google/protobuf/unknown_field_set.h&gt; +namespace google::protobuf +An UnknownFieldSet contains fields that were encountered while parsing a message but were not defined by its type. Keeping track of these can be useful, especially in that they may be written if the message is serialized again without being cleared in between.field_comparator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.field_comparator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.field_comparator/#include &lt;google/protobuf/util/field_comparator.h&gt; +namespace google::protobuf::util +Defines classes for field comparison. Classes in this fileFieldComparatorBase class specifying the interface for comparing protocol buffer fields. SimpleFieldComparatorBasic implementation of FieldComparator. DefaultFieldComparatorclass FieldComparator#include &lt;google/protobuf/util/field_comparator.h&gt; +namespace google::protobuf::util +Base class specifying the interface for comparing protocol buffer fields. Regular users should consider using or subclassing DefaultFieldComparator rather than this interface. Currently, this does not support comparing unknown fields. Known subclasses: +SimpleFieldComparatorMembersenumComparisonResult more...FieldComparator()virtual ~FieldComparator()virtual ComparisonResultCompare(const Message &amp; message_1, const Message &amp; message_2, const FieldDescriptor * field, int index_1, int index_2, const util::FieldContext * field_context) = 0Compares the values of a field in two protocol buffer messages.field_mask_util.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.field_mask_util/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.field_mask_util/#include &lt;google/protobuf/util/field_mask_util.h&gt; +namespace google::protobuf::util +Defines utilities for the FieldMask well known type. Classes in this fileFieldMaskUtilFieldMaskUtil::MergeOptionsFieldMaskUtil::TrimOptionsclass FieldMaskUtil#include &lt;google/protobuf/util/field_mask_util.h&gt; +namespace google::protobuf::util +Membersstatic std::stringToString(const FieldMask &amp; mask)Converts FieldMask to/from string, formatted by separating each path with a comma (e.g., "foo_bar,baz.quz"). static voidFromString(StringPiece str, FieldMask * out)template static voidFromFieldNumbers(const std::vector&lt; int64_t &gt; &amp; field_numbers, FieldMask * out)Populates the FieldMask with the paths corresponding to the fields with the given numbers, after checking that all field numbers are valid.json_util.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.json_util/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.json_util/#include &lt;google/protobuf/util/json_util.h&gt; +namespace google::protobuf::util +Utility functions to convert between protobuf binary format and proto3 JSON format. Classes in this fileJsonParseOptionsJsonPrintOptionsFile MembersThese definitions are not part of any class.typedefJsonPrintOptions JsonOptionsDEPRECATED. Use JsonPrintOptions instead. util::StatusMessageToJsonString(const Message &amp; message, std::string * output, const JsonOptions &amp; options)Converts from protobuf message to JSON and appends it to |output|. more...util::StatusMessageToJsonString(const Message &amp; message, std::string * output)util::StatusJsonStringToMessage(StringPiece input, Message * message, const JsonParseOptions &amp; options)Converts from JSON to protobuf message.message_differencer.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.message_differencer/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.message_differencer/#include &lt;google/protobuf/util/message_differencer.h&gt; +namespace google::protobuf::util +This file defines static methods and classes for comparing Protocol Messages. Aug. 2008: Added Unknown Fields Comparison for messages. Aug. 2009: Added different options to compare repeated fields. Apr. 2010: Moved field comparison to FieldComparator Sep. 2020: Added option to output map keys in path Classes in this fileMessageDifferencerA basic differencer that can be used to determine the differences between two specified Protocol Messages. MessageDifferencer::IgnoreCriteriaAbstract base class from which all IgnoreCriteria derive.time_util.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.time_util/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.time_util/#include &lt;google/protobuf/util/time_util.h&gt; +namespace google::protobuf::util +Defines utilities for the Timestamp and Duration well known types. Classes in this fileTimeUtilUtility functions for Timestamp and Duration. class TimeUtil#include &lt;google/protobuf/util/time_util.h&gt; +namespace google::protobuf::util +Utility functions for Timestamp and Duration. Membersconst int64_tkTimestampMinSeconds = = -62135596800LLThe min/max Timestamp/Duration values we support. more...const int64_tkTimestampMaxSeconds = = 253402300799LLFor "9999-12-31T23:59:59.999999999Z". const int64_tkDurationMinSeconds = = -315576000000LLconst int64_tkDurationMaxSeconds = = 315576000000LLstatic std::stringToString(const Timestamp &amp; timestamp)Converts Timestamp to/from RFC 3339 date string format. more.type_resolver.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.type_resolver/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.type_resolver/#include &lt;google/protobuf/util/type_resolver.h&gt; +namespace google::protobuf::util +Defines a TypeResolver for the Any message. Classes in this fileTypeResolverAbstract interface for a type resolver. class TypeResolver#include &lt;google/protobuf/util/type_resolver.h&gt; +namespace google::protobuf::util +Abstract interface for a type resolver. Implementations of this interface must be thread-safe. MembersTypeResolver()virtual ~TypeResolver()virtual util::StatusResolveMessageType(const std::string &amp; type_url, google::protobuf::Type * message_type) = 0Resolves a type url for a message type. virtual util::StatusResolveEnumType(const std::string &amp; type_url, google::protobuf::Enum * enum_type) = 0Resolves a type url for an enum type.type_resolver_util.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.type_resolver_util/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.type_resolver_util/#include &lt;google/protobuf/util/type_resolver_util.h&gt; +namespace google::protobuf::util +Defines utilities for the TypeResolver. Classes in this fileFile MembersThese definitions are not part of any class.TypeResolver *NewTypeResolverForDescriptorPool(const std::string &amp; url_prefix, const DescriptorPool * pool)Creates a TypeResolver that serves type information in the given descriptor pool. more... TypeResolver * util::NewTypeResolverForDescriptorPool( +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const std::string &amp; url_prefix, +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const DescriptorPool * pool)Creates a TypeResolver that serves type information in the given descriptor pool. Caller takes ownership of the returned TypeResolver.Changes announced on December 13, 2023https://protobuf.dev/news/2023-12-13/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-12-13/C++ Breaking Changes In v26, we are planning a major version bump for C++ as per our breaking changes policy and version support policy. +The following sections outline the set of breaking changes that we plan to include in the 26.0 release of protocol buffers. Note that plans can and do change. These are potential breaking changes to be aware of, but they may not happen in this particular release, or they may not happen at all.Changes announced December 13, 2024https://protobuf.dev/news/2024-12-13/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-12-13/Removing a Reflection-related Function In v30.x, we are removing the following reflection-related function: MutableRepeatedFieldRef&lt;T&gt;::Reserve(). +An upcoming performance improvement in RepeatedPtrField is incompatible with this API. The improvement is projected to accelerate repeated access to the elements of RepeatedPtrField, in particular and especially sequential access.Changes announced December 18, 2024https://protobuf.dev/news/2024-12-18/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-12-18/Go Protobuf: The new Opaque API Back in March 2020, we released the google.golang.org/protobuf module, a major overhaul of the Go Protobuf API. This package introduced first-class support for reflection, a dynamicpb implementation and the protocmp package for easier testing. +That release introduced a new protobuf module with a new API. Today, we are releasing an additional API for generated code, meaning the Go code in the .pb.go files created by the protocol compiler (protoc).Changes announced on December 27, 2023https://protobuf.dev/news/2023-12-27/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-12-27/Ruby Breaking Changes The following changes are planned for the 26.x line: +Fix RepeatedField#each_index to have the correct semantics. (#11767) Remove Ruby DSL and associated compatibility code, which will complete the migration announced in April. Message#to_h fixes: Remove unset oneof fields. (#6167) Remove unset sub-message fields Use message&rsquo;s pool for encode_json/decode_json. Remove the deprecated syntax accessor, FileDescriptor.syntax and add semantic checks in its place: FieldDescriptor.has_presence to test if a field has presence.Changes announced December 4, 2024https://protobuf.dev/news/2024-12-04/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-12-04/We are planning to modify the Protobuf debug APIs for C++ (including Protobuf AbslStringify, proto2::ShortFormat, proto2::Utf8Format, Message::DebugString, Message::ShortDebugString, Message::Utf8DebugString) in v30 to redact sensitive fields annotated by debug_redact; the outputs of these APIs will contain a per-process randomized prefix, and so will no longer be parseable by Protobuf TextFormat Parsers. +Motivation Currently Protobuf debug APIs print every field in a proto into human-readable formats. This may lead to privacy incidents where developers accidentally log Protobuf debug outputs containing sensitive fields.Changes announced on December 5, 2023https://protobuf.dev/news/2023-12-05/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-12-05/Java Breaking Changes In v26, we are planning a major version bump for Java per our breaking changes policy and version support policy. +The following sections outline the set of breaking changes that we plan to include in the 26.0 release of protocol buffers. Note that plans can and do change. These are potential breaking changes to be aware of, but they may not happen in this particular release, or they may not happen at all.Changes Announced on February 27, 2024https://protobuf.dev/news/2024-02-27/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-02-27/Dropping Ruby 2.7 Support As per our official Ruby support policy, we will be dropping support for Ruby 2.7 and lower on March 31, 2024. The minimum supported Ruby version will be 3.0.Changes announced February 5, 2024https://protobuf.dev/news/2024-02-05/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-02-05/This topic covers breaking changes in Java, C++, and Python in the 26.x line. +JSON Formatter Option Changes Starting in the 26.x line, the JSON formatter option to print default-valued fields is replaced with a fixed way to handle proto2 and proto3 optional fields consistently. +Java: includingDefaultValueFields() is replaced with alwaysPrintFieldsWithNoPresence(). C++: always_print_default_values is replaced with always_print_fields_with_no_presence=True. Py: including_default_value_fields=True is replaced with always_print_fields_with_no_presence=True. The new flag behaves identically to the old flag on proto3 messages, but no longer applies to proto2 optional fields.Changes Announced on January 16, 2026https://protobuf.dev/news/2026-01-16/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2026-01-16/Prebuilt proto compiler (protoc) for Bazel In an effort to speed up builds, protobuf 33.4 offers an option to skip re-compiling Protobuf tools and runtimes and use a pre-built protoc binary, available to Bazel 7 and later. Using a pre-built protoc also avoids build failures from incompatible or non-hermetic C++ compilation toolchain installed on your machine. +To use the prebuilt protoc, upgrade to protobuf version 33.4 or later, and set the --incompatible_enable_proto_toolchain_resolution and --@protobuf//bazel/flags:prefer_prebuilt_protoc flags.Changes announced January 23, 2025https://protobuf.dev/news/2025-01-23/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2025-01-23/Poison Java gencode We are patching a change into the 25.x branch that will poison Java gencode that was created prior to the 3.21.7 release. We will then mark all versions of Java protobuf from 3.21.7 through 3.25.5 as vulnerable to the footmitten CVE. +After this change is patched in, protobuf will throw an UnsupportedOperationException from the makeExtensionsImmutable method unless you set the system property &ldquo;-Dcom.google.protobuf.use_unsafe_pre22_gencode&rdquo;. Using this system property can buy you some time if you can&rsquo;t update your code immediately, but should be considered a short-term workaround.Changes announced January 31, 2024https://protobuf.dev/news/2024-01-31/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-01-31/This topic covers breaking changes in Python in the 26.x line. +Python Breaking Changes Removing setup.py and setup.cfg support from GitHub In the 26.x release, setup.py and setup.cfg will no longer be present in the python/ directory of the GitHub repository or GitHub release tarballs. This means it will no longer be possible to build a Python package directly from the GitHub repo or release tarball. +The Python source packages published on PyPI will continue to have a setup.Changes announced January 5, 2024https://protobuf.dev/news/2024-01-05/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-01-05/This topic covers breaking changes in Ruby and Python in the 26.x line. +Ruby Breaking Changes Freeze Is Now Recursive in Ruby Starting in the 26.x line, when freeze is applied it will be applied recursively, affecting all sub-messages, maps, and repeated fields. +Python Breaking Changes Removing Deprecated APIs In the 26.x release, the following deprecated APIs will be removed: +AddFileDescriptor AddDescriptor AddEnumDescriptor AddExtensionDescriptor AddServiceDescriptor Rejecting Extend Repeated Field with None Iterable Starting in the 26.Changes Announced on July 14, 2025https://protobuf.dev/news/2025-07-14/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2025-07-14/Deprecating FieldDescriptor Enums We are announcing an upcoming change regarding the FieldDescriptor enum and its associated values representing optional, required, and repeated. These are being deprecated as we encourage the use of more precise accessor methods. +Background While at one time the FieldDescriptor.label enum served a purpose, the evolution of Protocol Buffers has introduced more idiomatic ways to determine a field&rsquo;s cardinality (singular/repeated) and presence semantics. +In proto2, optional, required, and repeated are explicit keywords.Changes Announced on July 16, 2025https://protobuf.dev/news/2025-07-16/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2025-07-16/Retaining support for Bazel with MSVC We announced on January 23, 2025 that we were planning to drop support for using Bazel and MSVC together starting in v34. This plan is canceled due to Bazel&rsquo;s upcoming changes to virtual includes on Windows. Clang-cl support will be kept in place as an alternative on Windows. The opt-out flag --define=protobuf_allow_msvc=true will no longer be required as of the 32.0 release.Changes Announced on July 17, 2023https://protobuf.dev/news/2023-07-17/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-07-17/Dropping Bazel 5.x Support As per our official support policy, we will be dropping support for Bazel 5.x and lower. This means the minimum supported Bazel version is 6.2.x.Changes announced July 6, 2022https://protobuf.dev/news/2022-07-06/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2022-07-06/Library Breaking Change Policy Google released its OSS Library Breaking Change Policy, which some Google-sponsored open source projects have opted into. Protocol buffers has adopted this policy.Changes Announced on July 6, 2023https://protobuf.dev/news/2023-07-06/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-07-06/Dropping PHP 7.x Support As per our official PHP support policy, we will be dropping support for PHP 7.4 and lower. This means the minimum supported PHP version is 8.0. +If you are running an older version of PHP, you can install a previous release of the protobuf PHP extension by running pecl install protobuf-3.23.3. +Dropping Ruby 2.6 Support As per our official Ruby support policy, we will be dropping support for Ruby 2.Changes Announced on June 26, 2024https://protobuf.dev/news/2024-06-26/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-06-26/Dropping Support for Building Protobuf Java from Source with Maven We are planning to drop support for building Protobuf Java OSS from source with the Maven build system in the Protobuf Java 4.28 release. This has been marked deprecated in the 4.27 release. +After this point, you can continue to use Bazel, or another build system, to build Protobuf. You can read more about building from source in the Protobuf Java README.Changes Announced on June 27, 2025https://protobuf.dev/news/2025-06-27/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2025-06-27/Edition 2024 We are planning to release Protobuf Edition 2024 in 32.x in Q3 2025. +These describe changes as we anticipate them being implemented, but due to the flexible nature of software some of these changes may not land or may vary from how they are described in this topic. +More documentation on Edition 2024 will be published in Feature Settings for Editions, including information on migrating from Edition 2023.Changes Announced on June 29, 2023https://protobuf.dev/news/2023-06-29/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-06-29/TL;DR: We are planning to release Protobuf Editions to the open source project in the second half of 2023. While there is no requirement to move from proto2/proto3 syntax to Editions syntax at initial release, we encourage you to plan a move in your software project&rsquo;s future timeline. +Protobuf Editions Protobuf Editions replace the proto2 and proto3 designations that we have used for Protocol Buffers. Instead of adding syntax = &quot;proto2&quot; or syntax = &quot;proto3&quot; at the top of proto definition files, you use an edition number, such as edition = &quot;2024&quot;, to specify the default behaviors your file will have.Changes Announced on March 13, 2026https://protobuf.dev/news/2026-03-13/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2026-03-13/Changes in Bazel Migration of Proto Flags to Starlark --proto_toolchain_for* and --proto_compiler are no longer read by Proto rules. These toolchain-related flags are deprecated and will be removed in the future. Switching to the equivalent Starlark versions of the flags is a short-term fix: +--@protobuf//bazel/flags/cc:proto_toolchain_for_cc --@protobuf//bazel/flags/java:proto_toolchain_for_java --@protobuf//bazel/flags/java:proto_toolchain_for_javalite --@protobuf//bazel/flags:proto_compiler The longer-term fix is to enable --incompatible_enable_proto_toolchain_resolution (which is the default in Bazel 9 anyway) and to register toolchains using the normal platforms-related mechanisms (register_toolchain() in MODULE.Changes Announced on March 18, 2025https://protobuf.dev/news/2025-03-18/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2025-03-18/Dropping Ruby 3.0 Support As per our official Ruby support policy, we will be dropping support for Ruby 3.0 and lower in Protobuf version 31, due to release in April, 2025. The minimum supported Ruby version will be 3.1.Changes announced May 6, 2022https://protobuf.dev/news/2022-05-06/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2022-05-06/Versioning We changed our versioning scheme to enable more-nimble updates to language-specific parts of Protocol Buffers. In the new scheme, each language has its own major version that can be incremented independently of other languages, as covered later in this topic with the Python release. The minor and patch versions, however, will remain coupled. This allows us to introduce breaking changes into some languages without requiring a bump of the major version in languages that do not experience a breaking change.Changes Announced on November 7, 2024https://protobuf.dev/news/2024-11-07/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-11-07/The following sections cover planned breaking changes in the v30 release, expected in 2025 Q1. Also included are some changes that aren&rsquo;t breaking but may require action on your part. These are in addition to those mentioned in the News article from October 2. +These describe changes as we anticipate them being implemented, but due to the flexible nature of software some of these changes may not land or may vary from how they are described in this topic.Changes Announced on October 1, 2024https://protobuf.dev/news/2024-10-01/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-10-01/Bazel and Proto Rules There are upcoming changes to the way that Bazel will work for protobuf builds. These changes require awareness in the first stage, and action by project owners before the second stage. +Stage 1 With the release of Bazel 8, proto rules (proto_library, cc_proto_library, java_proto_library, java_lite_proto_library, and py_proto_library) will be removed from the Bazel project. The will be added to the Protocol Buffers project in v29. Bazel will be updated to automatically use the rules from the protobuf project, so the change is initially a no-op for project owners.Changes announced on October 10, 2023https://protobuf.dev/news/2023-10-10/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-10-10/Protobuf Editions Features Documentation that introduces Protobuf Editions features is now available.Changes Announced on October 2, 2024https://protobuf.dev/news/2024-10-02/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-10-02/The following sections cover planned breaking changes in the v30 release, expected in 2025 Q1. These describe changes as we anticipate them being implemented, but due to the flexible nature of software some of these changes may not land or may vary from how they are described in this topic. +Changes in C++ C++ will bump its major version from 5.29.x to 6.30.x. +Descriptor APIs v30 will update return types in descriptor (such as full_name) to be absl::string_view.Search Resultshttps://protobuf.dev/search/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/search/Changes announced on September 15, 2023https://protobuf.dev/news/2023-09-15/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-09-15/μpb Moving to the Protobuf Git Repository Starting with the v25 release, μpb now lives in the protobuf repo instead of in its former location in a separate repo. All μpb development going forward will take place only in the new location. +The merger of the two repos will simplify and speed up our development process by removing the need to update pinned version dependencies between protobuf and μpb. Changes to μpb now take effect immediately in protobuf code and vice versa, without the need for a manual upgrade step.Changes Announced on September 19, 2025https://protobuf.dev/news/2025-09-19/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2025-09-19/The following sections cover planned breaking changes in the v34 release, expected in 2026 Q1. These describe changes as we anticipate them being implemented, but due to the flexible nature of software some of these changes may not land or may vary from how they are described in this topic. +Changes in C++ C++ will bump its major version to 7 with the 7.34.0 release. 6.33 will be the final minor version release on 6.News Announcements for Version 21.xhttps://protobuf.dev/news/v21/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v21/The following announcements are specific to Version 21.x, which was released May 25, 2022. For information presented chronologically, see News. +Python Updates We made some changes in Python language support in Protocol Buffers. Version 4.21.0 is a new major version, following 3.20.1. The new version is based on the upb library, and offers significantly better parsing performance than previous releases, especially for large payloads. It also includes prebuilt binary modules for Apple silicon for increased performance without a manual build.News Announcements for Version 22.xhttps://protobuf.dev/news/v22/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v22/The following announcements are specific to Version 22.x, which was released February 16, 2023. For information presented chronologically, see News. +Changing Maven Release Candidate Artifact Names to Be More Idiomatic In 22.0 we plan to rename Maven artifacts to use “RC” instead of “rc-” as the release candidate prefix. +Adding an Abseil Dependency In order to reduce the Google vs. OSS differences between protobuf and to simplify our own project, we plan to take a formal dependency on Abseil.News Announcements for Version 23.xhttps://protobuf.dev/news/v23/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v23/The following announcements are specific to Version 23.x, which was released May 8, 2023. For information presented chronologically, see News. +Changes to Ruby Generator This GitHub PR, which will appear in the 23.x release, changes the Ruby code generator to emit a serialized proto instead of the DSL. +It removes the DSL from the code generator in anticipation of splitting the DSL out into a separate package. +Given a .proto file like:News Announcements for Version 24.xhttps://protobuf.dev/news/v24/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v24/The following announcements are specific to Version 24.x, which was released August 8, 2023. For information presented chronologically, see News. +Stricter validation for json_name v24 will forbid embedded null characters in the json_name field option. Going forward, any valid Unicode characters will be accepted, except \u0000. Null will still be allowed in field values. +Previously, the proto compiler allowed null characters, but support for this was inconsistent across languages and implementations.News Announcements for Version 25.xhttps://protobuf.dev/news/v25/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v25/The following announcements are specific to Version 25.x, which was released November 1, 2023. For information presented chronologically, see News. +Python Breaking Change In v25 message.UnknownFields() will be deprecated in pure Python and C++ extensions. It will be removed in v26. Use the new UnknownFieldSet(message) support in unknown_fields.py as a replacement. +μpb Moving to the Protobuf Git Repository Starting with the v25 release, μpb now lives in the protobuf repo instead of in its former location in a separate repo.News Announcements for Version 26.xhttps://protobuf.dev/news/v26/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v26/The following announcements are specific to Version 26.x, which was released March 13, 2024. For information presented chronologically, see News. +General Changes JSON Formatter Option Changes Starting in the 26.x line, the JSON formatter option to print default-valued fields is replaced with a fixed way to handle proto2 and proto3 optional fields consistently. +Java: includingDefaultValueFields() is replaced with alwaysPrintFieldsWithNoPresence(). C++: always_print_default_values is replaced with always_print_fields_with_no_presence=True. Py: including_default_value_fields=True is replaced with always_print_fields_with_no_presence=True.News Announcements for Version 29.xhttps://protobuf.dev/news/v29/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v29/The following announcements are specific to Version 29.x, which was released November 27, 2024. For information presented chronologically, see News. +Bazel and Proto Rules There are upcoming changes to the way that Bazel will work for protobuf builds. These changes require awareness in the first stage, and action by project owners before the second stage. +Stage 1 With the release of Bazel 8, proto rules (proto_library, cc_proto_library, java_proto_library, java_lite_proto_library, and py_proto_library) will be removed from the Bazel project.News Announcements for Version 30.xhttps://protobuf.dev/news/v30/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v30/The following announcements are specific to Version 30.x, which was released March 4, 2025. For information presented chronologically, see News. +The following sections cover planned breaking changes in the v30 release, expected in 2025 Q1. Also included are some changes that aren&rsquo;t breaking but may require action on your part. These describe changes as we anticipate them being implemented, but due to the flexible nature of software some of these changes may not land or may vary from how they are described in this topic.News Announcements for Version 31.xhttps://protobuf.dev/news/v31/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v31/The following announcements are specific to Version 31.x, which was released May 14, 2025. For information presented chronologically, see News. +The following sections cover planned breaking changes in the v31 release, expected in 2025 Q2. Also included are some changes that aren&rsquo;t breaking but may require action on your part. These describe changes as we anticipate them being implemented, but due to the flexible nature of software some of these changes may not land or may vary from how they are described in this topic.News Announcements for Version 32.xhttps://protobuf.dev/news/v32/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v32/Changes to Existing Features This section details any existing features whose default settings will change in Edition 2024. +C++ string_type The default for string_type feature, originally released in Edition 2023, will change from STRING to VIEW in Edition 2024. +See features.(pb.cpp).string_type and String View APIs for more information on this feature and its feature values. +New Features This section details any new features that will be introduced in Edition 2024.News Announcements for Version 34.xhttps://protobuf.dev/news/v34/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v34/The following news topics provide information about changes in the 34.x release. +March 13, 2026 - Breaking changes in Bazel for the upcoming 34.x release January 16, 2026 - Prebuilt proto compiler (protoc) for Bazel September 19, 2025 - Breaking changes in the upcoming 34.x release July 16, 2025 - Resuming support for Bazel with MSVC \ No newline at end of file diff --git a/installation/index.html b/installation/index.html new file mode 100644 index 000000000..5acc6517e --- /dev/null +++ b/installation/index.html @@ -0,0 +1,37 @@ +Protocol Buffer Compiler Installation | Protocol Buffers Documentation +

Protocol Buffer Compiler Installation

How to install the protocol buffer compiler.

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)

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-<version>-<os>-<arch>.zip), or fetch the file using commands such +as the following:

    PB_REL="https://github.com/protocolbuffers/protobuf/releases"
    +curl -LO $PB_REL/download/v30.2/protoc-30.2-linux-x86_64.zip
    +
  2. Unzip the file under $HOME/.local or a directory of your choice. For +example:

    unzip protoc-30.2-linux-x86_64.zip -d $HOME/.local
    +
  3. Update your environment’s path variable to include the path to the protoc +executable. For example:

    export PATH="$PATH:$HOME/.local/bin"
    +

Install Using a Package Manager

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:

    apt install -y protobuf-compiler
    +protoc --version  # Ensure compiler version is 3+
    +
  • MacOS, using Homebrew:

    brew install protobuf
    +protoc --version  # Ensure compiler version is 3+
    +
  • Windows, using +Winget

    > winget install protobuf
    +> protoc --version # Ensure compiler version is 3+
    +

Other Installation Options

If you’d like to build the protocol compiler from sources, or access older +versions of the pre-compiled binaries, see +Download Protocol Buffers.

\ No newline at end of file diff --git a/js/click-to-copy.min.73478a7d4807698aed7e355eb23f9890ca18fea3158604c8471746d046702bad.js b/js/click-to-copy.min.73478a7d4807698aed7e355eb23f9890ca18fea3158604c8471746d046702bad.js new file mode 100644 index 000000000..0b95e45e6 --- /dev/null +++ b/js/click-to-copy.min.73478a7d4807698aed7e355eb23f9890ca18fea3158604c8471746d046702bad.js @@ -0,0 +1,2 @@ +let codeListings=document.querySelectorAll(".highlight > pre");for(let t=0;t{e.setAttribute(t,o[t])}),e.classList.add("fas","fa-copy","btn","btn-sm","td-click-to-copy");const i=new bootstrap.Tooltip(e);e.onclick=()=>{copyCode(s),e.setAttribute("data-bs-original-title","Copied!"),i.show()},e.onmouseout=()=>{e.setAttribute("data-bs-original-title","Copy to clipboard"),i.hide()};const n=document.createElement("div");n.classList.add("click-to-copy"),n.append(e),codeListings[t].insertBefore(n,s)}const copyCode=e=>{navigator.clipboard.writeText(e.textContent.trim()+` +`)} \ No newline at end of file diff --git a/js/deflate.js b/js/deflate.js new file mode 100644 index 000000000..b452c84e9 --- /dev/null +++ b/js/deflate.js @@ -0,0 +1,1652 @@ +/* Copyright (C) 1999 Masanao Izumo +* Version: 1.0.1 +* LastModified: Dec 25 1999 +*/ + +/* Interface: +* data = deflate(src); +*/ +const deflate = (function () { + /* constant parameters */ + var zip_WSIZE = 32768; // Sliding Window size + var zip_STORED_BLOCK = 0; + var zip_STATIC_TREES = 1; + var zip_DYN_TREES = 2; + + /* for deflate */ + var zip_DEFAULT_LEVEL = 6; + var zip_FULL_SEARCH = true; + var zip_INBUFSIZ = 32768; // Input buffer size + var zip_INBUF_EXTRA = 64; // Extra buffer + var zip_OUTBUFSIZ = 1024 * 8; + var zip_window_size = 2 * zip_WSIZE; + var zip_MIN_MATCH = 3; + var zip_MAX_MATCH = 258; + var zip_BITS = 16; + // for SMALL_MEM + var zip_LIT_BUFSIZE = 0x2000; + var zip_HASH_BITS = 13; + // for MEDIUM_MEM + // var zip_LIT_BUFSIZE = 0x4000; + // var zip_HASH_BITS = 14; + // for BIG_MEM + // var zip_LIT_BUFSIZE = 0x8000; + // var zip_HASH_BITS = 15; + //if(zip_LIT_BUFSIZE > zip_INBUFSIZ) + // alert("error: zip_INBUFSIZ is too small"); + //if((zip_WSIZE<<1) > (1< zip_BITS-1) + // alert("error: zip_HASH_BITS is too large"); + //if(zip_HASH_BITS < 8 || zip_MAX_MATCH != 258) + // alert("error: Code too clever"); + var zip_DIST_BUFSIZE = zip_LIT_BUFSIZE; + var zip_HASH_SIZE = 1 << zip_HASH_BITS; + var zip_HASH_MASK = zip_HASH_SIZE - 1; + var zip_WMASK = zip_WSIZE - 1; + var zip_NIL = 0; // Tail of hash chains + var zip_TOO_FAR = 4096; + var zip_MIN_LOOKAHEAD = zip_MAX_MATCH + zip_MIN_MATCH + 1; + var zip_MAX_DIST = zip_WSIZE - zip_MIN_LOOKAHEAD; + var zip_SMALLEST = 1; + var zip_MAX_BITS = 15; + var zip_MAX_BL_BITS = 7; + var zip_LENGTH_CODES = 29; + var zip_LITERALS = 256; + var zip_END_BLOCK = 256; + var zip_L_CODES = zip_LITERALS + 1 + zip_LENGTH_CODES; + var zip_D_CODES = 30; + var zip_BL_CODES = 19; + var zip_REP_3_6 = 16; + var zip_REPZ_3_10 = 17; + var zip_REPZ_11_138 = 18; + var zip_HEAP_SIZE = 2 * zip_L_CODES + 1; + var zip_H_SHIFT = parseInt((zip_HASH_BITS + zip_MIN_MATCH - 1) / + zip_MIN_MATCH); + + /* variables */ + var zip_free_queue; + var zip_qhead, zip_qtail; + var zip_initflag; + var zip_outbuf = null; + var zip_outcnt, zip_outoff; + var zip_complete; + var zip_window; + var zip_d_buf; + var zip_l_buf; + var zip_prev; + var zip_bi_buf; + var zip_bi_valid; + var zip_block_start; + var zip_ins_h; + var zip_hash_head; + var zip_prev_match; + var zip_match_available; + var zip_match_length; + var zip_prev_length; + var zip_strstart; + var zip_match_start; + var zip_eofile; + var zip_lookahead; + var zip_max_chain_length; + var zip_max_lazy_match; + var zip_compr_level; + var zip_good_match; + var zip_nice_match; + var zip_dyn_ltree; + var zip_dyn_dtree; + var zip_static_ltree; + var zip_static_dtree; + var zip_bl_tree; + var zip_l_desc; + var zip_d_desc; + var zip_bl_desc; + var zip_bl_count; + var zip_heap; + var zip_heap_len; + var zip_heap_max; + var zip_depth; + var zip_length_code; + var zip_dist_code; + var zip_base_length; + var zip_base_dist; + var zip_flag_buf; + var zip_last_lit; + var zip_last_dist; + var zip_last_flags; + var zip_flags; + var zip_flag_bit; + var zip_opt_len; + var zip_static_len; + var zip_deflate_data; + var zip_deflate_pos; + + /* objects (deflate) */ + + function zip_DeflateCT() { + this.fc = 0; // frequency count or bit string + this.dl = 0; // father node in Huffman tree or length of bit string + } + + function zip_DeflateTreeDesc() { + this.dyn_tree = null; // the dynamic tree + this.static_tree = null; // corresponding static tree or NULL + this.extra_bits = null; // extra bits for each code or NULL + this.extra_base = 0; // base index for extra_bits + this.elems = 0; // max number of elements in the tree + this.max_length = 0; // max bit length for the codes + this.max_code = 0; // largest code with non zero frequency + } + + /* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ + function zip_DeflateConfiguration(a, b, c, d) { + this.good_length = a; // reduce lazy search above this match length + this.max_lazy = b; // do not perform lazy search above this match length + this.nice_length = c; // quit search above this match length + this.max_chain = d; + } + + function zip_DeflateBuffer() { + this.next = null; + this.len = 0; + this.ptr = new Array(zip_OUTBUFSIZ); + this.off = 0; + } + + /* constant tables */ + var zip_extra_lbits = [ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0]; + var zip_extra_dbits = [ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13]; + var zip_extra_blbits = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7]; + var zip_bl_order = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; + var zip_configuration_table = [ + new zip_DeflateConfiguration(0, 0, 0, 0), + new zip_DeflateConfiguration(4, 4, 8, 4), + new zip_DeflateConfiguration(4, 5, 16, 8), + new zip_DeflateConfiguration(4, 6, 32, 32), + new zip_DeflateConfiguration(4, 4, 16, 16), + new zip_DeflateConfiguration(8, 16, 32, 32), + new zip_DeflateConfiguration(8, 16, 128, 128), + new zip_DeflateConfiguration(8, 32, 128, 256), + new zip_DeflateConfiguration(32, 128, 258, 1024), + new zip_DeflateConfiguration(32, 258, 258, 4096)]; + + + /* routines (deflate) */ + + function zip_deflate_start(level) { + var i; + + if (!level) + level = zip_DEFAULT_LEVEL; + else if (level < 1) + level = 1; + else if (level > 9) + level = 9; + + zip_compr_level = level; + zip_initflag = false; + zip_eofile = false; + if (zip_outbuf != null) + return; + + zip_free_queue = zip_qhead = zip_qtail = null; + zip_outbuf = new Array(zip_OUTBUFSIZ); + zip_window = new Array(zip_window_size); + zip_d_buf = new Array(zip_DIST_BUFSIZE); + zip_l_buf = new Array(zip_INBUFSIZ + zip_INBUF_EXTRA); + zip_prev = new Array(1 << zip_BITS); + zip_dyn_ltree = new Array(zip_HEAP_SIZE); + for (i = 0; i < zip_HEAP_SIZE; i++) + zip_dyn_ltree[i] = new zip_DeflateCT(); + zip_dyn_dtree = new Array(2 * zip_D_CODES + 1); + for (i = 0; i < 2 * zip_D_CODES + 1; i++) + zip_dyn_dtree[i] = new zip_DeflateCT(); + zip_static_ltree = new Array(zip_L_CODES + 2); + for (i = 0; i < zip_L_CODES + 2; i++) + zip_static_ltree[i] = new zip_DeflateCT(); + zip_static_dtree = new Array(zip_D_CODES); + for (i = 0; i < zip_D_CODES; i++) + zip_static_dtree[i] = new zip_DeflateCT(); + zip_bl_tree = new Array(2 * zip_BL_CODES + 1); + for (i = 0; i < 2 * zip_BL_CODES + 1; i++) + zip_bl_tree[i] = new zip_DeflateCT(); + zip_l_desc = new zip_DeflateTreeDesc(); + zip_d_desc = new zip_DeflateTreeDesc(); + zip_bl_desc = new zip_DeflateTreeDesc(); + zip_bl_count = new Array(zip_MAX_BITS + 1); + zip_heap = new Array(2 * zip_L_CODES + 1); + zip_depth = new Array(2 * zip_L_CODES + 1); + zip_length_code = new Array(zip_MAX_MATCH - zip_MIN_MATCH + 1); + zip_dist_code = new Array(512); + zip_base_length = new Array(zip_LENGTH_CODES); + zip_base_dist = new Array(zip_D_CODES); + zip_flag_buf = new Array(parseInt(zip_LIT_BUFSIZE / 8)); + } + + function zip_deflate_end() { + zip_free_queue = zip_qhead = zip_qtail = null; + zip_outbuf = null; + zip_window = null; + zip_d_buf = null; + zip_l_buf = null; + zip_prev = null; + zip_dyn_ltree = null; + zip_dyn_dtree = null; + zip_static_ltree = null; + zip_static_dtree = null; + zip_bl_tree = null; + zip_l_desc = null; + zip_d_desc = null; + zip_bl_desc = null; + zip_bl_count = null; + zip_heap = null; + zip_depth = null; + zip_length_code = null; + zip_dist_code = null; + zip_base_length = null; + zip_base_dist = null; + zip_flag_buf = null; + } + + function zip_reuse_queue(p) { + p.next = zip_free_queue; + zip_free_queue = p; + } + + function zip_new_queue() { + var p; + + if (zip_free_queue != null) { + p = zip_free_queue; + zip_free_queue = zip_free_queue.next; + } + else + p = new zip_DeflateBuffer(); + p.next = null; + p.len = p.off = 0; + + return p; + } + + function zip_head1(i) { + return zip_prev[zip_WSIZE + i]; + } + + function zip_head2(i, val) { + return zip_prev[zip_WSIZE + i] = val; + } + + /* put_byte is used for the compressed output, put_ubyte for the + * uncompressed output. However unlzw() uses window for its + * suffix table instead of its output buffer, so it does not use put_ubyte + * (to be cleaned up). + */ + function zip_put_byte(c) { + zip_outbuf[zip_outoff + zip_outcnt++] = c; + if (zip_outoff + zip_outcnt == zip_OUTBUFSIZ) + zip_qoutbuf(); + } + + /* Output a 16 bit value, lsb first */ + function zip_put_short(w) { + w &= 0xffff; + if (zip_outoff + zip_outcnt < zip_OUTBUFSIZ - 2) { + zip_outbuf[zip_outoff + zip_outcnt++] = (w & 0xff); + zip_outbuf[zip_outoff + zip_outcnt++] = (w >>> 8); + } else { + zip_put_byte(w & 0xff); + zip_put_byte(w >>> 8); + } + } + + /* ========================================================================== + * Insert string s in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of s are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ + function zip_INSERT_STRING() { + zip_ins_h = ((zip_ins_h << zip_H_SHIFT) + ^ (zip_window[zip_strstart + zip_MIN_MATCH - 1] & 0xff)) + & zip_HASH_MASK; + zip_hash_head = zip_head1(zip_ins_h); + zip_prev[zip_strstart & zip_WMASK] = zip_hash_head; + zip_head2(zip_ins_h, zip_strstart); + } + + /* Send a code of the given tree. c and tree must not have side effects */ + function zip_SEND_CODE(c, tree) { + zip_send_bits(tree[c].fc, tree[c].dl); + } + + /* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. dist_code[256] and dist_code[257] are never + * used. + */ + function zip_D_CODE(dist) { + return (dist < 256 ? zip_dist_code[dist] + : zip_dist_code[256 + (dist >> 7)]) & 0xff; + } + + /* ========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ + function zip_SMALLER(tree, n, m) { + return tree[n].fc < tree[m].fc || + (tree[n].fc == tree[m].fc && zip_depth[n] <= zip_depth[m]); + } + + /* ========================================================================== + * read string data + */ + function zip_read_buff(buff, offset, n) { + var i; + for (i = 0; i < n && zip_deflate_pos < zip_deflate_data.length; i++) + buff[offset + i] = + zip_deflate_data.charCodeAt(zip_deflate_pos++) & 0xff; + return i; + } + + /* ========================================================================== + * Initialize the "longest match" routines for a new file + */ + function zip_lm_init() { + var j; + + /* Initialize the hash table. */ + for (j = 0; j < zip_HASH_SIZE; j++) + // zip_head2(j, zip_NIL); + zip_prev[zip_WSIZE + j] = 0; + /* prev will be initialized on the fly */ + + /* Set the default configuration parameters: + */ + zip_max_lazy_match = zip_configuration_table[zip_compr_level].max_lazy; + zip_good_match = zip_configuration_table[zip_compr_level].good_length; + if (!zip_FULL_SEARCH) + zip_nice_match = zip_configuration_table[zip_compr_level].nice_length; + zip_max_chain_length = zip_configuration_table[zip_compr_level].max_chain; + + zip_strstart = 0; + zip_block_start = 0; + + zip_lookahead = zip_read_buff(zip_window, 0, 2 * zip_WSIZE); + if (zip_lookahead <= 0) { + zip_eofile = true; + zip_lookahead = 0; + return; + } + zip_eofile = false; + /* Make sure that we always have enough lookahead. This is important + * if input comes from a device such as a tty. + */ + while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) + zip_fill_window(); + + /* If lookahead < MIN_MATCH, ins_h is garbage, but this is + * not important since only literal bytes will be emitted. + */ + zip_ins_h = 0; + for (j = 0; j < zip_MIN_MATCH - 1; j++) { + // UPDATE_HASH(ins_h, window[j]); + zip_ins_h = ((zip_ins_h << zip_H_SHIFT) ^ (zip_window[j] & 0xff)) & zip_HASH_MASK; + } + } + + /* ========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + */ + function zip_longest_match(cur_match) { + var chain_length = zip_max_chain_length; // max hash chain length + var scanp = zip_strstart; // current string + var matchp; // matched string + var len; // length of current match + var best_len = zip_prev_length; // best match length so far + + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + var limit = (zip_strstart > zip_MAX_DIST ? zip_strstart - zip_MAX_DIST : zip_NIL); + + var strendp = zip_strstart + zip_MAX_MATCH; + var scan_end1 = zip_window[scanp + best_len - 1]; + var scan_end = zip_window[scanp + best_len]; + + /* Do not waste too much time if we already have a good match: */ + if (zip_prev_length >= zip_good_match) + chain_length >>= 2; + + // Assert(encoder->strstart <= window_size-MIN_LOOKAHEAD, "insufficient lookahead"); + + do { + // Assert(cur_match < encoder->strstart, "no future"); + matchp = cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ + if (zip_window[matchp + best_len] != scan_end || + zip_window[matchp + best_len - 1] != scan_end1 || + zip_window[matchp] != zip_window[scanp] || + zip_window[++matchp] != zip_window[scanp + 1]) { + continue; + } + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scanp += 2; + matchp++; + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + scanp < strendp); + + len = zip_MAX_MATCH - (strendp - scanp); + scanp = strendp - zip_MAX_MATCH; + + if (len > best_len) { + zip_match_start = cur_match; + best_len = len; + if (zip_FULL_SEARCH) { + if (len >= zip_MAX_MATCH) break; + } else { + if (len >= zip_nice_match) break; + } + + scan_end1 = zip_window[scanp + best_len - 1]; + scan_end = zip_window[scanp + best_len]; + } + } while ((cur_match = zip_prev[cur_match & zip_WMASK]) > limit + && --chain_length != 0); + + return best_len; + } + + /* ========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead, and sets eofile if end of input file. + * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 + * OUT assertions: at least one byte has been read, or eofile is set; + * file reads are performed for at least two bytes (required for the + * translate_eol option). + */ + function zip_fill_window() { + var n, m; + + // Amount of free space at the end of the window. + var more = zip_window_size - zip_lookahead - zip_strstart; + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (more == -1) { + /* Very unlikely, but possible on 16 bit machine if strstart == 0 + * and lookahead == 1 (input done one byte at time) + */ + more--; + } else if (zip_strstart >= zip_WSIZE + zip_MAX_DIST) { + /* By the IN assertion, the window is not empty so we can't confuse + * more == 0 with more == 64K on a 16 bit machine. + */ + // Assert(window_size == (ulg)2*WSIZE, "no sliding with BIG_MEM"); + + // System.arraycopy(window, WSIZE, window, 0, WSIZE); + for (n = 0; n < zip_WSIZE; n++) + zip_window[n] = zip_window[n + zip_WSIZE]; + + zip_match_start -= zip_WSIZE; + zip_strstart -= zip_WSIZE; /* we now have strstart >= MAX_DIST: */ + zip_block_start -= zip_WSIZE; + + for (n = 0; n < zip_HASH_SIZE; n++) { + m = zip_head1(n); + zip_head2(n, m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL); + } + for (n = 0; n < zip_WSIZE; n++) { + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + m = zip_prev[n]; + zip_prev[n] = (m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL); + } + more += zip_WSIZE; + } + // At this point, more >= 2 + if (!zip_eofile) { + n = zip_read_buff(zip_window, zip_strstart + zip_lookahead, more); + if (n <= 0) + zip_eofile = true; + else + zip_lookahead += n; + } + } + + /* ========================================================================== + * Processes a new input file and return its compressed length. This + * function does not perform lazy evaluationof matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ + function zip_deflate_fast() { + while (zip_lookahead != 0 && zip_qhead == null) { + var flush; // set if current block must be flushed + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + zip_INSERT_STRING(); + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (zip_hash_head != zip_NIL && + zip_strstart - zip_hash_head <= zip_MAX_DIST) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + zip_match_length = zip_longest_match(zip_hash_head); + /* longest_match() sets match_start */ + if (zip_match_length > zip_lookahead) + zip_match_length = zip_lookahead; + } + if (zip_match_length >= zip_MIN_MATCH) { + // check_match(strstart, match_start, match_length); + + flush = zip_ct_tally(zip_strstart - zip_match_start, + zip_match_length - zip_MIN_MATCH); + zip_lookahead -= zip_match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (zip_match_length <= zip_max_lazy_match) { + zip_match_length--; // string at strstart already in hash table + do { + zip_strstart++; + zip_INSERT_STRING(); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH + * these bytes are garbage, but it does not matter since + * the next lookahead bytes will be emitted as literals. + */ + } while (--zip_match_length != 0); + zip_strstart++; + } else { + zip_strstart += zip_match_length; + zip_match_length = 0; + zip_ins_h = zip_window[zip_strstart] & 0xff; + // UPDATE_HASH(ins_h, window[strstart + 1]); + zip_ins_h = ((zip_ins_h << zip_H_SHIFT) ^ (zip_window[zip_strstart + 1] & 0xff)) & zip_HASH_MASK; + + //#if MIN_MATCH != 3 + // Call UPDATE_HASH() MIN_MATCH-3 more times + //#endif + + } + } else { + /* No match, output a literal byte */ + flush = zip_ct_tally(0, zip_window[zip_strstart] & 0xff); + zip_lookahead--; + zip_strstart++; + } + if (flush) { + zip_flush_block(0); + zip_block_start = zip_strstart; + } + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) + zip_fill_window(); + } + } + + function zip_deflate_better() { + /* Process the input block. */ + while (zip_lookahead != 0 && zip_qhead == null) { + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + zip_INSERT_STRING(); + + /* Find the longest match, discarding those <= prev_length. + */ + zip_prev_length = zip_match_length; + zip_prev_match = zip_match_start; + zip_match_length = zip_MIN_MATCH - 1; + + if (zip_hash_head != zip_NIL && + zip_prev_length < zip_max_lazy_match && + zip_strstart - zip_hash_head <= zip_MAX_DIST) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + zip_match_length = zip_longest_match(zip_hash_head); + /* longest_match() sets match_start */ + if (zip_match_length > zip_lookahead) + zip_match_length = zip_lookahead; + + /* Ignore a length 3 match if it is too distant: */ + if (zip_match_length == zip_MIN_MATCH && + zip_strstart - zip_match_start > zip_TOO_FAR) { + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + zip_match_length--; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (zip_prev_length >= zip_MIN_MATCH && + zip_match_length <= zip_prev_length) { + var flush; // set if current block must be flushed + + // check_match(strstart - 1, prev_match, prev_length); + flush = zip_ct_tally(zip_strstart - 1 - zip_prev_match, + zip_prev_length - zip_MIN_MATCH); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. + */ + zip_lookahead -= zip_prev_length - 1; + zip_prev_length -= 2; + do { + zip_strstart++; + zip_INSERT_STRING(); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH + * these bytes are garbage, but it does not matter since the + * next lookahead bytes will always be emitted as literals. + */ + } while (--zip_prev_length != 0); + zip_match_available = 0; + zip_match_length = zip_MIN_MATCH - 1; + zip_strstart++; + if (flush) { + zip_flush_block(0); + zip_block_start = zip_strstart; + } + } else if (zip_match_available != 0) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + if (zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff)) { + zip_flush_block(0); + zip_block_start = zip_strstart; + } + zip_strstart++; + zip_lookahead--; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + zip_match_available = 1; + zip_strstart++; + zip_lookahead--; + } + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) + zip_fill_window(); + } + } + + function zip_init_deflate() { + if (zip_eofile) + return; + zip_bi_buf = 0; + zip_bi_valid = 0; + zip_ct_init(); + zip_lm_init(); + + zip_qhead = null; + zip_outcnt = 0; + zip_outoff = 0; + + if (zip_compr_level <= 3) { + zip_prev_length = zip_MIN_MATCH - 1; + zip_match_length = 0; + } + else { + zip_match_length = zip_MIN_MATCH - 1; + zip_match_available = 0; + } + + zip_complete = false; + } + + /* ========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ + function zip_deflate_internal(buff, off, buff_size) { + var n; + + if (!zip_initflag) { + zip_init_deflate(); + zip_initflag = true; + if (zip_lookahead == 0) { // empty + zip_complete = true; + return 0; + } + } + + if ((n = zip_qcopy(buff, off, buff_size)) == buff_size) + return buff_size; + + if (zip_complete) + return n; + + if (zip_compr_level <= 3) // optimized for speed + zip_deflate_fast(); + else + zip_deflate_better(); + if (zip_lookahead == 0) { + if (zip_match_available != 0) + zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff); + zip_flush_block(1); + zip_complete = true; + } + return n + zip_qcopy(buff, n + off, buff_size - n); + } + + function zip_qcopy(buff, off, buff_size) { + var n, i, j; + + n = 0; + while (zip_qhead != null && n < buff_size) { + i = buff_size - n; + if (i > zip_qhead.len) + i = zip_qhead.len; + // System.arraycopy(qhead.ptr, qhead.off, buff, off + n, i); + for (j = 0; j < i; j++) + buff[off + n + j] = zip_qhead.ptr[zip_qhead.off + j]; + + zip_qhead.off += i; + zip_qhead.len -= i; + n += i; + if (zip_qhead.len == 0) { + var p; + p = zip_qhead; + zip_qhead = zip_qhead.next; + zip_reuse_queue(p); + } + } + + if (n == buff_size) + return n; + + if (zip_outoff < zip_outcnt) { + i = buff_size - n; + if (i > zip_outcnt - zip_outoff) + i = zip_outcnt - zip_outoff; + // System.arraycopy(outbuf, outoff, buff, off + n, i); + for (j = 0; j < i; j++) + buff[off + n + j] = zip_outbuf[zip_outoff + j]; + zip_outoff += i; + n += i; + if (zip_outcnt == zip_outoff) + zip_outcnt = zip_outoff = 0; + } + return n; + } + + /* ========================================================================== + * Allocate the match buffer, initialize the various tables and save the + * location of the internal file attribute (ascii/binary) and method + * (DEFLATE/STORE). + */ + function zip_ct_init() { + var n; // iterates over tree elements + var bits; // bit counter + var length; // length value + var code; // code value + var dist; // distance index + + if (zip_static_dtree[0].dl != 0) return; // ct_init already called + + zip_l_desc.dyn_tree = zip_dyn_ltree; + zip_l_desc.static_tree = zip_static_ltree; + zip_l_desc.extra_bits = zip_extra_lbits; + zip_l_desc.extra_base = zip_LITERALS + 1; + zip_l_desc.elems = zip_L_CODES; + zip_l_desc.max_length = zip_MAX_BITS; + zip_l_desc.max_code = 0; + + zip_d_desc.dyn_tree = zip_dyn_dtree; + zip_d_desc.static_tree = zip_static_dtree; + zip_d_desc.extra_bits = zip_extra_dbits; + zip_d_desc.extra_base = 0; + zip_d_desc.elems = zip_D_CODES; + zip_d_desc.max_length = zip_MAX_BITS; + zip_d_desc.max_code = 0; + + zip_bl_desc.dyn_tree = zip_bl_tree; + zip_bl_desc.static_tree = null; + zip_bl_desc.extra_bits = zip_extra_blbits; + zip_bl_desc.extra_base = 0; + zip_bl_desc.elems = zip_BL_CODES; + zip_bl_desc.max_length = zip_MAX_BL_BITS; + zip_bl_desc.max_code = 0; + + // Initialize the mapping length (0..255) -> length code (0..28) + length = 0; + for (code = 0; code < zip_LENGTH_CODES - 1; code++) { + zip_base_length[code] = length; + for (n = 0; n < (1 << zip_extra_lbits[code]); n++) + zip_length_code[length++] = code; + } + // Assert (length == 256, "ct_init: length != 256"); + + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + zip_length_code[length - 1] = code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0; code < 16; code++) { + zip_base_dist[code] = dist; + for (n = 0; n < (1 << zip_extra_dbits[code]); n++) { + zip_dist_code[dist++] = code; + } + } + // Assert (dist == 256, "ct_init: dist != 256"); + dist >>= 7; // from now on, all distances are divided by 128 + for (; code < zip_D_CODES; code++) { + zip_base_dist[code] = dist << 7; + for (n = 0; n < (1 << (zip_extra_dbits[code] - 7)); n++) + zip_dist_code[256 + dist++] = code; + } + // Assert (dist == 256, "ct_init: 256+dist != 512"); + + // Construct the codes of the static literal tree + for (bits = 0; bits <= zip_MAX_BITS; bits++) + zip_bl_count[bits] = 0; + n = 0; + while (n <= 143) { zip_static_ltree[n++].dl = 8; zip_bl_count[8]++; } + while (n <= 255) { zip_static_ltree[n++].dl = 9; zip_bl_count[9]++; } + while (n <= 279) { zip_static_ltree[n++].dl = 7; zip_bl_count[7]++; } + while (n <= 287) { zip_static_ltree[n++].dl = 8; zip_bl_count[8]++; } + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + zip_gen_codes(zip_static_ltree, zip_L_CODES + 1); + + /* The static distance tree is trivial: */ + for (n = 0; n < zip_D_CODES; n++) { + zip_static_dtree[n].dl = 5; + zip_static_dtree[n].fc = zip_bi_reverse(n, 5); + } + + // Initialize the first block of the first file: + zip_init_block(); + } + + /* ========================================================================== + * Initialize a new block. + */ + function zip_init_block() { + var n; // iterates over tree elements + + // Initialize the trees. + for (n = 0; n < zip_L_CODES; n++) zip_dyn_ltree[n].fc = 0; + for (n = 0; n < zip_D_CODES; n++) zip_dyn_dtree[n].fc = 0; + for (n = 0; n < zip_BL_CODES; n++) zip_bl_tree[n].fc = 0; + + zip_dyn_ltree[zip_END_BLOCK].fc = 1; + zip_opt_len = zip_static_len = 0; + zip_last_lit = zip_last_dist = zip_last_flags = 0; + zip_flags = 0; + zip_flag_bit = 1; + } + + /* ========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ + function zip_pqdownheap( + tree, // the tree to restore + k) { // node to move down + var v = zip_heap[k]; + var j = k << 1; // left son of k + + while (j <= zip_heap_len) { + // Set j to the smallest of the two sons: + if (j < zip_heap_len && + zip_SMALLER(tree, zip_heap[j + 1], zip_heap[j])) + j++; + + // Exit if v is smaller than both sons + if (zip_SMALLER(tree, v, zip_heap[j])) + break; + + // Exchange v with the smallest son + zip_heap[k] = zip_heap[j]; + k = j; + + // And continue down the tree, setting j to the left son of k + j <<= 1; + } + zip_heap[k] = v; + } + + /* ========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ + function zip_gen_bitlen(desc) { // the tree descriptor + var tree = desc.dyn_tree; + var extra = desc.extra_bits; + var base = desc.extra_base; + var max_code = desc.max_code; + var max_length = desc.max_length; + var stree = desc.static_tree; + var h; // heap index + var n, m; // iterate over the tree elements + var bits; // bit length + var xbits; // extra bits + var f; // frequency + var overflow = 0; // number of elements with bit length too large + + for (bits = 0; bits <= zip_MAX_BITS; bits++) + zip_bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[zip_heap[zip_heap_max]].dl = 0; // root of the heap + + for (h = zip_heap_max + 1; h < zip_HEAP_SIZE; h++) { + n = zip_heap[h]; + bits = tree[tree[n].dl].dl + 1; + if (bits > max_length) { + bits = max_length; + overflow++; + } + tree[n].dl = bits; + // We overwrite tree[n].dl which is no longer needed + + if (n > max_code) + continue; // not a leaf node + + zip_bl_count[bits]++; + xbits = 0; + if (n >= base) + xbits = extra[n - base]; + f = tree[n].fc; + zip_opt_len += f * (bits + xbits); + if (stree != null) + zip_static_len += f * (stree[n].dl + xbits); + } + if (overflow == 0) + return; + + // This happens for example on obj2 and pic of the Calgary corpus + + // Find the first bit length which could increase: + do { + bits = max_length - 1; + while (zip_bl_count[bits] == 0) + bits--; + zip_bl_count[bits]--; // move one leaf down the tree + zip_bl_count[bits + 1] += 2; // move one overflow item as its brother + zip_bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = zip_bl_count[bits]; + while (n != 0) { + m = zip_heap[--h]; + if (m > max_code) + continue; + if (tree[m].dl != bits) { + zip_opt_len += (bits - tree[m].dl) * tree[m].fc; + tree[m].fc = bits; + } + n--; + } + } + } + + /* ========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ + function zip_gen_codes(tree, // the tree to decorate + max_code) { // largest code with non zero frequency + var next_code = new Array(zip_MAX_BITS + 1); // next code value for each bit length + var code = 0; // running code value + var bits; // bit index + var n; // code index + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= zip_MAX_BITS; bits++) { + code = ((code + zip_bl_count[bits - 1]) << 1); + next_code[bits] = code; + } + + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + // Assert (code + encoder->bl_count[MAX_BITS]-1 == (1<> 1; n >= 1; n--) + zip_pqdownheap(tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + do { + n = zip_heap[zip_SMALLEST]; + zip_heap[zip_SMALLEST] = zip_heap[zip_heap_len--]; + zip_pqdownheap(tree, zip_SMALLEST); + + m = zip_heap[zip_SMALLEST]; // m = node of next least frequency + + // keep the nodes sorted by frequency + zip_heap[--zip_heap_max] = n; + zip_heap[--zip_heap_max] = m; + + // Create a new node father of n and m + tree[node].fc = tree[n].fc + tree[m].fc; + // depth[node] = (char)(MAX(depth[n], depth[m]) + 1); + if (zip_depth[n] > zip_depth[m] + 1) + zip_depth[node] = zip_depth[n]; + else + zip_depth[node] = zip_depth[m] + 1; + tree[n].dl = tree[m].dl = node; + + // and insert the new node in the heap + zip_heap[zip_SMALLEST] = node++; + zip_pqdownheap(tree, zip_SMALLEST); + + } while (zip_heap_len >= 2); + + zip_heap[--zip_heap_max] = zip_heap[zip_SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + zip_gen_bitlen(desc); + + // The field len is now set, we can generate the bit codes + zip_gen_codes(tree, max_code); + } + + /* ========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. Updates opt_len to take into account the repeat + * counts. (The contribution of the bit length codes will be added later + * during the construction of bl_tree.) + */ + function zip_scan_tree(tree,// the tree to be scanned + max_code) { // and its largest code of non zero frequency + var n; // iterates over all tree elements + var prevlen = -1; // last emitted length + var curlen; // length of current code + var nextlen = tree[0].dl; // length of next code + var count = 0; // repeat count of the current code + var max_count = 7; // max repeat count + var min_count = 4; // min repeat count + + if (nextlen == 0) { + max_count = 138; + min_count = 3; + } + tree[max_code + 1].dl = 0xffff; // guard + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[n + 1].dl; + if (++count < max_count && curlen == nextlen) + continue; + else if (count < min_count) + zip_bl_tree[curlen].fc += count; + else if (curlen != 0) { + if (curlen != prevlen) + zip_bl_tree[curlen].fc++; + zip_bl_tree[zip_REP_3_6].fc++; + } else if (count <= 10) + zip_bl_tree[zip_REPZ_3_10].fc++; + else + zip_bl_tree[zip_REPZ_11_138].fc++; + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138; + min_count = 3; + } else if (curlen == nextlen) { + max_count = 6; + min_count = 3; + } else { + max_count = 7; + min_count = 4; + } + } + } + + /* ========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ + function zip_send_tree(tree, // the tree to be scanned + max_code) { // and its largest code of non zero frequency + var n; // iterates over all tree elements + var prevlen = -1; // last emitted length + var curlen; // length of current code + var nextlen = tree[0].dl; // length of next code + var count = 0; // repeat count of the current code + var max_count = 7; // max repeat count + var min_count = 4; // min repeat count + + /* tree[max_code+1].dl = -1; */ /* guard already set */ + if (nextlen == 0) { + max_count = 138; + min_count = 3; + } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[n + 1].dl; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { zip_SEND_CODE(curlen, zip_bl_tree); } while (--count != 0); + } else if (curlen != 0) { + if (curlen != prevlen) { + zip_SEND_CODE(curlen, zip_bl_tree); + count--; + } + // Assert(count >= 3 && count <= 6, " 3_6?"); + zip_SEND_CODE(zip_REP_3_6, zip_bl_tree); + zip_send_bits(count - 3, 2); + } else if (count <= 10) { + zip_SEND_CODE(zip_REPZ_3_10, zip_bl_tree); + zip_send_bits(count - 3, 3); + } else { + zip_SEND_CODE(zip_REPZ_11_138, zip_bl_tree); + zip_send_bits(count - 11, 7); + } + count = 0; + prevlen = curlen; + if (nextlen == 0) { + max_count = 138; + min_count = 3; + } else if (curlen == nextlen) { + max_count = 6; + min_count = 3; + } else { + max_count = 7; + min_count = 4; + } + } + } + + /* ========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ + function zip_build_bl_tree() { + var max_blindex; // index of last bit length code of non zero freq + + // Determine the bit length frequencies for literal and distance trees + zip_scan_tree(zip_dyn_ltree, zip_l_desc.max_code); + zip_scan_tree(zip_dyn_dtree, zip_d_desc.max_code); + + // Build the bit length tree: + zip_build_tree(zip_bl_desc); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = zip_BL_CODES - 1; max_blindex >= 3; max_blindex--) { + if (zip_bl_tree[zip_bl_order[max_blindex]].dl != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + zip_opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; + // Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + // encoder->opt_len, encoder->static_len)); + + return max_blindex; + } + + /* ========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ + function zip_send_all_trees(lcodes, dcodes, blcodes) { // number of codes for each tree + var rank; // index in bl_order + + // Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + // Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + // "too many codes"); + // Tracev((stderr, "\nbl counts: ")); + zip_send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt + zip_send_bits(dcodes - 1, 5); + zip_send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt + for (rank = 0; rank < blcodes; rank++) { + // Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + zip_send_bits(zip_bl_tree[zip_bl_order[rank]].dl, 3); + } + + // send the literal tree + zip_send_tree(zip_dyn_ltree, lcodes - 1); + + // send the distance tree + zip_send_tree(zip_dyn_dtree, dcodes - 1); + } + + /* ========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ + function zip_flush_block(eof) { // true if this is the last block for a file + var opt_lenb, static_lenb; // opt_len and static_len in bytes + var max_blindex; // index of last bit length code of non zero freq + var stored_len; // length of input block + + stored_len = zip_strstart - zip_block_start; + zip_flag_buf[zip_last_flags] = zip_flags; // Save the flags for the last 8 items + + // Construct the literal and distance trees + zip_build_tree(zip_l_desc); + // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", + // encoder->opt_len, encoder->static_len)); + + zip_build_tree(zip_d_desc); + // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", + // encoder->opt_len, encoder->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = zip_build_bl_tree(); + + // Determine the best encoding. Compute first the block length in bytes + opt_lenb = (zip_opt_len + 3 + 7) >> 3; + static_lenb = (zip_static_len + 3 + 7) >> 3; + + // Trace((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", + // opt_lenb, encoder->opt_len, + // static_lenb, encoder->static_len, stored_len, + // encoder->last_lit, encoder->last_dist)); + + if (static_lenb <= opt_lenb) + opt_lenb = static_lenb; + if (stored_len + 4 <= opt_lenb // 4: two words for the lengths + && zip_block_start >= 0) { + var i; + + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + zip_send_bits((zip_STORED_BLOCK << 1) + eof, 3); /* send block type */ + zip_bi_windup(); /* align on byte boundary */ + zip_put_short(stored_len); + zip_put_short(~stored_len); + + // copy block + /* + p = &window[block_start]; + for(i = 0; i < stored_len; i++) + put_byte(p[i]); + */ + for (i = 0; i < stored_len; i++) + zip_put_byte(zip_window[zip_block_start + i]); + + } else if (static_lenb == opt_lenb) { + zip_send_bits((zip_STATIC_TREES << 1) + eof, 3); + zip_compress_block(zip_static_ltree, zip_static_dtree); + } else { + zip_send_bits((zip_DYN_TREES << 1) + eof, 3); + zip_send_all_trees(zip_l_desc.max_code + 1, + zip_d_desc.max_code + 1, + max_blindex + 1); + zip_compress_block(zip_dyn_ltree, zip_dyn_dtree); + } + + zip_init_block(); + + if (eof != 0) + zip_bi_windup(); + } + + /* ========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ + function zip_ct_tally( + dist, // distance of matched string + lc) { // match length-MIN_MATCH or unmatched char (if dist==0) + zip_l_buf[zip_last_lit++] = lc; + if (dist == 0) { + // lc is the unmatched char + zip_dyn_ltree[lc].fc++; + } else { + // Here, lc is the match length - MIN_MATCH + dist--; // dist = match distance - 1 + // Assert((ush)dist < (ush)MAX_DIST && + // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + // (ush)D_CODE(dist) < (ush)D_CODES, "ct_tally: bad match"); + + zip_dyn_ltree[zip_length_code[lc] + zip_LITERALS + 1].fc++; + zip_dyn_dtree[zip_D_CODE(dist)].fc++; + + zip_d_buf[zip_last_dist++] = dist; + zip_flags |= zip_flag_bit; + } + zip_flag_bit <<= 1; + + // Output the flags if they fill a byte + if ((zip_last_lit & 7) == 0) { + zip_flag_buf[zip_last_flags++] = zip_flags; + zip_flags = 0; + zip_flag_bit = 1; + } + // Try to guess if it is profitable to stop the current block here + if (zip_compr_level > 2 && (zip_last_lit & 0xfff) == 0) { + // Compute an upper bound for the compressed length + var out_length = zip_last_lit * 8; + var in_length = zip_strstart - zip_block_start; + var dcode; + + for (dcode = 0; dcode < zip_D_CODES; dcode++) { + out_length += zip_dyn_dtree[dcode].fc * (5 + zip_extra_dbits[dcode]); + } + out_length >>= 3; + // Trace((stderr,"\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", + // encoder->last_lit, encoder->last_dist, in_length, out_length, + // 100L - out_length*100L/in_length)); + if (zip_last_dist < parseInt(zip_last_lit / 2) && + out_length < parseInt(in_length / 2)) + return true; + } + return (zip_last_lit == zip_LIT_BUFSIZE - 1 || + zip_last_dist == zip_DIST_BUFSIZE); + /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ + } + + /* ========================================================================== + * Send the block data compressed using the given Huffman trees + */ + function zip_compress_block( + ltree, // literal tree + dtree) { // distance tree + var dist; // distance of matched string + var lc; // match length or unmatched char (if dist == 0) + var lx = 0; // running index in l_buf + var dx = 0; // running index in d_buf + var fx = 0; // running index in flag_buf + var flag = 0; // current flags + var code; // the code to send + var extra; // number of extra bits to send + + if (zip_last_lit != 0) do { + if ((lx & 7) == 0) + flag = zip_flag_buf[fx++]; + lc = zip_l_buf[lx++] & 0xff; + if ((flag & 1) == 0) { + zip_SEND_CODE(lc, ltree); /* send a literal byte */ + // Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + // Here, lc is the match length - MIN_MATCH + code = zip_length_code[lc]; + zip_SEND_CODE(code + zip_LITERALS + 1, ltree); // send the length code + extra = zip_extra_lbits[code]; + if (extra != 0) { + lc -= zip_base_length[code]; + zip_send_bits(lc, extra); // send the extra length bits + } + dist = zip_d_buf[dx++]; + // Here, dist is the match distance - 1 + code = zip_D_CODE(dist); + // Assert (code < D_CODES, "bad d_code"); + + zip_SEND_CODE(code, dtree); // send the distance code + extra = zip_extra_dbits[code]; + if (extra != 0) { + dist -= zip_base_dist[code]; + zip_send_bits(dist, extra); // send the extra distance bits + } + } // literal or match pair ? + flag >>= 1; + } while (lx < zip_last_lit); + + zip_SEND_CODE(zip_END_BLOCK, ltree); + } + + /* ========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ + var zip_Buf_size = 16; // bit size of bi_buf + function zip_send_bits( + value, // value to send + length) { // number of bits + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (zip_bi_valid > zip_Buf_size - length) { + zip_bi_buf |= (value << zip_bi_valid); + zip_put_short(zip_bi_buf); + zip_bi_buf = (value >> (zip_Buf_size - zip_bi_valid)); + zip_bi_valid += length - zip_Buf_size; + } else { + zip_bi_buf |= value << zip_bi_valid; + zip_bi_valid += length; + } + } + + /* ========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ + function zip_bi_reverse( + code, // the value to invert + len) { // its bit length + var res = 0; + do { + res |= code & 1; + code >>= 1; + res <<= 1; + } while (--len > 0); + return res >> 1; + } + + /* ========================================================================== + * Write out any remaining bits in an incomplete byte. + */ + function zip_bi_windup() { + if (zip_bi_valid > 8) { + zip_put_short(zip_bi_buf); + } else if (zip_bi_valid > 0) { + zip_put_byte(zip_bi_buf); + } + zip_bi_buf = 0; + zip_bi_valid = 0; + } + + function zip_qoutbuf() { + if (zip_outcnt != 0) { + var q, i; + q = zip_new_queue(); + if (zip_qhead == null) + zip_qhead = zip_qtail = q; + else + zip_qtail = zip_qtail.next = q; + q.len = zip_outcnt - zip_outoff; + // System.arraycopy(zip_outbuf, zip_outoff, q.ptr, 0, q.len); + for (i = 0; i < q.len; i++) + q.ptr[i] = zip_outbuf[zip_outoff + i]; + zip_outcnt = zip_outoff = 0; + } + } + + return function deflate(str, level) { + var i, j; + + zip_deflate_data = str; + zip_deflate_pos = 0; + if (typeof level == "undefined") + level = zip_DEFAULT_LEVEL; + zip_deflate_start(level); + + var buff = new Array(1024); + var aout = []; + while ((i = zip_deflate_internal(buff, 0, buff.length)) > 0) { + var cbuf = new Array(i); + for (j = 0; j < i; j++) { + cbuf[j] = String.fromCharCode(buff[j]); + } + aout[aout.length] = cbuf.join(""); + } + zip_deflate_data = null; // G.C. + return aout.join(""); + }; +})(); \ No newline at end of file diff --git a/js/main.min.c91cdfdcc1576ecc360abc6f1c3ca0485d047f65ac6d3203ec57ed29e0af808b.js b/js/main.min.c91cdfdcc1576ecc360abc6f1c3ca0485d047f65ac6d3203ec57ed29e0af808b.js new file mode 100644 index 000000000..e9fd97e7c --- /dev/null +++ b/js/main.min.c91cdfdcc1576ecc360abc6f1c3ca0485d047f65ac6d3203ec57ed29e0af808b.js @@ -0,0 +1,5 @@ +/*! + * Bootstrap v5.3.3 (https://getbootstrap.com/) + * Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */(function(e,t){typeof exports=="object"&&typeof module!="undefined"?module.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis!="undefined"?globalThis:e||self,e.bootstrap=t())})(this,function(){"use strict";const C=new Map,pt={set(e,t,n){C.has(e)||C.set(e,new Map);const s=C.get(e);if(!s.has(t)&&s.size!==0){console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`);return}s.set(t,n)},get(e,t){return C.has(e)?C.get(e).get(t)||null:null},remove(e,t){if(!C.has(e))return;const n=C.get(e);n.delete(t),n.size===0&&C.delete(e)}},Jr=1e6,Xr=1e3,lt="transitionend",is=e=>(e&&window.CSS&&window.CSS.escape&&(e=e.replace(/#([^\s"#']+)/g,(e,t)=>`#${CSS.escape(t)}`)),e),Gr=e=>e==null?`${e}`:Object.prototype.toString.call(e).match(/\s([a-z]+)/i)[1].toLowerCase(),Yr=e=>{do e+=Math.floor(Math.random()*Jr);while(document.getElementById(e))return e},Pr=e=>{if(!e)return 0;let{transitionDuration:t,transitionDelay:n}=window.getComputedStyle(e);const s=Number.parseFloat(t),o=Number.parseFloat(n);return!s&&!o?0:(t=t.split(",")[0],n=n.split(",")[0],(Number.parseFloat(t)+Number.parseFloat(n))*Xr)},ns=e=>{e.dispatchEvent(new Event(lt))},g=e=>!!e&&typeof e=="object"&&(typeof e.jquery!="undefined"&&(e=e[0]),typeof e.nodeType!="undefined"),w=e=>g(e)?e.jquery?e[0]:e:typeof e=="string"&&e.length>0?document.querySelector(is(e)):null,R=e=>{if(!g(e)||e.getClientRects().length===0)return!1;const n=getComputedStyle(e).getPropertyValue("visibility")==="visible",t=e.closest("details:not([open])");if(!t)return n;if(t!==e){const n=e.closest("summary");if(n&&n.parentNode!==t)return!1;if(n===null)return!1}return n},y=e=>!e||e.nodeType!==Node.ELEMENT_NODE||!!e.classList.contains("disabled")||(typeof e.disabled!="undefined"?e.disabled:e.hasAttribute("disabled")&&e.getAttribute("disabled")!=="false"),es=e=>{if(!document.documentElement.attachShadow)return null;if(typeof e.getRootNode=="function"){const t=e.getRootNode();return t instanceof ShadowRoot?t:null}return e instanceof ShadowRoot?e:e.parentNode?es(e.parentNode):null},le=()=>{},oe=e=>{e.offsetHeight},Jn=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,Ue=[],Nr=e=>{document.readyState==="loading"?(Ue.length||document.addEventListener("DOMContentLoaded",()=>{for(const e of Ue)e()}),Ue.push(e)):e()},c=()=>document.documentElement.dir==="rtl",u=e=>{Nr(()=>{const t=Jn();if(t){const n=e.NAME,s=t.fn[n];t.fn[n]=e.jQueryInterface,t.fn[n].Constructor=e,t.fn[n].noConflict=()=>(t.fn[n]=s,e.jQueryInterface)}})},o=(e,t=[],n=e)=>typeof e=="function"?e(...t):n,Zn=(e,t,n=!0)=>{if(!n){o(e);return}const a=5,r=Pr(t)+a;let s=!1;const i=({target:n})=>{if(n!==t)return;s=!0,t.removeEventListener(lt,i),o(e)};t.addEventListener(lt,i),setTimeout(()=>{s||ns(t)},r)},$e=(e,t,n,s)=>{const i=e.length;let o=e.indexOf(t);return o===-1?!n&&s?e[i-1]:e[0]:(o+=n?1:-1,s&&(o=(o+i)%i),e[Math.max(0,Math.min(o,i-1))])},zr=/[^.]*(?=\..*)\.|.*/,Tr=/\..*/,Ar=/::\d+$/,De={};let qn=1;const Un={mouseenter:"mouseover",mouseleave:"mouseout"},Er=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function Hn(e,t){return t&&`${t}::${qn++}`||e.uidEvent||qn++}function Fn(e){const t=Hn(e);return e.uidEvent=t,De[t]=De[t]||{},De[t]}function xr(t,n){return function s(o){return ht(o,{delegateTarget:t}),s.oneOff&&e.off(t,o.type,n),n.apply(t,[o])}}function Or(t,n,s){return function o(i){const a=t.querySelectorAll(n);for(let{target:r}=i;r&&r!==this;r=r.parentNode)for(const c of a){if(c!==r)continue;return ht(i,{delegateTarget:r}),o.oneOff&&e.off(t,i.type,n,s),s.apply(r,[i])}}}function Sn(e,t,n=null){return Object.values(e).find(e=>e.callable===t&&e.delegationSelector===n)}function An(e,t,n){const o=typeof t=="string",i=o?n:t||n;let s=xn(e);return Er.has(s)||(s=e),[o,i,s]}function Cn(e,t,n,s,o){if(typeof t!="string"||!e)return;let[r,i,c]=An(t,n,s);if(t in Un){const e=e=>function(t){if(!t.relatedTarget||t.relatedTarget!==t.delegateTarget&&!t.delegateTarget.contains(t.relatedTarget))return e.call(this,t)};i=e(i)}const d=Fn(e),u=d[c]||(d[c]={}),l=Sn(u,i,r?n:null);if(l){l.oneOff=l.oneOff&&o;return}const h=Hn(i,t.replace(zr,"")),a=r?Or(e,n,i):xr(e,i);a.delegationSelector=r?n:null,a.callable=i,a.oneOff=o,a.uidEvent=h,u[h]=a,e.addEventListener(c,a,r)}function dt(e,t,n,s,o){const i=Sn(t[n],s,o);if(!i)return;e.removeEventListener(n,i,Boolean(o)),delete t[n][i.uidEvent]}function wr(e,t,n,s){const o=t[n]||{};for(const[a,i]of Object.entries(o))a.includes(s)&&dt(e,t,n,i.callable,i.delegationSelector)}function xn(e){return e=e.replace(Tr,""),Un[e]||e}const e={on(e,t,n,s){Cn(e,t,n,s,!1)},one(e,t,n,s){Cn(e,t,n,s,!0)},off(e,t,n,s){if(typeof t!="string"||!e)return;const[c,a,i]=An(t,n,s),l=i!==t,o=Fn(e),r=o[i]||{},d=t.startsWith(".");if(typeof a!="undefined"){if(!Object.keys(r).length)return;dt(e,o,i,a,c?n:null);return}if(d)for(const n of Object.keys(o))wr(e,o,n,t.slice(1));for(const[s,n]of Object.entries(r)){const a=s.replace(Ar,"");(!l||t.includes(a))&&dt(e,o,i,n.callable,n.delegationSelector)}},trigger(e,t,n){if(typeof t!="string"||!e)return null;const i=Jn(),l=xn(t),d=t!==l;let s=null,a=!0,r=!0,c=!1;d&&i&&(s=i.Event(t,n),i(e).trigger(s),a=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),c=s.isDefaultPrevented());const o=ht(new Event(t,{bubbles:a,cancelable:!0}),n);return c&&o.preventDefault(),r&&e.dispatchEvent(o),o.defaultPrevented&&s&&s.preventDefault(),o}};function ht(e,t={}){for(const[n,s]of Object.entries(t))try{e[n]=s}catch{Object.defineProperty(e,n,{configurable:!0,get(){return s}})}return e}function On(e){if(e==="true")return!0;if(e==="false")return!1;if(e===Number(e).toString())return Number(e);if(e===""||e==="null")return null;if(typeof e!="string")return e;try{return JSON.parse(decodeURIComponent(e))}catch{return e}}function Le(e){return e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}const v={setDataAttribute(e,t,n){e.setAttribute(`data-bs-${Le(t)}`,n)},removeDataAttribute(e,t){e.removeAttribute(`data-bs-${Le(t)}`)},getDataAttributes(e){if(!e)return{};const t={},n=Object.keys(e.dataset).filter(e=>e.startsWith("bs")&&!e.startsWith("bsConfig"));for(const o of n){let s=o.replace(/^bs/,"");s=s.charAt(0).toLowerCase()+s.slice(1,s.length),t[s]=On(e.dataset[o])}return t},getDataAttribute(e,t){return On(e.getAttribute(`data-bs-${Le(t)}`))}};class se{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(e){return e=this._mergeConfigObj(e),e=this._configAfterMerge(e),this._typeCheckConfig(e),e}_configAfterMerge(e){return e}_mergeConfigObj(e,t){const n=g(t)?v.getDataAttribute(t,"config"):{};return{...this.constructor.Default,...typeof n=="object"?n:{},...g(t)?v.getDataAttributes(t):{},...typeof e=="object"?e:{}}}_typeCheckConfig(e,t=this.constructor.DefaultType){for(const[n,s]of Object.entries(t)){const o=e[n],i=g(o)?"element":Gr(o);if(!new RegExp(s).test(i))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${i}" but expected type "${s}".`)}}}const _r="5.3.3";class h extends se{constructor(e,t){if(super(),e=w(e),!e)return;this._element=e,this._config=this._getConfig(t),pt.set(this._element,this.constructor.DATA_KEY,this)}dispose(){pt.remove(this._element,this.constructor.DATA_KEY),e.off(this._element,this.constructor.EVENT_KEY);for(const e of Object.getOwnPropertyNames(this))this[e]=null}_queueCallback(e,t,n=!0){Zn(e,t,n)}_getConfig(e){return e=this._mergeConfigObj(e,this._element),e=this._configAfterMerge(e),this._typeCheckConfig(e),e}static getInstance(e){return pt.get(w(e),this.DATA_KEY)}static getOrCreateInstance(e,t={}){return this.getInstance(e)||new this(e,typeof t=="object"?t:null)}static get VERSION(){return _r}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(e){return`${e}${this.EVENT_KEY}`}}const tt=e=>{let t=e.getAttribute("data-bs-target");if(!t||t==="#"){let n=e.getAttribute("href");if(!n||!n.includes("#")&&!n.startsWith("."))return null;n.includes("#")&&!n.startsWith("#")&&(n=`#${n.split("#")[1]}`),t=n&&n!=="#"?n.trim():null}return t?t.split(",").map(e=>is(e)).join(","):null},t={find(e,t=document.documentElement){return[].concat(...Element.prototype.querySelectorAll.call(t,e))},findOne(e,t=document.documentElement){return Element.prototype.querySelector.call(t,e)},children(e,t){return[].concat(...e.children).filter(e=>e.matches(t))},parents(e,t){const s=[];let n=e.parentNode.closest(t);for(;n;)s.push(n),n=n.parentNode.closest(t);return s},prev(e,t){let n=e.previousElementSibling;for(;n;){if(n.matches(t))return[n];n=n.previousElementSibling}return[]},next(e,t){let n=e.nextElementSibling;for(;n;){if(n.matches(t))return[n];n=n.nextElementSibling}return[]},focusableChildren(e){const t=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map(e=>`${e}:not([tabindex^="-"])`).join(",");return this.find(t,e).filter(e=>!y(e)&&R(e))},getSelectorFromElement(e){const n=tt(e);return n?t.findOne(n)?n:null:null},getElementFromSelector(e){const n=tt(e);return n?t.findOne(n):null},getMultipleElementsFromSelector(e){const n=tt(e);return n?t.find(n):[]}},_e=(n,s="hide")=>{const i=`click.dismiss${n.EVENT_KEY}`,o=n.NAME;e.on(document,i,`[data-bs-dismiss="${o}"]`,function(e){if(["A","AREA"].includes(this.tagName)&&e.preventDefault(),y(this))return;const i=t.getElementFromSelector(this)||this.closest(`.${o}`),a=n.getOrCreateInstance(i);a[s]()})},yr="alert",jr="bs.alert",jn=`.${jr}`,vr=`close${jn}`,cr=`closed${jn}`,ir="fade",Qa="show";class de extends h{static get NAME(){return yr}close(){const t=e.trigger(this._element,vr);if(t.defaultPrevented)return;this._element.classList.remove(Qa);const n=this._element.classList.contains(ir);this._queueCallback(()=>this._destroyElement(),this._element,n)}_destroyElement(){this._element.remove(),e.trigger(this._element,cr),this.dispose()}static jQueryInterface(e){return this.each(function(){const t=de.getOrCreateInstance(this);if(typeof e!="string")return;if(t[e]===void 0||e.startsWith("_")||e==="constructor")throw new TypeError(`No method named "${e}"`);t[e](this)})}}_e(de,"close"),u(de);const Ga="button",qa="bs.button",Wa=`.${qa}`,Ba=".data-api",Pa="active",fn='[data-bs-toggle="button"]',Ta=`click${Wa}${Ba}`;class fe extends h{static get NAME(){return Ga}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle(Pa))}static jQueryInterface(e){return this.each(function(){const t=fe.getOrCreateInstance(this);e==="toggle"&&t[e]()})}}e.on(document,Ta,fn,e=>{e.preventDefault();const t=e.target.closest(fn),n=fe.getOrCreateInstance(t);n.toggle()}),u(fe);const ga="swipe",P=".bs.swipe",pa=`touchstart${P}`,fa=`touchmove${P}`,ma=`touchend${P}`,ua=`pointerdown${P}`,la=`pointerup${P}`,Qi="touch",Gi="pen",Vi="pointer-event",Bi=40,Ri={endCallback:null,leftCallback:null,rightCallback:null},Ni={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class Re extends se{constructor(e,t){if(super(),this._element=e,!e||!Re.isSupported())return;this._config=this._getConfig(t),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents()}static get Default(){return Ri}static get DefaultType(){return Ni}static get NAME(){return ga}dispose(){e.off(this._element,P)}_start(e){if(!this._supportPointerEvents){this._deltaX=e.touches[0].clientX;return}this._eventIsPointerPenTouch(e)&&(this._deltaX=e.clientX)}_end(e){this._eventIsPointerPenTouch(e)&&(this._deltaX=e.clientX-this._deltaX),this._handleSwipe(),o(this._config.endCallback)}_move(e){this._deltaX=e.touches&&e.touches.length>1?0:e.touches[0].clientX-this._deltaX}_handleSwipe(){const e=Math.abs(this._deltaX);if(e<=Bi)return;const t=e/this._deltaX;if(this._deltaX=0,!t)return;o(t>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(e.on(this._element,ua,e=>this._start(e)),e.on(this._element,la,e=>this._end(e)),this._element.classList.add(Vi)):(e.on(this._element,pa,e=>this._start(e)),e.on(this._element,fa,e=>this._move(e)),e.on(this._element,ma,e=>this._end(e)))}_eventIsPointerPenTouch(e){return this._supportPointerEvents&&(e.pointerType===Gi||e.pointerType===Qi)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const Di="carousel",zi="bs.carousel",_=`.${zi}`,Kt=".data-api",Mi="ArrowLeft",Si="ArrowRight",Ei=500,ie="next",U="prev",K="left",ke="right",ji=`slide${_}`,Be=`slid${_}`,bi=`keydown${_}`,gi=`mouseenter${_}`,li=`mouseleave${_}`,ci=`dragstart${_}`,si=`load${_}${Kt}`,ei=`click${_}${Kt}`,Pt="carousel",Ce="active",Jo="slide",Zo="carousel-item-end",Qo="carousel-item-start",Xo="carousel-item-next",Go="carousel-item-prev",zt=".active",gt=".carousel-item",Ko=zt+gt,Bo=".carousel-item img",Po=".carousel-indicators",No="[data-bs-slide], [data-bs-slide-to]",Do='[data-bs-ride="carousel"]',To={[Mi]:ke,[Si]:K},Fo={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},vo={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class ee extends h{constructor(e,n){super(e,n),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=t.findOne(Po,this._element),this._addEventListeners(),this._config.ride===Pt&&this.cycle()}static get Default(){return Fo}static get DefaultType(){return vo}static get NAME(){return Di}next(){this._slide(ie)}nextWhenVisible(){!document.hidden&&R(this._element)&&this.next()}prev(){this._slide(U)}pause(){this._isSliding&&ns(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval(()=>this.nextWhenVisible(),this._config.interval)}_maybeEnableCycle(){if(!this._config.ride)return;if(this._isSliding){e.one(this._element,Be,()=>this.cycle());return}this.cycle()}to(t){const n=this._getItems();if(t>n.length-1||t<0)return;if(this._isSliding){e.one(this._element,Be,()=>this.to(t));return}const s=this._getItemIndex(this._getActive());if(s===t)return;const o=t>s?ie:U;this._slide(o,n[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(e){return e.defaultInterval=e.interval,e}_addEventListeners(){this._config.keyboard&&e.on(this._element,bi,e=>this._keydown(e)),this._config.pause==="hover"&&(e.on(this._element,gi,()=>this.pause()),e.on(this._element,li,()=>this._maybeEnableCycle())),this._config.touch&&Re.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const n of t.find(Bo,this._element))e.on(n,ci,e=>e.preventDefault());const n=()=>{if(this._config.pause!=="hover")return;this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout(()=>this._maybeEnableCycle(),Ei+this._config.interval)},s={leftCallback:()=>this._slide(this._directionToOrder(K)),rightCallback:()=>this._slide(this._directionToOrder(ke)),endCallback:n};this._swipeHelper=new Re(this._element,s)}_keydown(e){if(/input|textarea/i.test(e.target.tagName))return;const t=To[e.key];t&&(e.preventDefault(),this._slide(this._directionToOrder(t)))}_getItemIndex(e){return this._getItems().indexOf(e)}_setActiveIndicatorElement(e){if(!this._indicatorsElement)return;const s=t.findOne(zt,this._indicatorsElement);s.classList.remove(Ce),s.removeAttribute("aria-current");const n=t.findOne(`[data-bs-slide-to="${e}"]`,this._indicatorsElement);n&&(n.classList.add(Ce),n.setAttribute("aria-current","true"))}_updateInterval(){const e=this._activeElement||this._getActive();if(!e)return;const t=Number.parseInt(e.getAttribute("data-bs-interval"),10);this._config.interval=t||this._config.defaultInterval}_slide(t,n=null){if(this._isSliding)return;const o=this._getActive(),a=t===ie,s=n||$e(this._getItems(),o,a,this._config.wrap);if(s===o)return;const c=this._getItemIndex(s),l=n=>e.trigger(this._element,n,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(o),to:c}),d=l(ji);if(d.defaultPrevented)return;if(!o||!s)return;const u=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(c),this._activeElement=s;const i=a?Qo:Zo,r=a?Xo:Go;s.classList.add(r),oe(s),o.classList.add(i),s.classList.add(i);const h=()=>{s.classList.remove(i,r),s.classList.add(Ce),o.classList.remove(Ce,r,i),this._isSliding=!1,l(Be)};this._queueCallback(h,o,this._isAnimated()),u&&this.cycle()}_isAnimated(){return this._element.classList.contains(Jo)}_getActive(){return t.findOne(Ko,this._element)}_getItems(){return t.find(gt,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(e){return c()?e===K?U:ie:e===K?ie:U}_orderToDirection(e){return c()?e===U?K:ke:e===U?ke:K}static jQueryInterface(e){return this.each(function(){const t=ee.getOrCreateInstance(this,e);if(typeof e=="number"){t.to(e);return}if(typeof e=="string"){if(t[e]===void 0||e.startsWith("_")||e==="constructor")throw new TypeError(`No method named "${e}"`);t[e]()}})}}e.on(document,ei,No,function(e){const s=t.getElementFromSelector(this);if(!s||!s.classList.contains(Pt))return;e.preventDefault();const n=ee.getOrCreateInstance(s),o=this.getAttribute("data-bs-slide-to");if(o){n.to(o),n._maybeEnableCycle();return}if(v.getDataAttribute(this,"slide")==="next"){n.next(),n._maybeEnableCycle();return}n.prev(),n._maybeEnableCycle()}),e.on(window,si,()=>{const e=t.find(Do);for(const t of e)ee.getOrCreateInstance(t)}),u(ee);const rs="collapse",po="bs.collapse",J=`.${po}`,co=".data-api",ao=`show${J}`,io=`shown${J}`,Js=`hide${J}`,Qs=`hidden${J}`,Gs=`click${J}${co}`,ct="show",L="collapse",pe="collapsing",Ys="collapsed",Ks=`:scope .${L} .${L}`,Us="collapse-horizontal",Ws="width",$s="height",Vs=".collapse.show, .collapse.collapsing",nt='[data-bs-toggle="collapse"]',Bs={parent:null,toggle:!0},Is={parent:"(null|element)",toggle:"boolean"};class te extends h{constructor(e,n){super(e,n),this._isTransitioning=!1,this._triggerArray=[];const s=t.find(nt);for(const e of s){const n=t.getSelectorFromElement(e),o=t.find(n).filter(e=>e===this._element);n!==null&&o.length&&this._triggerArray.push(e)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return Bs}static get DefaultType(){return Is}static get NAME(){return rs}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let n=[];if(this._config.parent&&(n=this._getFirstLevelChildren(Vs).filter(e=>e!==this._element).map(e=>te.getOrCreateInstance(e,{toggle:!1}))),n.length&&n[0]._isTransitioning)return;const s=e.trigger(this._element,ao);if(s.defaultPrevented)return;for(const e of n)e.hide();const t=this._getDimension();this._element.classList.remove(L),this._element.classList.add(pe),this._element.style[t]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const o=()=>{this._isTransitioning=!1,this._element.classList.remove(pe),this._element.classList.add(L,ct),this._element.style[t]="",e.trigger(this._element,io)},i=t[0].toUpperCase()+t.slice(1),a=`scroll${i}`;this._queueCallback(o,this._element,!0),this._element.style[t]=`${this._element[a]}px`}hide(){if(this._isTransitioning||!this._isShown())return;const s=e.trigger(this._element,Js);if(s.defaultPrevented)return;const n=this._getDimension();this._element.style[n]=`${this._element.getBoundingClientRect()[n]}px`,oe(this._element),this._element.classList.add(pe),this._element.classList.remove(L,ct);for(const e of this._triggerArray){const n=t.getElementFromSelector(e);n&&!this._isShown(n)&&this._addAriaAndCollapsedClass([e],!1)}this._isTransitioning=!0;const o=()=>{this._isTransitioning=!1,this._element.classList.remove(pe),this._element.classList.add(L),e.trigger(this._element,Qs)};this._element.style[n]="",this._queueCallback(o,this._element,!0)}_isShown(e=this._element){return e.classList.contains(ct)}_configAfterMerge(e){return e.toggle=Boolean(e.toggle),e.parent=w(e.parent),e}_getDimension(){return this._element.classList.contains(Us)?Ws:$s}_initializeChildren(){if(!this._config.parent)return;const e=this._getFirstLevelChildren(nt);for(const n of e){const s=t.getElementFromSelector(n);s&&this._addAriaAndCollapsedClass([n],this._isShown(s))}}_getFirstLevelChildren(e){const n=t.find(Ks,this._config.parent);return t.find(e,this._config.parent).filter(e=>!n.includes(e))}_addAriaAndCollapsedClass(e,t){if(!e.length)return;for(const n of e)n.classList.toggle(Ys,!t),n.setAttribute("aria-expanded",t)}static jQueryInterface(e){const t={};return typeof e=="string"&&/show|hide/.test(e)&&(t.toggle=!1),this.each(function(){const n=te.getOrCreateInstance(this,t);if(typeof e=="string"){if(typeof n[e]=="undefined")throw new TypeError(`No method named "${e}"`);n[e]()}})}}e.on(document,Gs,nt,function(e){(e.target.tagName==="A"||e.delegateTarget&&e.delegateTarget.tagName==="A")&&e.preventDefault();for(const e of t.getMultipleElementsFromSelector(this))te.getOrCreateInstance(e,{toggle:!1}).toggle()}),u(te);var k,A,Q,s="top",Nn,In,ae,Yn,Xn,ot,Tt,Ft,St,At,je,a="bottom",i="right",n="left",Ee="auto",Y=[s,a,i,n],T="start",q="end",Vt="clippingParents",Ve="viewport",I="popper",Ut="reference",Te=Y.reduce(function(e,t){return e.concat([t+"-"+T,t+"-"+q])},[]),Xe=[].concat(Y,[Ee]).reduce(function(e,t){return e.concat([t,t+"-"+T,t+"-"+q])},[]),Yt="beforeRead",Gt="read",Xt="afterRead",Qt="beforeMain",Zt="main",Jt="afterMain",en="beforeWrite",tn="write",nn="afterWrite",sn=[Yt,Gt,Xt,Qt,Zt,Jt,en,tn,nn];function f(e){return e?(e.nodeName||"").toLowerCase():null}function r(e){if(e==null)return window;if(e.toString()!=="[object Window]"){var t=e.ownerDocument;return t?t.defaultView||window:window}return e}function D(e){var t=r(e).Element;return e instanceof t||e instanceof Element}function l(e){var t=r(e).HTMLElement;return e instanceof t||e instanceof HTMLElement}function Me(e){if(typeof ShadowRoot=="undefined")return!1;var t=r(e).ShadowRoot;return e instanceof t||e instanceof ShadowRoot}function Hs(e){var t=e.state;Object.keys(t.elements).forEach(function(e){var o=t.styles[e]||{},s=t.attributes[e]||{},n=t.elements[e];if(!l(n)||!f(n))return;Object.assign(n.style,o),Object.keys(s).forEach(function(e){var t=s[e];t===!1?n.removeAttribute(e):n.setAttribute(e,t===!0?"":t)})})}function Ps(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow),function(){Object.keys(t.elements).forEach(function(e){var s=t.elements[e],o=t.attributes[e]||{},i=Object.keys(t.styles.hasOwnProperty(e)?t.styles[e]:n[e]),a=i.reduce(function(e,t){return e[t]="",e},{});if(!l(s)||!f(s))return;Object.assign(s.style,a),Object.keys(o).forEach(function(e){s.removeAttribute(e)})})}}const st={name:"applyStyles",enabled:!0,phase:"write",fn:Hs,effect:Ps,requires:["computeStyles"]};function p(e){return e.split("-")[0]}k=Math.max,Q=Math.min,A=Math.round;function et(){var e=navigator.userAgentData;return e!=null&&e.brands&&Array.isArray(e.brands)?e.brands.map(function(e){return e.brand+"/"+e.version}).join(" "):navigator.userAgent}function bn(){return!/^((?!chrome|android).)*safari/i.test(et())}function X(e,t,n){t===void 0&&(t=!1),n===void 0&&(n=!1),s=e.getBoundingClientRect(),o=1,i=1,t&&l(e)&&(o=e.offsetWidth>0?A(s.width)/e.offsetWidth||1:1,i=e.offsetHeight>0?A(s.height)/e.offsetHeight||1:1);var s,o,i,f=D(e)?r(e):window,a=f.visualViewport,u=!bn()&&n,c=(s.left+(u&&a?a.offsetLeft:0))/o,d=(s.top+(u&&a?a.offsetTop:0))/i,h=s.width/o,m=s.height/i;return{width:h,height:m,top:d,right:c+h,bottom:d+m,left:c,x:c,y:d}}function ut(e){var t=X(e),n=e.offsetWidth,s=e.offsetHeight;return Math.abs(t.width-n)<=1&&(n=t.width),Math.abs(t.height-s)<=1&&(s=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:s}}function _n(e,t){var n,s=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(s&&Me(s)){n=t;do{if(n&&e.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function j(e){return r(e).getComputedStyle(e)}function Rs(e){return["table","td","th"].indexOf(f(e))>=0}function E(e){return((D(e)?e.ownerDocument:e.document)||window.document).documentElement}function ge(e){return f(e)==="html"?e:e.assignedSlot||e.parentNode||(Me(e)?e.host:null)||E(e)}function En(e){return!l(e)||j(e).position==="fixed"?null:e.offsetParent}function As(e){var t,n,o,s=/firefox/i.test(et()),i=/Trident/i.test(et());if(i&&l(e)&&(o=j(e),o.position==="fixed"))return null;for(t=ge(e),Me(t)&&(t=t.host);l(t)&&["html","body"].indexOf(f(t))<0;){if(n=j(t),n.transform!=="none"||n.perspective!=="none"||n.contain==="paint"||["transform","perspective"].indexOf(n.willChange)!==-1||s&&n.willChange==="filter"||s&&n.filter&&n.filter!=="none")return t;t=t.parentNode}return null}function ce(e){for(var n=r(e),t=En(e);t&&Rs(t)&&j(t).position==="static";)t=En(t);return t&&(f(t)==="html"||f(t)==="body"&&j(t).position==="static")?n:t||As(e)||n}function Qe(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function re(e,t,n){return k(e,Q(t,n))}function Cs(e,t,n){var s=re(e,t,n);return s>n?n:s}function Tn(){return{top:0,right:0,bottom:0,left:0}}function zn(e){return Object.assign({},Tn(),e)}function Dn(e,t){return t.reduce(function(t,n){return t[n]=e,t},{})}Nn=function(t,n){return t=typeof t=="function"?t(Object.assign({},n.rects,{placement:n.placement})):t,zn(typeof t!="number"?t:Dn(t,Y))};function Os(e){var r,c,d,u,f,g,v,b,j,y,_,O,x,C,E,t=e.state,S=e.name,A=e.options,h=t.elements.arrow,m=t.modifiersData.popperOffsets,w=p(t.placement),o=Qe(w),k=[n,i].indexOf(w)>=0,l=k?"height":"width";if(!h||!m)return;g=Nn(A.padding,t),v=ut(h),b=o==="y"?s:n,j=o==="y"?a:i,y=t.rects.reference[l]+t.rects.reference[o]-m[o]-t.rects.popper[l],_=m[o]-t.rects.reference[o],c=ce(h),f=c?o==="y"?c.clientHeight||0:c.clientWidth||0:0,O=y/2-_/2,x=g[b],C=f-v[l]-g[j],u=f/2-v[l]/2+O,d=re(x,u,C),E=o,t.modifiersData[S]=(r={},r[E]=d,r.centerOffset=d-u,r)}function ys(e){var n=e.state,o=e.options,s=o.element,t=s===void 0?"[data-popper-arrow]":s;if(t==null)return;if(typeof t=="string"&&(t=n.elements.popper.querySelector(t),!t))return;if(!_n(n.elements.popper,t))return;n.elements.arrow=t}const Pn={name:"arrow",enabled:!0,phase:"main",fn:Os,effect:ys,requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function V(e){return e.split("-")[1]}In={top:"auto",right:"auto",bottom:"auto",left:"auto"};function bs(e,t){var s=e.x,o=e.y,n=t.devicePixelRatio||1;return{x:A(s*n)/n||0,y:A(o*n)/n||0}}function Vn(e){var c,u,h,p,g,b,y,T,z,f=e.popper,N=e.popperRect,d=e.placement,A=e.variation,m=e.offsets,x=e.position,v=e.gpuAcceleration,S=e.adaptive,_=e.roundOffsets,M=e.isFixed,L=m.x,t=L===void 0?0:L,D=m.y,o=D===void 0?0:D,C=typeof _=="function"?_({x:t,y:o}):{x:t,y:o},t=C.x,o=C.y,F=m.hasOwnProperty("x"),k=m.hasOwnProperty("y"),w=n,O=s,l=window;return S&&(c=ce(f),g="clientHeight",y="clientWidth",c===r(f)&&(c=E(f),j(c).position!=="static"&&x==="absolute"&&(g="scrollHeight",y="scrollWidth")),c=c,(d===s||(d===n||d===i)&&A===q)&&(O=a,T=M&&c===l&&l.visualViewport?l.visualViewport.height:c[g],o-=T-N.height,o*=v?1:-1),(d===n||(d===s||d===a)&&A===q)&&(w=i,z=M&&c===l&&l.visualViewport?l.visualViewport.width:c[y],t-=z-N.width,t*=v?1:-1)),p=Object.assign({position:x},S&&In),b=_===!0?bs({x:t,y:o},r(f)):{x:t,y:o},t=b.x,o=b.y,v?Object.assign({},p,(h={},h[O]=k?"0":"",h[w]=F?"0":"",h.transform=(l.devicePixelRatio||1)<=1?"translate("+t+"px, "+o+"px)":"translate3d("+t+"px, "+o+"px, 0)",h)):Object.assign({},p,(u={},u[O]=k?o+"px":"",u[w]=F?t+"px":"",u.transform="",u))}function vs(e){var t=e.state,n=e.options,s=n.gpuAcceleration,c=s===void 0||s,o=n.adaptive,l=o===void 0||o,i=n.roundOffsets,a=i===void 0||i,r={placement:p(t.placement),variation:V(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:c,isFixed:t.options.strategy==="fixed"};t.modifiersData.popperOffsets!=null&&(t.styles.popper=Object.assign({},t.styles.popper,Vn(Object.assign({},r,{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:l,roundOffsets:a})))),t.modifiersData.arrow!=null&&(t.styles.arrow=Object.assign({},t.styles.arrow,Vn(Object.assign({},r,{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:a})))),t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-placement":t.placement})}const Fe={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:vs,data:{}};ae={passive:!0};function gs(e){var n=e.state,t=e.instance,s=e.options,o=s.scroll,i=o===void 0||o,a=s.resize,c=a===void 0||a,l=r(n.elements.popper),d=[].concat(n.scrollParents.reference,n.scrollParents.popper);return i&&d.forEach(function(e){e.addEventListener("scroll",t.update,ae)}),c&&l.addEventListener("resize",t.update,ae),function(){i&&d.forEach(function(e){e.removeEventListener("scroll",t.update,ae)}),c&&l.removeEventListener("resize",t.update,ae)}}const ze={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:gs,data:{}};Yn={left:"right",right:"left",bottom:"top",top:"bottom"};function Ae(e){return e.replace(/left|right|bottom|top/g,function(e){return Yn[e]})}Xn={start:"end",end:"start"};function Qn(e){return e.replace(/start|end/g,function(e){return Xn[e]})}function We(e){var t=r(e),n=t.pageXOffset,s=t.pageYOffset;return{scrollLeft:n,scrollTop:s}}function Ke(e){return X(E(e)).left+We(e).scrollLeft}function hs(e,t){var s,d=r(e),o=E(e),n=d.visualViewport,i=o.clientWidth,a=o.clientHeight,c=0,l=0;return n&&(i=n.width,a=n.height,s=bn(),(s||!s&&t==="fixed")&&(c=n.offsetLeft,l=n.offsetTop)),{width:i,height:a,x:c+Ke(e),y:l}}function us(e){var s,n=E(e),o=We(e),t=(s=e.ownerDocument)==null?void 0:s.body,i=k(n.scrollWidth,n.clientWidth,t?t.scrollWidth:0,t?t.clientWidth:0),r=k(n.scrollHeight,n.clientHeight,t?t.scrollHeight:0,t?t.clientHeight:0),a=-o.scrollLeft+Ke(e),c=-o.scrollTop;return j(t||n).direction==="rtl"&&(a+=k(n.clientWidth,t?t.clientWidth:0)-i),{width:i,height:r,x:a,y:c}}function Je(e){var t=j(e),n=t.overflow,s=t.overflowX,o=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+o+s)}function ss(e){return["html","body","#document"].indexOf(f(e))>=0?e.ownerDocument.body:l(e)&&Je(e)?e:ss(ge(e))}function ne(e,t){t===void 0&&(t=[]);var s,n=ss(e),o=n===((s=e.ownerDocument)==null?void 0:s.body),i=r(n),a=o?[i].concat(i.visualViewport||[],Je(n)?n:[]):n,c=t.concat(a);return o?c:c.concat(ne(ge(a)))}function rt(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function Fi(e,t){var n=X(e,!1,t==="fixed");return n.top=n.top+e.clientTop,n.left=n.left+e.clientLeft,n.bottom=n.top+e.clientHeight,n.right=n.left+e.clientWidth,n.width=e.clientWidth,n.height=e.clientHeight,n.x=n.left,n.y=n.top,n}function Mt(e,t,n){return t===Ve?rt(hs(e,n)):D(t)?Fi(t,n):rt(us(E(e)))}function ls(e){var n=ne(ge(e)),s=["absolute","fixed"].indexOf(j(e).position)>=0,t=s&&l(e)?ce(e):e;return D(t)?n.filter(function(e){return D(e)&&_n(e,t)&&f(e)!=="body"}):[]}function ds(e,t,n,s){var a=t==="clippingParents"?ls(e):[].concat(t),i=[].concat(a,[n]),r=i[0],o=i.reduce(function(t,n){var o=Mt(e,n,s);return t.top=k(o.top,t.top),t.right=Q(o.right,t.right),t.bottom=Q(o.bottom,t.bottom),t.left=k(o.left,t.left),t},Mt(e,r,s));return o.width=o.right-o.left,o.height=o.bottom-o.top,o.x=o.left,o.y=o.top,o}function ts(e){var o,r,l,t=e.reference,c=e.element,d=e.placement,u=d?p(d):null,f=d?V(d):null,h=t.x+t.width/2-c.width/2,m=t.y+t.height/2-c.height/2;switch(u){case s:o={x:h,y:t.y-c.height};break;case a:o={x:h,y:t.y+t.height};break;case i:o={x:t.x+t.width,y:m};break;case n:o={x:t.x-c.width,y:m};break;default:o={x:t.x,y:t.y}}if(r=u?Qe(u):null,r!=null)switch(l=r==="y"?"height":"width",f){case T:o[r]=o[r]-(t[l]/2-c[l]/2);break;case q:o[r]=o[r]+(t[l]/2-c[l]/2);break}return o}function N(e,t){t===void 0&&(t={});var _,n=t,v=n.placement,j=v===void 0?e.placement:v,f=n.strategy,T=f===void 0?e.strategy:f,p=n.boundary,C=p===void 0?Vt:p,O=n.rootBoundary,F=O===void 0?Ve:O,x=n.elementContext,c=x===void 0?I:x,m=n.altBoundary,M=m!==void 0&&m,b=n.padding,d=b===void 0?0:b,o=zn(typeof d!="number"?d:Dn(d,Y)),S=c===I?Ut:I,w=e.rects.popper,h=e.elements[M?S:c],r=ds(D(h)?h:h.contextElement||E(e.elements.popper),C,F,T),y=X(e.elements.reference),k=ts({reference:y,element:w,strategy:"absolute",placement:j}),A=rt(Object.assign({},w,k)),l=c===I?A:y,u={top:r.top-l.top+o.top,bottom:l.bottom-r.bottom+o.bottom,left:r.left-l.left+o.left,right:l.right-r.right+o.right},g=e.modifiersData.offset;return c===I&&g&&(_=g[j],Object.keys(u).forEach(function(e){var t=[i,a].indexOf(e)>=0?1:-1,n=[s,a].indexOf(e)>=0?"y":"x";u[e]+=_[n]*t})),u}function ms(e,t){t===void 0&&(t={});var s,n=t,c=n.placement,l=n.boundary,d=n.rootBoundary,u=n.padding,h=n.flipVariations,i=n.allowedAutoPlacements,m=i===void 0?Xe:i,a=V(c),r=a?h?Te:Te.filter(function(e){return V(e)===a}):Y,o=r.filter(function(e){return m.indexOf(e)>=0});return o.length===0&&(o=r),s=o.reduce(function(t,n){return t[n]=N(e,{placement:n,boundary:l,rootBoundary:d,padding:u})[p(n)],t},{}),Object.keys(s).sort(function(e,t){return s[e]-s[t]})}function fs(e){if(p(e)===Ee)return[];var t=Ae(e);return[Qn(e),t,Qn(t)]}function ps(e){var r,c,l,u,h,g,v,y,_,x,E,k,z,t=e.state,o=e.options,C=e.name;if(t.modifiersData[C]._skip)return;for(var M=o.mainAxis,I=M===void 0||M,D=o.altAxis,P=D===void 0||D,R=o.fallbackPlacements,L=o.padding,w=o.boundary,O=o.rootBoundary,B=o.altBoundary,F=o.flipVariations,j=F===void 0||F,$=o.allowedAutoPlacements,d=t.options.placement,K=p(d),H=K===d,q=R||(H||!j?[Ae(d)]:fs(d)),f=[d].concat(q).reduce(function(e,n){return e.concat(p(n)===Ee?ms(t,{placement:n,boundary:w,rootBoundary:O,padding:L,flipVariations:j,allowedAutoPlacements:$}):n)},[]),U=t.rects.reference,W=t.rects.popper,A=new Map,S=!0,m=f[0],b=0;b=0,_=y?"width":"height",h=N(t,{placement:r,boundary:w,rootBoundary:O,altBoundary:B,padding:L}),l=y?g?i:n:g?a:s,U[_]>W[_]&&(l=Ae(l)),z=Ae(l),c=[],I&&c.push(h[v]<=0),P&&c.push(h[l]<=0,h[z]<=0),c.every(function(e){return e})){m=r,S=!1;break}A.set(r,c)}if(S)for(k=j?3:1,E=function(t){var n=f.find(function(e){var n=A.get(e);if(n)return n.slice(0,t).every(function(e){return e})});if(n)return m=n,"break"},u=k;u>0;u--)if(x=E(u),x==="break")break;t.placement!==m&&(t.modifiersData[C]._skip=!0,t.placement=m,t.reset=!0)}const Kn={name:"flip",enabled:!0,phase:"main",fn:ps,requiresIfExists:["offset"],data:{_skip:!1}};function $n(e,t,n){return n===void 0&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function Bn(e){return[s,i,a,n].some(function(t){return e[t]>=0})}function js(e){var t=e.state,a=e.name,r=t.rects.reference,c=t.rects.popper,l=t.modifiersData.preventOverflow,d=N(t,{elementContext:"reference"}),u=N(t,{altBoundary:!0}),n=$n(d,r),s=$n(u,c,l),o=Bn(n),i=Bn(s);t.modifiersData[a]={referenceClippingOffsets:n,popperEscapeOffsets:s,isReferenceHidden:o,hasPopperEscaped:i},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":o,"data-popper-escaped":i})}const Rn={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:js};function _s(e,t,o){var c=p(e),d=[n,s].indexOf(c)>=0?-1:1,l=typeof o=="function"?o(Object.assign({},t,{placement:e})):o,a=l[0],r=l[1],a=a||0,r=(r||0)*d;return[n,i].indexOf(c)>=0?{x:r,y:a}:{x:a,y:r}}function ws(e){var t=e.state,i=e.options,a=e.name,n=i.offset,r=n===void 0?[0,0]:n,s=Xe.reduce(function(e,n){return e[n]=_s(n,t.rects,r),e},{}),o=s[t.placement],c=o.x,l=o.y;t.modifiersData.popperOffsets!=null&&(t.modifiersData.popperOffsets.x+=c,t.modifiersData.popperOffsets.y+=l),t.modifiersData[a]=s}const Ln={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:ws};function xs(e){var t=e.state,n=e.name;t.modifiersData[n]=ts({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})}const He={name:"popperOffsets",enabled:!0,phase:"read",fn:xs,data:{}};function Es(e){return e==="x"?"y":"x"}function ks(e){var r,c,h,f,v,w,x,E,A,M,F,z,D,R,P,H,I,B,$,W,U,K,q,Y,G,X,Z,J,t=e.state,l=e.options,be=e.name,fe,ue,te,ne,oe,ae,le,me,pe=l.mainAxis,ge=pe===void 0||pe,se=l.altAxis,we=se!==void 0&&se,_e=l.boundary,ye=l.rootBoundary,ve=l.altBoundary,je=l.padding,de=l.tether,d=de===void 0||de,ie=l.tetherOffset,S=ie===void 0?0:ie,O=N(t,{boundary:_e,rootBoundary:ye,padding:je,altBoundary:ve}),ee=p(t.placement),C=V(t.placement),he=!C,o=Qe(ee),j=Es(o),b=t.modifiersData.popperOffsets,u=t.rects.reference,g=t.rects.popper,_=typeof S=="function"?S(Object.assign({},t.rects,{placement:t.placement})):S,m=typeof _=="number"?{mainAxis:_,altAxis:_}:Object.assign({mainAxis:0,altAxis:0},_),y=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,L={x:0,y:0};if(!b)return;ge&&(P=o==="y"?s:n,H=o==="y"?a:i,r=o==="y"?"height":"width",h=b[o],$=h+O[P],W=h-O[H],U=d?-g[r]/2:0,J=C===T?u[r]:g[r],Z=C===T?-g[r]:-u[r],Y=t.elements.arrow,ue=d&&Y?ut(Y):{width:0,height:0},E=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:Tn(),q=E[P],K=E[H],v=re(0,u[r],ue[r]),te=he?u[r]/2-U-v-q-m.mainAxis:J-v-q-m.mainAxis,ne=he?-u[r]/2+U+v+K+m.mainAxis:Z+v+K+m.mainAxis,x=t.elements.arrow&&ce(t.elements.arrow),oe=x?o==="y"?x.clientTop||0:x.clientLeft||0:0,B=(fe=y?.[o])!=null?fe:0,ae=h+te-B-oe,le=h+ne-B,I=re(d?Q($,ae):$,h,d?k(W,le):W),b[o]=I,L[o]=I-h),we&&(G=o==="x"?s:n,me=o==="x"?a:i,c=b[j],f=j==="y"?"height":"width",R=c+O[G],D=c-O[me],w=[s,n].indexOf(ee)!==-1,z=(X=y?.[j])!=null?X:0,F=w?R:c-u[f]-g[f]-z+m.altAxis,M=w?c+u[f]+g[f]-z-m.altAxis:D,A=d&&w?Cs(F,c,M):re(d?F:R,c,d?M:D),b[j]=A,L[j]=A-c),t.modifiersData[be]=L}const kn={name:"preventOverflow",enabled:!0,phase:"main",fn:ks,requiresIfExists:["offset"]};function Ss(e){return{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}}function Ms(e){return e===r(e)||!l(e)?We(e):Ss(e)}function Fs(e){var t=e.getBoundingClientRect(),n=A(t.width)/e.offsetWidth||1,s=A(t.height)/e.offsetHeight||1;return n!==1||s!==1}function Ts(e,t,n){n===void 0&&(n=!1);var r=l(t),c=l(t)&&Fs(t),i=E(t),o=X(e,c,n),a={scrollLeft:0,scrollTop:0},s={x:0,y:0};return(r||!r&&!n)&&((f(t)!=="body"||Je(i))&&(a=Ms(t)),l(t)?(s=X(t,!0),s.x+=t.clientLeft,s.y+=t.clientTop):i&&(s.x=Ke(i))),{x:o.left+a.scrollLeft-s.x,y:o.top+a.scrollTop-s.y,width:o.width,height:o.height}}function zs(e){var n=new Map,t=new Set,s=[];e.forEach(function(e){n.set(e.name,e)});function o(e){t.add(e.name);var i=[].concat(e.requires||[],e.requiresIfExists||[]);i.forEach(function(e){if(!t.has(e)){var s=n.get(e);s&&o(s)}}),s.push(e)}return e.forEach(function(e){t.has(e.name)||o(e)}),s}function Ds(e){var t=zs(e);return sn.reduce(function(e,n){return e.concat(t.filter(function(e){return e.phase===n}))},[])}function Ns(e){var t;return function(){return t||(t=new Promise(function(n){Promise.resolve().then(function(){t=void 0,n(e())})})),t}}function Ls(e){var t=e.reduce(function(e,t){var n=e[t.name];return e[t.name]=n?Object.assign({},n,t,{options:Object.assign({},n.options,t.options),data:Object.assign({},n.data,t.data)}):t,e},{});return Object.keys(t).map(function(e){return t[e]})}ot={placement:"bottom",modifiers:[],strategy:"absolute"};function un(){for(var t=arguments.length,n=new Array(t),e=0;eNumber.parseInt(e,10)):typeof e=="function"?t=>e(t,this._element):e}_getPopperConfig(){const e={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||this._config.display==="static")&&(v.setDataAttribute(this._menu,"popper","static"),e.modifiers=[{name:"applyStyles",enabled:!1}]),{...e,...o(this._config.popperConfig,[e])}}_selectMenuItem({key:e,target:n}){const s=t.find(yo,this._menu).filter(e=>R(e));if(!s.length)return;$e(s,n,e===bt,!s.includes(n)).focus()}static jQueryInterface(e){return this.each(function(){const t=m.getOrCreateInstance(this,e);if(typeof e!="string")return;if(typeof t[e]=="undefined")throw new TypeError(`No method named "${e}"`);t[e]()})}static clearMenus(e){if(e.button===eo||e.type==="keyup"&&e.key!==jt)return;const n=t.find(go);for(const a of n){const t=m.getInstance(a);if(!t||t._config.autoClose===!1)continue;const s=e.composedPath(),o=s.includes(t._menu);if(s.includes(t._element)||t._config.autoClose==="inside"&&!o||t._config.autoClose==="outside"&&o)continue;if(t._menu.contains(e.target)&&(e.type==="keyup"&&e.key===jt||/input|select|option|textarea|form/i.test(e.target.tagName)))continue;const i={relatedTarget:t._element};e.type==="click"&&(i.clickEvent=e),t._completeHide(i)}}static dataApiKeydownHandler(e){const a=/input|textarea/i.test(e.target.tagName),s=e.key===Xs,o=[Zs,bt].includes(e.key);if(!o&&!s)return;if(a&&!s)return;e.preventDefault();const i=this.matches(z)?this:t.prev(this,z)[0]||t.next(this,z)[0]||t.findOne(z,e.delegateTarget.parentNode),n=m.getOrCreateInstance(i);if(o){e.stopPropagation(),n.show(),n._selectMenuItem(e);return}n._isShown()&&(e.stopPropagation(),n.hide(),i.focus())}}e.on(document,yt,z,m.dataApiKeydownHandler),e.on(document,yt,me,m.dataApiKeydownHandler),e.on(document,vt,m.clearMenus),e.on(document,ro,m.clearMenus),e.on(document,vt,z,function(e){e.preventDefault(),m.getOrCreateInstance(this).toggle()}),u(m);const _t="backdrop",zo="fade",wt="show",Ot=`mousedown.bs.${_t}`,Lo={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Ro={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class xt extends se{constructor(e){super(),this._config=this._getConfig(e),this._isAppended=!1,this._element=null}static get Default(){return Lo}static get DefaultType(){return Ro}static get NAME(){return _t}show(e){if(!this._config.isVisible){o(e);return}this._append();const t=this._getElement();this._config.isAnimated&&oe(t),t.classList.add(wt),this._emulateAnimation(()=>{o(e)})}hide(e){if(!this._config.isVisible){o(e);return}this._getElement().classList.remove(wt),this._emulateAnimation(()=>{this.dispose(),o(e)})}dispose(){if(!this._isAppended)return;e.off(this._element,Ot),this._element.remove(),this._isAppended=!1}_getElement(){if(!this._element){const e=document.createElement("div");e.className=this._config.className,this._config.isAnimated&&e.classList.add(zo),this._element=e}return this._element}_configAfterMerge(e){return e.rootElement=w(e.rootElement),e}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),e.on(t,Ot,()=>{o(this._config.clickCallback)}),this._isAppended=!0}_emulateAnimation(e){Zn(e,this._getElement(),this._config.isAnimated)}}const Ho="focustrap",Io="bs.focustrap",be=`.${Io}`,Vo=`focusin${be}`,$o=`keydown.tab${be}`,Wo="Tab",Uo="forward",kt="backward",qo={autofocus:!0,trapElement:null},Yo={autofocus:"boolean",trapElement:"element"};class Dt extends se{constructor(e){super(),this._config=this._getConfig(e),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return qo}static get DefaultType(){return Yo}static get NAME(){return Ho}activate(){if(this._isActive)return;this._config.autofocus&&this._config.trapElement.focus(),e.off(document,be),e.on(document,Vo,e=>this._handleFocusin(e)),e.on(document,$o,e=>this._handleKeydown(e)),this._isActive=!0}deactivate(){if(!this._isActive)return;this._isActive=!1,e.off(document,be)}_handleFocusin(e){const{trapElement:n}=this._config;if(e.target===document||e.target===n||n.contains(e.target))return;const s=t.focusableChildren(n);s.length===0?n.focus():this._lastTabNavDirection===kt?s[s.length-1].focus():s[0].focus()}_handleKeydown(e){if(e.key!==Wo)return;this._lastTabNavDirection=e.shiftKey?kt:Uo}}const Nt=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",Lt=".sticky-top",Oe="padding-right",Rt="margin-right";class qe{constructor(){this._element=document.body}getWidth(){const e=document.documentElement.clientWidth;return Math.abs(window.innerWidth-e)}hide(){const e=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,Oe,t=>t+e),this._setElementAttributes(Nt,Oe,t=>t+e),this._setElementAttributes(Lt,Rt,t=>t-e)}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,Oe),this._resetElementAttributes(Nt,Oe),this._resetElementAttributes(Lt,Rt)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(e,t,n){const s=this.getWidth(),o=e=>{if(e!==this._element&&window.innerWidth>e.clientWidth+s)return;this._saveInitialAttribute(e,t);const o=window.getComputedStyle(e).getPropertyValue(t);e.style.setProperty(t,`${n(Number.parseFloat(o))}px`)};this._applyManipulationCallback(e,o)}_saveInitialAttribute(e,t){const n=e.style.getPropertyValue(t);n&&v.setDataAttribute(e,t,n)}_resetElementAttributes(e,t){const n=e=>{const n=v.getDataAttribute(e,t);if(n===null){e.style.removeProperty(t);return}v.removeDataAttribute(e,t),e.style.setProperty(t,n)};this._applyManipulationCallback(e,n)}_applyManipulationCallback(e,n){if(g(e)){n(e);return}for(const s of t.find(e,this._element))n(s)}}const ti="modal",ni="bs.modal",d=`.${ni}`,oi=".data-api",ii="Escape",ai=`hide${d}`,ri=`hidePrevented${d}`,Ht=`hidden${d}`,It=`show${d}`,di=`shown${d}`,ui=`resize${d}`,hi=`click.dismiss${d}`,mi=`mousedown.dismiss${d}`,fi=`keydown.dismiss${d}`,pi=`click${d}${oi}`,Bt="modal-open",vi="fade",$t="show",Se="modal-static",yi=".modal.show",_i=".modal-dialog",wi=".modal-body",Oi='[data-bs-toggle="modal"]',xi={backdrop:!0,focus:!0,keyboard:!0},Ci={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class $ extends h{constructor(e,n){super(e,n),this._dialog=t.findOne(_i,this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new qe,this._addEventListeners()}static get Default(){return xi}static get DefaultType(){return Ci}static get NAME(){return ti}toggle(e){return this._isShown?this.hide():this.show(e)}show(t){if(this._isShown||this._isTransitioning)return;const n=e.trigger(this._element,It,{relatedTarget:t});if(n.defaultPrevented)return;this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(Bt),this._adjustDialog(),this._backdrop.show(()=>this._showElement(t))}hide(){if(!this._isShown||this._isTransitioning)return;const t=e.trigger(this._element,ai);if(t.defaultPrevented)return;this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove($t),this._queueCallback(()=>this._hideModal(),this._element,this._isAnimated())}dispose(){e.off(window,d),e.off(this._dialog,d),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new xt({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Dt({trapElement:this._element})}_showElement(n){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const s=t.findOne(wi,this._dialog);s&&(s.scrollTop=0),oe(this._element),this._element.classList.add($t);const o=()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,e.trigger(this._element,di,{relatedTarget:n})};this._queueCallback(o,this._dialog,this._isAnimated())}_addEventListeners(){e.on(this._element,fi,e=>{if(e.key!==ii)return;if(this._config.keyboard){this.hide();return}this._triggerBackdropTransition()}),e.on(window,ui,()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()}),e.on(this._element,mi,t=>{e.one(this._element,hi,e=>{if(this._element!==t.target||this._element!==e.target)return;if(this._config.backdrop==="static"){this._triggerBackdropTransition();return}this._config.backdrop&&this.hide()})})}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide(()=>{document.body.classList.remove(Bt),this._resetAdjustments(),this._scrollBar.reset(),e.trigger(this._element,Ht)})}_isAnimated(){return this._element.classList.contains(vi)}_triggerBackdropTransition(){const n=e.trigger(this._element,ri);if(n.defaultPrevented)return;const s=this._element.scrollHeight>document.documentElement.clientHeight,t=this._element.style.overflowY;if(t==="hidden"||this._element.classList.contains(Se))return;s||(this._element.style.overflowY="hidden"),this._element.classList.add(Se),this._queueCallback(()=>{this._element.classList.remove(Se),this._queueCallback(()=>{this._element.style.overflowY=t},this._dialog)},this._dialog),this._element.focus()}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),n=e>0;if(n&&!t){const t=c()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!n&&t){const t=c()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(e,t){return this.each(function(){const n=$.getOrCreateInstance(this,e);if(typeof e!="string")return;if(typeof n[e]=="undefined")throw new TypeError(`No method named "${e}"`);n[e](t)})}}e.on(document,pi,Oi,function(n){const s=t.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&n.preventDefault(),e.one(s,It,t=>{if(t.defaultPrevented)return;e.one(s,Ht,()=>{R(this)&&this.focus()})});const o=t.findOne(yi);o&&$.getInstance(o).hide();const i=$.getOrCreateInstance(s);i.toggle(this)}),_e($),u($);const ki="offcanvas",Ai="bs.offcanvas",b=`.${Ai}`,Wt=".data-api",cs=`load${b}${Wt}`,Ti="Escape",qt="show",on="showing",an="hiding",Li="offcanvas-backdrop",rn=".offcanvas.show",Pi=`show${b}`,Hi=`shown${b}`,Ii=`hide${b}`,cn=`hidePrevented${b}`,ln=`hidden${b}`,$i=`resize${b}`,Wi=`click${b}${Wt}`,Ui=`keydown.dismiss${b}`,Ki='[data-bs-toggle="offcanvas"]',qi={backdrop:!0,keyboard:!0,scroll:!1},Yi={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class O extends h{constructor(e,t){super(e,t),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return qi}static get DefaultType(){return Yi}static get NAME(){return ki}toggle(e){return this._isShown?this.hide():this.show(e)}show(t){if(this._isShown)return;const n=e.trigger(this._element,Pi,{relatedTarget:t});if(n.defaultPrevented)return;this._isShown=!0,this._backdrop.show(),this._config.scroll||(new qe).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(on);const s=()=>{(!this._config.scroll||this._config.backdrop)&&this._focustrap.activate(),this._element.classList.add(qt),this._element.classList.remove(on),e.trigger(this._element,Hi,{relatedTarget:t})};this._queueCallback(s,this._element,!0)}hide(){if(!this._isShown)return;const t=e.trigger(this._element,Ii);if(t.defaultPrevented)return;this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(an),this._backdrop.hide();const n=()=>{this._element.classList.remove(qt,an),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new qe).reset(),e.trigger(this._element,ln)};this._queueCallback(n,this._element,!0)}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const n=()=>{if(this._config.backdrop==="static"){e.trigger(this._element,cn);return}this.hide()},t=Boolean(this._config.backdrop);return new xt({className:Li,isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?n:null})}_initializeFocusTrap(){return new Dt({trapElement:this._element})}_addEventListeners(){e.on(this._element,Ui,t=>{if(t.key!==Ti)return;if(this._config.keyboard){this.hide();return}e.trigger(this._element,cn)})}static jQueryInterface(e){return this.each(function(){const t=O.getOrCreateInstance(this,e);if(typeof e!="string")return;if(t[e]===void 0||e.startsWith("_")||e==="constructor")throw new TypeError(`No method named "${e}"`);t[e](this)})}}e.on(document,Wi,Ki,function(n){const s=t.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&n.preventDefault(),y(this))return;e.one(s,ln,()=>{R(this)&&this.focus()});const o=t.findOne(rn);o&&o!==s&&O.getInstance(o).hide();const i=O.getOrCreateInstance(s);i.toggle(this)}),e.on(window,cs,()=>{for(const e of t.find(rn))O.getOrCreateInstance(e).show()}),e.on(window,$i,()=>{for(const e of t.find("[aria-modal][class*=show][class*=offcanvas-]"))getComputedStyle(e).position!=="fixed"&&O.getOrCreateInstance(e).hide()}),_e(O),u(O);const Xi=/^aria-[\w-]*$/i,dn={"*":["class","dir","id","lang","role",Xi],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],dd:[],div:[],dl:[],dt:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Zi=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Ji=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,ea=(e,t)=>{const n=e.nodeName.toLowerCase();return t.includes(n)?!Zi.has(n)||Boolean(Ji.test(e.nodeValue)):t.filter(e=>e instanceof RegExp).some(e=>e.test(n))};function ta(e,t,n){if(!e.length)return e;if(n&&typeof n=="function")return n(e);const o=new window.DOMParser,s=o.parseFromString(e,"text/html"),i=[].concat(...s.body.querySelectorAll("*"));for(const e of i){const n=e.nodeName.toLowerCase();if(!Object.keys(t).includes(n)){e.remove();continue}const s=[].concat(...e.attributes),o=[].concat(t["*"]||[],t[n]||[]);for(const t of s)ea(t,o)||e.removeAttribute(t.nodeName)}return s.body.innerHTML}const na="TemplateFactory",sa={allowList:dn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},oa={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},ia={entry:"(string|element|function|null)",selector:"(string|element)"};class aa extends se{constructor(e){super(),this._config=this._getConfig(e)}static get Default(){return sa}static get DefaultType(){return oa}static get NAME(){return na}getContent(){return Object.values(this._config.content).map(e=>this._resolvePossibleFunction(e)).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(e){return this._checkContent(e),this._config.content={...this._config.content,...e},this}toHtml(){const e=document.createElement("div");e.innerHTML=this._maybeSanitize(this._config.template);for(const[t,n]of Object.entries(this._config.content))this._setContent(e,n,t);const t=e.children[0],n=this._resolvePossibleFunction(this._config.extraClass);return n&&t.classList.add(...n.split(" ")),t}_typeCheckConfig(e){super._typeCheckConfig(e),this._checkContent(e.content)}_checkContent(e){for(const[t,n]of Object.entries(e))super._typeCheckConfig({selector:t,entry:n},ia)}_setContent(e,n,s){const o=t.findOne(s,e);if(!o)return;if(n=this._resolvePossibleFunction(n),!n){o.remove();return}if(g(n)){this._putElementInTemplate(w(n),o);return}if(this._config.html){o.innerHTML=this._maybeSanitize(n);return}o.textContent=n}_maybeSanitize(e){return this._config.sanitize?ta(e,this._config.allowList,this._config.sanitizeFn):e}_resolvePossibleFunction(e){return o(e,[this])}_putElementInTemplate(e,t){if(this._config.html){t.innerHTML="",t.append(e);return}t.textContent=e.textContent}}const ra="tooltip",ca=new Set(["sanitize","allowList","sanitizeFn"]),Ze="fade",da="modal",ye="show",ha=".tooltip-inner",hn=`.${da}`,mn="hide.bs.modal",Z="hover",at="focus",va="click",ba="manual",ja="hide",ya="hidden",_a="show",wa="shown",Oa="inserted",xa="click",Ca="focusin",Ea="focusout",ka="mouseenter",Aa="mouseleave",Sa={AUTO:"auto",TOP:"top",RIGHT:c()?"left":"right",BOTTOM:"bottom",LEFT:c()?"right":"left"},Ma={allowList:dn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},Fa={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class H extends h{constructor(e,t){if(typeof Et=="undefined")throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(e,t),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return Ma}static get DefaultType(){return Fa}static get NAME(){return ra}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){if(!this._isEnabled)return;if(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()){this._leave();return}this._enter()}dispose(){clearTimeout(this._timeout),e.off(this._element.closest(hn),mn,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if(this._element.style.display==="none")throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const n=e.trigger(this._element,this.constructor.eventName(_a)),s=es(this._element),o=(s||this._element.ownerDocument.documentElement).contains(this._element);if(n.defaultPrevented||!o)return;this._disposePopper();const t=this._getTipElement();this._element.setAttribute("aria-describedby",t.getAttribute("id"));const{container:i}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(i.append(t),e.trigger(this._element,this.constructor.eventName(Oa))),this._popper=this._createPopper(t),t.classList.add(ye),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))e.on(t,"mouseover",le);const a=()=>{e.trigger(this._element,this.constructor.eventName(wa)),this._isHovered===!1&&this._leave(),this._isHovered=!1};this._queueCallback(a,this.tip,this._isAnimated())}hide(){if(!this._isShown())return;const t=e.trigger(this._element,this.constructor.eventName(ja));if(t.defaultPrevented)return;const n=this._getTipElement();if(n.classList.remove(ye),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))e.off(t,"mouseover",le);this._activeTrigger[va]=!1,this._activeTrigger[at]=!1,this._activeTrigger[Z]=!1,this._isHovered=null;const s=()=>{if(this._isWithActiveTrigger())return;this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),e.trigger(this._element,this.constructor.eventName(ya))};this._queueCallback(s,this.tip,this._isAnimated())}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(e){const t=this._getTemplateFactory(e).toHtml();if(!t)return null;t.classList.remove(Ze,ye),t.classList.add(`bs-${this.constructor.NAME}-auto`);const n=Yr(this.constructor.NAME).toString();return t.setAttribute("id",n),this._isAnimated()&&t.classList.add(Ze),t}setContent(e){this._newContent=e,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(e){return this._templateFactory?this._templateFactory.changeContent(e):this._templateFactory=new aa({...this._config,content:e,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{[ha]:this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(e){return this.constructor.getOrCreateInstance(e.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(Ze)}_isShown(){return this.tip&&this.tip.classList.contains(ye)}_createPopper(e){const t=o(this._config.placement,[this,e,this._element]),n=Sa[t.toUpperCase()];return je(this._element,e,this._getPopperConfig(n))}_getOffset(){const{offset:e}=this._config;return typeof e=="string"?e.split(",").map(e=>Number.parseInt(e,10)):typeof e=="function"?t=>e(t,this._element):e}_resolvePossibleFunction(e){return o(e,[this._element])}_getPopperConfig(e){const t={placement:e,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:e=>{this._getTipElement().setAttribute("data-popper-placement",e.state.placement)}}]};return{...t,...o(this._config.popperConfig,[t])}}_setListeners(){const t=this._config.trigger.split(" ");for(const n of t)if(n==="click")e.on(this._element,this.constructor.eventName(xa),this._config.selector,e=>{const t=this._initializeOnDelegatedTarget(e);t.toggle()});else if(n!==ba){const t=n===Z?this.constructor.eventName(ka):this.constructor.eventName(Ca),s=n===Z?this.constructor.eventName(Aa):this.constructor.eventName(Ea);e.on(this._element,t,this._config.selector,e=>{const t=this._initializeOnDelegatedTarget(e);t._activeTrigger[e.type==="focusin"?at:Z]=!0,t._enter()}),e.on(this._element,s,this._config.selector,e=>{const t=this._initializeOnDelegatedTarget(e);t._activeTrigger[e.type==="focusout"?at:Z]=t._element.contains(e.relatedTarget),t._leave()})}this._hideModalHandler=()=>{this._element&&this.hide()},e.on(this._element.closest(hn),mn,this._hideModalHandler)}_fixTitle(){const e=this._element.getAttribute("title");if(!e)return;!this._element.getAttribute("aria-label")&&!this._element.textContent.trim()&&this._element.setAttribute("aria-label",e),this._element.setAttribute("data-bs-original-title",e),this._element.removeAttribute("title")}_enter(){if(this._isShown()||this._isHovered){this._isHovered=!0;return}this._isHovered=!0,this._setTimeout(()=>{this._isHovered&&this.show()},this._config.delay.show)}_leave(){if(this._isWithActiveTrigger())return;this._isHovered=!1,this._setTimeout(()=>{this._isHovered||this.hide()},this._config.delay.hide)}_setTimeout(e,t){clearTimeout(this._timeout),this._timeout=setTimeout(e,t)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(e){const t=v.getDataAttributes(this._element);for(const e of Object.keys(t))ca.has(e)&&delete t[e];return e={...t,...typeof e=="object"&&e?e:{}},e=this._mergeConfigObj(e),e=this._configAfterMerge(e),this._typeCheckConfig(e),e}_configAfterMerge(e){return e.container=e.container===!1?document.body:w(e.container),typeof e.delay=="number"&&(e.delay={show:e.delay,hide:e.delay}),typeof e.title=="number"&&(e.title=e.title.toString()),typeof e.content=="number"&&(e.content=e.content.toString()),e}_getDelegateConfig(){const e={};for(const[t,n]of Object.entries(this._config))this.constructor.Default[t]!==n&&(e[t]=n);return e.selector=!1,e.trigger="manual",e}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(e){return this.each(function(){const t=H.getOrCreateInstance(this,e);if(typeof e!="string")return;if(typeof t[e]=="undefined")throw new TypeError(`No method named "${e}"`);t[e]()})}}u(H);const za="popover",Da=".popover-header",Na=".popover-body",La={...H.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},Ra={...H.DefaultType,content:"(null|string|element|function)"};class mt extends H{static get Default(){return La}static get DefaultType(){return Ra}static get NAME(){return za}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{[Da]:this._getTitle(),[Na]:this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(e){return this.each(function(){const t=mt.getOrCreateInstance(this,e);if(typeof e!="string")return;if(typeof t[e]=="undefined")throw new TypeError(`No method named "${e}"`);t[e]()})}}u(mt);const Ha="scrollspy",Ia="bs.scrollspy",Ie=`.${Ia}`,Va=".data-api",$a=`activate${Ie}`,pn=`click${Ie}`,Ua=`load${Ie}${Va}`,Ka="dropdown-item",W="active",Ya='[data-bs-spy="scroll"]',Ge="[href]",Xa=".nav, .list-group",gn=".nav-link",Za=".nav-item",Ja=".list-group-item",er=`${gn}, ${Za} > ${gn}, ${Ja}`,tr=".dropdown",nr=".dropdown-toggle",sr={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},or={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class xe extends h{constructor(e,t){super(e,t),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement=getComputedStyle(this._element).overflowY==="visible"?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return sr}static get DefaultType(){return or}static get NAME(){return Ha}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const e of this._observableSections.values())this._observer.observe(e)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(e){return e.target=w(e.target)||document.body,e.rootMargin=e.offset?`${e.offset}px 0px -30%`:e.rootMargin,typeof e.threshold=="string"&&(e.threshold=e.threshold.split(",").map(e=>Number.parseFloat(e))),e}_maybeEnableSmoothScroll(){if(!this._config.smoothScroll)return;e.off(this._config.target,pn),e.on(this._config.target,pn,Ge,e=>{const t=this._observableSections.get(e.target.hash);if(t){e.preventDefault();const n=this._rootElement||window,s=t.offsetTop-this._element.offsetTop;if(n.scrollTo){n.scrollTo({top:s,behavior:"smooth"});return}n.scrollTop=s}})}_getNewObserver(){const e={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver(e=>this._observerCallback(e),e)}_observerCallback(e){const n=e=>this._targetLinks.get(`#${e.target.id}`),s=e=>{this._previousScrollData.visibleEntryTop=e.target.offsetTop,this._process(n(e))},t=(this._rootElement||document.documentElement).scrollTop,o=t>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=t;for(const i of e){if(!i.isIntersecting){this._activeTarget=null,this._clearActiveClass(n(i));continue}const a=i.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(o&&a){if(s(i),!t)return;continue}!o&&!a&&s(i)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const e=t.find(Ge,this._config.target);for(const n of e){if(!n.hash||y(n))continue;const s=t.findOne(decodeURI(n.hash),this._element);R(s)&&(this._targetLinks.set(decodeURI(n.hash),n),this._observableSections.set(n.hash,s))}}_process(t){if(this._activeTarget===t)return;this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(W),this._activateParents(t),e.trigger(this._element,$a,{relatedTarget:t})}_activateParents(e){if(e.classList.contains(Ka)){t.findOne(nr,e.closest(tr)).classList.add(W);return}for(const n of t.parents(e,Xa))for(const e of t.prev(n,er))e.classList.add(W)}_clearActiveClass(e){e.classList.remove(W);const n=t.find(`${Ge}.${W}`,e);for(const e of n)e.classList.remove(W)}static jQueryInterface(e){return this.each(function(){const t=xe.getOrCreateInstance(this,e);if(typeof e!="string")return;if(t[e]===void 0||e.startsWith("_")||e==="constructor")throw new TypeError(`No method named "${e}"`);t[e]()})}}e.on(window,Ua,()=>{for(const e of t.find(Ya))xe.getOrCreateInstance(e)}),u(xe);const ar="tab",rr="bs.tab",M=`.${rr}`,lr=`hide${M}`,dr=`hidden${M}`,ur=`show${M}`,hr=`shown${M}`,mr=`click${M}`,fr=`keydown${M}`,pr=`load${M}`,gr="ArrowLeft",vn="ArrowRight",br="ArrowUp",yn="ArrowDown",ft="Home",wn="End",S="active",Mn="fade",Ye="show",Cr="dropdown",Wn=".dropdown-toggle",kr=".dropdown-menu",Ne=`:not(${Wn})`,Sr='.list-group, .nav, [role="tablist"]',Mr=".nav-item, .list-group-item",Fr=`.nav-link${Ne}, .list-group-item${Ne}, [role="tab"]${Ne}`,Gn='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Pe=`${Fr}, ${Gn}`,Dr=`.${S}[data-bs-toggle="tab"], .${S}[data-bs-toggle="pill"], .${S}[data-bs-toggle="list"]`;class B extends h{constructor(t){if(super(t),this._parent=this._element.closest(Sr),!this._parent)return;this._setInitialAttributes(this._parent,this._getChildren()),e.on(this._element,fr,e=>this._keydown(e))}static get NAME(){return ar}show(){const t=this._element;if(this._elemIsActive(t))return;const n=this._getActiveElem(),s=n?e.trigger(n,lr,{relatedTarget:t}):null,o=e.trigger(t,ur,{relatedTarget:n});if(o.defaultPrevented||s&&s.defaultPrevented)return;this._deactivate(n,t),this._activate(t,n)}_activate(n,s){if(!n)return;n.classList.add(S),this._activate(t.getElementFromSelector(n));const o=()=>{if(n.getAttribute("role")!=="tab"){n.classList.add(Ye);return}n.removeAttribute("tabindex"),n.setAttribute("aria-selected",!0),this._toggleDropDown(n,!0),e.trigger(n,hr,{relatedTarget:s})};this._queueCallback(o,n,n.classList.contains(Mn))}_deactivate(n,s){if(!n)return;n.classList.remove(S),n.blur(),this._deactivate(t.getElementFromSelector(n));const o=()=>{if(n.getAttribute("role")!=="tab"){n.classList.remove(Ye);return}n.setAttribute("aria-selected",!1),n.setAttribute("tabindex","-1"),this._toggleDropDown(n,!1),e.trigger(n,dr,{relatedTarget:s})};this._queueCallback(o,n,n.classList.contains(Mn))}_keydown(e){if(![gr,vn,br,yn,ft,wn].includes(e.key))return;e.stopPropagation(),e.preventDefault();const n=this._getChildren().filter(e=>!y(e));let t;if([ft,wn].includes(e.key))t=n[e.key===ft?0:n.length-1];else{const s=[vn,yn].includes(e.key);t=$e(n,e.target,s,!0)}t&&(t.focus({preventScroll:!0}),B.getOrCreateInstance(t).show())}_getChildren(){return t.find(Pe,this._parent)}_getActiveElem(){return this._getChildren().find(e=>this._elemIsActive(e))||null}_setInitialAttributes(e,t){this._setAttributeIfNotExists(e,"role","tablist");for(const e of t)this._setInitialAttributesOnChild(e)}_setInitialAttributesOnChild(e){e=this._getInnerElement(e);const t=this._elemIsActive(e),n=this._getOuterElement(e);e.setAttribute("aria-selected",t),n!==e&&this._setAttributeIfNotExists(n,"role","presentation"),t||e.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(e,"role","tab"),this._setInitialAttributesOnTargetPanel(e)}_setInitialAttributesOnTargetPanel(e){const n=t.getElementFromSelector(e);if(!n)return;this._setAttributeIfNotExists(n,"role","tabpanel"),e.id&&this._setAttributeIfNotExists(n,"aria-labelledby",`${e.id}`)}_toggleDropDown(e,n){const s=this._getOuterElement(e);if(!s.classList.contains(Cr))return;const o=(e,o)=>{const i=t.findOne(e,s);i&&i.classList.toggle(o,n)};o(Wn,S),o(kr,Ye),s.setAttribute("aria-expanded",n)}_setAttributeIfNotExists(e,t,n){e.hasAttribute(t)||e.setAttribute(t,n)}_elemIsActive(e){return e.classList.contains(S)}_getInnerElement(e){return e.matches(Pe)?e:t.findOne(Pe,e)}_getOuterElement(e){return e.closest(Mr)||e}static jQueryInterface(e){return this.each(function(){const t=B.getOrCreateInstance(this);if(typeof e!="string")return;if(t[e]===void 0||e.startsWith("_")||e==="constructor")throw new TypeError(`No method named "${e}"`);t[e]()})}}e.on(document,mr,Gn,function(e){if(["A","AREA"].includes(this.tagName)&&e.preventDefault(),y(this))return;B.getOrCreateInstance(this).show()}),e.on(window,pr,()=>{for(const e of t.find(Dr))B.getOrCreateInstance(e)}),u(B);const Lr="toast",Rr="bs.toast",x=`.${Rr}`,Hr=`mouseover${x}`,Ir=`mouseout${x}`,Br=`focusin${x}`,Vr=`focusout${x}`,$r=`hide${x}`,Wr=`hidden${x}`,Ur=`show${x}`,Kr=`shown${x}`,qr="fade",os="hide",ve="show",he="showing",Qr={animation:"boolean",autohide:"boolean",delay:"number"},Zr={animation:!0,autohide:!0,delay:5e3};class ue extends h{constructor(e,t){super(e,t),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return Zr}static get DefaultType(){return Qr}static get NAME(){return Lr}show(){const t=e.trigger(this._element,Ur);if(t.defaultPrevented)return;this._clearTimeout(),this._config.animation&&this._element.classList.add(qr);const n=()=>{this._element.classList.remove(he),e.trigger(this._element,Kr),this._maybeScheduleHide()};this._element.classList.remove(os),oe(this._element),this._element.classList.add(ve,he),this._queueCallback(n,this._element,this._config.animation)}hide(){if(!this.isShown())return;const t=e.trigger(this._element,$r);if(t.defaultPrevented)return;const n=()=>{this._element.classList.add(os),this._element.classList.remove(he,ve),e.trigger(this._element,Wr)};this._element.classList.add(he),this._queueCallback(n,this._element,this._config.animation)}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(ve),super.dispose()}isShown(){return this._element.classList.contains(ve)}_maybeScheduleHide(){if(!this._config.autohide)return;if(this._hasMouseInteraction||this._hasKeyboardInteraction)return;this._timeout=setTimeout(()=>{this.hide()},this._config.delay)}_onInteraction(e,t){switch(e.type){case"mouseover":case"mouseout":{this._hasMouseInteraction=t;break}case"focusin":case"focusout":{this._hasKeyboardInteraction=t;break}}if(t){this._clearTimeout();return}const n=e.relatedTarget;if(this._element===n||this._element.contains(n))return;this._maybeScheduleHide()}_setListeners(){e.on(this._element,Hr,e=>this._onInteraction(e,!0)),e.on(this._element,Ir,e=>this._onInteraction(e,!1)),e.on(this._element,Br,e=>this._onInteraction(e,!0)),e.on(this._element,Vr,e=>this._onInteraction(e,!1))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(e){return this.each(function(){const t=ue.getOrCreateInstance(this,e);if(typeof e=="string"){if(typeof t[e]=="undefined")throw new TypeError(`No method named "${e}"`);t[e](this)}})}}_e(ue),u(ue);const ec={Alert:de,Button:fe,Carousel:ee,Collapse:te,Dropdown:m,Modal:$,Offcanvas:O,Popover:mt,ScrollSpy:xe,Tab:B,Toast:ue,Tooltip:H};return ec}),function(e){"use strict";e(function(){e('[data-bs-toggle="tooltip"]').tooltip(),e('[data-bs-toggle="popover"]').popover(),e(".popover-dismiss").popover({trigger:"focus"})});function t(e){return e.offset().top+e.outerHeight()}e(function(){var n,o,i,s=e(".js-td-cover");if(!s.length)return;o=t(s),i=e(".js-navbar-scroll").offset().top,n=Math.ceil(e(".js-navbar-scroll").outerHeight()),o-i=g.reach);A+=w.value.length,w=w.next){var E=w.value;if(n.length>e.length)return;if(!(E instanceof i)){var P,L=1;if(y){if(!(P=l(b,A,e,m))||P.index>=e.length)break;var S=P.index,O=P.index+P[0].length,j=A;for(j+=w.value.length;S>=j;)j+=(w=w.next).value.length;if(A=j-=w.value.length,w.value instanceof i)continue;for(var C=w;C!==n.tail&&(jg.reach&&(g.reach=W);var z=w.prev;if(_&&(z=u(n,z,_),A+=_.length),c(n,z,L),w=u(n,z,new i(f,p?a.tokenize(N,p):N,k,N)),M&&u(n,w,M),L>1){var I={cause:f+","+d,reach:W};o(e,n,t,w.prev,A,I),g&&I.reach>g.reach&&(g.reach=I.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function u(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function c(e,n,t){for(var r=n.next,a=0;a"+i.content+""},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",(function(n){var t=JSON.parse(n.data),r=t.language,i=t.code,l=t.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),l&&e.close()}),!1),a):a;var g=a.util.currentScript();function f(){a.manual||a.highlightAll()}if(g&&(a.filename=g.src,g.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var h=document.readyState;"loading"===h||"interactive"===h&&g&&g.defer?document.addEventListener("DOMContentLoaded",f):window.requestAnimationFrame?window.requestAnimationFrame(f):window.setTimeout(f,16)}return a}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); +Prism.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",(function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))})),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^$/i;var t={"included-cdata":{pattern://i,inside:s}};t["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var n={};n[a]={pattern:RegExp("(<__[^>]*>)(?:))*\\]\\]>|(?!)".replace(/__/g,(function(){return a})),"i"),lookbehind:!0,greedy:!0,inside:t},Prism.languages.insertBefore("markup","cdata",n)}}),Object.defineProperty(Prism.languages.markup.tag,"addAttribute",{value:function(a,e){Prism.languages.markup.tag.inside["special-attr"].push({pattern:RegExp("(^|[\"'\\s])(?:"+a+")\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s'\">=]+(?=[\\s>]))","i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[e,"language-"+e],inside:Prism.languages[e]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml; +!function(s){var e=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:[^;{\\s\"']|\\s+(?!\\s)|"+e.source+")*?(?:;|(?=\\s*\\{))"),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+e.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+e.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+e.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:e,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var t=s.languages.markup;t&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(Prism); +Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/}; +Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp("(^|[^\\w$])(?:NaN|Infinity|0[bB][01]+(?:_[01]+)*n?|0[oO][0-7]+(?:_[0-7]+)*n?|0[xX][\\dA-Fa-f]+(?:_[\\dA-Fa-f]+)*n?|\\d+(?:_\\d+)*n|(?:\\d+(?:_\\d+)*(?:\\.(?:\\d+(?:_\\d+)*)?)?|\\.\\d+(?:_\\d+)*)(?:[Ee][+-]?\\d+(?:_\\d+)*)?)(?![\\w$])"),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp("((?:^|[^$\\w\\xA0-\\uFFFF.\"'\\])\\s]|\\b(?:return|yield))\\s*)/(?:(?:\\[(?:[^\\]\\\\\r\n]|\\\\.)*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}|(?:\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.)*\\])*\\])*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}v[dgimyus]{0,7})(?=(?:\\s|/\\*(?:[^*]|\\*(?!/))*\\*/)*(?:$|[\r\n,.;:})\\]]|//))"),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),Prism.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),Prism.languages.markup&&(Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.markup.tag.addAttribute("on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)","javascript")),Prism.languages.js=Prism.languages.javascript; +!function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},a={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?:\.\w+)*(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},parameter:{pattern:/(^|\s)-{1,2}(?:\w+:[+-]?)?\w+(?:\.\w+)*(?=[=\s]|$)/,alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:a},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:a},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:a.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:a.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cargo|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|java|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|sysctl|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var s=["comment","function-name","for-or-select","assign-left","parameter","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=a.variable[1].inside,i=0;i>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),Prism.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),Prism.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},Prism.languages.c.string],char:Prism.languages.c.char,comment:Prism.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:Prism.languages.c}}}}),Prism.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete Prism.languages.c.boolean; +!function(e){function n(e,n){return e.replace(/<<(\d+)>>/g,(function(e,s){return"(?:"+n[+s]+")"}))}function s(e,s,a){return RegExp(n(e,s),a||"")}function a(e,n){for(var s=0;s>/g,(function(){return"(?:"+e+")"}));return e.replace(/<>/g,"[^\\s\\S]")}var t="bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void",r="class enum interface record struct",i="add alias and ascending async await by descending from(?=\\s*(?:\\w|$)) get global group into init(?=\\s*;) join let nameof not notnull on or orderby partial remove select set unmanaged value when where with(?=\\s*{)",o="abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield";function l(e){return"\\b(?:"+e.trim().replace(/ /g,"|")+")\\b"}var d=l(r),p=RegExp(l(t+" "+r+" "+i+" "+o)),c=l(r+" "+i+" "+o),u=l(t+" "+r+" "+o),g=a("<(?:[^<>;=+\\-*/%&|^]|<>)*>",2),b=a("\\((?:[^()]|<>)*\\)",2),h="@?\\b[A-Za-z_]\\w*\\b",f=n("<<0>>(?:\\s*<<1>>)?",[h,g]),m=n("(?!<<0>>)<<1>>(?:\\s*\\.\\s*<<1>>)*",[c,f]),k="\\[\\s*(?:,\\s*)*\\]",y=n("<<0>>(?:\\s*(?:\\?\\s*)?<<1>>)*(?:\\s*\\?)?",[m,k]),w=n("[^,()<>[\\];=+\\-*/%&|^]|<<0>>|<<1>>|<<2>>",[g,b,k]),v=n("\\(<<0>>+(?:,<<0>>+)+\\)",[w]),x=n("(?:<<0>>|<<1>>)(?:\\s*(?:\\?\\s*)?<<2>>)*(?:\\s*\\?)?",[v,m,k]),$={keyword:p,punctuation:/[<>()?,.:[\]]/},_="'(?:[^\r\n'\\\\]|\\\\.|\\\\[Uux][\\da-fA-F]{1,8})'",B='"(?:\\\\.|[^\\\\"\r\n])*"';e.languages.csharp=e.languages.extend("clike",{string:[{pattern:s("(^|[^$\\\\])<<0>>",['@"(?:""|\\\\[^]|[^\\\\"])*"(?!")']),lookbehind:!0,greedy:!0},{pattern:s("(^|[^@$\\\\])<<0>>",[B]),lookbehind:!0,greedy:!0}],"class-name":[{pattern:s("(\\busing\\s+static\\s+)<<0>>(?=\\s*;)",[m]),lookbehind:!0,inside:$},{pattern:s("(\\busing\\s+<<0>>\\s*=\\s*)<<1>>(?=\\s*;)",[h,x]),lookbehind:!0,inside:$},{pattern:s("(\\busing\\s+)<<0>>(?=\\s*=)",[h]),lookbehind:!0},{pattern:s("(\\b<<0>>\\s+)<<1>>",[d,f]),lookbehind:!0,inside:$},{pattern:s("(\\bcatch\\s*\\(\\s*)<<0>>",[m]),lookbehind:!0,inside:$},{pattern:s("(\\bwhere\\s+)<<0>>",[h]),lookbehind:!0},{pattern:s("(\\b(?:is(?:\\s+not)?|as)\\s+)<<0>>",[y]),lookbehind:!0,inside:$},{pattern:s("\\b<<0>>(?=\\s+(?!<<1>>|with\\s*\\{)<<2>>(?:\\s*[=,;:{)\\]]|\\s+(?:in|when)\\b))",[x,u,h]),inside:$}],keyword:p,number:/(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:[dflmu]|lu|ul)?\b/i,operator:/>>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,punctuation:/\?\.?|::|[{}[\];(),.:]/}),e.languages.insertBefore("csharp","number",{range:{pattern:/\.\./,alias:"operator"}}),e.languages.insertBefore("csharp","punctuation",{"named-parameter":{pattern:s("([(,]\\s*)<<0>>(?=\\s*:)",[h]),lookbehind:!0,alias:"punctuation"}}),e.languages.insertBefore("csharp","class-name",{namespace:{pattern:s("(\\b(?:namespace|using)\\s+)<<0>>(?:\\s*\\.\\s*<<0>>)*(?=\\s*[;{])",[h]),lookbehind:!0,inside:{punctuation:/\./}},"type-expression":{pattern:s("(\\b(?:default|sizeof|typeof)\\s*\\(\\s*(?!\\s))(?:[^()\\s]|\\s(?!\\s)|<<0>>)*(?=\\s*\\))",[b]),lookbehind:!0,alias:"class-name",inside:$},"return-type":{pattern:s("<<0>>(?=\\s+(?:<<1>>\\s*(?:=>|[({]|\\.\\s*this\\s*\\[)|this\\s*\\[))",[x,m]),inside:$,alias:"class-name"},"constructor-invocation":{pattern:s("(\\bnew\\s+)<<0>>(?=\\s*[[({])",[x]),lookbehind:!0,inside:$,alias:"class-name"},"generic-method":{pattern:s("<<0>>\\s*<<1>>(?=\\s*\\()",[h,g]),inside:{function:s("^<<0>>",[h]),generic:{pattern:RegExp(g),alias:"class-name",inside:$}}},"type-list":{pattern:s("\\b((?:<<0>>\\s+<<1>>|record\\s+<<1>>\\s*<<5>>|where\\s+<<2>>)\\s*:\\s*)(?:<<3>>|<<4>>|<<1>>\\s*<<5>>|<<6>>)(?:\\s*,\\s*(?:<<3>>|<<4>>|<<6>>))*(?=\\s*(?:where|[{;]|=>|$))",[d,f,h,x,p.source,b,"\\bnew\\s*\\(\\s*\\)"]),lookbehind:!0,inside:{"record-arguments":{pattern:s("(^(?!new\\s*\\()<<0>>\\s*)<<1>>",[f,b]),lookbehind:!0,greedy:!0,inside:e.languages.csharp},keyword:p,"class-name":{pattern:RegExp(x),greedy:!0,inside:$},punctuation:/[,()]/}},preprocessor:{pattern:/(^[\t ]*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(#)\b(?:define|elif|else|endif|endregion|error|if|line|nullable|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});var E=B+"|"+_,R=n("/(?![*/])|//[^\r\n]*[\r\n]|/\\*(?:[^*]|\\*(?!/))*\\*/|<<0>>",[E]),z=a(n("[^\"'/()]|<<0>>|\\(<>*\\)",[R]),2),S="\\b(?:assembly|event|field|method|module|param|property|return|type)\\b",j=n("<<0>>(?:\\s*\\(<<1>>*\\))?",[m,z]);e.languages.insertBefore("csharp","class-name",{attribute:{pattern:s("((?:^|[^\\s\\w>)?])\\s*\\[\\s*)(?:<<0>>\\s*:\\s*)?<<1>>(?:\\s*,\\s*<<1>>)*(?=\\s*\\])",[S,j]),lookbehind:!0,greedy:!0,inside:{target:{pattern:s("^<<0>>(?=\\s*:)",[S]),alias:"keyword"},"attribute-arguments":{pattern:s("\\(<<0>>*\\)",[z]),inside:e.languages.csharp},"class-name":{pattern:RegExp(m),inside:{punctuation:/\./}},punctuation:/[:,]/}}});var A=":[^}\r\n]+",F=a(n("[^\"'/()]|<<0>>|\\(<>*\\)",[R]),2),P=n("\\{(?!\\{)(?:(?![}:])<<0>>)*<<1>>?\\}",[F,A]),U=a(n("[^\"'/()]|/(?!\\*)|/\\*(?:[^*]|\\*(?!/))*\\*/|<<0>>|\\(<>*\\)",[E]),2),Z=n("\\{(?!\\{)(?:(?![}:])<<0>>)*<<1>>?\\}",[U,A]);function q(n,a){return{interpolation:{pattern:s("((?:^|[^{])(?:\\{\\{)*)<<0>>",[n]),lookbehind:!0,inside:{"format-string":{pattern:s("(^\\{(?:(?![}:])<<0>>)*)<<1>>(?=\\}$)",[a,A]),lookbehind:!0,inside:{punctuation:/^:/}},punctuation:/^\{|\}$/,expression:{pattern:/[\s\S]+/,alias:"language-csharp",inside:e.languages.csharp}}},string:/[\s\S]+/}}e.languages.insertBefore("csharp","string",{"interpolation-string":[{pattern:s('(^|[^\\\\])(?:\\$@|@\\$)"(?:""|\\\\[^]|\\{\\{|<<0>>|[^\\\\{"])*"',[P]),lookbehind:!0,greedy:!0,inside:q(P,F)},{pattern:s('(^|[^@\\\\])\\$"(?:\\\\.|\\{\\{|<<0>>|[^\\\\"{])*"',[Z]),lookbehind:!0,greedy:!0,inside:q(Z,U)}],char:{pattern:RegExp(_),greedy:!0}}),e.languages.dotnet=e.languages.cs=e.languages.csharp}(Prism); +!function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n="\\b(?!)\\w+(?:\\s*\\.\\s*\\w+)*\\b".replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp("(\\b(?:class|concept|enum|struct|typename)\\s+)(?!)\\w+".replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp('(\\b(?:import|module)\\s+)(?:"(?:\\\\(?:\r\n|[^])|[^"\\\\\r\n])*"|<[^<>\r\n]*>|'+"(?:\\s*:\\s*)?|:\\s*".replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(Prism); +Prism.languages.go=Prism.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),Prism.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete Prism.languages.go["class-name"]; +!function(e){var n=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,t="(?:[a-z]\\w*\\s*\\.\\s*)*(?:[A-Z]\\w*\\s*\\.\\s*)*",s={pattern:RegExp("(^|[^\\w.])"+t+"[A-Z](?:[\\d_A-Z]*[a-z]\\w*)?\\b"),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[s,{pattern:RegExp("(^|[^\\w.])"+t+"[A-Z]\\w*(?=\\s+\\w+\\s*[;,=()]|\\s*(?:\\[[\\s,]*\\]\\s*)?::\\s*new\\b)"),lookbehind:!0,inside:s.inside},{pattern:RegExp("(\\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\\s+)"+t+"[A-Z]\\w*\\b"),lookbehind:!0,inside:s.inside}],keyword:n,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\b[A-Z][A-Z_\d]+\b/}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":s,keyword:n,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp("(\\bimport\\s+)"+t+"(?:[A-Z]\\w*|\\*)(?=\\s*;)"),lookbehind:!0,inside:{namespace:s.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp("(\\bimport\\s+static\\s+)"+t+"(?:\\w+|\\*)(?=\\s*;)"),lookbehind:!0,alias:"static",inside:{namespace:s.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp("(\\b(?:exports|import(?:\\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\\s+)(?!)[a-z]\\w*(?:\\.[a-z]\\w*)*\\.?".replace(//g,(function(){return n.source}))),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism); +!function(n){function e(n){return n=n.replace(//g,(function(){return"(?:\\\\.|[^\\\\\n\r]|(?:\n|\r\n?)(?![\r\n]))"})),RegExp("((?:^|[^\\\\])(?:\\\\{2})*)(?:"+n+")")}var t="(?:\\\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\\\|\r\n`])+",a="\\|?__(?:\\|__)+\\|?(?:(?:\n|\r\n?)|(?![^]))".replace(/__/g,(function(){return t})),i="\\|?[ \t]*:?-{3,}:?[ \t]*(?:\\|[ \t]*:?-{3,}:?[ \t]*)+\\|?(?:\n|\r\n?)";n.languages.markdown=n.languages.extend("markup",{}),n.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:n.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+i+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+i+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(t),inside:n.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+i+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(t),alias:"important",inside:n.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:e("\\b__(?:(?!_)|_(?:(?!_))+_)+__\\b|\\*\\*(?:(?!\\*)|\\*(?:(?!\\*))+\\*)+\\*\\*"),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:e("\\b_(?:(?!_)|__(?:(?!_))+__)+_\\b|\\*(?:(?!\\*)|\\*\\*(?:(?!\\*))+\\*\\*)+\\*"),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:e("(~~?)(?:(?!~))+\\2"),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:e('!?\\[(?:(?!\\]))+\\](?:\\([^\\s)]+(?:[\t ]+"(?:\\\\.|[^"\\\\])*")?\\)|[ \t]?\\[(?:(?!\\]))+\\])'),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(e){["url","bold","italic","strike","code-snippet"].forEach((function(t){e!==t&&(n.languages.markdown[e].inside.content.inside[t]=n.languages.markdown[t])}))})),n.hooks.add("after-tokenize",(function(n){"markdown"!==n.language&&"md"!==n.language||function n(e){if(e&&"string"!=typeof e)for(var t=0,a=e.length;t",quot:'"'},l=String.fromCodePoint||String.fromCharCode;n.languages.md=n.languages.markdown}(Prism); +Prism.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},Prism.languages.python["string-interpolation"].inside.interpolation.inside.rest=Prism.languages.python,Prism.languages.py=Prism.languages.python; +Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),Prism.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),Prism.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),Prism.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),Prism.languages.scss.atrule.inside.rest=Prism.languages.scss; +Prism.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/}; +!function(e){function n(e){return e.replace(/__/g,(function(){return"(?:[\\w-]+|'[^'\n\r]*'|\"(?:\\\\.|[^\\\\\"\r\n])*\")"}))}e.languages.toml={comment:{pattern:/#.*/,greedy:!0},table:{pattern:RegExp(n("(^[\t ]*\\[\\s*(?:\\[\\s*)?)__(?:\\s*\\.\\s*__)*(?=\\s*\\])"),"m"),lookbehind:!0,greedy:!0,alias:"class-name"},key:{pattern:RegExp(n("(^[\t ]*|[{,]\\s*)__(?:\\s*\\.\\s*__)*(?=\\s*=)"),"m"),lookbehind:!0,greedy:!0,alias:"property"},string:{pattern:/"""(?:\\[\s\S]|[^\\])*?"""|'''[\s\S]*?'''|'[^'\n\r]*'|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},date:[{pattern:/\b\d{4}-\d{2}-\d{2}(?:[T\s]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?)?\b/i,alias:"number"},{pattern:/\b\d{2}:\d{2}:\d{2}(?:\.\d+)?\b/,alias:"number"}],number:/(?:\b0(?:x[\da-zA-Z]+(?:_[\da-zA-Z]+)*|o[0-7]+(?:_[0-7]+)*|b[10]+(?:_[10]+)*))\b|[-+]?\b\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?\b|[-+]?\b(?:inf|nan)\b/,boolean:/\b(?:false|true)\b/,punctuation:/[.,=[\]{}]/}}(Prism); +!function(e){var n=/[*&][^\s[\]{},]+/,r=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,t="(?:"+r.source+"(?:[ \t]+"+n.source+")?|"+n.source+"(?:[ \t]+"+r.source+")?)",a="(?:[^\\s\\x00-\\x08\\x0e-\\x1f!\"#%&'*,\\-:>?@[\\]`{|}\\x7f-\\x84\\x86-\\x9f\\ud800-\\udfff\\ufffe\\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*".replace(//g,(function(){return"[^\\s\\x00-\\x08\\x0e-\\x1f,[\\]{}\\x7f-\\x84\\x86-\\x9f\\ud800-\\udfff\\ufffe\\uffff]"})),d="\"(?:[^\"\\\\\r\n]|\\\\.)*\"|'(?:[^'\\\\\r\n]|\\\\.)*'";function o(e,n){n=(n||"").replace(/m/g,"")+"m";var r="([:\\-,[{]\\s*(?:\\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\\]|\\}|(?:[\r\n]\\s*)?#))".replace(/<>/g,(function(){return t})).replace(/<>/g,(function(){return e}));return RegExp(r,n)}e.languages.yaml={scalar:{pattern:RegExp("([\\-:]\\s*(?:\\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\\S[^\r\n]*(?:\\2[^\r\n]+)*)".replace(/<>/g,(function(){return t}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp("((?:^|[:\\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\\s*:\\s)".replace(/<>/g,(function(){return t})).replace(/<>/g,(function(){return"(?:"+a+"|"+d+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:o("\\d{4}-\\d\\d?-\\d\\d?(?:[tT]|[ \t]+)\\d\\d?:\\d{2}:\\d{2}(?:\\.\\d*)?(?:[ \t]*(?:Z|[-+]\\d\\d?(?::\\d{2})?))?|\\d{4}-\\d{2}-\\d{2}|\\d\\d?:\\d{2}(?::\\d{2}(?:\\.\\d*)?)?"),lookbehind:!0,alias:"number"},boolean:{pattern:o("false|true","i"),lookbehind:!0,alias:"important"},null:{pattern:o("null|~","i"),lookbehind:!0,alias:"important"},string:{pattern:o(d),lookbehind:!0,greedy:!0},number:{pattern:o("[+-]?(?:0x[\\da-f]+|0o[0-7]+|(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:e[+-]?\\d+)?|\\.inf|\\.nan)","i"),lookbehind:!0},tag:r,important:n,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(Prism); +!function(){if("undefined"!=typeof Prism&&"undefined"!=typeof document){var e=[],t={},n=function(){};Prism.plugins.toolbar={};var a=Prism.plugins.toolbar.registerButton=function(n,a){var r;r="function"==typeof a?a:function(e){var t;return"function"==typeof a.onClick?((t=document.createElement("button")).type="button",t.addEventListener("click",(function(){a.onClick.call(this,e)}))):"string"==typeof a.url?(t=document.createElement("a")).href=a.url:t=document.createElement("span"),a.className&&t.classList.add(a.className),t.textContent=a.text,t},n in t?console.warn('There is a button with the key "'+n+'" registered already.'):e.push(t[n]=r)},r=Prism.plugins.toolbar.hook=function(a){var r=a.element.parentNode;if(r&&/pre/i.test(r.nodeName)&&!r.parentNode.classList.contains("code-toolbar")){var o=document.createElement("div");o.classList.add("code-toolbar"),r.parentNode.insertBefore(o,r),o.appendChild(r);var i=document.createElement("div");i.classList.add("toolbar");var l=e,d=function(e){for(;e;){var t=e.getAttribute("data-toolbar-order");if(null!=t)return(t=t.trim()).length?t.split(/\s*,\s*/g):[];e=e.parentElement}}(a.element);d&&(l=d.map((function(e){return t[e]||n}))),l.forEach((function(e){var t=e(a);if(t){var n=document.createElement("div");n.classList.add("toolbar-item"),n.appendChild(t),i.appendChild(n)}})),o.appendChild(i)}};a("label",(function(e){var t=e.element.parentNode;if(t&&/pre/i.test(t.nodeName)&&t.hasAttribute("data-label")){var n,a,r=t.getAttribute("data-label");try{a=document.querySelector("template#"+r)}catch(e){}return a?n=a.content:(t.hasAttribute("data-url")?(n=document.createElement("a")).href=t.getAttribute("data-url"):n=document.createElement("span"),n.textContent=r),n}})),Prism.hooks.add("complete",r)}}(); +!function(){function t(t){var e=document.createElement("textarea");e.value=t.getText(),e.style.top="0",e.style.left="0",e.style.position="fixed",document.body.appendChild(e),e.focus(),e.select();try{var o=document.execCommand("copy");setTimeout((function(){o?t.success():t.error()}),1)}catch(e){setTimeout((function(){t.error(e)}),1)}document.body.removeChild(e)}"undefined"!=typeof Prism&&"undefined"!=typeof document&&(Prism.plugins.toolbar?Prism.plugins.toolbar.registerButton("copy-to-clipboard",(function(e){var o=e.element,n=function(t){var e={copy:"Copy","copy-error":"Press Ctrl+C to copy","copy-success":"Copied!","copy-timeout":5e3};for(var o in e){for(var n="data-prismjs-"+o,c=t;c&&!c.hasAttribute(n);)c=c.parentElement;c&&(e[o]=c.getAttribute(n))}return e}(o),c=document.createElement("button");c.className="copy-to-clipboard-button",c.setAttribute("type","button");var r=document.createElement("span");return c.appendChild(r),u("copy"),function(e,o){e.addEventListener("click",(function(){!function(e){navigator.clipboard?navigator.clipboard.writeText(e.getText()).then(e.success,(function(){t(e)})):t(e)}(o)}))}(c,{getText:function(){return o.textContent},success:function(){u("copy-success"),i()},error:function(){u("copy-error"),setTimeout((function(){!function(t){window.getSelection().selectAllChildren(t)}(o)}),1),i()}}),c;function i(){setTimeout((function(){u("copy")}),n["copy-timeout"])}function u(t){r.textContent=n[t],c.setAttribute("data-copy-state",t)}})):console.warn("Copy to Clipboard plugin loaded before Toolbar plugin."))}(); diff --git a/js/tabpane-persist.js b/js/tabpane-persist.js new file mode 100644 index 000000000..236213075 --- /dev/null +++ b/js/tabpane-persist.js @@ -0,0 +1,116 @@ +// Storage key names and data attribute name: +const td_persistStorageKeyNameBase = 'td-tp-persist'; +const td_persistCounterStorageKeyName = `${td_persistStorageKeyNameBase}-count`; +const td_persistDataAttrName = `data-${td_persistStorageKeyNameBase}`; + +// Utilities + +const _tdPersistCssSelector = (attrValue) => + attrValue + ? `[${td_persistDataAttrName}="${attrValue}"]` + : `[${td_persistDataAttrName}]`; + +const _tdStoragePersistKey = (tabKey) => + td_persistStorageKeyNameBase + ':' + (tabKey || ''); + +const _tdSupportsLocalStorage = () => typeof Storage !== 'undefined'; + +// Helpers + +function tdPersistKey(key, value) { + // @requires: tdSupportsLocalStorage(); + + try { + if (value) { + localStorage.setItem(key, value); + } else { + localStorage.removeItem(key); + } + } catch (error) { + const action = value ? 'add' : 'remove'; + console.error( + `Docsy tabpane: unable to ${action} localStorage key '${key}': `, + error + ); + } +} + +// Retrieve, increment, and store tab-select event count, then returns it. +function tdGetTabSelectEventCountAndInc() { + // @requires: tdSupportsLocalStorage(); + + const storedCount = localStorage.getItem(td_persistCounterStorageKeyName); + let numTabSelectEvents = parseInt(storedCount) || 0; + numTabSelectEvents++; + tdPersistKey(td_persistCounterStorageKeyName, numTabSelectEvents.toString()); + return numTabSelectEvents; +} + +// Main functions + +function tdActivateTabsWithKey(key) { + if (!key) return; + + document.querySelectorAll(_tdPersistCssSelector(key)).forEach((element) => { + new bootstrap.Tab(element).show(); + }); +} + +function tdPersistActiveTab(activeTabKey) { + if (!_tdSupportsLocalStorage()) return; + + tdPersistKey( + _tdStoragePersistKey(activeTabKey), + tdGetTabSelectEventCountAndInc() + ); + tdActivateTabsWithKey(activeTabKey); +} + +// Handlers + +function tdGetAndActivatePersistedTabs(tabs) { + // Get unique persistence keys of tabs in this page + var keyOfTabsInThisPage = [ + ...new Set( + Array.from(tabs).map((el) => el.getAttribute(td_persistDataAttrName)) + ), + ]; + + // Create a list of active tabs with their age: + let key_ageList = keyOfTabsInThisPage + // Map to [tab-key, last-activated-age] + .map((k) => [ + k, + parseInt(localStorage.getItem(_tdStoragePersistKey(k))) || 0, + ]) + // Exclude tabs that have never been activated + .filter(([k, v]) => v) + // Sort from oldest selected to most recently selected + .sort((a, b) => a[1] - b[1]); + + // Activate tabs from the oldest to the newest + key_ageList.forEach(([key]) => { + tdActivateTabsWithKey(key); + }); + + return key_ageList; +} + +function tdRegisterTabClickHandler(tabs) { + tabs.forEach((tab) => { + tab.addEventListener('click', () => { + const activeTabKey = tab.getAttribute(td_persistDataAttrName); + tdPersistActiveTab(activeTabKey); + }); + }); +} + +// Register listeners and activate tabs + +window.addEventListener('DOMContentLoaded', () => { + if (!_tdSupportsLocalStorage()) return; + + var allTabsInThisPage = document.querySelectorAll(_tdPersistCssSelector()); + tdRegisterTabClickHandler(allTabsInThisPage); + tdGetAndActivatePersistedTabs(allTabsInThisPage); +}); diff --git a/layouts/_default/rss.xml b/layouts/_default/rss.xml deleted file mode 100644 index 9345ab707..000000000 --- a/layouts/_default/rss.xml +++ /dev/null @@ -1,64 +0,0 @@ - -{{- $authorEmail := "" }} -{{- with site.Params.author }} - {{- if reflect.IsMap . }} - {{- with .email }} - {{- $authorEmail = . }} - {{- end }} - {{- end }} -{{- end }} - -{{- $authorName := "" }} -{{- with site.Params.author }} - {{- if reflect.IsMap . }} - {{- with .name }} - {{- $authorName = . }} - {{- end }} - {{- else }} - {{- $authorName = . }} - {{- end }} -{{- end }} - -{{- $pctx := . }} -{{- if .IsHome }}{{ $pctx = .Site }}{{ end }} -{{- $pages := slice }} -{{- if or $.IsHome $.IsSection }} -{{- $pages = $pctx.RegularPages }} -{{- else }} -{{- $pages = $pctx.Pages }} -{{- end }} -{{- $limit := .Site.Config.Services.RSS.Limit }} -{{- if ge $limit 1 }} -{{- $pages = $pages | first $limit }} -{{- end }} -{{- printf "" | safeHTML }} - - - {{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{ . }} on {{ end }}{{ .Site.Title }}{{ end }} - {{ .Permalink }} - Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{ . }} {{ end }}{{ end }}on {{ .Site.Title }} - Hugo - {{ site.Language.LanguageCode }}{{ with $authorEmail }} - {{.}}{{ with $authorName }} ({{ . }}){{ end }}{{ end }}{{ with $authorEmail }} - {{ . }}{{ with $authorName }} ({{ . }}){{ end }}{{ end }}{{ with .Site.Copyright }} - {{ . }}{{ end }}{{ if not .Date.IsZero }} - {{ (index $pages.ByLastmod.Reverse 0).Lastmod.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}{{ end }} - {{- with .OutputFormats.Get "RSS" }} - {{ printf "" .Permalink .MediaType | safeHTML }} - {{- end }} - {{- range $pages }} - - {{ .Title }} - {{ .Permalink }} - {{ .PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }} - {{- with $authorEmail }}{{ . }}{{ with $authorName }} ({{ . }}){{ end }}{{ end }} - {{ .Permalink }} - {{ .Summary | transform.XMLEscape | safeHTML }} - - {{- end }} - - diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html deleted file mode 100644 index a5d8c30cb..000000000 --- a/layouts/partials/footer.html +++ /dev/null @@ -1,54 +0,0 @@ -{{ $links := .Site.Params.links }} -
-
-
-
- {{ with $links }} - {{ with index . "user"}} - {{ template "footer-links-block" . }} - {{ end }} - {{ end }} -
-
- {{ with $links }} - {{ with index . "developer"}} - {{ template "footer-links-block" . }} - {{ end }} - {{ end }} -
-
- {{ with .Site.Params.copyright }}© {{ now.Year}} {{ .}} {{ T "footer_all_rights_reserved" }}{{ end }} - {{ with .Site.Params.privacy_policy }}{{ T "footer_privacy_policy" }}{{ end }} - {{ if not .Site.Params.ui.footer_about_disable }} - {{ with .Site.GetPage "about" }}

{{ .Title }}

{{ end }} - {{ end }} - Hosted by GitHub Pages. GitHub Privacy Statement -
-
-
-
-{{ define "footer-links-block" }} -
    - {{ range . }} -
  • - - - -
  • - {{ end }} -
- -{{ end }} diff --git a/layouts/partials/page-meta-links.html b/layouts/partials/page-meta-links.html deleted file mode 100644 index 9c2c69605..000000000 --- a/layouts/partials/page-meta-links.html +++ /dev/null @@ -1,47 +0,0 @@ -{{ if .File }} -{{ $pathFormatted := replace .File.Path "\\" "/" -}} -{{ $gh_repo := ($.Param "github_repo") -}} -{{ $gh_url := ($.Param "github_url") -}} -{{ $gh_subdir := ($.Param "github_subdir") -}} -{{ $gh_project_repo := ($.Param "github_project_repo") -}} -{{ $gh_branch := (default "main" ($.Param "github_branch")) -}} -
-{{ if $gh_url -}} - {{ warnf "Warning: use of `github_url` is deprecated. For details see https://www.docsy.dev/docs/adding-content/repository-links/#github_url-optional" -}} - {{ T "post_edit_this" }} -{{ else if $gh_repo -}} - {{ $gh_repo_path := printf "%s/content/%s" $gh_branch $pathFormatted -}} - - {{/* Adjust $gh_repo_path based on path_base_for_github_subdir */ -}} - {{ $ghs_base := $.Param "path_base_for_github_subdir" -}} - {{ $ghs_rename := "" -}} - {{ if reflect.IsMap $ghs_base -}} - {{ $ghs_rename = $ghs_base.to -}} - {{ $ghs_base = $ghs_base.from -}} - {{ end -}} - {{ with $ghs_base -}} - {{ $gh_repo_path = replaceRE . $ghs_rename $gh_repo_path -}} - {{ end -}} - - {{ $viewURL := printf "%s/tree/%s" $gh_repo $gh_repo_path -}} - {{ $editURL := printf "%s/edit/%s" $gh_repo $gh_repo_path -}} - {{ $issuesURL := printf "%s/issues/new?title=%s" $gh_repo (safeURL $.Title ) -}} - {{ $newPageStub := resources.Get "stubs/new-page-template.md" -}} - {{ $newPageQS := querify "value" $newPageStub.Content "filename" "change-me.md" | safeURL -}} - {{ $newPageURL := printf "%s/new/%s?%s" $gh_repo $gh_repo_path $newPageQS -}} - - {{ T "post_view_this" }} - {{ T "post_edit_this" }} - {{ T "post_create_child_page" }} - {{ T "post_create_issue" }} - {{ with $gh_project_repo -}} - {{ $project_issueURL := printf "%s/issues/new" . -}} - {{ T "post_create_project_issue" }} - {{ end -}} - -{{ end -}} -{{ with .CurrentSection.AlternativeOutputFormats.Get "print" -}} - {{ T "print_entire_section" }} -{{ end }} -
-{{ end -}} \ No newline at end of file diff --git a/navbar/index.html b/navbar/index.html new file mode 100644 index 000000000..c97228e85 --- /dev/null +++ b/navbar/index.html @@ -0,0 +1,4 @@ +Protocol Buffers Documentation +
\ No newline at end of file diff --git a/news/2022-05-06/index.html b/news/2022-05-06/index.html new file mode 100644 index 000000000..dd7412a36 --- /dev/null +++ b/news/2022-05-06/index.html @@ -0,0 +1,39 @@ +Changes announced May 6, 2022 | Protocol Buffers Documentation +

Changes announced May 6, 2022

Changes announced for Protocol Buffers on May 6, 2022.

Versioning

We changed our versioning scheme to enable more-nimble updates to +language-specific parts of Protocol Buffers. In the new scheme, each language +has its own major version that can be incremented independently of other +languages, as covered later in this topic with the Python release. The minor and +patch versions, however, will remain coupled. This allows us to introduce +breaking changes into some languages without requiring a bump of the major +version in languages that do not experience a breaking change.

The first instance of this new versioning scheme is the new version of the +Python API, 4.21.0, which follows the preceding version, 3.20.1. Other language +APIs will be released as 3.21.0.

Python Updates

We made some changes in Python language support in Protocol Buffers. Version +4.21.0 is a new major version, following 3.20.1. The new version is based on the +upb library, and offers +significantly better parsing performance than previous releases, especially for +large payloads. It also includes prebuilt binary modules for Apple silicon for +increased performance without a manual build.

The new release does contain some breaking changes. Specifically:

  • The +UnknownFields() +method, which relied on an implicitly created class, is replaced with the +explicitly-created UnknownFieldSet class.
  • Some non-core characteristics may have changed, such as the specific format +of certain strings or error messages. These are not considered breaking +changes, but may still impact your existing code base.
  • Applications that rely on sharing messages between Python and C++ break in +the new version. Most developers won’t be affected by this, but users of +Nucleus and possibly other +libraries may be. As a workaround, you can +set an environment variable +that forces the library to preserve compatibility.
  • Python upb requires generated code that has been generated from protoc +3.19.0 or newer.

JavaScript Support

We moved some things around for Protocol Buffer support of JavaScript to allow +JavaScript to evolve and release independently of the main repo. Specifically, +we decoupled the language support from the +main project and moved +it into its +own repository.

If you have created any pull requests related to JavaScript support in Protocol +Buffers that you’d still like to merge, feel free to replicate those against the +JavaScript repository. We will transfer GitHub issues automatically.

\ No newline at end of file diff --git a/news/2022-07-06/index.html b/news/2022-07-06/index.html new file mode 100644 index 000000000..9ba8a5e6f --- /dev/null +++ b/news/2022-07-06/index.html @@ -0,0 +1,11 @@ +Changes announced July 6, 2022 | Protocol Buffers Documentation +

Changes announced July 6, 2022

Changes announced for Protocol Buffers on July 6, 2022.

Library Breaking Change Policy

Google released its +OSS Library Breaking Change Policy, +which some Google-sponsored open source projects have opted into. Protocol +buffers has adopted this policy.

\ No newline at end of file diff --git a/news/2022-08-03/index.html b/news/2022-08-03/index.html new file mode 100644 index 000000000..49dbf535b --- /dev/null +++ b/news/2022-08-03/index.html @@ -0,0 +1,42 @@ +Changes announced August 3, 2022 | Protocol Buffers Documentation +

Changes announced August 3, 2022

Changes announced for Protocol Buffers on August 3, 2022.

This topic covers two areas: general platform support changes, and C++-specific +changes that are being considered for the 22.x release line.

Platform Support Changes

We’ve added guidance about the platforms that we support in +this section of +the documentation. The section currently covers C++ and PHP, but may be expanded +with information about other platforms in the future.

Official C++ Support Matrix

With the policy, mentioned earlier in this announcement, of using Google’s +official +foundational C++ support policy, +our +C++ compiler and toolchain support matrix will change.

C++ Changes

Following the announcement of our +new major version and breaking changes policy, +we are planning a major version bump for C++. We plan to make some changes to +the assets that we release starting with our 22.x release line.

The following sections outline the set of breaking changes that we plan to +include in the 22.0 release of protocol buffers. Note that plans can and do +change. These are potential breaking changes to be aware of, but they may not +happen in this particular release, or they may not happen at all.

Adding C++20 Support

Because of the addition of new keywords to the C++ language, adding support for +C++20 is a breaking change for users even if they do not currently use C++20.

Mitigations for this to conditionally change names only in certain compiler +modes would break projects that support multiple language standards.

Dropping C++11 Support

Per our +C++ support policy, +we plan to drop C++11 support. This is a breaking change.

Dropping Autotools Support

Per our +build systems support policy, +we plan to drop autotools support. This is a breaking change. After autotools +support is dropped, protobuf will support only CMake and Bazel.

Dropping Support for PHP <7.4

Per our +PHP support policy, +we plan to drop support for EOL versions of PHP. This is not considered a +breaking change since these versions are already EOL in the broader ecosystem.

Adding an Abseil Dependency

In order to reduce the Google vs. OSS differences between protobuf and to +simplify our own project, we plan to take a formal dependency on Abseil. In +time, we plan to start using Abseil types in our public APIs, but simply adding +the dependency is a breaking change.

Dropping Language-Specific Source Distributions

To reduce dependence on autotools and minimize the number of artifacts we +release, we plan to stop publishing language-specific source distributions on +our +GitHub release page. +Instead, we advise users to download the +source code distribution +automatically generated by GitHub on the release page.

Changing Maven Release Candidate Artifact Names to Be More Idiomatic

In 22.0 we plan to rename Maven artifacts to use “RC” instead of “rc-” as the +release candidate prefix.

\ No newline at end of file diff --git a/news/2023-04-11/index.html b/news/2023-04-11/index.html new file mode 100644 index 000000000..6a04cea36 --- /dev/null +++ b/news/2023-04-11/index.html @@ -0,0 +1,35 @@ +Changes announced April 11, 2023 | Protocol Buffers Documentation +

Changes announced April 11, 2023

Changes announced for Protocol Buffers on April 11, 2023.

Syntax Reflection Deprecation

v23 will deprecate the ability to check syntax version using reflection. The +deprecation will be included as warnings at build time. The capability will be +removed in a future release.

Adding support for ctype=CORD in C++

v23 will add ctype=CORD support for singular bytes +fields, including oneof fields, to specify that data should be stored using +absl::cord +instead of string. Support may be added in future releases for singular +string field types and for repeated string and byte fields if there is +enough interest from the open source community.

ctype=CORD will have no effect on extensions.

You will be able to add the support using field options:

optional bytes foo = 25 [ctype=CORD];
+

Option Retention

Options now have a notion of retention, which controls whether an option is +retained in the generated code. Options have always had runtime retention by +default, meaning that they are retained in the generated code and are thus +visible at runtime in the generated descriptor pool. However, you can now set +retention = RETENTION_SOURCE to specify that an option (or field within an +option) must not be retained at runtime. This is called source retention.

Setting retention looks like this:

extend google.protobuf.FileOptions {
+  optional int32 source_retention_option = 1234
+      [retention = RETENTION_SOURCE];
+}
+

It can also be set on a plain field, in which case it takes effect only when +that field appears inside an option:

message OptionsMessage {
+  optional int32 source_retention_field = 1 [retention = RETENTION_SOURCE];
+}
+

For more information, see +Option Retention.

Dropping Support for Bazel <5.3

v23 will drop support for Bazel 4. Protobuf will continue to support the Bazel 5 +LTS with Bazel 5.3 as the minimum required version. This is per the build +support policy described in +Foundational C++ Support Policy +and as reflected in the versions in +Foundational C++ Support.

\ No newline at end of file diff --git a/news/2023-04-20/index.html b/news/2023-04-20/index.html new file mode 100644 index 000000000..45e618d0f --- /dev/null +++ b/news/2023-04-20/index.html @@ -0,0 +1,100 @@ +Changes announced April 20, 2023 | Protocol Buffers Documentation +

Changes announced April 20, 2023

Changes announced for Protocol Buffers on April 20, 2023.

Changes to Ruby Generator

This GitHub PR, which +will appear in the 23.x release, changes the Ruby code generator to emit a +serialized proto instead of the DSL.

It removes the DSL from the code generator in anticipation of splitting the DSL +out into a separate package.

Given a .proto file like:

syntax = "proto3";
+
+package pkg;
+
+message TestMessage {
+  optional int32 i32 = 1;
+  optional TestMessage msg = 2;
+}
+

Generated code before:

# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: protoc_explorer/main.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+  add_file("test.proto", :syntax => :proto3) do
+    add_message "pkg.TestMessage" do
+      proto3_optional :i32, :int32, 1
+      proto3_optional :msg, :message, 2, "pkg.TestMessage"
+    end
+  end
+end
+
+module Pkg
+  TestMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("pkg.TestMessage").msgclass
+end
+

Generated code after:

# frozen_string_literal: true
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: test.proto
+
+require 'google/protobuf'
+
+descriptor_data = "\n\ntest.proto\x12\x03pkg\"S\n\x0bTestMessage\x12\x10\n\x03i32\x18\x01 \x01(\x05H\x00\x88\x01\x01\x12\"\n\x03msg\x18\x02 \x01(\x0b\x32\x10.pkg.TestMessageH\x01\x88\x01\x01\x42\x06\n\x04_i32B\x06\n\x04_msgb\x06proto3"
+begin
+  Google::Protobuf::DescriptorPool.generated_pool.add_serialized_file(descriptor_data)
+rescue TypeError => e
+  # <compatibility code, see below>
+end
+
+module Pkg
+  TestMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("pkg.TestMessage").msgclass
+end
+

This change fixes nearly all remaining conformance problems that existed +previously. This is a side effect of moving from the DSL (which is lossy) to a +serialized descriptor (which preserves all information).

Backward Compatibility

This change should be 100% compatible with Ruby Protobuf >= 3.18.0, released in +Sept 2021. Additionally, it should be compatible with all existing users and +deployments.

There is some special compatibility code inserted to achieve this level of +backward compatibility that you should be aware of. Without the compatibility +code, there is an edge case that could break backward compatibility. The +previous code is lax in a way that the new code will be more strict.

When using a full serialized descriptor, it contains a list of all .proto +files imported by this file (whereas the DSL never added dependencies properly). +See the code in +descriptor.proto.

add_serialized_file verifies that all dependencies listed in the descriptor +were previously added with add_serialized_file. Generally that should be fine, +because the generated code will contain Ruby require statements for all +dependencies, and the descriptor will fail to load anyway if the types depended +on were not previously defined in the DescriptorPool.

But there is a potential for problems if there are ambiguities around file +paths. For example, consider the following scenario:

// foo/bar.proto
+
+syntax = "proto2";
+
+message Bar {}
+
// foo/baz.proto
+
+syntax = "proto2";
+
+import "bar.proto";
+
+message Baz {
+  optional Bar bar = 1;
+}
+

If you invoke protoc like so, it will work correctly:

$ protoc --ruby_out=. -Ifoo foo/bar.proto foo/baz.proto
+$ RUBYLIB=. ruby baz_pb.rb
+

However if you invoke protoc like so, and didn’t have any compatibility code, +it would fail to load:

$ protoc --ruby_out=. -I. -Ifoo foo/baz.proto
+$ protoc --ruby_out=. -I. -Ifoo foo/bar.proto
+$ RUBYLIB=foo ruby foo/baz_pb.rb
+foo/baz_pb.rb:10:in `add_serialized_file': Unable to build file to DescriptorPool: Depends on file 'bar.proto', but it has not been loaded (Google::Protobuf::TypeError)
+    from foo/baz_pb.rb:10:in `<main>'
+

The problem is that bar.proto is being referred to by two different canonical +names: bar.proto and foo/bar.proto. This is a user error: each import should +always be referred to by a consistent full path. Hopefully user errors of this +sort will be rare, but it is hard to know without trying.

The code in this change prints a warning using warn if we detect that this +edge case has occurred:

$ RUBYLIB=foo ruby foo/baz_pb.rb
+Warning: Protobuf detected an import path issue while loading generated file foo/baz_pb.rb
+- foo/baz.proto imports bar.proto, but that import was loaded as foo/bar.proto
+Each proto file must use a consistent fully-qualified name.
+This will become an error in the next major version.
+

There are two possible fixes in this case. One is to consistently use the name +bar.proto for the import (removing -I.). The other is to consistently use +the name foo/bar.proto for the import (changing the import line to import "foo/bar.proto" and removing -Ifoo).

We plan to remove this compatibility code in the next major version.

\ No newline at end of file diff --git a/news/2023-04-28/index.html b/news/2023-04-28/index.html new file mode 100644 index 000000000..584cca098 --- /dev/null +++ b/news/2023-04-28/index.html @@ -0,0 +1,16 @@ +Changes announced April 28, 2023 | Protocol Buffers Documentation +

Changes announced April 28, 2023

Changes announced for Protocol Buffers on April 28, 2023.

Stricter validation for json_name

v24 will forbid zero unicode code points (\u0000) in the +json_name field option. +Going forward, any valid Unicode characters will be accepted in json_name, +except \u0000. \0 characters will still be allowed to be used as values.

Previously, the proto compiler allowed \0 characters in the json_name field +option, but support for this was inconsistent across languages and +implementations. To help prevent interoperability problems relating to +mishandling of keys containing a \0 character, we are clarifying the spec to +say that \0 is not allowed in json_name, and will be rejected by the +compiler.

\ No newline at end of file diff --git a/news/2023-06-29/index.html b/news/2023-06-29/index.html new file mode 100644 index 000000000..02551b992 --- /dev/null +++ b/news/2023-06-29/index.html @@ -0,0 +1,111 @@ +Changes Announced on June 29, 2023 | Protocol Buffers Documentation +

Changes Announced on June 29, 2023

Changes announced for Protocol Buffers on June 29, 2023.

TL;DR: We are planning to release Protobuf Editions to the open source project in the second half of 2023. While there is no requirement to move from proto2/proto3 syntax to Editions syntax at initial release, we encourage you to plan a move in your software project’s future timeline.

Protobuf Editions

Protobuf Editions replace the proto2 and proto3 designations that we have used +for Protocol Buffers. Instead of adding syntax = "proto2" or syntax = "proto3" at the top of proto definition files, you use an edition number, such +as edition = "2024", to specify the default behaviors your file will have. +Editions enable the language to evolve incrementally over time.

Instead of the hardcoded behaviors in older versions, editions will represent a +collection of “features” with a default value (behavior) per feature, which you +can override. Features are options on a file, message, field, enum, and so on +that specify the behavior of protoc, the code generators, and protobuf runtimes. +You can explicitly override the desired behavior at those different levels +(file, message, field, …) when your needs don’t match the default behavior for +the edition you’ve selected.

Editions won’t break existing binaries, and the first edition will be minimally +disruptive; it will establish the baseline and will combine proto2 and proto3 +definitions into a new single definition format. It won’t require any changes to +your code. We will be providing a tool, called Prototiller, to migrate .proto +files. The following examples show a proto2 definition file and a proto3 file, +and what each might look like after using Prototiller to convert them to +Protobuf Editions format:

Proto2 syntax

// proto2 file
+syntax = "proto2";
+
+message Player {
+  // in proto2, optional fields have explicit presence
+  optional string name = 1;
+  // proto2 still supports the problematic "required" field rule
+  required int32 id = 2;
+  // in proto2 this is not packed by default
+  repeated int32 scores = 3;
+
+  enum Handed {
+    HANDED_UNSPECIFIED = 0,
+    HANDED_LEFT = 1,
+    HANDED_RIGHT = 2,
+    HANDED_AMBIDEXTROUS = 3,
+  }
+
+  // in proto2 enums are closed
+  optional Handed handed = 4;
+}
+

Editions syntax

// Editions version of proto2 file
+edition = "2023";
+
+message Player {
+  string name = 1;
+  int32 id = 2 [features.field_presence = LEGACY_REQUIRED];
+  repeated int32 scores = 3 [features.repeated_field_encoding = EXPANDED];
+
+  enum Handed {
+    // this overrides the default Edition 2023 behavior, which is OPEN
+    option features.enum = CLOSED;
+    HANDED_UNSPECIFIED = 0,
+    HANDED_LEFT = 1,
+    HANDED_RIGHT = 2,
+    HANDED_AMBIDEXTROUS = 3,
+  }
+
+  Handed handed = 4;
+}
+

And this is what a similar proto3 definition file might look like:

Proto3 syntax

// proto3 file
+syntax = "proto3";
+
+message Player {
+  // in proto3, optional fields have explicit presence
+  optional string name = 1;
+  // in proto3 no specified field rule defaults to implicit presence
+  int32 id = 2;
+  // in proto3 this is packed by default
+  repeated int32 scores = 3;
+
+  enum Handed {
+    HANDED_UNSPECIFIED = 0,
+    HANDED_LEFT = 1,
+    HANDED_RIGHT = 2,
+    HANDED_AMBIDEXTROUS = 3,
+  }
+
+  // in proto3 enums are open
+  optional Handed handed = 4;
+}
+

Editions syntax

// Editions version of proto3 file
+edition = "2023";
+
+message Player {
+  string name = 1;
+  int32 id = 2 [features.field_presence = IMPLICIT];
+  repeated int32 scores = 3;
+
+  enum Handed {
+    HANDED_UNSPECIFIED = 0,
+    HANDED_LEFT = 1,
+    HANDED_RIGHT = 2,
+    HANDED_AMBIDEXTROUS = 3,
+  }
+
+  Handed handed = 4;
+}
+

While the examples provided in this topic show a direct translation of proto2 +and proto3 to the equivalent representation using Protobuf Editions, you will be +able to mix and match the settings to your project’s needs.

Features have a lifecycle that is governed by the releases of editions. For +example, features.awesome_new_feature might be added in Edition 2031, with the +new behavior applying to all definitions that don’t explicitly override the new +behavior. In Edition 2033, the new feature is deprecated. Overrides still work, +but developers are alerted to the fact that they need to adapt to the new +behavior soon. In Edition 2036, the feature is removed and the new behavior +applies to all protos; there is no way to override the new behavior at this +point.

Editions lifecycle
Figure 1: Editions lifecycle flowchart

Editions are planned to be released roughly once a year. For more information on +Protobuf Editions, see the overview at https://protobuf.dev/editions/overview.

\ No newline at end of file diff --git a/news/2023-07-06/index.html b/news/2023-07-06/index.html new file mode 100644 index 000000000..b91e34672 --- /dev/null +++ b/news/2023-07-06/index.html @@ -0,0 +1,18 @@ +Changes Announced on July 6, 2023 | Protocol Buffers Documentation +

Changes Announced on July 6, 2023

Changes announced for Protocol Buffers on July 6, 2023.

Dropping PHP 7.x Support

As per our official +PHP support policy, +we will be dropping support for PHP 7.4 and lower. This means the minimum +supported PHP version is 8.0.

If you are running an older version of PHP, you can install a previous release +of the protobuf PHP extension by running pecl install protobuf-3.23.3.

Dropping Ruby 2.6 Support

As per our official +Ruby support policy, +we will be dropping support for Ruby 2.6 and lower. This means the minimum +supported Ruby version is 2.7.

Dropping Python 3.7 Support

As per our official +Python support policy, +we will be dropping support for Python 3.7 and lower. This means the minimum +supported Python version is 3.8.

\ No newline at end of file diff --git a/news/2023-07-17/index.html b/news/2023-07-17/index.html new file mode 100644 index 000000000..9a06a7060 --- /dev/null +++ b/news/2023-07-17/index.html @@ -0,0 +1,11 @@ +Changes Announced on July 17, 2023 | Protocol Buffers Documentation +

Changes Announced on July 17, 2023

Changes announced for Protocol Buffers on July 17, 2023.

Dropping Bazel 5.x Support

As per our official +support policy, +we will be dropping support for Bazel 5.x and lower. This means the minimum +supported Bazel version is 6.2.x.

\ No newline at end of file diff --git a/news/2023-08-09/index.html b/news/2023-08-09/index.html new file mode 100644 index 000000000..9f8434e09 --- /dev/null +++ b/news/2023-08-09/index.html @@ -0,0 +1,25 @@ +Changes Announced on August 9, 2023 | Protocol Buffers Documentation +

Changes Announced on August 9, 2023

Changes announced for Protocol Buffers on August 9, 2023.

.NET support policy

The Protobuf team supports .NET in two ways:

  • Generation of C# code by protoc
  • The Google.Protobuf NuGet package, +which provides runtime support for the generated code, as well as reflection +and other facilities

The support policy for these has previously been unclear, particularly in terms +of which .NET runtimes are supported. From August 2023 onwards, support will be +provided in accordance with the Google Open Source support policy for +.NET. We +expect this to mean that some old versions of .NET will be dropped from the +Google.Protobuf package without taking a new major version.

Protobuf is relatively unusual within Google projects supporting .NET in two +respects: Firstly, as we support generating C# which we expect customers to +compile, we need to consider language versions as well as runtime versions. The +current policy does not cover this aspect of support, so we will publish a +separate policy for this. Secondly, while Unity is not a first-class +supported platform, we understand that Protobuf is commonly used on Unity, and +we will intend to avoid breaking that usage as far as is reasonably possible.

More details will be published when a new set of target platforms has been +decided for Google.Protobuf. This will be at least one month ahead of the +release in which it will take effect, in order to provide time for community +feedback. For now, we recommend that users review the +support policy.

\ No newline at end of file diff --git a/news/2023-08-15/index.html b/news/2023-08-15/index.html new file mode 100644 index 000000000..13b2c0d6f --- /dev/null +++ b/news/2023-08-15/index.html @@ -0,0 +1,13 @@ +Changes Announced on August 15, 2023 | Protocol Buffers Documentation +

Changes Announced on August 15, 2023

Changes announced for Protocol Buffers on August 15, 2023.

Python Breaking Change

In v25 +message.UnknownFields() +will be deprecated in pure Python and C++ extensions. It will be removed in v26. +Use the new +UnknownFieldSet(message) +support in unknown_fields.py as a replacement.

\ No newline at end of file diff --git a/news/2023-09-15/index.html b/news/2023-09-15/index.html new file mode 100644 index 000000000..1d02ae7f4 --- /dev/null +++ b/news/2023-09-15/index.html @@ -0,0 +1,23 @@ +Changes announced on September 15, 2023 | Protocol Buffers Documentation +

Changes announced on September 15, 2023

Changes announced for Protocol Buffers on September 15, 2023.

μpb Moving to the Protobuf Git Repository

Starting with the v25 release, μpb now lives in the +protobuf repo instead +of in its former location +in a separate repo. All μpb development going forward will take place only in +the new location.

The merger of the two repos will simplify and speed up our development process +by removing the need to update pinned version dependencies between protobuf and +μpb. Changes to μpb now take effect immediately in protobuf code and vice versa, +without the need for a manual upgrade step.

We expect that most users will not need to take much, if any, action to +accommodate the change. μpb is the engine behind our Ruby, PHP, and Python +implementations, but you will most likely not notice the change unless you have +code that refers to μpb directly.

If you refer to μpb from a Bazel project, you will need to update μpb references +to point to protobuf instead (for example, replace @upb with +@com_google_protobuf). We are keeping μpb file paths and Bazel targets the +same to minimize the need for additional changes, but there are two exceptions:

  • The upbc directory has been renamed upb_generator.
  • The top-level BUILD file for μpb has moved into the upb directory. So, +for example, references to @upb//:reflection should now be written +@com_google_protobuf//upb:reflection.
\ No newline at end of file diff --git a/news/2023-10-10/index.html b/news/2023-10-10/index.html new file mode 100644 index 000000000..e4278ed87 --- /dev/null +++ b/news/2023-10-10/index.html @@ -0,0 +1,10 @@ +Changes announced on October 10, 2023 | Protocol Buffers Documentation +

Changes announced on October 10, 2023

Changes announced for Protocol Buffers on October 10, 2023.

Protobuf Editions Features

Documentation that introduces +Protobuf Editions features is now +available.

\ No newline at end of file diff --git a/news/2023-12-05/index.html b/news/2023-12-05/index.html new file mode 100644 index 000000000..149a24a35 --- /dev/null +++ b/news/2023-12-05/index.html @@ -0,0 +1,32 @@ +Changes announced on December 5, 2023 | Protocol Buffers Documentation +

Changes announced on December 5, 2023

Changes announced for Protocol Buffers on December 5, 2023.

Java Breaking Changes

In v26, we are planning a major version bump for Java per our +breaking changes policy and +version support policy.

The following sections outline the set of breaking changes that we plan to +include in the 26.0 release of protocol buffers. Note that plans can and do +change. These are potential breaking changes to be aware of, but they may not +happen in this particular release, or they may not happen at all.

Poison Pilling Gencode / Runtime Mismatches

Per our +Cross-Version Runtime Guarantees, +Protobuf does not support mixing generated code and runtimes across major +version boundaries, or mixing generated code from a newer version of protoc with +older runtimes within a single major runtime version. We plan to introduce +“poison pills” to detect and enforce these disallowed mismatches.

This is not considered a breaking change since this simply adds enforcement of +existing policies, but may require users to update their generated code.

Breaking Compatibility with Old Generated Code

v26.x will break compatibility with generated code from older major versions. +Users should regenerate old generated code to be from the same version.

For example, GeneratedMessageV3, which was originally introduced for backwards +compatibility with generated code from v2.x.x against v3.x.x runtime, will be +renamed to GeneratedMessage. Runtimes will be updated to support +Editions, which will not be +compatible with old generated code.

This is in accordance with our existing +Cross-Version Runtime Guarantees +and is a breaking change.

Removing Deprecated Methods/Variables

v26.x will remove access to deprecated methods and variables. These will +generally have already been marked @Deprecated in a previous release.

This will remove access to the following non-exhaustive list:

  • Descriptor syntax APIs, which should be replaced with corresponding feature +accessors (such as FieldDescriptor.hasPresence(), +EnumDescriptor.isClosed())

  • TextFormat print methods, which should be replaced by corresponding +TextFormat.printer() methods.

  • PARSER variable, which should be replaced by the parser() method.

  • Runtime methods for old v2.x.x gencode compatibility. This is no longer +supported, as per our +Cross Version Runtime Guarantees.

More details will be available in the corresponding release notes.

\ No newline at end of file diff --git a/news/2023-12-13/index.html b/news/2023-12-13/index.html new file mode 100644 index 000000000..44349bd6c --- /dev/null +++ b/news/2023-12-13/index.html @@ -0,0 +1,34 @@ +Changes announced on December 13, 2023 | Protocol Buffers Documentation +

Changes announced on December 13, 2023

Changes announced for Protocol Buffers on December 13, 2023.

C++ Breaking Changes

In v26, we are planning a major version bump for C++ as per our +breaking changes policy and +version support policy.

The following sections outline the set of breaking changes that we plan to +include in the 26.0 release of protocol buffers. Note that plans can and do +change. These are potential breaking changes to be aware of, but they may not +happen in this particular release, or they may not happen at all.

Remove deprecated clear APIs on repeated fields

The following deprecated methods are removed:

  • RepeatedPtrField::ReleaseCleared()
  • RepeatedPtrField::ClearedCount()
  • RepeatedPtrField::AddCleared()

Remove C++ legacy syntax descriptor APIs

With the release of editions, syntax is no +longer supported for business logic. Instead, use the various feature helpers +defined in +descriptor.h +to query more targeted behaviors, such as +has_presence, +to query features in C++.

Remove deprecated syntax accessor

We plan to remove the deprecated syntax accessor, FileDescriptor::Syntax, in +v26. We recommend using the getters from FileDescriptor::edition instead.

Remove deprecated SupportsUnknownEnumValues method

The SupportsUnknownEnumValues method was +deprecated in March, 2023. +We plan to remove it in v26.

Remove std::string error collector overrides

We are planning to remove the deprecated std::string methods in error +collectors.

Python Breaking Changes

In v26, we are planning a major version bump for Python as per our +breaking changes policy and +version support policy.

Timestamps are checked for validity

In v26, the system will check if Timestamp values are valid. Seconds must be +in the range [-62135596800, 253402300799] and nanos must be in range [0, +999999999]. Values outside those ranges will raise an exception.

Remove deprecated syntax accessor

We plan to remove the deprecated syntax accessor, FileDescriptor.syntax, in +v26. We plan to add FileDescriptor.edition in its place.

UnknownFields support removal

In v25 +message.UnknownFields() +was deprecated in pure Python and C++ extensions. We plan to remove it v26. Use +the new +UnknownFieldSet(message) +support in unknown_fields.py as a replacement.

More details about all of these changes will be available in the corresponding +release notes.

\ No newline at end of file diff --git a/news/2023-12-27/index.html b/news/2023-12-27/index.html new file mode 100644 index 000000000..fe569b8cb --- /dev/null +++ b/news/2023-12-27/index.html @@ -0,0 +1,18 @@ +Changes announced on December 27, 2023 | Protocol Buffers Documentation +

Changes announced on December 27, 2023

Changes announced for Protocol Buffers on December 27, 2023.

Ruby Breaking Changes

The following changes are planned for the 26.x line:

  • Fix RepeatedField#each_index to have the correct semantics. +(#11767)
  • Remove Ruby DSL and associated compatibility code, which will complete the +migration announced in April.
  • Message#to_h fixes:
    • Remove unset oneof fields. +(#6167)
    • Remove unset sub-message fields
  • Use message’s pool for +encode_json/decode_json.
  • Remove the deprecated syntax accessor, FileDescriptor.syntax and add +semantic checks in its place:
    • FieldDescriptor.has_presence to test if a field has presence.
    • FieldDescriptor.is_packed to test if a repeated field is packed.
    • FieldDescriptor.requires_utf8_validation to test if a string field +requires UTF-8 validation.
    • EnumDescriptor.is_closed to test if an enum is closed.

PHP Breaking Changes

The following changes are planned for the 26.x line:

  • Validate UTF-8 for string fields in setters.
  • Remove generic services. +(commit 40ad3fa)

Python Breaking Changes

The following changes are planned for the 26.x line:

  • Make str(msg) escape any invalid UTF-8 in string fields.
  • Make text_format.MessageToString() default to outputting raw UTF-8, while +escaping any invalid UTF-8 sequences.
  • Fix timestamp bounds (commit 1250d5f)

upb Breaking Changes

The following changes are planned for the 26.x line:

\ No newline at end of file diff --git a/news/2024-01-05/index.html b/news/2024-01-05/index.html new file mode 100644 index 000000000..131d426ff --- /dev/null +++ b/news/2024-01-05/index.html @@ -0,0 +1,15 @@ +Changes announced January 5, 2024 | Protocol Buffers Documentation +

Changes announced January 5, 2024

Changes announced for Protocol Buffers on January 5, 2024.

This topic covers breaking changes in Ruby and Python in the 26.x line.

Ruby Breaking Changes

Freeze Is Now Recursive in Ruby

Starting in the 26.x line, when freeze is applied it will be applied +recursively, affecting all sub-messages, maps, and repeated fields.

Python Breaking Changes

Removing Deprecated APIs

In the 26.x release, the following deprecated APIs will be removed:

Rejecting Extend Repeated Field with None Iterable

Starting in the 26.x release, extending repeated fields with a None iterable +will be rejected (it will raise a TypeError). For example, +m.repeated_int32.extend(None) will be rejected.

Removing RegisterExtension in message class

Starting in the 26.x release, +RegisterExtension +will be removed. You can access extensions in Python using the Extensions +property on message objects.

This affects both pure Python and the C++ implementation of Python, but not upb +Python.

\ No newline at end of file diff --git a/news/2024-01-31/index.html b/news/2024-01-31/index.html new file mode 100644 index 000000000..009194ef9 --- /dev/null +++ b/news/2024-01-31/index.html @@ -0,0 +1,19 @@ +Changes announced January 31, 2024 | Protocol Buffers Documentation +

Changes announced January 31, 2024

Changes announced for Protocol Buffers on January 31, 2024.

This topic covers breaking changes in Python in the 26.x line.

Python Breaking Changes

Removing setup.py and setup.cfg support from GitHub

In the 26.x release, setup.py and setup.cfg will no longer be present in the +python/ directory of +the GitHub repository +or GitHub +release tarballs. This +means it will no longer be possible to build a Python package directly from the +GitHub repo or release tarball.

The Python source packages published +on PyPI will continue to have a +setup.py in the top-level directory. This is the supported and recommended way +of building Python binary packages, for users who do not want to use the binary +packages that we distribute on PyPI.

For more information, see +#15671.

\ No newline at end of file diff --git a/news/2024-02-05/index.html b/news/2024-02-05/index.html new file mode 100644 index 000000000..212c3c9b1 --- /dev/null +++ b/news/2024-02-05/index.html @@ -0,0 +1,15 @@ +Changes announced February 5, 2024 | Protocol Buffers Documentation +

Changes announced February 5, 2024

Changes announced for Protocol Buffers on February 5, 2024.

This topic covers breaking changes in Java, C++, and Python in the 26.x line.

JSON Formatter Option Changes

Starting in the 26.x line, the JSON formatter option to print default-valued +fields is replaced with a fixed way to handle proto2 and proto3 optional +fields consistently.

  • Java: includingDefaultValueFields() is replaced with +alwaysPrintFieldsWithNoPresence().
  • C++: always_print_default_values is replaced with +always_print_fields_with_no_presence=True.
  • Py: including_default_value_fields=True is replaced with +always_print_fields_with_no_presence=True.

The new flag behaves identically to the old flag on proto3 messages, but no +longer applies to proto2 optional fields. The old flags applied to proto2 +optional fields but not proto3 optional fields.

\ No newline at end of file diff --git a/news/2024-02-27/index.html b/news/2024-02-27/index.html new file mode 100644 index 000000000..cc4b6bf47 --- /dev/null +++ b/news/2024-02-27/index.html @@ -0,0 +1,11 @@ +Changes Announced on February 27, 2024 | Protocol Buffers Documentation +

Changes Announced on February 27, 2024

Changes announced for Protocol Buffers on February 27, 2024.

Dropping Ruby 2.7 Support

As per our official +Ruby support policy, +we will be dropping support for Ruby 2.7 and lower on March 31, 2024. The +minimum supported Ruby version will be 3.0.

\ No newline at end of file diff --git a/news/2024-06-26/index.html b/news/2024-06-26/index.html new file mode 100644 index 000000000..c3c04f788 --- /dev/null +++ b/news/2024-06-26/index.html @@ -0,0 +1,17 @@ +Changes Announced on June 26, 2024 | Protocol Buffers Documentation +

Changes Announced on June 26, 2024

Changes announced for Protocol Buffers on June 26, 2024.

Dropping Support for Building Protobuf Java from Source with Maven

We are planning to drop support for building Protobuf Java OSS from source with +the Maven build system in the Protobuf Java 4.28 release. This has been marked +deprecated in the 4.27 release.

After this point, you can continue to use Bazel, or another build system, to +build Protobuf. You can read more about building from source in +the Protobuf Java README.

This change may impact Protobuf Java contributors that build protobuf from +source. It does not impact the majority of users that uses the precompiled +protobuf-java or protobuf-javalite artifacts from a repository. Note +specifically that we do not plan to stop supporting the ability to compile +gencode with Maven, and we plan to continue to make prebuilt artifacts available +in the Maven Central repository.

\ No newline at end of file diff --git a/news/2024-10-01/index.html b/news/2024-10-01/index.html new file mode 100644 index 000000000..cf6b506c4 --- /dev/null +++ b/news/2024-10-01/index.html @@ -0,0 +1,27 @@ +Changes Announced on October 1, 2024 | Protocol Buffers Documentation +

Changes Announced on October 1, 2024

Changes announced for Protocol Buffers on October 1, 2024.

Bazel and Proto Rules

There are upcoming changes to the way that Bazel will work for protobuf builds. +These changes require awareness in the first stage, and action by project owners +before the second stage.

Stage 1

With the release of Bazel 8, proto rules (proto_library, cc_proto_library, +java_proto_library, java_lite_proto_library, and py_proto_library) will be +removed from the Bazel project. The will be added to the Protocol Buffers +project in v29. Bazel will be updated to automatically use the rules from the +protobuf project, so the change is initially a no-op for project owners.

After the release of Bazel 8 and before the release of Bazel 9, users will need +to explicitly load the rules from the Protocol Buffers project repository. The +automatic use of the rules is only temporary to support the migration.

Users should add the following load() statements to any BUILD or .bzl +files that use these proto rules. Note that these require Protobuf v29.0 or +higher.

load("@protobuf//bazel:proto_library.bzl", "proto_library")
+
+load("@protobuf//bazel:cc_proto_library.bzl", "cc_proto_library")
+load("@protobuf//bazel:java_proto_library.bzl", "java_proto_library")
+load("@protobuf//bazel:java_lite_proto_library.bzl", "java_lite_proto_library")
+load("@protobuf//bazel:py_proto_library.bzl", "py_proto_library")
+

Stage 2

When Bazel 9 is released, the automatic loading of the protobuf library’s rules +will be removed. At that point, you will need to have load statements in your +Bazel build files.

End Goal

Once the rules are in the protobuf repo, we intend to address common user +requests, such as using prebuilts for the proto compiler where possible.

\ No newline at end of file diff --git a/news/2024-10-02/index.html b/news/2024-10-02/index.html new file mode 100644 index 000000000..a12e7bd50 --- /dev/null +++ b/news/2024-10-02/index.html @@ -0,0 +1,91 @@ +Changes Announced on October 2, 2024 | Protocol Buffers Documentation +

Changes Announced on October 2, 2024

Changes announced for Protocol Buffers on October 2, 2024.

The following sections cover planned breaking changes in the v30 release, +expected in 2025 Q1. These describe changes as we anticipate them being +implemented, but due to the flexible nature of software some of these changes +may not land or may vary from how they are described in this topic.

Changes in C++

C++ will bump its major version from 5.29.x to 6.30.x.

Descriptor APIs

v30 will update return types in descriptor (such as full_name) to be +absl::string_view. This opens up memory savings in descriptors.

v28 introduced the PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE macro, which you +can use in the meantime to enable the updated return type ahead of the breaking +release. The v30 release will flip the default and remove the macro.

ctype Removed from FieldDescriptor Options

v30 will stop exposing the ctype from FieldDescriptor options. You can use +the FieldDescriptor::cpp_string_type() API, added in the +v28 release, +in its place.

Replace CMake Submodules with Fetched Deps

v30 will remove submodules and switches to upb’s old CMake pattern of fetching +dependencies.

If you use installed packages, you won’t be affected. It could break some CMake +workflows.

Remove Deprecated APIs

v30 will remove the following public runtime APIs, which have been marked +deprecated (such as ABSL_DEPRECATED) for at least one minor or major release +and that are obsolete or replaced.

Arena::CreateMessage

API: +Arena::CreateMessage

Replacement: +Arena::Create

Arena::GetArena

API: +Arena::GetArena

Replacement: value->GetArena()

RepeatedPtrField::ClearedCount

API: +RepeatedPtrField::ClearedCount

Replacement: Migrate to Arenas +(migration guide).

JsonOptions

API: +JsonOptions

Replacement: JsonPrintOptions

Dropping C++14 Support

This release will drop C++ 14 as the minimum supported version and raise it to +17, as per the +Foundational C++ Support matrix.

Per our policies, we do not +consider this to be a breaking change.

Changes in JRuby

v30 will flip the default implementation for JRuby to FFI, which may be breaking +for some JRuby users.

Note that this change doesn’t create a Ruby major version bump because JRuby is +not officially supported.

Changes in Python

Python will bump its major version from 5.29.x to 6.30.x.

Dropping Python 3.8 Support

As per our official Python support policy, we will be dropping support for +Python 3.8 and lower. This means the minimum supported Python version is 3.9.

Remove bazel/system_python.bzl Alias

v30 will remove the legacy bazel/system_python.bzl alias.

Remove direct references to system_python.bzl in favor of using +protobuf_deps.bzl instead. Use python/dist/system_python.bzl where it was +moved +in v5.27.0 +if you need a direct reference.

Field Setter Validation Changes

Python’s and upb’s field setters will be fixed in v30 to validate closed enums +under edition 2023. Closed enum fields updated with invalid values will generate +errors.

Remove Deprecated APIs

v30 will remove the following public runtime APIs, which have been marked +deprecated for at least one minor or major release and are obsolete or replaced.

Reflection Methods

APIs: +reflection.ParseMessage, +reflection.MakeClass

Replacement: message_factory.GetMessageClass()

RPC Service Interfaces

APIs: +service.RpcException, +service.Service, +service.RpcController, +and +service.RpcChannel

Replacement: Starting with version 2.3.0, RPC implementations should not try +to build on these, but should instead provide code generator plugins which +generate code specific to the particular RPC implementation.

MessageFactory and SymbolDatabase Methods

APIs: +MessageFactory.GetPrototype, +MessageFactory.CreatePrototype, +MessageFactory.GetMessages, +SymbolDatabase.GetPrototype, +SymbolDatabase.CreatePrototype, +and +SymbolDatabase.GetMessages

Replacement: message_factory.GetMessageClass() and +message_factory.GetMessageClassesForFiles().

GetDebugString

APIs: +GetDebugString

Replacement:

No replacement. It’s only in Python C++ which is no longer released. It is not +supported in pure Python or UPB.

Changes in Objective-C

This will be the first breaking release for Objective-C.

Objective-C will bump its major version from 3.x.x to 4.30.x.

Overhaul Unknown Field Handling APIs Deprecating Most of the Existing APIs

v30 will deprecate GPBUnknownFieldSet and replace it with GPBUnknownFields. +The new type will preserve the ordering of unknown fields from the original +input or API calls, to ensure any semantic meaning to the ordering is maintained +when a message is written back out.

As part of this, the GPBUnknownField type also has its APIs changed, with +almost all of the existing APIs becoming deprecated and new ones added.

Deprecated property APIs:

  • varintList
  • fixed32List
  • fixed64List
  • lengthDelimitedList
  • groupList

Deprecated modification APIs:

  • addVarint:
  • addFixed32:
  • addFixed64:
  • addLengthDelimited:
  • addGroup:

Deprecated initializer initWithNumber:.

New property APIs:

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

This type will model a single field number in its value, rather than grouping +all the values for a given field number. The APIs for creating new fields are +the add* APIs on the GPBUnknownFields class.

v30 will also deprecate -[GPBMessage unknownFields]. In its place, there will +be new APIs to extract and update the unknown fields of the message.

Remove Deprecated APIs

v30 will remove the following public runtime APIs, which have been marked +deprecated for at least one minor or major release and are obsolete or replaced.

GPBFileDescriptor

API: +-[GPBFileDescriptor syntax]

Replacement: Obsolete.

GPBMessage mergeFrom:extensionRegistry

API: +-[GPBMessage mergeFrom:extensionRegistry:]

Replacement: +-[GPBMessage mergeFrom:extensionRegistry:error:]

GPBDuration timeIntervalSince1970

API: +-[GPBDuration timeIntervalSince1970]

Replacement: +-[GPBDuration timeInterval]

GPBTextFormatForUnknownFieldSet

API: +GPBTextFormatForUnknownFieldSet()

Replacement: Obsolete - Use +GPBTextFormatForMessage(), +which includes any unknown fields.

GPBUnknownFieldSet

API: +GPBUnknownFieldSet

Replacement: +GPBUnknownFields

GPBMessage unknownFields

API: +GPBMessage unknownFields property

Replacement: +-[GPBUnknownFields initFromMessage:], +-[GPBMessage mergeUnknownFields:extensionRegistry:error:], +and +-[GPBMessage clearUnknownFields]

Remove Deprecated Runtime APIs for Old Gencode

This release will remove deprecated runtime methods that support the Objective-C +gencode from before the 3.22.x release. The library will also issue a log +message at runtime when old generated code is starting up.

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

Replacement: Regenerate with a current version of the library.

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

Replacement: Regenerate with a current version of the library.

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

Replacement: Regenerate with a current version of the library.

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

Replacement: Regenerate with a current version of the library.

API: +-[GPBExtensionDescriptor initWithExtensionDescription:]

Replacement: Regenerate with a current version of the library.

Other Changes

In addition to those breaking changes are some other changes worth noting. While +the following are not considered breaking changes, they may still impact users.

Poison Pill Warnings

v30 will update poison pills to emit warnings for old gencode + new runtime +combinations that work under the new rolling upgrade policy, but will break in +the next major bump. For example, Java 4.x.x gencode should work against 5.x.x +runtime but warn of upcoming breakage against 6.x.x runtime.

Changes to UTF-8 Enforcement in C# and Ruby

v30 will includes a fix to make UTF-8 enforcement consistent across languages. +Users with bad non-UTF8 data in string fields may see surfaced UTF-8 enforcement +errors earlier.

\ No newline at end of file diff --git a/news/2024-11-07/index.html b/news/2024-11-07/index.html new file mode 100644 index 000000000..1144679e8 --- /dev/null +++ b/news/2024-11-07/index.html @@ -0,0 +1,38 @@ +Changes Announced on November 7, 2024 | Protocol Buffers Documentation +

Changes Announced on November 7, 2024

Changes announced for Protocol Buffers on November 7, 2024.

The following sections cover planned breaking changes in the v30 release, +expected in 2025 Q1. Also included are some changes that aren’t breaking but may +require action on your part. These are in addition to those mentioned in the +News article from October 2.

These describe changes as we anticipate them being implemented, but due to the +flexible nature of software some of these changes may not land or may vary from +how they are described in this topic.

Introduce ASAN Poisoning After Clearing Oneof Messages on Arena

This change adds a hardening check that affects C++ protobufs using Arenas. +Oneof messages allocated on the protobuf arena will now be cleared in debug and +poisoned in ASAN mode. After calling clear, future attempts to use the memory +region will cause a crash in ASAN as a use-after-free error.

This implementation +requires C++17.

Python setdefault Behavior Change for Map Fields

Starting in v30, setdefault will be similar to dict for ScalarMap, except +that both key and value must be set. setdefault will be rejected for +MessageMaps.

Remove Deprecated py_proto_library Macro

The deprecated internal py_proto_library Bazel macro in protobuf.bzl will be +removed in v30.x.

This should be replaced by the official py_proto_library which will be moved +to protobuf in bazel/py_proto_library as of v29.x. This implementation was +previously available in rules_python prior to v29.x.

Python Nested Message Class __qualname__ Contains the Outer Message Name

Python nested message class __qualname__ now contains the outer message name. +Prior to v30, __qualname__ has the same result with __name__ for nested +message, in that the outer message name was not included.

For example:

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
+

Dropping our C++ CocoaPods release

In v30, we will be dropping our C++ CocoaPods release, which has been broken +since v4.x.x. C++ users should use our +GitHub release directly +instead.

Ruby and PHP Errors in JSON Parsing

v30 fixes non-conformance in JSON parsing of strings in numeric fields per the +JSON spec.

This fix will not be accompanied by a major version bump, but Ruby and PHP will +now raise errors for non-numeric strings (e.g. “”, “12abc”, “abc”) in numeric +fields. v29.x will include a warning for these error cases.

\ No newline at end of file diff --git a/news/2024-12-04/index.html b/news/2024-12-04/index.html new file mode 100644 index 000000000..82b9d1244 --- /dev/null +++ b/news/2024-12-04/index.html @@ -0,0 +1,49 @@ +Changes announced December 4, 2024 | Protocol Buffers Documentation +

Changes announced December 4, 2024

Changes announced for Protocol Buffers on December 4, 2024.

We are planning to modify the Protobuf debug APIs for C++ (including Protobuf +AbslStringify, proto2::ShortFormat, proto2::Utf8Format, +Message::DebugString, Message::ShortDebugString, Message::Utf8DebugString) +in v30 to redact sensitive fields annotated by debug_redact; the outputs of +these APIs will contain a per-process randomized prefix, and so will no longer +be parseable by Protobuf TextFormat Parsers.

Motivation

Currently Protobuf debug APIs print every field in a proto into human-readable +formats. This may lead to privacy incidents where developers accidentally log +Protobuf debug outputs containing sensitive fields.

How to Annotate Sensitive Fields

There are two ways to mark fields sensitive:

  • Mark a field with the field option debug_redact = true, directly.

    message Foo {
    +  optional string secret = 1 [debug_redact = true];
    +}
    +
  • If you have already defined a field annotation of type Enum by extending +proto2.FieldOptions, and certain values of this annotation are used to +annotate fields you would like to redact, then you can annotate these values +with debug_redact = true. All the fields that have been annotated with +such values will be redacted.

    package my.package;
    +
    +extend proto2.FieldOptions {
    +  # The existing field annotation
    +  optional ContentType content_type = 1234567;
    +};
    +
    +enum ContentType {
    +  PUBLIC = 0;
    +  SECRET = 1 [debug_redact = true];
    +};
    +
    +message Foo {
    +  # will not be redacted
    +  optional string public_info = 1 [
    +    (my.package.content_type) = PUBLIC
    +  ];
    +  # will be redacted
    +  optional string secret = 1 [
    +    (my.package.content_type) = SECRET
    +  ];
    +}
    +

New Debug Format

Compared to the existing debug format, the new debug format has two major +differences:

  • The sensitive fields annotated with debug_redact are redacted +automatically in the output formats
  • The output formats will contain a per-process randomized prefix, which will +make them no longer be parsable by TextFormat parsers.

Note that the second change is true regardless of whether the proto contains +sensitive fields or not, which ensures that any debug output always cannot be +deserialized regardless of the proto content.

\ No newline at end of file diff --git a/news/2024-12-13/index.html b/news/2024-12-13/index.html new file mode 100644 index 000000000..54a8bb940 --- /dev/null +++ b/news/2024-12-13/index.html @@ -0,0 +1,13 @@ +Changes announced December 13, 2024 | Protocol Buffers Documentation +

Changes announced December 13, 2024

Changes announced for Protocol Buffers on December 13, 2024.

In v30.x, we are removing the following reflection-related function: +MutableRepeatedFieldRef<T>::Reserve().

An upcoming performance improvement in +RepeatedPtrField +is incompatible with this API. The improvement is projected to accelerate +repeated access to the elements of RepeatedPtrField, in particular and +especially sequential access.

\ No newline at end of file diff --git a/news/2024-12-18/index.html b/news/2024-12-18/index.html new file mode 100644 index 000000000..35d1b3db9 --- /dev/null +++ b/news/2024-12-18/index.html @@ -0,0 +1,23 @@ +Changes announced December 18, 2024 | Protocol Buffers Documentation +

Changes announced December 18, 2024

Changes announced for Protocol Buffers on December 18, 2024.

Go Protobuf: The new Opaque API

Back in March 2020, we released the google.golang.org/protobuf module, +a major overhaul of the Go Protobuf API. +This package introduced first-class +support for reflection, +a dynamicpb +implementation and the +protocmp +package for easier testing.

That release introduced a new protobuf module with a new API. Today, we are +releasing an additional API for generated code, meaning the Go code in the +.pb.go files created by the protocol compiler (protoc). The blog post at +https://go.dev/blog/protobuf-opaque explains our motivation for creating a new +API and shows you how to use it in your projects.

To be clear: We are not removing anything. We will continue to support the +existing API for generated code, just like we still support the older protobuf +module (by wrapping the google.golang.org/protobuf implementation). Go is +committed to backwards compatibility and this +applies to Go Protobuf, too!

\ No newline at end of file diff --git a/news/2025-01-23/index.html b/news/2025-01-23/index.html new file mode 100644 index 000000000..b4dc58b89 --- /dev/null +++ b/news/2025-01-23/index.html @@ -0,0 +1,28 @@ +Changes announced January 23, 2025 | Protocol Buffers Documentation +

Changes announced January 23, 2025

Changes announced for Protocol Buffers on January 23, 2025.

Poison Java gencode

We are patching a change into the 25.x branch that will poison Java gencode that +was created prior to the +3.21.7 release. +We will then mark all versions of Java protobuf from 3.21.7 through 3.25.5 as +vulnerable to the +footmitten CVE.

After this change is patched in, protobuf will throw an +UnsupportedOperationException from the +makeExtensionsImmutable +method unless you set the system property +“-Dcom.google.protobuf.use_unsafe_pre22_gencode”. Using this system property +can buy you some time if you can’t update your code immediately, but should be +considered a short-term workaround.

Poison MSVC + Bazel

Update: This plan has been canceled. You can learn more about this in the +announcement on July 16, 2025.

We will be dropping support for using Bazel and MSVC together in v34. As of +v30, we will poison this combination with an error unless you specify the +opt-out flag --define=protobuf_allow_msvc=true to silence it.

MSVC’s path length limits combined with Bazel’s sandboxing have become +increasingly difficult to support in combination. Rather than randomly break +users who install protobuf into a long path, we will prohibit the use of MSVC +from Bazel altogether. We will continue to support MSVC with CMake, and begin +supporting clang-cl +with Bazel. For any feedback or discussion, see +https://github.com/protocolbuffers/protobuf/issues/20085.

\ No newline at end of file diff --git a/news/2025-03-18/index.html b/news/2025-03-18/index.html new file mode 100644 index 000000000..2d7edffe9 --- /dev/null +++ b/news/2025-03-18/index.html @@ -0,0 +1,11 @@ +Changes Announced on March 18, 2025 | Protocol Buffers Documentation +

Changes Announced on March 18, 2025

Changes announced for Protocol Buffers on March 18, 2025.

Dropping Ruby 3.0 Support

As per our official +Ruby support policy, +we will be dropping support for Ruby 3.0 and lower in Protobuf version 31, due +to release in April, 2025. The minimum supported Ruby version will be 3.1.

\ No newline at end of file diff --git a/news/2025-06-27/index.html b/news/2025-06-27/index.html new file mode 100644 index 000000000..71f948a26 --- /dev/null +++ b/news/2025-06-27/index.html @@ -0,0 +1,101 @@ +Changes Announced on June 27, 2025 | Protocol Buffers Documentation +

Changes Announced on June 27, 2025

Changes announced for Protocol Buffers on June 27, 2025.

Edition 2024

We are planning to release Protobuf Edition 2024 in 32.x in Q3 2025.

These describe changes as we anticipate them being implemented, but due to the +flexible nature of software some of these changes may not land or may vary from +how they are described in this topic.

More documentation on Edition 2024 will be published in +Feature Settings for Editions, +including information on migrating from Edition 2023.

Changes to Existing Features

This section details any existing features whose default settings will change in +Edition 2024.

C++ string_type

The default for string_type feature, originally released in Edition 2023, will +change from STRING to VIEW in Edition 2024.

See +features.(pb.cpp).string_type +and String View APIs for +more information on this feature and its feature values.

New Features

This section details any new features that will be introduced in Edition 2024.

enforce_naming_style

feature.enforce_naming_style +enables strict naming style enforcement to ensure protos are round-trippable by +default with a feature value to opt-out to use legacy naming style.

default_symbol_visibility

This feature controls whether the default symbol visibility of importable +symbols (such as messages and enums) is either:

  • export: referenceable from other protos via import statements
  • local: un-referenceable outside of current file

The default feature value EXPORT_TOP_LEVEL in Edition 2024 ensures top-level +symbols are export by default, whereas nested symbols are local by default.

This can be used along with the export and local keywords +to explicitly annotate symbol visibility, also added in Edition 2024.

Symbol visibility only controls which symbols can be imported from other proto +files, but does not affect code-generation.

C++: enum_name_uses_string_view

Previously, all generated enum types provide the following function to obtain +the label out of an enum value, which has significant overhead to construct the +std::string instances at runtime:

const std::string& Foo_Name(int);
+

The default feature value in Edition 2024 instead migrates this signature to +return absl::string_view to allow for better storage decoupling and potential +memory/CPU savings.

absl::string_view Foo_Name(int);
+

Users should migrate their code to handle the new return-type following +the migration guide.

See String View APIs for +more information.

Java: nest_in_file_class

This feature controls whether the Java generator will nest the generated class +in the Java generated file class.

The default value in Edition 2024 generates classes in their own files by +default, which is also the default behavior of the previous +java_multiple_files = true file option. This replaces java_multiple_files +which is removed in Edition 2024.

The default outer classname is also updated to always be the camel-cased +.proto filename suffixed with Proto by default (for example, +foo/bar_baz.proto -> BarBazProto). You can override this using the +java_outer_classname file option and replace the pre-Edition 2024 default of +BarBaz or BarBazOuterClass depending on the presence of conflicts.

Java: large_enum

This feature allows creation of large Java enums, extending beyond the enum +limit due to standard constant limits imposed by the Java language.

Creation of large enums is not enabled by default, but you can explicitly enable +it using this feature. Note that this feature replicates enum-like behavior but +has some notable differences (for example, switch statements are not supported).

Grammar Changes

import option

Edition 2024 adds support for option imports using the syntax import option.

Unlike normal import statements, import option only imports custom options +defined in a .proto file, without importing other symbols.

This means that messages and enums are excluded from the option import. In the +following example, the Bar message cannot be used as a field type in +foo.proto, but options with type Bar can still be set.

Option imports must also come after any other import statements.

Example:

// bar.proto
+edition = "2024";
+
+import "google/protobuf/descriptor.proto";
+
+message Bar {
+  bool bar = 1;
+}
+
+extend proto2.FileOptions {
+  bool file_opt1 = 5000;
+  Bar file_opt2 = 5001;
+}
+
// foo.proto:
+edition = "2024";
+
+import option "bar.proto";
+
+option (file_opt1) = true;
+option (file_opt2) = {bar: true};
+
+message Foo {
+  // Bar bar = 1; // This is not allowed
+}
+

Option imports do not require generated code for its symbols and thus must be +provided as option_deps in proto_library instead of deps. This avoids +generating unreachable code.

proto_library(
+  name = "foo",
+  srcs = ["foo.proto"],
+  option_deps = [":custom_option"]
+)
+

Option imports and option_deps are strongly recommended when importing +protobuf language features and other custom options to avoid generating +unnecessary code.

option_deps requires Bazel 8 or later since the native.proto_library in +Bazel 7 does not support this.

This also replaces import weak, which is removed in Edition 2024.

export / local Keywords

export and local keywords are added in Edition 2024 as modifiers for the +symbol visibility of importable symbols, from the default behavior specified by +the +default_symbol_visibility feature.

This controls which symbols can be imported from other proto files, but does not +affect code-generation.

In Edition 2024, these can be set on all message and enum symbols by default. +However, some values of the default_symbol_visibility feature further restrict +which symbols are exportable.

Example:

// Top-level symbols are exported by default in Edition 2024
+local message LocalMessage {
+  // Nested symbols are local by default in Edition 2024
+  export enum ExportedNestedEnum {
+    UNKNOWN_EXPORTED_NESTED_ENUM_VALUE = 0;
+  }
+}
+

“import weak” and weak Field Option

Weak imports are no longer allowed as of Edition 2024.

Most users previously relying on import weak to declare a “weak dependency” to +import custom options without generated code for C++ and Go should instead +migrate to use +import option +instead.

ctype Field Option

ctype field option is no longer allowed as of Edition 2024. Use the +features.(pb.cpp).string_type +feature, instead.

java_multiple_files File Option

The java_multiple_files file option is removed in Edition 2024 in favor of the +new +features.nest_in_file_class +Java feature.

\ No newline at end of file diff --git a/news/2025-07-14/index.html b/news/2025-07-14/index.html new file mode 100644 index 000000000..30c842d09 --- /dev/null +++ b/news/2025-07-14/index.html @@ -0,0 +1,32 @@ +Changes Announced on July 14, 2025 | Protocol Buffers Documentation +

Changes Announced on July 14, 2025

Changes announced for Protocol Buffers on July 14, 2025.

Deprecating FieldDescriptor Enums

We are announcing an upcoming change regarding the FieldDescriptor enum and +its associated values representing optional, required, and repeated. These are +being deprecated as we encourage the use of more precise accessor methods.

Background

While at one time the FieldDescriptor.label enum served a purpose, the +evolution of Protocol Buffers has introduced more idiomatic ways to determine a +field’s cardinality (singular/repeated) and presence semantics.

  • In proto2, optional, required, and repeated are explicit keywords.
  • In proto3, required is no longer supported. All scalar fields are +implicitly “optional” in the sense that they have default values if not +set. The optional keyword was later reintroduced in proto3 to explicitly +track presence for scalar fields (distinguishing between an unset field and +a field set to its default value).
  • In edition 2023 we removed the optional and required keywords and use +features to control those behaviors.

The label enum conflates these distinct concepts (cardinality, requiredness, +and explicit presence tracking), leading to potential confusion, especially with +proto3’s field presence model.

Impact and Migration

The FieldDescriptor.label field will eventually be removed from the API.

Note that the method names in this topic may be spelled slightly differently in +some languages.

  • For Protocol Buffer Editions fields:
    • Key Methods for Editions:
      • hasPresence becomes the primary method to determine if a singular +field tracks presence, reflecting the +features.field_presence +setting for that field.
    • Migration: Rely on isRepeated and isRequired for cardinality and +hasPresence to check for explicit presence tracking in singular +fields.
  • For proto2/proto3 fields: getLabel will eventually be removed, and is +not recommended in the meantime.

All users of Protocol Buffers who interact with FieldDescriptor objects in +their code (for example for code generation, reflection, and dynamic message +handling) should migrate away from using FieldDescriptor.label directly.

Instead, update your code to use the following methods:

  • To check if a field is repeated: field.isRepeated
  • To check if a field is required (proto2 and editions only): +field.isRequired
  • To check if a singular field has explicit presence, use hasPresence

Timeline

This deprecation is effective immediately. While getLabel will continue to +function, we recommend migrating your code proactively to ensure future +compatibility and clarity. This change will lead to a more robust and +understandable experience for developers using Protocol Buffers.

\ No newline at end of file diff --git a/news/2025-07-16/index.html b/news/2025-07-16/index.html new file mode 100644 index 000000000..a0375e05d --- /dev/null +++ b/news/2025-07-16/index.html @@ -0,0 +1,13 @@ +Changes Announced on July 16, 2025 | Protocol Buffers Documentation +

Changes Announced on July 16, 2025

Changes announced for Protocol Buffers on July 16, 2025.

Retaining support for Bazel with MSVC

We announced on January 23, 2025 that we were planning to drop support for using +Bazel and MSVC together starting in v34. This plan is canceled due to Bazel’s +upcoming changes to virtual +includes on Windows. Clang-cl support will be kept in place as an alternative on +Windows. The opt-out flag --define=protobuf_allow_msvc=true will no longer be +required as of the 32.0 release.

\ No newline at end of file diff --git a/news/2025-09-19/index.html b/news/2025-09-19/index.html new file mode 100644 index 000000000..2db751eeb --- /dev/null +++ b/news/2025-09-19/index.html @@ -0,0 +1,62 @@ +Changes Announced on September 19, 2025 | Protocol Buffers Documentation +

Changes Announced on September 19, 2025

Changes announced for Protocol Buffers on September 19, 2025.

The following sections cover planned breaking changes in the v34 release, +expected in 2026 Q1. These describe changes as we anticipate them being +implemented, but due to the flexible nature of software some of these changes +may not land or may vary from how they are described in this topic.

Changes in C++

C++ will bump its major version to 7 with the 7.34.0 release. 6.33 will be the +final minor version release on 6.x

Removal of Future Macros

The following macros, introduced for staged roll-out of breaking changes, will +be removed and their behavior will become the default:

  • PROTOBUF_FUTURE_RENAME_ADD_UNUSED_IMPORT
  • PROTOBUF_FUTURE_REMOVE_ADD_IGNORE_CRITERIA
  • PROTOBUF_FUTURE_STRING_VIEW_DESCRIPTOR_DATABASE
  • PROTOBUF_FUTURE_NO_RECURSIVE_MESSAGE_COPY
  • PROTOBUF_FUTURE_REMOVE_REPEATED_PTR_FIELD_ARENA_CONSTRUCTOR
  • PROTOBUF_FUTURE_REMOVE_MAP_FIELD_ARENA_CONSTRUCTOR
  • PROTOBUF_FUTURE_REMOVE_REPEATED_FIELD_ARENA_CONSTRUCTOR

New RepeatedPtrField Layout

RepeatedPtrField will transition to a new internal element layout where +elements are stored in contiguous chunks of preallocated memory, similar to +std::deque. This results in some changes to copy/move semantics of some APIs, +and some UnsafeArena APIs may become functional equivalents of their +arena-safe counterparts and be deprecated.

MSB Hardening Check on RepeatedField::Get and RepeatedPtrField::Get

Protobufs will be hardened against OOB errors by adding comprehensive bounds +checking to repeated field accesses.

Remove Arena-enabled constructors from Repeated/Map Fields

The RepeatedField(Arena*), RepeatedPtrField(Arena*), and Map(Arena*) +constructors will be deleted.

Remove Deprecated APIs

This release will remove the following public runtime APIs, which have been +marked deprecated for at least one minor or major release and that are obsolete +or replaced.

AddUnusedImportTrackFile() and ClearUnusedImportTrackFiles()

API: AddUnusedImportTrackFile(), ClearUnusedImportTrackFiles()

Replacement: AddDirectInputFile() and ClearDirectInputFiles()

AddIgnoreCriteria from message differencer

PROTOBUF_FUTURE_REMOVE_ADD_IGNORE_CRITERIA was added for the breaking change. +This release will remove the macro.

API: AddIgnoreCriteria()

Replacement: Wrap the raw pointer in a unique_ptr.

FieldDescriptor::has_optional_keyword()

API: FieldDescriptor::has_optional_keyword()

Replacement: has_presence()

FieldDescriptor::label()

API: FieldDescriptor::label()

Replacement: is_repeated() or is_required()

FieldDescriptor::is_optional()

API: FieldDescriptor::is_optional()

Replacement: !is_required() && !is_repeated()

UseDeprecatedLegacyJsonFieldConflicts()

API: UseDeprecatedLegacyJsonFieldConflicts()

Replacement: No replacement.

Stricter Name Length Limits

The protobuf compiler will enforce stricter limits on the length of symbol +names, such as field names, to prevent potential issues. If the length of any +field name is > 2^16, it will generate an error.

Hide Private Generator Headers in CMake

The protoc generator headers will no longer be installed by CMake. This should +not affect most users.

[[nodiscard]] on Logically Constant Operations

[[nodiscard]] will be added to several logically constant protobuf APIs where +failure to consume the returned value indicates a probable bug. This follows +patterns used commonly in the C++ standard library.

Changes in Python

Python will bump its major version to 7 with the 7.34.0 release. 6.33 will be +the final minor version release on 6.x

There is no change in the gencode and we will relax the poison pills. No +warnings or errors will be raised for old generated files for 7.34.x.

Raise TypeError on Incorrect Type Conversion to Timestamp/Duration

This release will raise a TypeError instead of an AttributeError when +converting an incorrect type to a Timestamp or Duration.

Reject bool to enum and int field

This release will reject setting enum or int fields with boolean values. The API +will raise an error instead of implicitly converting them.

Remove float_precision from json_format

This release will remove the deprecated float_precision option from the +json_format serializer. This option does not exist in other ProtoJSON +serializers and has confusing semantics.

Remove float_format/double_format from text_format

This release will remove the deprecated float_format and double_format +options from text_format. These options are not available in other proto text +format serializers.

Remove Deprecated APIs

This release will remove the following public runtime APIs.

FieldDescriptor.label

API: FieldDescriptor.label

Replacement: Use is_repeated() or is_required().

Changes in PHP

PHP will bump its major version to 5 with the 5.34.0 release. 4.33 will be the +final minor version release on 4.x

Remove Deprecated APIs

This release will remove the following public runtime APIs.

FieldDescriptor getLabel

API: FieldDescriptor getLabel

Replacement: isRepeated() or isRequired()

Google\Protobuf\Field_Kind

API: Google\Protobuf\Field_Kind

Replacement: Google\Protobuf\Field\Kind

Google\Protobuf\Field_Cardinality

API: Google\Protobuf\Field_Cardinality

Replacement: Google\Protobuf\Field\Cardinality

Google\Protobuf\Internal\RepeatedField

API: Google\Protobuf\Internal\RepeatedField

Replacement: Google\Protobuf\RepeatedField

JSON Parsing Strictness

The JSON parser will become stricter and reject several cases that were +previously accepted. This includes out-of-bound values, non-integer numeric +values for integer fields, duplicate oneof fields, and non-string values for +string fields. The JSON serializer will also reject Infinity and NaN for +number values.

Fix Silent Ignoring of Default Values

The PHP runtime will be fixed to honor default values on scalar fields in proto2 +and editions, instead of silently ignoring them.

Type Checking Alignment

Type checking for pure-PHP and upb-PHP implementations will be aligned. Notably, +pure-PHP will reject null for string fields, matching the behavior of upb-PHP.

Changes in Objective-C

Objective-C will bump its major version to 5 with the 5.34.0 release. 4.33 will +be the final minor version release on 4.x

The nullability annotations for some GPB*Dictionary APIs will be corrected to +mark when APIs could return nil. This will result in Swift code getting a +Swift Optional<T> and thus becoming a breaking API change. For Objective-C +callers, the annotation correction is less likely to have any impact on the +source code.

Remove Deprecated APIs

This release will remove the following public runtime APIs.

-[GPBFieldDescriptor optional]

API: -[GPBFieldDescriptor optional]

Replacement: Use !required && fieldType == GPBFieldTypeSingle instead.

Changes in Bazel

Migration of Proto Flags to Starlark

--proto_toolchain_for* and --proto_compiler are no longer read by Proto +rules. These toolchain-related flags are deprecated and will be removed in the +future. Switching to the equivalent Starlark flags is a short-term fix:

  • --@protobuf//bazel/flags/cc:proto_toolchain_for_cc
  • --@protobuf//bazel/flags/java:proto_toolchain_for_java
  • --@protobuf//bazel/flags/java:proto_toolchain_for_javalite
  • --@protobuf//bazel/flags:proto_compiler

The longer-term fix is to enable +--incompatible_enable_proto_toolchain_resolution (which is the default in +Bazel 9 anyway) and to register toolchains using the normal platforms-related +mechanisms (register_toolchain() in MODULE.bazel or WORKSPACE, or +--extra_toolchains).

All other Bazel Proto flags have also been migrated to Starlark, and the native +flags will be deprecated with the next Bazel release. Use the following Starlark +flags to avoid future breakages:

  • --@protobuf//bazel/flags:strict_proto_deps
  • --@protobuf//bazel/flags:strict_public_imports
  • --@protobuf//bazel/flags:experimental_proto_descriptor_sets_include_source_info
  • --@protobuf//bazel/flags/cc:cc_proto_library_header_suffixes
  • --@protobuf//bazel/flags/cc:cc_proto_library_source_suffixes
  • --@protobuf//bazel/flags:protocopt

NOTE: In v34.0, --@protobuf//bazel/flags:protocopt was incorrectly located +at --@protobuf//bazel/flags/cc:protocopt. The flag will be moved to its +correct location, and the cc location will remain as a deprecated alias +starting in v34.1. This alias should not be used and will be removed in the next +breaking change.

Remove deprecated ProtoInfo.transitive_imports

The deprecated transitive_imports field in ProtoInfo will be removed. Users +should migrate to transitive_sources.

Remove protobuf_allow_msvc flag and continue support Bazel+MSVC

Due to Bazel’s recent improvements on Windows, we now plan to continue to +support Bazel+MSVC. The --define=protobuf_allow_msvc flag will be removed.

Other Changes

The following are additional breaking changes.

Languages Without a Major Version Bump

Java, Ruby, C#, Rust, and JRuby will not have a major version bump in this +release.

\ No newline at end of file diff --git a/news/2026-01-16/index.html b/news/2026-01-16/index.html new file mode 100644 index 000000000..0a1244317 --- /dev/null +++ b/news/2026-01-16/index.html @@ -0,0 +1,22 @@ +Changes Announced on January 16, 2026 | Protocol Buffers Documentation +

Changes Announced on January 16, 2026

Changes announced for Protocol Buffers on January 16, 2026.

Prebuilt proto compiler (protoc) for Bazel

In an effort to speed up builds, protobuf 33.4 offers an option to skip +re-compiling Protobuf tools and runtimes and use a pre-built protoc binary, +available to Bazel 7 and later. Using a pre-built protoc also avoids build +failures from incompatible or non-hermetic C++ compilation toolchain installed +on your machine.

To use the prebuilt protoc, upgrade to protobuf version 33.4 or later, and set +the --incompatible_enable_proto_toolchain_resolution and +--@protobuf//bazel/flags:prefer_prebuilt_protoc flags. The first flag is set +by default in Bazel 9 onwards.

In the breaking v34 release, protobuf will change the default of +--@protobuf//bazel/flags:prefer_prebuilt_protoc to true.

Reasons not to use the prebuilt compiler

There are some use cases in which using the prebuilt protoc is not recommended:

  • Your corporate security policy requires all dependencies be built from +source.
  • You need to build for the exec platform with a specific compiler or specific +compiler flags.
  • You are making changes to protoc, itself, and want to ensure that those +changes are tested.

Troubleshooting

For information on troubleshooting the prebuilt protoc compiler configuration, +see +Bazel: Resolving Issues with Prebuilt Protoc

For more information on other changes in Bazel 9 that affect Protocol Buffers, +see https://bazel.build/about/roadmap.

\ No newline at end of file diff --git a/news/2026-03-13/index.html b/news/2026-03-13/index.html new file mode 100644 index 000000000..ab364e81e --- /dev/null +++ b/news/2026-03-13/index.html @@ -0,0 +1,21 @@ +Changes Announced on March 13, 2026 | Protocol Buffers Documentation +

Changes Announced on March 13, 2026

Changes announced for Protocol Buffers on March 13, 2026.

Changes in Bazel

Migration of Proto Flags to Starlark

--proto_toolchain_for* and --proto_compiler are no longer read by Proto +rules. These toolchain-related flags are deprecated and will be removed in the +future. Switching to the equivalent Starlark versions of the flags is a +short-term fix:

  • --@protobuf//bazel/flags/cc:proto_toolchain_for_cc
  • --@protobuf//bazel/flags/java:proto_toolchain_for_java
  • --@protobuf//bazel/flags/java:proto_toolchain_for_javalite
  • --@protobuf//bazel/flags:proto_compiler

The longer-term fix is to enable +--incompatible_enable_proto_toolchain_resolution (which is the default in +Bazel 9 anyway) and to register toolchains using the normal platforms-related +mechanisms (register_toolchain() in MODULE.bazel or WORKSPACE, or +--extra_toolchains).

All other Bazel Proto flags have also been migrated to Starlark, and the native +flags will be deprecated with the next Bazel release. Use the following Starlark +flags to avoid future breakages:

  • --@protobuf//bazel/flags:strict_proto_deps
  • --@protobuf//bazel/flags:strict_public_imports
  • --@protobuf//bazel/flags:experimental_proto_descriptor_sets_include_source_info
  • --@protobuf//bazel/flags/cc:cc_proto_library_header_suffixes
  • --@protobuf//bazel/flags/cc:cc_proto_library_source_suffixes
  • --@protobuf//bazel/flags:protocopt

NOTE: In v34.0, --@protobuf//bazel/flags:protocopt was incorrectly located +at --@protobuf//bazel/flags/cc:protocopt. The flag will be moved to its +correct location, and the cc location will remain as a deprecated alias +starting in v34.1. This alias should not be used and will be removed in the next +breaking change.

\ No newline at end of file diff --git a/news/index.html b/news/index.html new file mode 100644 index 000000000..f0e09a82e --- /dev/null +++ b/news/index.html @@ -0,0 +1,56 @@ +News | Protocol Buffers Documentation +

News

Get the latest news about Protocol Buffers.

News topics provide information about past events and changes with Protocol +Buffers, and plans for upcoming changes. The information is available both +chronologically and per-release. Note that not everything is included in the +per-release topics, as some content is not tied to a version.

New news topics will also be published to the +protobuf@ mailing list under the subject +[Announcement].

Chronological

The following news topics provide information in the reverse order in which it +was released.

Per Release

The following new topics provide per-release information. All News entries +appear in the chronological listing in the previous section, but only entries +that are specific to a particular version appear in the pages listed in this +section.

These pages do not replace the +release notes, as the +release notes will be more complete. Also, not everything from the chronological +listing will be in these topics, as some content is not specific to a particular +release.

\ No newline at end of file diff --git a/news/index.xml b/news/index.xml new file mode 100644 index 000000000..8d287f8b8 --- /dev/null +++ b/news/index.xml @@ -0,0 +1,59 @@ +News on Protocol Buffers Documentationhttps://protobuf.dev/news/Recent content in News on Protocol Buffers DocumentationHugoenChanges announced April 11, 2023https://protobuf.dev/news/2023-04-11/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-04-11/Syntax Reflection Deprecation v23 will deprecate the ability to check syntax version using reflection. The deprecation will be included as warnings at build time. The capability will be removed in a future release. +Adding support for ctype=CORD in C++ v23 will add ctype=CORD support for singular bytes fields, including oneof fields, to specify that data should be stored using absl::cord instead of string. Support may be added in future releases for singular string field types and for repeated string and byte fields if there is enough interest from the open source community.Changes announced April 20, 2023https://protobuf.dev/news/2023-04-20/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-04-20/Changes to Ruby Generator This GitHub PR, which will appear in the 23.x release, changes the Ruby code generator to emit a serialized proto instead of the DSL. +It removes the DSL from the code generator in anticipation of splitting the DSL out into a separate package. +Given a .proto file like: +syntax = &#34;proto3&#34;; package pkg; message TestMessage { optional int32 i32 = 1; optional TestMessage msg = 2; } Generated code before:Changes announced April 28, 2023https://protobuf.dev/news/2023-04-28/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-04-28/Stricter validation for json_name v24 will forbid zero unicode code points (\u0000) in the json_name field option. Going forward, any valid Unicode characters will be accepted in json_name, except \u0000. \0 characters will still be allowed to be used as values. +Previously, the proto compiler allowed \0 characters in the json_name field option, but support for this was inconsistent across languages and implementations. To help prevent interoperability problems relating to mishandling of keys containing a \0 character, we are clarifying the spec to say that \0 is not allowed in json_name, and will be rejected by the compiler.Changes Announced on August 15, 2023https://protobuf.dev/news/2023-08-15/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-08-15/Python Breaking Change In v25 message.UnknownFields() will be deprecated in pure Python and C++ extensions. It will be removed in v26. Use the new UnknownFieldSet(message) support in unknown_fields.py as a replacement.Changes announced August 3, 2022https://protobuf.dev/news/2022-08-03/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2022-08-03/This topic covers two areas: general platform support changes, and C++-specific changes that are being considered for the 22.x release line. +Platform Support Changes We&rsquo;ve added guidance about the platforms that we support in this section of the documentation. The section currently covers C++ and PHP, but may be expanded with information about other platforms in the future. +Official C++ Support Matrix With the policy, mentioned earlier in this announcement, of using Google&rsquo;s official foundational C++ support policy, our C++ compiler and toolchain support matrix will change.Changes Announced on August 9, 2023https://protobuf.dev/news/2023-08-09/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-08-09/.NET support policy The Protobuf team supports .NET in two ways: +Generation of C# code by protoc The Google.Protobuf NuGet package, which provides runtime support for the generated code, as well as reflection and other facilities The support policy for these has previously been unclear, particularly in terms of which .NET runtimes are supported. From August 2023 onwards, support will be provided in accordance with the Google Open Source support policy for .Changes announced on December 13, 2023https://protobuf.dev/news/2023-12-13/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-12-13/C++ Breaking Changes In v26, we are planning a major version bump for C++ as per our breaking changes policy and version support policy. +The following sections outline the set of breaking changes that we plan to include in the 26.0 release of protocol buffers. Note that plans can and do change. These are potential breaking changes to be aware of, but they may not happen in this particular release, or they may not happen at all.Changes announced December 13, 2024https://protobuf.dev/news/2024-12-13/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-12-13/Removing a Reflection-related Function In v30.x, we are removing the following reflection-related function: MutableRepeatedFieldRef&lt;T&gt;::Reserve(). +An upcoming performance improvement in RepeatedPtrField is incompatible with this API. The improvement is projected to accelerate repeated access to the elements of RepeatedPtrField, in particular and especially sequential access.Changes announced December 18, 2024https://protobuf.dev/news/2024-12-18/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-12-18/Go Protobuf: The new Opaque API Back in March 2020, we released the google.golang.org/protobuf module, a major overhaul of the Go Protobuf API. This package introduced first-class support for reflection, a dynamicpb implementation and the protocmp package for easier testing. +That release introduced a new protobuf module with a new API. Today, we are releasing an additional API for generated code, meaning the Go code in the .pb.go files created by the protocol compiler (protoc).Changes announced on December 27, 2023https://protobuf.dev/news/2023-12-27/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-12-27/Ruby Breaking Changes The following changes are planned for the 26.x line: +Fix RepeatedField#each_index to have the correct semantics. (#11767) Remove Ruby DSL and associated compatibility code, which will complete the migration announced in April. Message#to_h fixes: Remove unset oneof fields. (#6167) Remove unset sub-message fields Use message&rsquo;s pool for encode_json/decode_json. Remove the deprecated syntax accessor, FileDescriptor.syntax and add semantic checks in its place: FieldDescriptor.has_presence to test if a field has presence.Changes announced December 4, 2024https://protobuf.dev/news/2024-12-04/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-12-04/We are planning to modify the Protobuf debug APIs for C++ (including Protobuf AbslStringify, proto2::ShortFormat, proto2::Utf8Format, Message::DebugString, Message::ShortDebugString, Message::Utf8DebugString) in v30 to redact sensitive fields annotated by debug_redact; the outputs of these APIs will contain a per-process randomized prefix, and so will no longer be parseable by Protobuf TextFormat Parsers. +Motivation Currently Protobuf debug APIs print every field in a proto into human-readable formats. This may lead to privacy incidents where developers accidentally log Protobuf debug outputs containing sensitive fields.Changes announced on December 5, 2023https://protobuf.dev/news/2023-12-05/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-12-05/Java Breaking Changes In v26, we are planning a major version bump for Java per our breaking changes policy and version support policy. +The following sections outline the set of breaking changes that we plan to include in the 26.0 release of protocol buffers. Note that plans can and do change. These are potential breaking changes to be aware of, but they may not happen in this particular release, or they may not happen at all.Changes Announced on February 27, 2024https://protobuf.dev/news/2024-02-27/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-02-27/Dropping Ruby 2.7 Support As per our official Ruby support policy, we will be dropping support for Ruby 2.7 and lower on March 31, 2024. The minimum supported Ruby version will be 3.0.Changes announced February 5, 2024https://protobuf.dev/news/2024-02-05/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-02-05/This topic covers breaking changes in Java, C++, and Python in the 26.x line. +JSON Formatter Option Changes Starting in the 26.x line, the JSON formatter option to print default-valued fields is replaced with a fixed way to handle proto2 and proto3 optional fields consistently. +Java: includingDefaultValueFields() is replaced with alwaysPrintFieldsWithNoPresence(). C++: always_print_default_values is replaced with always_print_fields_with_no_presence=True. Py: including_default_value_fields=True is replaced with always_print_fields_with_no_presence=True. The new flag behaves identically to the old flag on proto3 messages, but no longer applies to proto2 optional fields.Changes Announced on January 16, 2026https://protobuf.dev/news/2026-01-16/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2026-01-16/Prebuilt proto compiler (protoc) for Bazel In an effort to speed up builds, protobuf 33.4 offers an option to skip re-compiling Protobuf tools and runtimes and use a pre-built protoc binary, available to Bazel 7 and later. Using a pre-built protoc also avoids build failures from incompatible or non-hermetic C++ compilation toolchain installed on your machine. +To use the prebuilt protoc, upgrade to protobuf version 33.4 or later, and set the --incompatible_enable_proto_toolchain_resolution and --@protobuf//bazel/flags:prefer_prebuilt_protoc flags.Changes announced January 23, 2025https://protobuf.dev/news/2025-01-23/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2025-01-23/Poison Java gencode We are patching a change into the 25.x branch that will poison Java gencode that was created prior to the 3.21.7 release. We will then mark all versions of Java protobuf from 3.21.7 through 3.25.5 as vulnerable to the footmitten CVE. +After this change is patched in, protobuf will throw an UnsupportedOperationException from the makeExtensionsImmutable method unless you set the system property &ldquo;-Dcom.google.protobuf.use_unsafe_pre22_gencode&rdquo;. Using this system property can buy you some time if you can&rsquo;t update your code immediately, but should be considered a short-term workaround.Changes announced January 31, 2024https://protobuf.dev/news/2024-01-31/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-01-31/This topic covers breaking changes in Python in the 26.x line. +Python Breaking Changes Removing setup.py and setup.cfg support from GitHub In the 26.x release, setup.py and setup.cfg will no longer be present in the python/ directory of the GitHub repository or GitHub release tarballs. This means it will no longer be possible to build a Python package directly from the GitHub repo or release tarball. +The Python source packages published on PyPI will continue to have a setup.Changes announced January 5, 2024https://protobuf.dev/news/2024-01-05/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-01-05/This topic covers breaking changes in Ruby and Python in the 26.x line. +Ruby Breaking Changes Freeze Is Now Recursive in Ruby Starting in the 26.x line, when freeze is applied it will be applied recursively, affecting all sub-messages, maps, and repeated fields. +Python Breaking Changes Removing Deprecated APIs In the 26.x release, the following deprecated APIs will be removed: +AddFileDescriptor AddDescriptor AddEnumDescriptor AddExtensionDescriptor AddServiceDescriptor Rejecting Extend Repeated Field with None Iterable Starting in the 26.Changes Announced on July 14, 2025https://protobuf.dev/news/2025-07-14/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2025-07-14/Deprecating FieldDescriptor Enums We are announcing an upcoming change regarding the FieldDescriptor enum and its associated values representing optional, required, and repeated. These are being deprecated as we encourage the use of more precise accessor methods. +Background While at one time the FieldDescriptor.label enum served a purpose, the evolution of Protocol Buffers has introduced more idiomatic ways to determine a field&rsquo;s cardinality (singular/repeated) and presence semantics. +In proto2, optional, required, and repeated are explicit keywords.Changes Announced on July 16, 2025https://protobuf.dev/news/2025-07-16/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2025-07-16/Retaining support for Bazel with MSVC We announced on January 23, 2025 that we were planning to drop support for using Bazel and MSVC together starting in v34. This plan is canceled due to Bazel&rsquo;s upcoming changes to virtual includes on Windows. Clang-cl support will be kept in place as an alternative on Windows. The opt-out flag --define=protobuf_allow_msvc=true will no longer be required as of the 32.0 release.Changes Announced on July 17, 2023https://protobuf.dev/news/2023-07-17/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-07-17/Dropping Bazel 5.x Support As per our official support policy, we will be dropping support for Bazel 5.x and lower. This means the minimum supported Bazel version is 6.2.x.Changes announced July 6, 2022https://protobuf.dev/news/2022-07-06/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2022-07-06/Library Breaking Change Policy Google released its OSS Library Breaking Change Policy, which some Google-sponsored open source projects have opted into. Protocol buffers has adopted this policy.Changes Announced on July 6, 2023https://protobuf.dev/news/2023-07-06/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-07-06/Dropping PHP 7.x Support As per our official PHP support policy, we will be dropping support for PHP 7.4 and lower. This means the minimum supported PHP version is 8.0. +If you are running an older version of PHP, you can install a previous release of the protobuf PHP extension by running pecl install protobuf-3.23.3. +Dropping Ruby 2.6 Support As per our official Ruby support policy, we will be dropping support for Ruby 2.Changes Announced on June 26, 2024https://protobuf.dev/news/2024-06-26/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-06-26/Dropping Support for Building Protobuf Java from Source with Maven We are planning to drop support for building Protobuf Java OSS from source with the Maven build system in the Protobuf Java 4.28 release. This has been marked deprecated in the 4.27 release. +After this point, you can continue to use Bazel, or another build system, to build Protobuf. You can read more about building from source in the Protobuf Java README.Changes Announced on June 27, 2025https://protobuf.dev/news/2025-06-27/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2025-06-27/Edition 2024 We are planning to release Protobuf Edition 2024 in 32.x in Q3 2025. +These describe changes as we anticipate them being implemented, but due to the flexible nature of software some of these changes may not land or may vary from how they are described in this topic. +More documentation on Edition 2024 will be published in Feature Settings for Editions, including information on migrating from Edition 2023.Changes Announced on June 29, 2023https://protobuf.dev/news/2023-06-29/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-06-29/TL;DR: We are planning to release Protobuf Editions to the open source project in the second half of 2023. While there is no requirement to move from proto2/proto3 syntax to Editions syntax at initial release, we encourage you to plan a move in your software project&rsquo;s future timeline. +Protobuf Editions Protobuf Editions replace the proto2 and proto3 designations that we have used for Protocol Buffers. Instead of adding syntax = &quot;proto2&quot; or syntax = &quot;proto3&quot; at the top of proto definition files, you use an edition number, such as edition = &quot;2024&quot;, to specify the default behaviors your file will have.Changes Announced on March 13, 2026https://protobuf.dev/news/2026-03-13/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2026-03-13/Changes in Bazel Migration of Proto Flags to Starlark --proto_toolchain_for* and --proto_compiler are no longer read by Proto rules. These toolchain-related flags are deprecated and will be removed in the future. Switching to the equivalent Starlark versions of the flags is a short-term fix: +--@protobuf//bazel/flags/cc:proto_toolchain_for_cc --@protobuf//bazel/flags/java:proto_toolchain_for_java --@protobuf//bazel/flags/java:proto_toolchain_for_javalite --@protobuf//bazel/flags:proto_compiler The longer-term fix is to enable --incompatible_enable_proto_toolchain_resolution (which is the default in Bazel 9 anyway) and to register toolchains using the normal platforms-related mechanisms (register_toolchain() in MODULE.Changes Announced on March 18, 2025https://protobuf.dev/news/2025-03-18/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2025-03-18/Dropping Ruby 3.0 Support As per our official Ruby support policy, we will be dropping support for Ruby 3.0 and lower in Protobuf version 31, due to release in April, 2025. The minimum supported Ruby version will be 3.1.Changes announced May 6, 2022https://protobuf.dev/news/2022-05-06/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2022-05-06/Versioning We changed our versioning scheme to enable more-nimble updates to language-specific parts of Protocol Buffers. In the new scheme, each language has its own major version that can be incremented independently of other languages, as covered later in this topic with the Python release. The minor and patch versions, however, will remain coupled. This allows us to introduce breaking changes into some languages without requiring a bump of the major version in languages that do not experience a breaking change.Changes Announced on November 7, 2024https://protobuf.dev/news/2024-11-07/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-11-07/The following sections cover planned breaking changes in the v30 release, expected in 2025 Q1. Also included are some changes that aren&rsquo;t breaking but may require action on your part. These are in addition to those mentioned in the News article from October 2. +These describe changes as we anticipate them being implemented, but due to the flexible nature of software some of these changes may not land or may vary from how they are described in this topic.Changes Announced on October 1, 2024https://protobuf.dev/news/2024-10-01/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-10-01/Bazel and Proto Rules There are upcoming changes to the way that Bazel will work for protobuf builds. These changes require awareness in the first stage, and action by project owners before the second stage. +Stage 1 With the release of Bazel 8, proto rules (proto_library, cc_proto_library, java_proto_library, java_lite_proto_library, and py_proto_library) will be removed from the Bazel project. The will be added to the Protocol Buffers project in v29. Bazel will be updated to automatically use the rules from the protobuf project, so the change is initially a no-op for project owners.Changes announced on October 10, 2023https://protobuf.dev/news/2023-10-10/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-10-10/Protobuf Editions Features Documentation that introduces Protobuf Editions features is now available.Changes Announced on October 2, 2024https://protobuf.dev/news/2024-10-02/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2024-10-02/The following sections cover planned breaking changes in the v30 release, expected in 2025 Q1. These describe changes as we anticipate them being implemented, but due to the flexible nature of software some of these changes may not land or may vary from how they are described in this topic. +Changes in C++ C++ will bump its major version from 5.29.x to 6.30.x. +Descriptor APIs v30 will update return types in descriptor (such as full_name) to be absl::string_view.Changes announced on September 15, 2023https://protobuf.dev/news/2023-09-15/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2023-09-15/μpb Moving to the Protobuf Git Repository Starting with the v25 release, μpb now lives in the protobuf repo instead of in its former location in a separate repo. All μpb development going forward will take place only in the new location. +The merger of the two repos will simplify and speed up our development process by removing the need to update pinned version dependencies between protobuf and μpb. Changes to μpb now take effect immediately in protobuf code and vice versa, without the need for a manual upgrade step.Changes Announced on September 19, 2025https://protobuf.dev/news/2025-09-19/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/2025-09-19/The following sections cover planned breaking changes in the v34 release, expected in 2026 Q1. These describe changes as we anticipate them being implemented, but due to the flexible nature of software some of these changes may not land or may vary from how they are described in this topic. +Changes in C++ C++ will bump its major version to 7 with the 7.34.0 release. 6.33 will be the final minor version release on 6.News Announcements for Version 21.xhttps://protobuf.dev/news/v21/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v21/The following announcements are specific to Version 21.x, which was released May 25, 2022. For information presented chronologically, see News. +Python Updates We made some changes in Python language support in Protocol Buffers. Version 4.21.0 is a new major version, following 3.20.1. The new version is based on the upb library, and offers significantly better parsing performance than previous releases, especially for large payloads. It also includes prebuilt binary modules for Apple silicon for increased performance without a manual build.News Announcements for Version 22.xhttps://protobuf.dev/news/v22/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v22/The following announcements are specific to Version 22.x, which was released February 16, 2023. For information presented chronologically, see News. +Changing Maven Release Candidate Artifact Names to Be More Idiomatic In 22.0 we plan to rename Maven artifacts to use “RC” instead of “rc-” as the release candidate prefix. +Adding an Abseil Dependency In order to reduce the Google vs. OSS differences between protobuf and to simplify our own project, we plan to take a formal dependency on Abseil.News Announcements for Version 23.xhttps://protobuf.dev/news/v23/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v23/The following announcements are specific to Version 23.x, which was released May 8, 2023. For information presented chronologically, see News. +Changes to Ruby Generator This GitHub PR, which will appear in the 23.x release, changes the Ruby code generator to emit a serialized proto instead of the DSL. +It removes the DSL from the code generator in anticipation of splitting the DSL out into a separate package. +Given a .proto file like:News Announcements for Version 24.xhttps://protobuf.dev/news/v24/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v24/The following announcements are specific to Version 24.x, which was released August 8, 2023. For information presented chronologically, see News. +Stricter validation for json_name v24 will forbid embedded null characters in the json_name field option. Going forward, any valid Unicode characters will be accepted, except \u0000. Null will still be allowed in field values. +Previously, the proto compiler allowed null characters, but support for this was inconsistent across languages and implementations.News Announcements for Version 25.xhttps://protobuf.dev/news/v25/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v25/The following announcements are specific to Version 25.x, which was released November 1, 2023. For information presented chronologically, see News. +Python Breaking Change In v25 message.UnknownFields() will be deprecated in pure Python and C++ extensions. It will be removed in v26. Use the new UnknownFieldSet(message) support in unknown_fields.py as a replacement. +μpb Moving to the Protobuf Git Repository Starting with the v25 release, μpb now lives in the protobuf repo instead of in its former location in a separate repo.News Announcements for Version 26.xhttps://protobuf.dev/news/v26/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v26/The following announcements are specific to Version 26.x, which was released March 13, 2024. For information presented chronologically, see News. +General Changes JSON Formatter Option Changes Starting in the 26.x line, the JSON formatter option to print default-valued fields is replaced with a fixed way to handle proto2 and proto3 optional fields consistently. +Java: includingDefaultValueFields() is replaced with alwaysPrintFieldsWithNoPresence(). C++: always_print_default_values is replaced with always_print_fields_with_no_presence=True. Py: including_default_value_fields=True is replaced with always_print_fields_with_no_presence=True.News Announcements for Version 29.xhttps://protobuf.dev/news/v29/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v29/The following announcements are specific to Version 29.x, which was released November 27, 2024. For information presented chronologically, see News. +Bazel and Proto Rules There are upcoming changes to the way that Bazel will work for protobuf builds. These changes require awareness in the first stage, and action by project owners before the second stage. +Stage 1 With the release of Bazel 8, proto rules (proto_library, cc_proto_library, java_proto_library, java_lite_proto_library, and py_proto_library) will be removed from the Bazel project.News Announcements for Version 30.xhttps://protobuf.dev/news/v30/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v30/The following announcements are specific to Version 30.x, which was released March 4, 2025. For information presented chronologically, see News. +The following sections cover planned breaking changes in the v30 release, expected in 2025 Q1. Also included are some changes that aren&rsquo;t breaking but may require action on your part. These describe changes as we anticipate them being implemented, but due to the flexible nature of software some of these changes may not land or may vary from how they are described in this topic.News Announcements for Version 31.xhttps://protobuf.dev/news/v31/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v31/The following announcements are specific to Version 31.x, which was released May 14, 2025. For information presented chronologically, see News. +The following sections cover planned breaking changes in the v31 release, expected in 2025 Q2. Also included are some changes that aren&rsquo;t breaking but may require action on your part. These describe changes as we anticipate them being implemented, but due to the flexible nature of software some of these changes may not land or may vary from how they are described in this topic.News Announcements for Version 32.xhttps://protobuf.dev/news/v32/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v32/Changes to Existing Features This section details any existing features whose default settings will change in Edition 2024. +C++ string_type The default for string_type feature, originally released in Edition 2023, will change from STRING to VIEW in Edition 2024. +See features.(pb.cpp).string_type and String View APIs for more information on this feature and its feature values. +New Features This section details any new features that will be introduced in Edition 2024.News Announcements for Version 34.xhttps://protobuf.dev/news/v34/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/news/v34/The following news topics provide information about changes in the 34.x release. +March 13, 2026 - Breaking changes in Bazel for the upcoming 34.x release January 16, 2026 - Prebuilt proto compiler (protoc) for Bazel September 19, 2025 - Breaking changes in the upcoming 34.x release July 16, 2025 - Resuming support for Bazel with MSVC \ No newline at end of file diff --git a/news/v21/index.html b/news/v21/index.html new file mode 100644 index 000000000..d28b527aa --- /dev/null +++ b/news/v21/index.html @@ -0,0 +1,26 @@ +News Announcements for Version 21.x | Protocol Buffers Documentation +

News Announcements for Version 21.x

Changes announced for Protocol Buffers version 21.x.

The following announcements are specific to Version 21.x, which was released May +25, 2022. For information presented chronologically, see +News.

Python Updates

We made some changes in Python language support in Protocol Buffers. Version +4.21.0 is a new major version, following 3.20.1. The new version is based on the +upb library, and offers +significantly better parsing performance than previous releases, especially for +large payloads. It also includes prebuilt binary modules for Apple silicon for +increased performance without a manual build.

The new release does contain some breaking changes. Specifically:

  • The +UnknownFields() +method, which relied on an implicitly created class, is replaced with the +explicitly-created UnknownFieldSet class.
  • Some non-core characteristics may have changed, such as the specific format +of certain strings or error messages. These are not considered breaking +changes, but may still impact your existing code base.
  • Applications that rely on sharing messages between Python and C++ break in +the new version. Most developers won’t be affected by this, but users of +Nucleus and possibly other +libraries may be. As a workaround, you can +set an environment variable +that forces the library to preserve compatibility.
  • Python upb requires generated code that has been generated from protoc +3.19.0 or newer.
\ No newline at end of file diff --git a/news/v22/index.html b/news/v22/index.html new file mode 100644 index 000000000..94347d234 --- /dev/null +++ b/news/v22/index.html @@ -0,0 +1,30 @@ +News Announcements for Version 22.x | Protocol Buffers Documentation +

News Announcements for Version 22.x

Changes announced for Protocol Buffers version 22.x.

The following announcements are specific to Version 22.x, which was released +February 16, 2023. For information presented chronologically, see +News.

Changing Maven Release Candidate Artifact Names to Be More Idiomatic

In 22.0 we plan to rename Maven artifacts to use “RC” instead of “rc-” as the +release candidate prefix.

Adding an Abseil Dependency

In order to reduce the Google vs. OSS differences between protobuf and to +simplify our own project, we plan to take a formal dependency on Abseil. In +time, we plan to start using Abseil types in our public APIs, but simply adding +the dependency is a breaking change.

Dropping Support for PHP <7.4

Per our +PHP support policy, +we plan to drop support for EOL versions of PHP. This is not considered a +breaking change since these versions are already EOL in the broader ecosystem.

Dropping Autotools Support

Per our +build systems support policy, +we plan to drop autotools support. This is a breaking change. After autotools +support is dropped, protobuf will support only CMake and Bazel.

Dropping C++11 Support

Per our +C++ support policy, +we plan to drop C++11 support. This is a breaking change.

Adding C++20 Support

Because of the addition of new keywords to the C++ language, adding support for +C++20 is a breaking change for users even if they do not currently use C++20.

Mitigations for this to conditionally change names only in certain compiler +modes would break projects that support multiple language standards.

C++ Changes

Following the announcement of our +new major version and breaking changes policy, +we are planning a major version bump for C++. We plan to make some changes to +the assets that we release starting with our 22.x release line.

The following sections outline the set of breaking changes that we plan to +include in the 22.0 release of protocol buffers. Note that plans can and do +change. These are potential breaking changes to be aware of, but they may not +happen in this particular release, or they may not happen at all.

\ No newline at end of file diff --git a/news/v23/index.html b/news/v23/index.html new file mode 100644 index 000000000..0b76b1946 --- /dev/null +++ b/news/v23/index.html @@ -0,0 +1,109 @@ +News Announcements for Version 23.x | Protocol Buffers Documentation +

News Announcements for Version 23.x

Changes announced for Protocol Buffers version 23.x.

The following announcements are specific to Version 23.x, which was released May +8, 2023. For information presented chronologically, see +News.

Changes to Ruby Generator

This GitHub PR, which +will appear in the 23.x release, changes the Ruby code generator to emit a +serialized proto instead of the DSL.

It removes the DSL from the code generator in anticipation of splitting the DSL +out into a separate package.

Given a .proto file like:

syntax = "proto3";
+
+package pkg;
+
+message TestMessage {
+  optional int32 i32 = 1;
+  optional TestMessage msg = 2;
+}
+

Generated code before:

# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: protoc_explorer/main.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+  add_file("test.proto", :syntax => :proto3) do
+    add_message "pkg.TestMessage" do
+      proto3_optional :i32, :int32, 1
+      proto3_optional :msg, :message, 2, "pkg.TestMessage"
+    end
+  end
+end
+
+module Pkg
+  TestMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("pkg.TestMessage").msgclass
+end
+

Generated code after:

# frozen_string_literal: true
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: test.proto
+
+require 'google/protobuf'
+
+descriptor_data = "\n\ntest.proto\x12\x03pkg\"S\n\x0bTestMessage\x12\x10\n\x03i32\x18\x01 \x01(\x05H\x00\x88\x01\x01\x12\"\n\x03msg\x18\x02 \x01(\x0b\x32\x10.pkg.TestMessageH\x01\x88\x01\x01\x42\x06\n\x04_i32B\x06\n\x04_msgb\x06proto3"
+begin
+  Google::Protobuf::DescriptorPool.generated_pool.add_serialized_file(descriptor_data)
+rescue TypeError => e
+  # <compatibility code, see below>
+end
+
+module Pkg
+  TestMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("pkg.TestMessage").msgclass
+end
+

This change fixes nearly all remaining conformance problems that existed +previously. This is a side effect of moving from the DSL (which is lossy) to a +serialized descriptor (which preserves all information).

Backward Compatibility

This change should be 100% compatible with Ruby Protobuf >= 3.18.0, released in +Sept 2021. Additionally, it should be compatible with all existing users and +deployments.

There is some special compatibility code inserted to achieve this level of +backward compatibility that you should be aware of. Without the compatibility +code, there is an edge case that could break backward compatibility. The +previous code is lax in a way that the new code will be more strict.

When using a full serialized descriptor, it contains a list of all .proto +files imported by this file (whereas the DSL never added dependencies properly). +See the code in +descriptor.proto.

add_serialized_file verifies that all dependencies listed in the descriptor +were previously added with add_serialized_file. Generally that should be fine, +because the generated code will contain Ruby require statements for all +dependencies, and the descriptor will fail to load anyway if the types depended +on were not previously defined in the DescriptorPool.

But there is a potential for problems if there are ambiguities around file +paths. For example, consider the following scenario:

// foo/bar.proto
+
+syntax = "proto2";
+
+message Bar {}
+
// foo/baz.proto
+
+syntax = "proto2";
+
+import "bar.proto";
+
+message Baz {
+  optional Bar bar = 1;
+}
+

If you invoke protoc like so, it will work correctly:

$ protoc --ruby_out=. -Ifoo foo/bar.proto foo/baz.proto
+$ RUBYLIB=. ruby baz_pb.rb
+

However if you invoke protoc like so, and didn’t have any compatibility code, +it would fail to load:

$ protoc --ruby_out=. -I. -Ifoo foo/baz.proto
+$ protoc --ruby_out=. -I. -Ifoo foo/bar.proto
+$ RUBYLIB=foo ruby foo/baz_pb.rb
+foo/baz_pb.rb:10:in `add_serialized_file': Unable to build file to DescriptorPool: Depends on file 'bar.proto', but it has not been loaded (Google::Protobuf::TypeError)
+    from foo/baz_pb.rb:10:in `<main>'
+

The problem is that bar.proto is being referred to by two different canonical +names: bar.proto and foo/bar.proto. This is a user error: each import should +always be referred to by a consistent full path. Hopefully user errors of this +sort will be rare, but it is hard to know without trying.

The code in this change prints a warning using warn if we detect that this +edge case has occurred:

$ RUBYLIB=foo ruby foo/baz_pb.rb
+Warning: Protobuf detected an import path issue while loading generated file foo/baz_pb.rb
+- foo/baz.proto imports bar.proto, but that import was loaded as foo/bar.proto
+Each proto file must use a consistent fully-qualified name.
+This will become an error in the next major version.
+

There are two possible fixes in this case. One is to consistently use the name +bar.proto for the import (removing -I.). The other is to consistently use +the name foo/bar.proto for the import (changing the import line to import "foo/bar.proto" and removing -Ifoo).

We plan to remove this compatibility code in the next major version.

Dropping Support for Bazel <5.3

v23 will drop support for Bazel 4. Protobuf will continue to support the Bazel 5 +LTS with Bazel 5.3 as the minimum required version. This is per the build +support policy described in +Foundational C++ Support Policy +and as reflected in the versions in +Foundational C++ Support.

Syntax Reflection Deprecation

v23 will deprecate the ability to check syntax version using reflection. The +deprecation will be included as warnings at build time. The capability will be +removed in a future release.

\ No newline at end of file diff --git a/news/v24/index.html b/news/v24/index.html new file mode 100644 index 000000000..80aba0b64 --- /dev/null +++ b/news/v24/index.html @@ -0,0 +1,16 @@ +News Announcements for Version 24.x | Protocol Buffers Documentation +

News Announcements for Version 24.x

Changes announced for Protocol Buffers version 24.x.

The following announcements are specific to Version 24.x, which was released +August 8, 2023. For information presented chronologically, see +News.

Stricter validation for json_name

v24 will forbid embedded null characters in the +json_name field option. +Going forward, any valid Unicode characters will be accepted, except +\u0000. Null will still be allowed in field values.

Previously, the proto compiler allowed null characters, but support for this was +inconsistent across languages and implementations. To fix this, we are +clarifying the spec to say that null is not allowed in json_name, and will be +rejected by the compiler.

\ No newline at end of file diff --git a/news/v25/index.html b/news/v25/index.html new file mode 100644 index 000000000..82054b257 --- /dev/null +++ b/news/v25/index.html @@ -0,0 +1,41 @@ +News Announcements for Version 25.x | Protocol Buffers Documentation +

News Announcements for Version 25.x

Changes announced for Protocol Buffers version 25.x.

The following announcements are specific to Version 25.x, which was released +November 1, 2023. For information presented chronologically, see +News.

Python Breaking Change

In v25 +message.UnknownFields() +will be deprecated in pure Python and C++ extensions. It will be removed in v26. +Use the new +UnknownFieldSet(message) +support in unknown_fields.py as a replacement.

μpb Moving to the Protobuf Git Repository

Starting with the v25 release, μpb now lives in the +protobuf repo instead +of in its former location +in a separate repo. All μpb development going forward will take place only in +the new location.

The merger of the two repos will simplify and speed up our development process +by removing the need to update pinned version dependencies between protobuf and +μpb. Changes to μpb now take effect immediately in protobuf code and vice versa, +without the need for a manual upgrade step.

We expect that most users will not need to take much, if any, action to +accommodate the change. μpb is the engine behind our Ruby, PHP, and Python +implementations, but you will most likely not notice the change unless you have +code that refers to μpb directly.

If you refer to μpb from a Bazel project, you will need to update μpb references +to point to protobuf instead (for example, replace @upb with +@com_google_protobuf). We are keeping μpb file paths and Bazel targets the +same to minimize the need for additional changes, but there are two exceptions:

  • The upbc directory has been renamed upb_generator.
  • The top-level BUILD file for μpb has moved into the upb directory. So, +for example, references to @upb//:reflection should now be written +@com_google_protobuf//upb:reflection.

Poison Java gencode

We are patching a change into the 25.x branch that will poison Java gencode that +was created prior to the +3.21.7 release. +We will then mark all versions of Java protobuf from 3.21.7 through 3.25.5 as +vulnerable to the +footmitten CVE.

After this change is patched in, protobuf will throw an +UnsupportedOperationException from the +makeExtensionsImmutable +method unless you set the system property +“-Dcom.google.protobuf.use_unsafe_pre22_gencode”. Using this system property +can buy you some time if you can’t update your code immediately, but should be +considered a short-term workaround.

\ No newline at end of file diff --git a/news/v26/index.html b/news/v26/index.html new file mode 100644 index 000000000..a9b3be29a --- /dev/null +++ b/news/v26/index.html @@ -0,0 +1,95 @@ +News Announcements for Version 26.x | Protocol Buffers Documentation +

News Announcements for Version 26.x

Changes announced for Protocol Buffers version 26.x.

The following announcements are specific to Version 26.x, which was released +March 13, 2024. For information presented chronologically, see +News.

General Changes

JSON Formatter Option Changes

Starting in the 26.x line, the JSON formatter option to print default-valued +fields is replaced with a fixed way to handle proto2 and proto3 optional +fields consistently.

  • Java: includingDefaultValueFields() is replaced with +alwaysPrintFieldsWithNoPresence().
  • C++: always_print_default_values is replaced with +always_print_fields_with_no_presence=True.
  • Py: including_default_value_fields=True is replaced with +always_print_fields_with_no_presence=True.

The new flag behaves identically to the old flag on proto3 messages, but no +longer applies to proto2 optional fields. The old flags applied to proto2 +optional fields but not proto3 optional fields.

Poison Pilling Gencode / Runtime Mismatches

Per our +Cross-Version Runtime Guarantees, +Protobuf does not support mixing generated code and runtimes across major +version boundaries, or mixing generated code from a newer version of protoc with +older runtimes within a single major runtime version. We plan to introduce +“poison pills” to detect and enforce these disallowed mismatches.

This is not considered a breaking change since this simply adds enforcement of +existing policies, but may require users to update their generated code.

C++ Breaking Changes

In v26, we are planning a major version bump for C++ as per our +breaking changes policy and +version support policy.

The following sections outline the set of breaking changes that we plan to +include in the 26.0 release of protocol buffers. Note that plans can and do +change. These are potential breaking changes to be aware of, but they may not +happen in this particular release, or they may not happen at all.

Remove deprecated clear APIs on repeated fields

The following deprecated methods are removed:

  • RepeatedPtrField::ReleaseCleared()
  • RepeatedPtrField::ClearedCount()
  • RepeatedPtrField::AddCleared()

Remove C++ legacy syntax descriptor APIs

With the release of editions, syntax is no +longer supported for business logic. Instead, use the various feature helpers +defined in +descriptor.h +to query more targeted behaviors, such as +has_presence, +to query features in C++.

Remove deprecated syntax accessor

We plan to remove the deprecated syntax accessor, FileDescriptor::Syntax, in +v26. We recommend using the getters from FileDescriptor::edition instead.

Remove deprecated SupportsUnknownEnumValues method

The SupportsUnknownEnumValues method was +deprecated in March, 2023. +We plan to remove it in v26.

Remove std::string error collector overrides

We are planning to remove the deprecated std::string methods in error +collectors.

Java Breaking Changes

In v26, we are planning a major version bump for Java per our +breaking changes policy and +version support policy.

The following sections outline the set of breaking changes that we plan to +include in the 26.0 release of protocol buffers. Note that plans can and do +change. These are potential breaking changes to be aware of, but they may not +happen in this particular release, or they may not happen at all.

Breaking Compatibility with Old Generated Code

v26.x will break compatibility with generated code from older major versions. +Users should regenerate old generated code to be from the same version.

For example, GeneratedMessageV3, which was originally introduced for backwards +compatibility with generated code from v2.x.x against v3.x.x runtime, will be +renamed to GeneratedMessage. Runtimes will be updated to support +Editions, which will not be +compatible with old generated code.

This is in accordance with our existing +Cross-Version Runtime Guarantees +and is a breaking change.

Removing Deprecated Methods/Variables

v26.x will remove access to deprecated methods and variables. These will +generally have already been marked @Deprecated in a previous release.

This will remove access to the following non-exhaustive list:

  • Descriptor syntax APIs, which should be replaced with corresponding feature +accessors (such as FieldDescriptor.hasPresence(), +EnumDescriptor.isClosed())

  • TextFormat print methods, which should be replaced by corresponding +TextFormat.printer() methods.

  • PARSER variable, which should be replaced by the parser() method.

  • Runtime methods for old v2.x.x gencode compatibility. This is no longer +supported, as per our +Cross Version Runtime Guarantees.

More details will be available in the corresponding release notes.

PHP Breaking Changes

The following changes are planned for the 26.x line:

  • Validate UTF-8 for string fields in setters.
  • Remove generic services. +(commit 40ad3fa)

Python Breaking Changes

In v26, we are planning a major version bump for Python as per our +breaking changes policy and +version support policy.

The following changes are planned for the 26.x line:

  • Make str(msg) escape any invalid UTF-8 in string fields.
  • Make text_format.MessageToString() default to outputting raw UTF-8, while +escaping any invalid UTF-8 sequences.
  • Fix timestamp bounds (commit 1250d5f)

Removing Deprecated APIs

In the 26.x release, the following deprecated APIs will be removed:

Rejecting Extend Repeated Field with None Iterable

Starting in the 26.x release, extending repeated fields with a None iterable +will be rejected (it will raise a TypeError). For example, +m.repeated_int32.extend(None) will be rejected.

Removing RegisterExtension in message class

Starting in the 26.x release, +RegisterExtension +will be removed. You can access extensions in Python using the Extensions +property on message objects.

This affects both pure Python and the C++ implementation of Python, but not upb +Python.

Removing setup.py and setup.cfg support from GitHub

In the 26.x release, setup.py and setup.cfg will no longer be present in the +python/ directory of +the GitHub repository +or GitHub +release tarballs. This +means it will no longer be possible to build a Python package directly from the +GitHub repo or release tarball.

The Python source packages published +on PyPI will continue to have a +setup.py in the top-level directory. This is the supported and recommended way +of building Python binary packages, for users who do not want to use the binary +packages that we distribute on PyPI.

For more information, see +#15671.

Timestamps are checked for validity

In v26, the system will check if Timestamp values are valid. Seconds must be +in the range [-62135596800, 253402300799] and nanos must be in range [0, +999999999]. Values outside those ranges will raise an exception.

Remove deprecated syntax accessor

We plan to remove the deprecated syntax accessor, FileDescriptor.syntax, in +v26. We plan to add FileDescriptor.edition in its place.

UnknownFields support removal

In v25 +message.UnknownFields() +was deprecated in pure Python and C++ extensions. We plan to remove it v26. Use +the new +UnknownFieldSet(message) +support in unknown_fields.py as a replacement.

More details about all of these changes will be available in the corresponding +release notes.

Ruby Breaking Changes

  • Fix RepeatedField#each_index to have the correct semantics. +(#11767)
  • Remove Ruby DSL and associated compatibility code, which will complete the +migration announced in April.
  • Message#to_h fixes:
    • Remove unset oneof fields. +(#6167)
    • Remove unset sub-message fields
  • Use message’s pool for +encode_json/decode_json.
  • Remove the deprecated syntax accessor, FileDescriptor.syntax and add +semantic checks in its place:
    • FieldDescriptor.has_presence to test if a field has presence.
    • FieldDescriptor.is_packed to test if a repeated field is packed.
    • FieldDescriptor.requires_utf8_validation to test if a string field +requires UTF-8 validation.
    • EnumDescriptor.is_closed to test if an enum is closed.

Freeze Is Now Recursive in Ruby

Starting in the 26.x line, when freeze is applied it will be applied +recursively, affecting all sub-messages, maps, and repeated fields.

upb Breaking Changes

The following changes are planned for the 26.x line:

\ No newline at end of file diff --git a/news/v29/index.html b/news/v29/index.html new file mode 100644 index 000000000..9789c52bc --- /dev/null +++ b/news/v29/index.html @@ -0,0 +1,29 @@ +News Announcements for Version 29.x | Protocol Buffers Documentation +

News Announcements for Version 29.x

Changes announced for Protocol Buffers version 29.x.

The following announcements are specific to Version 29.x, which was released +November 27, 2024. For information presented chronologically, see +News.

Bazel and Proto Rules

There are upcoming changes to the way that Bazel will work for protobuf builds. +These changes require awareness in the first stage, and action by project owners +before the second stage.

Stage 1

With the release of Bazel 8, proto rules (proto_library, cc_proto_library, +java_proto_library, java_lite_proto_library, and py_proto_library) will be +removed from the Bazel project. The will be added to the Protocol Buffers +project in v29. Bazel will be updated to automatically use the rules from the +protobuf project, so the change is initially a no-op for project owners.

After the release of Bazel 8 and before the release of Bazel 9, users will need +to explicitly load the rules from the Protocol Buffers project repository. The +automatic use of the rules is only temporary to support the migration.

Users should add the following load() statements to any BUILD or .bzl +files that use these proto rules. Note that these require Protobuf v29.0 or +higher.

load("@protobuf//bazel:proto_library.bzl", "proto_library")
+
+load("@protobuf//bazel:cc_proto_library.bzl", "cc_proto_library")
+load("@protobuf//bazel:java_proto_library.bzl", "java_proto_library")
+load("@protobuf//bazel:java_lite_proto_library.bzl", "java_lite_proto_library")
+load("@protobuf//bazel:py_proto_library.bzl", "py_proto_library")
+

Stage 2

When Bazel 9 is released, the automatic loading of the protobuf library’s rules +will be removed. At that point, you will need to have load statements in your +Bazel build files.

End Goal

Once the rules are in the protobuf repo, we intend to address common user +requests, such as using prebuilts for the proto compiler where possible.

\ No newline at end of file diff --git a/news/v30/index.html b/news/v30/index.html new file mode 100644 index 000000000..5d6efacc2 --- /dev/null +++ b/news/v30/index.html @@ -0,0 +1,137 @@ +News Announcements for Version 30.x | Protocol Buffers Documentation +

News Announcements for Version 30.x

Changes announced for Protocol Buffers version 30.x.

The following announcements are specific to Version 30.x, which was released +March 4, 2025. For information presented chronologically, see +News.

The following sections cover planned breaking changes in the v30 release, +expected in 2025 Q1. Also included are some changes that aren’t breaking but may +require action on your part. These describe changes as we anticipate them being +implemented, but due to the flexible nature of software some of these changes +may not land or may vary from how they are described in this topic.

Changes in C++

C++ will bump its major version from 5.29.x to 6.30.x.

Descriptor APIs

v30 will update return types in descriptor (such as full_name) to be +absl::string_view. This opens up memory savings in descriptors.

v28 introduced the PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE macro, which you +can use in the meantime to enable the updated return type ahead of the breaking +release. The v30 release will flip the default and remove the macro.

ctype Removed from FieldDescriptor Options

v30 will stop exposing the ctype from FieldDescriptor options. You can use +the FieldDescriptor::cpp_string_type() API, added in the +v28 release, +in its place.

Replace CMake Submodules with Fetched Deps

v30 will remove submodules and switches to upb’s old CMake pattern of fetching +dependencies.

If you use installed packages, you won’t be affected. It could break some CMake +workflows.

Modify Debug APIs to Redact Sensitive Fields

We are planning to modify the Protobuf debug APIs (including Protobuf +AbslStringify, proto2::ShortFormat, proto2::Utf8Format, +Message::DebugString, Message::ShortDebugString, Message::Utf8DebugString) +in v30 to redact sensitive fields annotated by debug_redact; the outputs of +these APIs will contain a per-process randomized prefix, and so will no longer +be parseable by Protobuf TextFormat Parsers.

Read more about this in the +news article released November 21, 2024.

Removing a Reflection-related Function

We are removing the following reflection-related function: +MutableRepeatedFieldRef<T>::Reserve().

An upcoming performance improvement in +RepeatedPtrField +is incompatible with this API. The improvement is projected to accelerate +repeated access to the elements of RepeatedPtrField, in particular and +especially sequential access.

Remove Deprecated APIs

v30 will remove the following public runtime APIs, which have been marked +deprecated (such as ABSL_DEPRECATED) for at least one minor or major release +and that are obsolete or replaced.

Arena::CreateMessage

API: +Arena::CreateMessage

Replacement: +Arena::Create

Arena::GetArena

API: +Arena::GetArena

Replacement: value->GetArena()

RepeatedPtrField::ClearedCount

API: +RepeatedPtrField::ClearedCount

Replacement: Migrate to Arenas +(migration guide).

JsonOptions

API: +JsonOptions

Replacement: JsonPrintOptions

Dropping C++14 Support

This release will drop C++ 14 as the minimum supported version and raise it to +17, as per the +Foundational C++ Support matrix.

Per our policies, we do not +consider this to be a breaking change.

Introduce ASAN Poisoning After Clearing Oneof Messages on Arena

This change adds a hardening check that affects C++ protobufs using Arenas. +Oneof messages allocated on the protobuf arena will now be cleared in debug and +poisoned in ASAN mode. After calling clear, future attempts to use the memory +region will cause a crash in ASAN as a use-after-free error.

This implementation requires C++17.

Dropping our C++ CocoaPods release

In v30, we will be dropping our C++ CocoaPods release, which has been broken +since v4.x.x. C++ users should use our +GitHub release directly +instead.

Changes in JRuby

v30 will flip the default implementation for JRuby to FFI, which may be breaking +for some JRuby users.

Note that this change doesn’t create a Ruby major version bump because JRuby is +not officially supported.

Changes in Python

Python will bump its major version from 5.29.x to 6.30.x.

Dropping Python 3.8 Support

As per our official Python support policy, we will be dropping support for +Python 3.8 and lower. This means the minimum supported Python version is 3.9.

Remove bazel/system_python.bzl Alias

v30 will remove the legacy bazel/system_python.bzl alias.

Remove direct references to system_python.bzl in favor of using +protobuf_deps.bzl instead. Use python/dist/system_python.bzl where it was +moved +in v5.27.0 +if you need a direct reference.

Field Setter Validation Changes

Python’s and upb’s field setters will be fixed in v30 to validate closed enums +under edition 2023. Closed enum fields updated with invalid values will generate +errors.

Remove Deprecated py_proto_library Macro

The deprecated internal py_proto_library Bazel macro in protobuf.bzl will be +removed in v30.x.

This should be replaced by the official py_proto_library which will be moved +to protobuf in bazel/py_proto_library as of v29.x. This implementation was +previously available in rules_python prior to v29.x.

Remove Deprecated APIs

v30 will remove the following public runtime APIs, which have been marked +deprecated for at least one minor or major release and are obsolete or replaced.

Reflection Methods

APIs: +reflection.ParseMessage, +reflection.MakeClass

Replacement: message_factory.GetMessageClass()

RPC Service Interfaces

APIs: +service.RpcException, +service.Service, +service.RpcController, +and +service.RpcChannel

Replacement: Starting with version 2.3.0, RPC implementations should not try +to build on these, but should instead provide code generator plugins which +generate code specific to the particular RPC implementation.

MessageFactory and SymbolDatabase Methods

APIs: +MessageFactory.GetPrototype, +MessageFactory.CreatePrototype, +MessageFactory.GetMessages, +SymbolDatabase.GetPrototype, +SymbolDatabase.CreatePrototype, +and +SymbolDatabase.GetMessages

Replacement: message_factory.GetMessageClass() and +message_factory.GetMessageClassesForFiles().

GetDebugString

APIs: +GetDebugString

Replacement:

No replacement. It’s only in Python C++ which is no longer released. It is not +supported in pure Python or UPB.

Python setdefault Behavior Change for Map Fields

Starting in v30, setdefault will be similar to dict for ScalarMap, except +that both key and value must be set. setdefault will be rejected for +MessageMaps.

Python Nested Message Class __qualname__ Contains the Outer Message Name

Python nested message class __qualname__ now contains the outer message name. +Prior to v30, __qualname__ has the same result with __name__ for nested +message, in that the outer message name was not included.

For example:

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
+

Changes in Objective-C

This will be the first breaking release for Objective-C.

Objective-C will bump its major version from 3.x.x to 4.30.x.

Overhaul Unknown Field Handling APIs Deprecating Most of the Existing APIs

v30 will deprecate GPBUnknownFieldSet and replace it with GPBUnknownFields. +The new type will preserve the ordering of unknown fields from the original +input or API calls, to ensure any semantic meaning to the ordering is maintained +when a message is written back out.

As part of this, the GPBUnknownField type also has its APIs changed, with +almost all of the existing APIs becoming deprecated and new ones added.

Deprecated property APIs:

  • varintList
  • fixed32List
  • fixed64List
  • lengthDelimitedList
  • groupList

Deprecated modification APIs:

  • addVarint:
  • addFixed32:
  • addFixed64:
  • addLengthDelimited:
  • addGroup:

Deprecated initializer initWithNumber:.

New property APIs:

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

This type will model a single field number in its value, rather than grouping +all the values for a given field number. The APIs for creating new fields are +the add* APIs on the GPBUnknownFields class.

v30 will also deprecate -[GPBMessage unknownFields]. In its place, there will +be new APIs to extract and update the unknown fields of the message.

Remove Deprecated APIs

v30 will remove the following public runtime APIs, which have been marked +deprecated for at least one minor or major release and are obsolete or replaced.

GPBFileDescriptor

API: +-[GPBFileDescriptor syntax]

Replacement: Obsolete.

GPBMessage mergeFrom:extensionRegistry

API: +-[GPBMessage mergeFrom:extensionRegistry:]

Replacement: +-[GPBMessage mergeFrom:extensionRegistry:error:]

GPBDuration timeIntervalSince1970

API: +-[GPBDuration timeIntervalSince1970]

Replacement: +-[GPBDuration timeInterval]

GPBTextFormatForUnknownFieldSet

API: +GPBTextFormatForUnknownFieldSet()

Replacement: Obsolete - Use +GPBTextFormatForMessage(), +which includes any unknown fields.

GPBUnknownFieldSet

API: +GPBUnknownFieldSet

Replacement: +GPBUnknownFields

GPBMessage unknownFields

API: +GPBMessage unknownFields property

Replacement: +-[GPBUnknownFields initFromMessage:], +-[GPBMessage mergeUnknownFields:extensionRegistry:error:], +and +-[GPBMessage clearUnknownFields]

Remove Deprecated Runtime APIs for Old Gencode

This release will remove deprecated runtime methods that support the Objective-C +gencode from before the 3.22.x release. The library will also issue a log +message at runtime when old generated code is starting up.

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

Replacement: Regenerate with a current version of the library.

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

Replacement: Regenerate with a current version of the library.

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

Replacement: Regenerate with a current version of the library.

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

Replacement: Regenerate with a current version of the library.

API: +-[GPBExtensionDescriptor initWithExtensionDescription:]

Replacement: Regenerate with a current version of the library.

Other Changes

Poison MSVC + Bazel

We will be dropping support for using Bazel and MSVC together in v34. As of v30, +we will poison this combination with an error unless you specify the opt-out +flag --define=protobuf_allow_msvc=true to silence it.

MSVC’s path length limits combined with Bazel’s sandboxing have become +increasingly difficult to support in combination. Rather than randomly break +users who install protobuf into a long path, we will prohibit the use of MSVC +from Bazel altogether. We will continue to support MSVC with CMake, and begin +supporting clang-cl +with Bazel. For any feedback or discussion, see +https://github.com/protocolbuffers/protobuf/issues/20085.

Other Changes (Non-Breaking)

In addition to those breaking changes are some other changes worth noting. While +the following are not considered breaking changes, they may still impact users.

Poison Pill Warnings

v30 will update poison pills to emit warnings for old gencode + new runtime +combinations that work under the new rolling upgrade policy, but will break in +the next major bump. For example, Java 4.x.x gencode should work against 5.x.x +runtime but warn of upcoming breakage against 6.x.x runtime.

Changes to UTF-8 Enforcement in C# and Ruby

v30 will includes a fix to make UTF-8 enforcement consistent across languages. +Users with bad non-UTF8 data in string fields may see surfaced UTF-8 enforcement +errors earlier.

Ruby and PHP Errors in JSON Parsing

v30 fixes non-conformance in JSON parsing of strings in numeric fields per the +JSON spec.

This fix will not be accompanied by a major version bump, but Ruby and PHP will +now raise errors for non-numeric strings (e.g. “”, “12abc”, “abc”) in numeric +fields. v29.x will include a warning for these error cases.

\ No newline at end of file diff --git a/news/v31/index.html b/news/v31/index.html new file mode 100644 index 000000000..85f52a76f --- /dev/null +++ b/news/v31/index.html @@ -0,0 +1,50 @@ +News Announcements for Version 31.x | Protocol Buffers Documentation +

News Announcements for Version 31.x

Changes announced for Protocol Buffers version 31.x.

The following announcements are specific to Version 31.x, which was released May +14, 2025. For information presented chronologically, see +News.

The following sections cover planned breaking changes in the v31 release, +expected in 2025 Q2. Also included are some changes that aren’t breaking but may +require action on your part. These describe changes as we anticipate them being +implemented, but due to the flexible nature of software some of these changes +may not land or may vary from how they are described in this topic.

Dropping Ruby 3.0 Support

As per our official +Ruby support policy, +we will be dropping support for Ruby 3.0. The minimum supported Ruby version +will be 3.1.

Deprecating Label Enums

We are announcing an upcoming change regarding the FieldDescriptor.label enum +and its associated values: FieldDescriptor.LABEL_OPTIONAL, +FieldDescriptor.LABEL_REQUIRED, and FieldDescriptor.LABEL_REPEATED. These +are being deprecated as we encourage the use of more precise accessor methods.

Background

While at one time the FieldDescriptor.label enum served a purpose, the +evolution of Protocol Buffers has introduced more explicit ways to determine a +field’s cardinality (singular/repeated) and presence semantics.

  • In proto2, optional, required, and repeated are explicit keywords.
  • In proto3, required is no longer supported. All scalar fields are +implicitly “optional” in the sense that they have default values if not +set. The optional keyword was later reintroduced in proto3 to explicitly +track presence for scalar fields (distinguishing between an unset field and +a field set to its default value).
  • In edition 2023 we removed the optional and required keywords and use +features to control those behaviors.

The label enum conflates these distinct concepts (cardinality, requiredness, +and explicit presence tracking), leading to potential confusion, especially with +proto3’s field presence model.

Impact and Migration

The FieldDescriptor.label field will eventually be removed from the API to +maintain backward compatibility. Note that the method names in this topic may be +spelled slightly differently in some languages.

  • For Protocol Buffer Editions fields:
    • Behavior: The getLabel method will be simplified:
      • It will return FieldDescriptor.LABEL_OPTIONAL for all singular +fields.
      • It will return FieldDescriptor.LABEL_REPEATED for all repeated +fields.
    • Key Methods for Editions:
      • hasOptionalKeyword will always return false (as the optional +keyword’s role in presence is superseded by feature-based presence +in Editions).
      • hasPresence becomes the primary method to determine if a singular +field tracks presence, reflecting the +features.field_presence +setting for that field.
    • Migration: Rely on isRepeated for cardinality and hasPresence to +check for explicit presence tracking in singular fields.
  • For proto3 fields: getLabel will eventually be removed, and is not +recommended in the meantime. Update your code to use hasOptionalKeyword +and getRealContainingOneof instead.
  • For proto2 fields: getLabel will continue to reflect LABEL_OPTIONAL, +LABEL_REQUIRED, or LABEL_REPEATED as defined in the .proto file for the +time being.

All users of Protocol Buffers who interact with FieldDescriptor objects in +their code (for example for code generation, reflection, and dynamic message +handling) should migrate away from using FieldDescriptor.label directly.

Instead, update your code to use the following methods:

  • To check if a field is repeated: field.isRepeated
  • To check if a field is required (proto2 and editions only): +field.isRequired
  • To check if a singular proto3 field has explicit presence, use hasPresence
  • To check if a singular field has explicit presence via a oneof, use +hasPresence

Timeline

This deprecation is effective immediately. While getLabel will continue to +function, we recommend migrating your code proactively to ensure future +compatibility and clarity. This change will lead to a more robust and +understandable experience for developers using Protocol Buffers.

\ No newline at end of file diff --git a/news/v32/index.html b/news/v32/index.html new file mode 100644 index 000000000..1e310555d --- /dev/null +++ b/news/v32/index.html @@ -0,0 +1,97 @@ +News Announcements for Version 32.x | Protocol Buffers Documentation +

News Announcements for Version 32.x

Changes announced for Protocol Buffers version 32.x.

Changes to Existing Features

This section details any existing features whose default settings will change in +Edition 2024.

C++ string_type

The default for string_type feature, originally released in Edition 2023, will +change from STRING to VIEW in Edition 2024.

See +features.(pb.cpp).string_type +and String View APIs for +more information on this feature and its feature values.

New Features

This section details any new features that will be introduced in Edition 2024.

enforce_naming_style

feature.enforce_naming_style +enables strict naming style enforcement to ensure protos are round-trippable by +default with a feature value to opt-out to use legacy naming style.

default_symbol_visibility

This feature controls whether the default symbol visibility of importable +symbols (such as messages and enums) is either:

  • export: referenceable from other protos via import statements
  • local: un-referenceable outside of current file

The default feature value EXPORT_TOP_LEVEL in Edition 2024 ensures top-level +symbols are export by default, whereas nested symbols are local by default.

This can be used along with the export and local keywords +to explicitly annotate symbol visibility, also added in Edition 2024.

Symbol visibility only controls which symbols can be imported from other proto +files, but does not affect code-generation.

C++: enum_name_uses_string_view

Previously, all generated enum types provide the following function to obtain +the label out of an enum value, which has significant overhead to construct the +std::string instances at runtime:

const std::string& Foo_Name(int);
+

The default feature value in Edition 2024 instead migrates this signature to +return absl::string_view to allow for better storage decoupling and potential +memory/CPU savings.

absl::string_view Foo_Name(int);
+

Users should migrate their code to handle the new return-type following +the migration guide.

See String View APIs for +more information.

Java: nest_in_file_class

This feature controls whether the Java generator will nest the generated class +in the Java generated file class.

The default value in Edition 2024 generates classes in their own files by +default, which is also the default behavior of the previous +java_multiple_files = true file option. This replaces java_multiple_files +which is removed in Edition 2024.

The default outer classname is also updated to always be the camel-cased +.proto filename suffixed with Proto by default (for example, +foo/bar_baz.proto -> BarBazProto). You can override this using the +java_outer_classname file option and replace the pre-Edition 2024 default of +BarBaz or BarBazOuterClass depending on the presence of conflicts.

Java: large_enum

This feature allows creation of large Java enums, extending beyond the enum +limit due to standard constant limits imposed by the Java language.

Creation of large enums is not enabled by default, but you can explicitly enable +it using this feature. Note that this feature replicates enum-like behavior but +has some notable differences (for example, switch statements are not supported).

Grammar Changes

import option

Edition 2024 adds support for option imports using the syntax import option.

Unlike normal import statements, import option only imports custom options +defined in a .proto file, without importing other symbols.

This means that messages and enums are excluded from the option import. In the +following example, the Bar message cannot be used as a field type in +foo.proto, but options with type Bar can still be set.

Option imports must also come after any other import statements.

Example:

// bar.proto
+edition = "2024";
+
+import "google/protobuf/descriptor.proto";
+
+message Bar {
+  bool bar = 1;
+}
+
+extend proto2.FileOptions {
+  bool file_opt1 = 5000;
+  Bar file_opt2 = 5001;
+}
+
// foo.proto:
+edition = "2024";
+
+import option "bar.proto";
+
+option (file_opt1) = true;
+option (file_opt2) = {bar: true};
+
+message Foo {
+  // Bar bar = 1; // This is not allowed
+}
+

Option imports do not require generated code for its symbols and thus must be +provided as option_deps in proto_library instead of deps. This avoids +generating unreachable code.

proto_library(
+  name = "foo",
+  srcs = ["foo.proto"],
+  option_deps = [":custom_option"]
+)
+

Option imports and option_deps are strongly recommended when importing +protobuf language features and other custom options to avoid generating +unnecessary code.

option_deps requires Bazel 8 or later since the native.proto_library in +Bazel 7 does not support this.

This also replaces import weak, which is removed in Edition 2024.

export / local Keywords

export and local keywords are added in Edition 2024 as modifiers for the +symbol visibility of importable symbols, from the default behavior specified by +the +default_symbol_visibility feature.

This controls which symbols can be imported from other proto files, but does not +affect code-generation.

In Edition 2024, these can be set on all message and enum symbols by default. +However, some values of the default_symbol_visibility feature further restrict +which symbols are exportable.

Example:

// Top-level symbols are exported by default in Edition 2024
+local message LocalMessage {
+  // Nested symbols are local by default in Edition 2024
+  export enum ExportedNestedEnum {
+    UNKNOWN_EXPORTED_NESTED_ENUM_VALUE = 0;
+  }
+}
+

“import weak” and weak Field Option

Weak imports are no longer allowed as of Edition 2024.

Most users previously relying on import weak to declare a “weak dependency” to +import custom options without generated code for C++ and Go should instead +migrate to use +import option +instead.

ctype Field Option

ctype field option is no longer allowed as of Edition 2024. Use the +features.(pb.cpp).string_type +feature, instead.

java_multiple_files File Option

The java_multiple_files file option is removed in Edition 2024 in favor of the +new +features.nest_in_file_class +Java feature.

\ No newline at end of file diff --git a/news/v34/index.html b/news/v34/index.html new file mode 100644 index 000000000..5cc0a5ed1 --- /dev/null +++ b/news/v34/index.html @@ -0,0 +1,12 @@ +News Announcements for Version 34.x | Protocol Buffers Documentation +

News Announcements for Version 34.x

Changes announced for Protocol Buffers version 34.x.

The following news topics provide information about changes in the 34.x release.

\ No newline at end of file diff --git a/overview/index.html b/overview/index.html new file mode 100644 index 000000000..4bc6e8149 --- /dev/null +++ b/overview/index.html @@ -0,0 +1,152 @@ +Overview | Protocol Buffers Documentation +

Overview

Protocol Buffers are a language-neutral, platform-neutral extensible mechanism for serializing structured data.

It’s like JSON, except it’s +smaller and faster, and it generates native language bindings. You define how +you want your data to be structured once, then you can use special generated +source code to easily write and read your structured data to and from a variety +of data streams and using a variety of languages.

Protocol buffers are a combination of the definition language (created in +.proto files), the code that the proto compiler generates to interface with +data, language-specific runtime libraries, the serialization format for data +that is written to a file (or sent across a network connection), and the +serialized data.

What Problems do Protocol Buffers Solve?

Protocol buffers provide a serialization format for packets of typed, structured +data that are up to a few megabytes in size. The format is suitable for both +ephemeral network traffic and long-term data storage. Protocol buffers can be +extended with new information without invalidating existing data or requiring +code to be updated.

Protocol buffers are the most commonly-used data format at Google. They are used +extensively in inter-server communications as well as for archival storage of +data on disk. Protocol buffer messages and services are described by +engineer-authored .proto files. The following shows an example message:

edition = "2023";
+
+message Person {
+  string name = 1;
+  int32 id = 2;
+  string email = 3;
+}
+

The proto compiler is invoked at build time on .proto files to generate code +in various programming languages (covered in +Cross-language Compatibility later in this topic) to manipulate +the corresponding protocol buffer. Each generated class contains simple +accessors for each field and methods to serialize and parse the whole structure +to and from raw bytes. The following shows you an example that uses those +generated methods:

Person john = Person.newBuilder()
+    .setId(1234)
+    .setName("John Doe")
+    .setEmail("jdoe@example.com")
+    .build();
+output = new FileOutputStream(args[0]);
+john.writeTo(output);
+

Because protocol buffers are used extensively across all manner of services at +Google and data within them may persist for some time, maintaining backwards +compatibility is crucial. Protocol buffers allow for the seamless support of +changes, including the addition of new fields and the deletion of existing +fields, to any protocol buffer without breaking existing services. For more on +this topic, see +Updating Proto Definitions Without Updating Code, later in +this topic.

What are the Benefits of Using Protocol Buffers?

Protocol buffers are ideal for any situation in which you need to serialize +structured, record-like, typed data in a language-neutral, platform-neutral, +extensible manner. They are most often used for defining communications +protocols (together with gRPC) and for data storage.

Some of the advantages of using protocol buffers include:

  • Compact data storage
  • Fast parsing
  • Availability in many programming languages
  • Optimized functionality through automatically-generated classes

Cross-language Compatibility

The same messages can be read by code written in any supported programming +language. You can have a Java program on one platform capture data from one +software system, serialize it based on a .proto definition, and then extract +specific values from that serialized data in a separate Python application +running on another platform.

The following languages are supported directly in the protocol buffers compiler, +protoc:

The following languages are supported by Google, but the projects’ source code +resides in GitHub repositories. The protoc compiler uses plugins for these +languages:

Additional languages are not directly supported by Google, but rather by other +GitHub projects. These languages are covered in +Third-Party Add-ons for Protocol Buffers.

Cross-project Support

You can use protocol buffers across projects by defining message types in +.proto files that reside outside of a specific project’s code base. If you’re +defining message types or enums that you anticipate will be widely used +outside of your immediate team, you can put them in their own file with no +dependencies.

A couple of examples of proto definitions widely-used within Google are +timestamp.proto +and +status.proto.

Updating Proto Definitions Without Updating Code

It’s standard for software products to be backward compatible, but it is less +common for them to be forward compatible. As long as you follow some +simple practices +when updating .proto definitions, old code will read new messages without +issues, ignoring any newly added fields. To the old code, fields that were +deleted will have their default value, and deleted repeated fields will be +empty. For information on what “repeated” fields are, see +Protocol Buffers Definition Syntax later in this topic.

New code will also transparently read old messages. New fields will not be +present in old messages; in these cases protocol buffers provide a reasonable +default value.

When are Protocol Buffers not a Good Fit?

Protocol buffers do not fit all data. In particular:

  • Protocol buffers tend to assume that entire messages can be loaded into +memory at once and are not larger than an object graph. For data that +exceeds a few megabytes, consider a different solution; when working with +larger data, you may effectively end up with several copies of the data due +to serialized copies, which can cause surprising spikes in memory usage.
  • When protocol buffers are serialized, the same data can have many different +binary serializations. You cannot compare two messages for equality without +fully parsing them.
  • Messages are not compressed. While messages can be zipped or gzipped like +any other file, special-purpose compression algorithms like the ones used by +JPEG and PNG will produce much smaller files for data of the appropriate +type.
  • Protocol buffer messages are less than maximally efficient in both size and +speed for many scientific and engineering uses that involve large, +multi-dimensional arrays of floating point numbers. For these applications, +FITS and similar formats have less +overhead.
  • Protocol buffers are not well supported in non-object-oriented languages +popular in scientific computing, such as Fortran and IDL.
  • Protocol buffer messages don’t inherently self-describe their data, but they +have a fully reflective schema that you can use to implement +self-description. That is, you cannot fully interpret one without access to +its corresponding .proto file.
  • Protocol buffers are not a formal standard of any organization. This makes +them unsuitable for use in environments with legal or other requirements to +build on top of standards.

Who Uses Protocol Buffers?

Many projects use protocol buffers, including the following:

How do Protocol Buffers Work?

The following diagram shows how you use protocol buffers to work with your data.

Compilation workflow showing the creation of a proto file, generated code, and compiled classes
Figure 1. Protocol buffers workflow

The code generated by protocol buffers provides utility methods to retrieve data +from files and streams, extract individual values from the data, check if data +exists, serialize data back to a file or stream, and other useful functions.

The following code samples show you an example of this flow in Java. As shown +earlier, this is a .proto definition:

message Person {
+  string name = 1;
+  int32 id = 2;
+  string email = 3;
+}
+

Compiling this .proto file creates a Builder class that you can use to +create new instances, as in the following Java code:

Person john = Person.newBuilder()
+    .setId(1234)
+    .setName("John Doe")
+    .setEmail("jdoe@example.com")
+    .build();
+output = new FileOutputStream(args[0]);
+john.writeTo(output);
+

You can then deserialize data using the methods protocol buffers creates in +other languages, like C++:

Person john;
+fstream input(argv[1], ios::in | ios::binary);
+john.ParseFromIstream(&input);
+int id = john.id();
+std::string name = john.name();
+std::string email = john.email();
+

Protocol Buffers Definition Syntax

When defining .proto files, you can specify cardinality (singular or +repeated). In proto2 and proto3, you can also specify if the field is optional. +In proto3, setting a field to optional +changes it from implicit presence to explicit presence.

After setting the cardinality of a field, you specify the data type. Protocol +buffers support the usual primitive data types, such as integers, booleans, and +floats. For the full list, see +Scalar Value Types.

A field can also be of:

  • A message type, so that you can nest parts of the definition, such as for +repeating sets of data.
  • An enum type, so you can specify a set of values to choose from.
  • A oneof type, which you can use when a message has many optional fields +and at most one field will be set at the same time.
  • A map type, to add key-value pairs to your definition.

Messages can allow extensions to define fields outside of the message, +itself. For example, the protobuf library’s internal message schema allows +extensions for custom, usage-specific options.

For more information about the options available, see the language guide for +proto2, +proto3, or +edition 2023.

After setting cardinality and data type, you choose a name for the field. There +are some things to keep in mind when setting field names:

  • It can sometimes be difficult, or even impossible, to change field names +after they’ve been used in production.
  • Field names cannot contain dashes. For more on field name syntax, see +Message and Field Names.
  • Use pluralized names for repeated fields.

After assigning a name to the field, you assign a field number. Field +numbers cannot be repurposed or reused. If you delete a field, you should +reserve its field number to prevent someone from accidentally reusing the +number.

Additional Data Type Support

Protocol buffers support many scalar value types, including integers that use +both variable-length encoding and fixed sizes. You can also create your own +composite data types by defining messages that are, themselves, data types that +you can assign to a field. In addition to the simple and composite value types, +several common types +are published.

History

To read about the history of the protocol buffers project, see +History of Protocol Buffers.

Protocol Buffers Open Source Philosophy

Protocol buffers were open sourced in 2008 as a way to provide developers +outside of Google with the same benefits that we derive from them internally. We +support the open source community through regular updates to the language as we +make those changes to support our internal requirements. While we accept select +pull requests from external developers, we cannot always prioritize feature +requests and bug fixes that don’t conform to Google’s specific needs.

Developer Community

To be alerted to upcoming changes in Protocol Buffers and to connect with +protobuf developers and users, +join the Google Group.

Additional Resources

\ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index f72d38875..000000000 --- a/package-lock.json +++ /dev/null @@ -1,302 +0,0 @@ -{ - "name": "protobuf-dev", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "dependencies": { - "autoprefixer": "^10.4.7" - } - }, - "node_modules/autoprefixer": { - "version": "10.4.7", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.7.tgz", - "integrity": "sha512-ypHju4Y2Oav95SipEcCcI5J7CGPuvz8oat7sUtYj3ClK44bldfvtvcxK6IEK++7rqB7YchDGzweZIBG+SD0ZAA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - } - ], - "dependencies": { - "browserslist": "^4.20.3", - "caniuse-lite": "^1.0.30001335", - "fraction.js": "^4.2.0", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/browserslist": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.2.tgz", - "integrity": "sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001366", - "electron-to-chromium": "^1.4.188", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.4" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001366", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001366.tgz", - "integrity": "sha512-yy7XLWCubDobokgzudpkKux8e0UOOnLHE6mlNJBzT3lZJz6s5atSEzjoL+fsCPkI0G8MP5uVdDx1ur/fXEWkZA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ] - }, - "node_modules/electron-to-chromium": { - "version": "1.4.188", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.188.tgz", - "integrity": "sha512-Zpa1+E+BVmD/orkyz1Z2dAT1XNUuVAHB3GrogfyY66dXN0ZWSsygI8+u6QTDai1ZayLcATDJpcv2Z2AZjEcr1A==" - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/fraction.js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", - "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://www.patreon.com/infusion" - } - }, - "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", - "peer": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "node_modules/postcss": { - "version": "8.4.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", - "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - } - ], - "peer": true, - "dependencies": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, - "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.4.tgz", - "integrity": "sha512-jnmO2BEGUjsMOe/Fg9u0oczOe/ppIDZPebzccl1yDWGLFP16Pa1/RM5wEoKYPG2zstNcDuAStejyxsOuKINdGA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist-lint": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - } - }, - "dependencies": { - "autoprefixer": { - "version": "10.4.7", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.7.tgz", - "integrity": "sha512-ypHju4Y2Oav95SipEcCcI5J7CGPuvz8oat7sUtYj3ClK44bldfvtvcxK6IEK++7rqB7YchDGzweZIBG+SD0ZAA==", - "requires": { - "browserslist": "^4.20.3", - "caniuse-lite": "^1.0.30001335", - "fraction.js": "^4.2.0", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - } - }, - "browserslist": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.2.tgz", - "integrity": "sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA==", - "requires": { - "caniuse-lite": "^1.0.30001366", - "electron-to-chromium": "^1.4.188", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.4" - } - }, - "caniuse-lite": { - "version": "1.0.30001366", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001366.tgz", - "integrity": "sha512-yy7XLWCubDobokgzudpkKux8e0UOOnLHE6mlNJBzT3lZJz6s5atSEzjoL+fsCPkI0G8MP5uVdDx1ur/fXEWkZA==" - }, - "electron-to-chromium": { - "version": "1.4.188", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.188.tgz", - "integrity": "sha512-Zpa1+E+BVmD/orkyz1Z2dAT1XNUuVAHB3GrogfyY66dXN0ZWSsygI8+u6QTDai1ZayLcATDJpcv2Z2AZjEcr1A==" - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "fraction.js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", - "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==" - }, - "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", - "peer": true - }, - "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "postcss": { - "version": "8.4.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", - "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", - "peer": true, - "requires": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - } - }, - "postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, - "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "peer": true - }, - "update-browserslist-db": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.4.tgz", - "integrity": "sha512-jnmO2BEGUjsMOe/Fg9u0oczOe/ppIDZPebzccl1yDWGLFP16Pa1/RM5wEoKYPG2zstNcDuAStejyxsOuKINdGA==", - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - } - } -} \ No newline at end of file diff --git a/package.json b/package.json deleted file mode 100644 index 79663fd81..000000000 --- a/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "autoprefixer": "^10.4.7" - } -} \ No newline at end of file diff --git a/programming-guides/1-1-1/index.html b/programming-guides/1-1-1/index.html new file mode 100644 index 000000000..e76a99fb8 --- /dev/null +++ b/programming-guides/1-1-1/index.html @@ -0,0 +1,2 @@ +https://protobuf.dev/best-practices/1-1-1/ + \ No newline at end of file diff --git a/programming-guides/addons/index.html b/programming-guides/addons/index.html new file mode 100644 index 000000000..bb703c21b --- /dev/null +++ b/programming-guides/addons/index.html @@ -0,0 +1,10 @@ +Third-Party Add-ons | Protocol Buffers Documentation +

Third-Party Add-ons

Links out to many open source projects that seek to add useful functionality on top of Protocol Buffers.

Many open source projects seek to add useful functionality on top of Protocol +Buffers. For a list of links to projects we know about, see the +third-party add-ons wiki page.

\ No newline at end of file diff --git a/programming-guides/deserialize-debug/index.html b/programming-guides/deserialize-debug/index.html new file mode 100644 index 000000000..60a5aa39a --- /dev/null +++ b/programming-guides/deserialize-debug/index.html @@ -0,0 +1,69 @@ +Deserializing Debug Proto Representations | Protocol Buffers Documentation +

Deserializing Debug Proto Representations

How to log debugging information in Protocol Buffers.

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.

Unlike the Protobuf DebugString output format, the new debugging format +automatically redacts sensitive fields by replacing their values with the string +“[REDACTED]” (without the quotation marks). In +addition, to ensure that this new output format cannot be deserialized by +Protobuf TextFormat parsers, regardless of whether the underlying proto contains +SPII fields, we add a set of randomized links pointing to this article +and a randomized-length whitespace sequence. The new debugging format looks as +follows:

goo.gle/debugstr
+spii_field: [REDACTED]
+normal_field: "value"
+

Note that the new debugging format is only different from the output format of +DebugString format in two ways:

  • The URL prefix
  • The values of SPII fields are replaced by +“[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. +If you don’t see certain fields in the output, it is because those fields are +not set in the proto.

Tip: If you see only the URL and nothing else, your proto is empty!

Why is this URL here?

We want to make sure nobody deserializes human-readable representations of a +protobuf message intended for humans debugging a system. Historically, +.DebugString() and TextFormat were interchangeable, and existing systems use +DebugString to transport and store data.

We want to make sure sensitive data does not accidentally end up in logs. +Therefore, we are transparently redacting some field values from protobuf +messages before turning them into a string +("[REDACTED]"). This reduces the security & privacy +risk of accidental logging, but risks data loss if other systems deserialize +your message. To address this risk, we are intentionally splitting the +machine-readable TextFormat from the human-readable debug format to be used in +log messages.

This is intentional, to make the “debug representation” of your protos +(produced, for example, by logging) incompatible with TextFormat. We want to +prevent anyone from depending on debugging mechanisms to transport data between +programs. Historically, the debug format (generated by the DebugString APIs) and +TextFormat have been incorrectly used in a interchangeable fashion. We hope this +intentional effort will prevent that going forward.

We intentionally picked a link over less visible format changes to get an +opportunity to provide context. This might stand out in UIs, such as if you +display status information on a table in a webpage. You may use +TextFormat::PrintToString instead, which will not redact any information and +preserves formatting. However, use this API cautiously – there are no built in +protections. As a rule of thumb, if you are writing data to debug logs, or +producing status messages, you should continue to use the Debug Format with the +link. Even if you are currently not handling sensitive data, keep in mind that +systems can change and code gets re-used.

I tried converting this message into TextFormat, but I noticed the format changes every time my process restarts.

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 should be +using a TextFormat API rather than using the debug representation of a proto.

FAQ

Can I Just Use TextFormat Everywhere?

Don’t use TextFormat for producing log messages. This will bypass all built-in +protections, and you risk accidentally logging sensitive information. Even if +your systems are currently not handling any sensitive data, this can change in +the future.

Distinguish logs from information that’s meant for further processing by other +systems by using either the debug representation or TextFormat as appropriate.

I Want to Write Configuration Files That Need to Be Both Human-Readable And Machine-Readable

For this use case, you can use TextFormat explicitly. You are responsible for +making sure your configuration files don’t contain any PII.

I Am Writing a Unit Test, and Want to Compare Debugstring in a Test Assertion

If you want to compare protobuf values, use MessageDifferencer like in the +following:

using google::protobuf::util::MessageDifferencer;
+...
+MessageDifferencer diff;
+...
+diff.Compare(foo, bar);
+

Besides ignoring formatting and field order differences, you will also get +better error messages.

\ No newline at end of file diff --git a/programming-guides/dos-donts/index.html b/programming-guides/dos-donts/index.html new file mode 100644 index 000000000..8e3890449 --- /dev/null +++ b/programming-guides/dos-donts/index.html @@ -0,0 +1,2 @@ +https://protobuf.dev/best-practices/dos-donts/ + \ No newline at end of file diff --git a/programming-guides/editions/index.html b/programming-guides/editions/index.html new file mode 100644 index 000000000..9ad2eacad --- /dev/null +++ b/programming-guides/editions/index.html @@ -0,0 +1,1025 @@ +Language Guide (editions) | Protocol Buffers Documentation +

Language Guide (editions)

Covers how to use the editions revisions of the Protocol Buffers language in your project.

This guide describes how to use the protocol buffer language to structure your +protocol buffer data, including .proto file syntax and how to generate data +access classes from your .proto files. It covers edition 2023 to edition +2024 of the protocol buffers language. For information about how editions +differ from proto2 and proto3 conceptually, see +Protobuf Editions Overview.

For information on the proto2 syntax, see the +Proto2 Language Guide.

For information on proto3 syntax, see the +Proto3 Language Guide.

This is a reference guide – for a step by step example that uses many of the +features described in this document, see the +tutorial +for your chosen language.

Defining A Message Type

First let’s look at a very simple example. Let’s say you want to define a search +request message format, where each search request has a query string, the +particular page of results you are interested in, and a number of results per +page. Here’s the .proto file you use to define the message type.

edition = "2023";
+
+message SearchRequest {
+  string query = 1;
+  int32 page_number = 2;
+  int32 results_per_page = 3;
+}
+
  • The first line of the file specifies that you’re using edition 2023 of the +protobuf language spec.

    • The edition (or syntax for proto2/proto3) must be the first +non-empty, non-comment line of the file.
    • If no edition or syntax is specified, the protocol buffer compiler +will assume you are using +proto2.
  • The SearchRequest message definition specifies three fields (name/value +pairs), one for each piece of data that you want to include in this type of +message. Each field has a name and a type.

Specifying Field Types

In the earlier example, all the fields are scalar types: two integers +(page_number and results_per_page) and a string (query). You can also +specify enumerations and composite types like other message types for +your field.

Assigning Field Numbers

You must give each field in your message definition a number between 1 and +536,870,911 with the following restrictions:

  • The given number must be unique among all fields for that message.
  • Field numbers 19,000 to 19,999 are reserved for the Protocol Buffers +implementation. The protocol buffer compiler will complain if you use one of +these reserved field numbers in your message.
  • You cannot use any previously reserved field numbers or +any field numbers that have been allocated to extensions.

This number cannot be changed once your message type is in use because it +identifies the field in the +message wire format. +“Changing” a field number is equivalent to deleting that field and creating a +new field with the same type but a new number. See Deleting Fields +for how to do this properly.

Field numbers should never be reused. Never take a field number out of the +reserved list for reuse with a new field definition. See +Consequences of Reusing Field Numbers.

You should use the field numbers 1 through 15 for the most-frequently-set +fields. Lower field number values take less space in the wire format. For +example, field numbers in the range 1 through 15 take one byte to encode. Field +numbers in the range 16 through 2047 take two bytes. You can find out more about +this in +Protocol Buffer Encoding.

Consequences of Reusing Field Numbers

Reusing a field number makes decoding wire-format messages ambiguous.

The protobuf wire format is lean and doesn’t provide a way to detect fields +encoded using one definition and decoded using another.

Encoding a field using one definition and then decoding that same field with a +different definition can lead to:

  • Developer time lost to debugging
  • A parse/merge error (best case scenario)
  • Leaked PII/SPII
  • Data corruption

Common causes of field number reuse:

  • renumbering fields (sometimes done to achieve a more aesthetically pleasing +number order for fields). Renumbering effectively deletes and re-adds all +the fields involved in the renumbering, resulting in incompatible +wire-format changes.

  • deleting a field and not reserving the number to prevent +future reuse.

The field number is limited to 29 bits rather than 32 bits because three bits +are used to specify the field’s wire format. For more on this, see the +Encoding topic.

Specifying Field Cardinality

Message fields can be one of the following:

  • Singular:

    A singular field has no explicit cardinality label. It has two possible +states:

    • the field is set, and contains a value that was explicitly set or parsed +from the wire. It will be serialized to the wire.
    • the field is unset, and will return the default value. It will not be +serialized to the wire.

    You can check to see if the value was explicitly set.

    Proto3 implicit fields that have been migrated to editions will use the +field_presence feature set to the IMPLICIT value.

    Proto2 required fields that have been migrated to editions will also use +the field_presence feature, but set to LEGACY_REQUIRED.

  • repeated: this field type can be repeated zero or more times in a +well-formed message. The order of the repeated values will be preserved.

  • map: this is a paired key/value field type. See +Maps for more on +this field type.

Repeated Fields are Packed by Default

In proto editions, repeated fields of scalar numeric types use packed +encoding by default.

You can find out more about packed encoding in +Protocol Buffer Encoding.

Well-formed Messages

The term “well-formed,” when applied to protobuf messages, refers to the bytes +serialized/deserialized. The protoc parser validates that a given proto +definition file is parseable.

Singular fields can appear more than once in wire-format bytes. The parser will +accept the input, but only the last instance of that field will be accessible +through the generated bindings. See +Last One Wins +for more on this topic.

Adding More Message Types

Multiple message types can be defined in a single .proto file. This is useful +if you are defining multiple related messages – so, for example, if you wanted +to define the reply message format that corresponds to your SearchResponse +message type, you could add it to the same .proto:

message SearchRequest {
+  string query = 1;
+  int32 page_number = 2;
+  int32 results_per_page = 3;
+}
+
+message SearchResponse {
+ ...
+}
+

Combining Messages leads to bloat While multiple message types (such as +message, enum, and service) can be defined in a single .proto file, it can +also lead to dependency bloat when large numbers of messages with varying +dependencies are defined in a single file. It’s recommended to include as few +message types per .proto file as possible.

Adding Comments

To add comments to your .proto files:

  • Prefer C/C++/Java line-end-style comments ‘//’ on the line before the .proto +code element

  • C-style inline/multi-line comments /* ... */ are also accepted.

    • When using multi-line comments, a margin line of ‘*’ is preferred.
/**
+ * SearchRequest represents a search query, with pagination options to
+ * indicate which results to include in the response.
+ */
+message SearchRequest {
+  string query = 1;
+
+  // Which page number do we want?
+  int32 page_number = 2;
+
+  // Number of results to return per page.
+  int32 results_per_page = 3;
+}
+

Deleting Fields

Deleting fields can cause serious problems if not done properly.

When you no longer need a field and all references have been deleted from client +code, you may delete the field definition from the message. However, you +must reserve the deleted field number. If you do not +reserve the field number, it is possible for a developer to reuse that number in +the future.

You should also reserve the field name to allow JSON and TextFormat encodings of +your message to continue to parse.

Reserved Field Numbers

If you update a message type by entirely deleting a field, or +commenting it out, future developers can reuse the field number when making +their own updates to the type. This can cause severe issues, as described in +Consequences of Reusing Field Numbers. To make sure this +doesn’t happen, add your deleted field number to the reserved list.

The protoc compiler will generate error messages if any future developers try to +use these reserved field numbers.

message Foo {
+  reserved 2, 15, 9 to 11;
+}
+

Reserved field number ranges are inclusive (9 to 11 is the same as 9, 10, 11).

Reserved Field Names

Reusing an old field name later is generally safe, except when using TextProto +or JSON encodings where the field name is serialized. To avoid this risk, you +can add the deleted field name to the reserved list.

Reserved names affect only the protoc compiler behavior and not runtime +behavior, with one exception: TextProto implementations may discard unknown +fields (without raising an error like with other unknown fields) with reserved +names at parse time (only the C++ and Go implementations do so today). Runtime +JSON parsing is not affected by reserved names.

message Foo {
+  reserved 2, 15, 9 to 11;
+  reserved foo, bar;
+}
+

Note that you can’t mix field names and field numbers in the same reserved +statement.

What’s Generated from Your .proto?

When you run the protocol buffer compiler on a .proto, the +compiler generates the code in your chosen language you’ll need to work with the +message types you’ve described in the file, including getting and setting field +values, serializing your messages to an output stream, and parsing your messages +from an input stream.

  • For C++, the compiler generates a .h and .cc file from each +.proto, with a class for each message type described in your file.
  • For Java, the compiler generates a .java file with a class for each +message type, as well as a special Builder class for creating message +class instances.
  • For Kotlin, in addition to the Java generated code, the compiler +generates a .kt file for each message type with an improved Kotlin API. +This includes a DSL that simplifies creating message instances, a nullable +field accessor, and a copy function.
  • Python is a little different — the Python compiler generates a module +with a static descriptor of each message type in your .proto, which is +then used with a metaclass to create the necessary Python data access +class at runtime.
  • For Go, the compiler generates a .pb.go file with a type for each +message type in your file.
  • For Ruby, the compiler generates a .rb file with a Ruby module +containing your message types.
  • For Objective-C, the compiler generates a pbobjc.h and pbobjc.m file +from each .proto, with a class for each message type described in your +file.
  • For C#, the compiler generates a .cs file from each .proto, with a +class for each message type described in your file.
  • For PHP, the compiler generates a .php message file for each message +type described in your file, and a .php metadata file for each .proto +file you compile. The metadata file is used to load the valid message types +into the descriptor pool.
  • For Dart, the compiler generates a .pb.dart file with a class for each +message type in your file.

You can find out more about using the APIs for each language by following the +tutorial for your chosen language. For even more API +details, see the relevant API reference.

Scalar Value Types

A scalar message field can have one of the following types – the table shows the +type specified in the .proto file, and the corresponding type in the +automatically generated class:

Proto TypeNotes
double
float
int32Uses variable-length encoding. Inefficient for encoding negative +numbers – if your field is likely to have negative values, use sint32 +instead.
int64Uses variable-length encoding. Inefficient for encoding negative +numbers – if your field is likely to have negative values, use sint64 +instead.
uint32Uses variable-length encoding.
uint64Uses variable-length encoding.
sint32Uses variable-length encoding. Signed int value. These more +efficiently encode negative numbers than regular int32s.
sint64Uses variable-length encoding. Signed int value. These more +efficiently encode negative numbers than regular int64s.
fixed32Always four bytes. More efficient than uint32 if values are often +greater than 228.
fixed64Always eight bytes. More efficient than uint64 if values are often +greater than 256.
sfixed32Always four bytes.
sfixed64Always eight bytes.
bool
stringA string must always contain UTF-8 encoded or 7-bit ASCII text, and cannot +be longer than 232.
bytesMay contain any arbitrary sequence of bytes no longer than 232.
Proto TypeC++ TypeJava/Kotlin Type[1]Python Type[3]Go TypeRuby TypeC# TypePHP TypeDart TypeRust Type
doubledoubledoublefloatfloat64Floatdoublefloatdoublef64
floatfloatfloatfloatfloat32Floatfloatfloatdoublef32
int32int32_tintintint32Fixnum or Bignum (as required)intintegerinti32
int64int64_tlongint/long[4]int64Bignumlonginteger/string[6]Int64i64
uint32uint32_tint[2]int/long[4]uint32Fixnum or Bignum (as required)uintintegerintu32
uint64uint64_tlong[2]int/long[4]uint64Bignumulonginteger/string[6]Int64u64
sint32int32_tintintint32Fixnum or Bignum (as required)intintegerinti32
sint64int64_tlongint/long[4]int64Bignumlonginteger/string[6]Int64i64
fixed32uint32_tint[2]int/long[4]uint32Fixnum or Bignum (as required)uintintegerintu32
fixed64uint64_tlong[2]int/long[4]uint64Bignumulonginteger/string[6]Int64u64
sfixed32int32_tintintint32Fixnum or Bignum (as required)intintegerinti32
sfixed64int64_tlongint/long[4]int64Bignumlonginteger/string[6]Int64i64
boolboolbooleanboolboolTrueClass/FalseClassboolbooleanboolbool
stringstringStringstr/unicode[5]stringString (UTF-8)stringstringStringProtoString
bytesstringByteStringstr (Python 2), bytes (Python 3)[]byteString (ASCII-8BIT)ByteStringstringListProtoBytes

[1] Kotlin uses the corresponding types from Java, even for unsigned +types, to ensure compatibility in mixed Java/Kotlin codebases.

[2] In Java, unsigned 32-bit and 64-bit integers are represented +using their signed counterparts, with the top bit simply being stored in the +sign bit.

[3] In all cases, setting values to a field will perform type +checking to make sure it is valid.

[4] 64-bit or unsigned 32-bit integers are always represented as long +when decoded, but can be an int if an int is given when setting the field. In +all cases, the value must fit in the type represented when set. See [2].

[5] Python strings are represented as unicode on decode but can be +str if an ASCII string is given (this is subject to change).

[6] Integer is used on 64-bit machines and string is used on 32-bit +machines.

You can find out more about how these types are encoded when you serialize your +message in +Protocol Buffer Encoding.

Default Field Values

When a message is parsed, if the encoded message bytes do not contain a +particular field, accessing that field in the parsed object returns the default +value for that field. The default values are type-specific:

  • For strings, the default value is the empty string.
  • For bytes, the default value is empty bytes.
  • For bools, the default value is false.
  • For numeric types, the default value is zero.
  • For message fields, the field is not set. Its exact value is +language-dependent. See the +generated code guide for details.
  • For enums, the default value is the first defined enum value, which must +be 0. See Enum Default Value.

The default value for repeated fields is empty (generally an empty list in the +appropriate language).

The default value for map fields is empty (generally an empty map in the +appropriate language).

Overriding Default Scalar Values

In protobuf editions, you can specify explicit default values for singular +non-message fields. For example, let’s say you want to provide a default value +of 10 for the SearchRequest.result_per_page field:

int32 result_per_page = 3 [default = 10];
+

If the sender does not specify result_per_page, the receiver will observe the +following state:

  • The result_per_page field is not present. That is, the +has_result_per_page() (hazzer method) method would return false.
  • The value of result_per_page (returned from the “getter”) is 10.

If the sender does send a value for result_per_page the default value of 10 is +ignored and the sender’s value is returned from the “getter”.

See the generated code guide for your +chosen language for more details about how defaults work in generated code.

Explicit default values cannot be specified for fields that have the +field_presence feature set to IMPLICIT.

Enumerations

When you’re defining a message type, you might want one of its fields to only +have one of a predefined list of values. For example, let’s say you want to add +a corpus field for each SearchRequest, where the corpus can be UNIVERSAL, +WEB, IMAGES, LOCAL, NEWS, PRODUCTS or VIDEO. You can do this very +simply by adding an enum to your message definition with a constant for each +possible value.

In the following example we’ve added an enum called Corpus with all the +possible values, and a field of type Corpus:

enum Corpus {
+  CORPUS_UNSPECIFIED = 0;
+  CORPUS_UNIVERSAL = 1;
+  CORPUS_WEB = 2;
+  CORPUS_IMAGES = 3;
+  CORPUS_LOCAL = 4;
+  CORPUS_NEWS = 5;
+  CORPUS_PRODUCTS = 6;
+  CORPUS_VIDEO = 7;
+}
+
+message SearchRequest {
+  string query = 1;
+  int32 page_number = 2;
+  int32 results_per_page = 3;
+  Corpus corpus = 4;
+}
+

Enum Default Value

The default value for the SearchRequest.corpus field is CORPUS_UNSPECIFIED +because that is the first value defined in the enum.

In edition 2023, the first value defined in an enum definition must have the +value zero and should have the name ENUM_TYPE_NAME_UNSPECIFIED or +ENUM_TYPE_NAME_UNKNOWN. This is because:

  • The zero value needs to be the first element for compatibility with +proto2 +semantics, where the first enum value is the default unless a different +value is explicitly specified.
  • There must be a zero value for compatibility with +proto3 +semantics, where the zero value is used as the default value for all +implicit-presence fields using this enum type.

It is also recommended that this first, default value have no semantic meaning +other than “this value was unspecified”.

The default value for an enum field like SearchRequest.corpus field can be +explicitly overridden like this:

  Corpus corpus = 4 [default = CORPUS_UNIVERSAL];
+

If an enum type has been migrated from proto2 using option features.enum_type = CLOSED; there is no restriction on the first value in the enum. It is not +recommended to change the first value of these types of enums because it will +change the default value for any fields using that enum type without an explicit +field default.

Enum Value Aliases

You can define aliases by assigning the same value to different enum constants. +To do this you need to set the allow_alias option to true. Otherwise, the +protocol buffer compiler generates a warning message when aliases are +found. Though all alias values are valid for serialization, only the first value +is used when deserializing.

enum EnumAllowingAlias {
+  option allow_alias = true;
+  EAA_UNSPECIFIED = 0;
+  EAA_STARTED = 1;
+  EAA_RUNNING = 1;
+  EAA_FINISHED = 2;
+}
+
+enum EnumNotAllowingAlias {
+  ENAA_UNSPECIFIED = 0;
+  ENAA_STARTED = 1;
+  // ENAA_RUNNING = 1;  // Uncommenting this line will cause a warning message.
+  ENAA_FINISHED = 2;
+}
+

Enum Constants

Enumerator constants must be in the range of a 32-bit integer. Since enum +values use +varint encoding on the +wire, negative values are inefficient and thus not recommended. You can define +enums within a message definition, as in the earlier example, or outside – +these enums can be reused in any message definition in your .proto file. You +can also use an enum type declared in one message as the type of a field in a +different message, using the syntax _MessageType_._EnumType_.

Language-specific Enum Implementations

When you run the protocol buffer compiler on a .proto that uses an enum, the +generated code will have a corresponding enum for Java, Kotlin, or C++, or a +special EnumDescriptor class for Python that’s used to create a set of +symbolic constants with integer values in the runtime-generated class.

During deserialization, unrecognized enum values will be preserved in the +message, though how this is represented when the message is deserialized is +language-dependent. In languages that support open enum types with values +outside the range of specified symbols, such as C++ and Go, the unknown enum +value is simply stored as its underlying integer representation. In languages +with closed enum types such as Java, a case in the enum is used to represent an +unrecognized value, and the underlying integer can be accessed with special +accessors. In either case, if the message is serialized the unrecognized value +will still be serialized with the message.

For more information about how to work with message enums in your +applications, see the generated code guide +for your chosen language.

Reserved Values

If you update an enum type by entirely removing an enum entry, or +commenting it out, future users can reuse the numeric value when making their +own updates to the type. This can cause severe issues if they later load old +instances of the same .proto, including data corruption, privacy bugs, and so +on. One way to make sure this doesn’t happen is to specify that the numeric +values (and/or names, which can also cause issues for JSON serialization) of +your deleted entries are reserved. The protocol buffer compiler will complain +if any future users try to use these identifiers. You can specify that your +reserved numeric value range goes up to the maximum possible value using the +max keyword.

enum Foo {
+  reserved 2, 15, 9 to 11, 40 to max;
+  reserved FOO, BAR;
+}
+

Note that you can’t mix field names and numeric values in the same reserved +statement.

Using Other Message Types

You can use other message types as field types. For example, let’s say you +wanted to include Result messages in each SearchResponse message – to do +this, you can define a Result message type in the same .proto and then +specify a field of type Result in SearchResponse:

message SearchResponse {
+  repeated Result results = 1;
+}
+
+message Result {
+  string url = 1;
+  string title = 2;
+  repeated string snippets = 3;
+}
+

Importing Definitions

In the earlier example, the Result message type is defined in the same file as +SearchResponse – what if the message type you want to use as a field type is +already defined in another .proto file?

You can use definitions from other .proto files by importing them. To import +another .proto’s definitions, you add an import statement to the top of your +file:

import "myproject/other_protos.proto";
+

As of Edition 2024, you can also use import option to use +custom option definitions from other .proto files. Unlike +regular imports, this only allows use of custom options definitions but not +other message or enum definitions to avoid dependencies in the generated code.

import option "myproject/other_protos.proto";
+

By default, you can use definitions only from directly imported .proto files. +However, sometimes you may need to move a .proto file to a new location. +Instead of moving the .proto file directly and updating all the call sites in +a single change, you can put a placeholder .proto file in the old location to +forward all the imports to the new location using the import public notion.

Note that the public import functionality is not available in Java, Kotlin, +TypeScript, JavaScript, or GCL.

import public dependencies can be transitively relied upon by any code +importing the proto containing the import public statement. For example:

// new.proto
+// All definitions are moved here
+
// old.proto
+// This is the proto that all clients are importing.
+import public "new.proto";
+import "other.proto";
+
// client.proto
+import "old.proto";
+// You use definitions from old.proto and new.proto, but not other.proto
+

The protocol compiler searches for imported files in a set of directories +specified on the protocol compiler command line using the -I/--proto_path +flag. If no flag was given, it looks in the directory in which the compiler was +invoked. In general you should set the --proto_path flag to the root of your +project and use fully qualified names for all imports.

Symbol Visibility

Visibility of what symbols are available or unavailable when imported by other +protos is controlled by the +features.default_symbol_visibility +feature and the +export and local keywords +which were added in Edition 2024.

Only symbols that are exported, either via the default symbol visibility or with +an export keyword, can be referenced by the importing file.

Using proto2 and proto3 Message Types

It’s possible to import +proto2 and +proto3 message types and +use them in your editions messages, and vice versa.

Nested Types

You can define and use message types inside other message types, as in the +following example – here the Result message is defined inside the +SearchResponse message:

message SearchResponse {
+  message Result {
+    string url = 1;
+    string title = 2;
+    repeated string snippets = 3;
+  }
+  repeated Result results = 1;
+}
+

If you want to reuse this message type outside its parent message type, you +refer to it as _Parent_._Type_:

message SomeOtherMessage {
+  SearchResponse.Result result = 1;
+}
+

You can nest messages as deeply as you like. In the example below, note that the +two nested types named Inner are entirely independent, since they are defined +within different messages:

message Outer {       // Level 0
+  message MiddleAA {  // Level 1
+    message Inner {   // Level 2
+      int64 ival = 1;
+      bool  booly = 2;
+    }
+  }
+  message MiddleBB {  // Level 1
+    message Inner {   // Level 2
+      int32 ival = 1;
+      bool  booly = 2;
+    }
+  }
+}
+

Updating A Message Type

If an existing message type no longer meets all your needs – for example, you’d +like the message format to have an extra field – but you’d still like to use +code created with the old format, don’t worry! It’s very simple to update +message types without breaking any of your existing code when you use the binary +wire format.

Check +Proto Best Practices and the +following rules:

Binary Wire-unsafe Changes

Wire-unsafe changes are schema changes that will break if you use parse data +that was serialized using the old schema with a parser that is using the new +schema (or vice versa). Only make wire-unsafe changes if you know that all +serializers and deserializers of the data are using the new schema.

  • Changing field numbers for any existing field is not safe.
    • Changing the field number is equivalent to deleting the field and adding +a new field with the same type. If you want to renumber a field, see the +instructions for deleting a field.
  • Moving fields into an existing oneof is not safe.

Binary Wire-safe Changes

Wire-safe changes are ones where it is fully safe to evolve the schema in this +way without risk of data loss or new parse failures.

Note that any wire-safe changes may be a breaking change to application code in +a given language. For example, adding a value to a preexisting enum would be a +compilation break for any code with an exhaustive switch on that enum. For that +reason, Google may avoid making some of these types of changes on public +messages: the AIPs contain guidance for which of these changes are safe to make +there.

  • Adding new fields is safe.
    • If you add new fields, any messages serialized by code using your “old” +message format can still be parsed by your new generated code. You +should keep in mind the default values for these elements so +that new code can properly interact with messages generated by old code. +Similarly, messages created by your new code can be parsed by your old +code: old binaries simply ignore the new field when parsing. See the +Unknown Fields section for details.
  • Removing fields is safe.
    • The same field number must not used again in your updated message type. +You may want to rename the field instead, perhaps adding the prefix +“OBSOLETE_”, or make the field number reserved, so +that future users of your .proto can’t accidentally reuse the number.
  • Adding additional values to an enum is safe.
  • Changing a single explicit presence field or extension into a member of a +new oneof is safe.
  • Changing a oneof which contains only one field to an explicit presence +field is safe.
  • Changing a field into an extension of same number and type is safe.

Binary Wire-compatible Changes (Conditionally Safe)

Unlike Wire-safe changes, wire-compatible means that the same data can be parsed +both before and after a given change. However, a parse of the data may be lossy +under this shape of change. For example, changing an int32 to an int64 is a +compatible change, but if a value larger than INT32_MAX is written, a client +that reads it as an int32 will discard the high order bits of the number.

You can make compatible changes to your schema only if you manage the roll out +to your system carefully. For example, you may change an int32 to an int64 but +ensure you continue to only write legal int32 values until the new schema is +deployed to all endpoints, and then subsequently start writing larger values +after that.

If your schema is published outside of your organization, you should generally +not make wire-compatible changes, as you cannot manage the deployment of the new +schema to know when the different range of values may be safe to use.

  • int32, uint32, int64, uint64, and bool are all compatible.
    • If a number is parsed from the wire which doesn’t fit in the +corresponding type, you will get the same effect as if you had cast the +number to that type in C++ (for example, if a 64-bit number is read as +an int32, it will be truncated to 32 bits).
  • sint32 and sint64 are compatible with each other but are not +compatible with the other integer types.
    • If the value written was between INT_MIN and INT_MAX inclusive it will +parse as the same value with either type. If an sint64 value was written +outside of that range and parsed as an sint32, the varint is truncated +to 32 bits and then zigzag decoding occurs (which will cause a different +value to be observed).
  • string and bytes are compatible as long as the bytes are valid UTF-8.
  • Embedded messages are compatible with bytes if the bytes contain an +encoded instance of the message.
  • fixed32 is compatible with sfixed32, and fixed64 with sfixed64.
  • For string, bytes, and message fields, singular is compatible with +repeated.
    • Given serialized data of a repeated field as input, clients that expect +this field to be singular will take the last input value if it’s a +primitive type field or merge all input elements if it’s a message type +field. Note that this is not generally safe for numeric types, +including bools and enums. Repeated fields of numeric types are +serialized in the +packed +format by default, which will not be parsed correctly when a singular +field is expected.
  • enum is compatible with int32, uint32, int64, and uint64
    • Be aware that client code may treat them differently when the message is +deserialized: for example, unrecognized proto3 enum values will be +preserved in the message, but how this is represented when the message +is deserialized is language-dependent.
  • Changing a field between a map<K, V> and the corresponding repeated +message field is binary compatible (see Maps, below, for the +message layout and other restrictions).
    • However, the safety of the change is application-dependent: when +deserializing and reserializing a message, clients using the repeated +field definition will produce a semantically identical result; however, +clients using the map field definition may reorder entries and drop +entries with duplicate keys.

Unknown Fields

Unknown fields are well-formed protocol buffer serialized data representing +fields that the parser does not recognize. For example, when an old binary +parses data sent by a new binary with new fields, those new fields become +unknown fields in the old binary.

Editions messages preserve unknown fields and include them during parsing and in +the serialized output, which matches proto2 and proto3 behavior.

Retaining Unknown Fields

Some actions can cause unknown fields to be lost. For example, if you do one of +the following, unknown fields are lost:

  • Serialize a proto to JSON.
  • Iterate over all of the fields in a message to populate a new message.

To avoid losing unknown fields, do the following:

  • Use binary; avoid using text formats for data exchange.
  • Use message-oriented APIs, such as CopyFrom() and MergeFrom(), to copy data +rather than copying field-by-field

TextFormat is a bit of a special case. Serializing to TextFormat prints unknown +fields using their field numbers. But parsing TextFormat data back into a binary +proto fails if there are entries that use field numbers.

Extensions

An extension is a field defined outside of its container message; usually in a +.proto file separate from the container message’s .proto file.

Why Use Extensions?

There are two main reasons to use extensions:

  • The container message’s .proto file will have fewer imports/dependencies. +This can improve build times, break circular dependencies, and otherwise +promote loose coupling. Extensions are very good for this.
  • Allow systems to attach data to a container message with minimal dependency +and coordination. Extensions are not a great solution for this because of +the limited field number space and the +Consequences of Reusing Field Numbers. If your use case +requires very low coordination for a large number of extensions, consider +using the +Any message type +instead.

Example Extension

Using an extension is a two-step process. First, in the message you want to +extend (the “container”), you must reserve a range of field numbers for +extensions. Then, in a separate file, you define the extension field itself.

Here is an example that shows how to add an extension for kitten videos to a +generic UserContent message.

Step 1: Reserve an extension range in the container message.

The container message must use the extensions keyword to reserve a range of +field numbers for others to use. It is a best practice to also add a +declaration for the specific extension you plan to add. This declaration acts +as a forward-declaration, making it easier for developers to discover extensions +and avoid reusing field numbers.

// media/user_content.proto
+edition = "2023";
+
+package media;
+
+// A container for user-created content.
+message UserContent {
+  extensions 100 to 199 [
+    declaration = {
+      number: 126,
+      full_name: ".kittens.kitten_videos",
+      type: ".kittens.Video",
+      repeated: true
+    }
+  ];
+}
+

This declaration specifies the field number, full name, type, and cardinality of +the extension that will be defined elsewhere.

Step 2: Define the extension in a separate file.

The extension itself is defined in a different .proto file, which typically +focuses on a specific feature (like kitten videos). This avoids adding a +dependency from the generic container to the specific feature.

// kittens/video_ext.proto
+edition = "2023";
+
+import "media/user_content.proto"; // Imports the container message
+import "kittens/video.proto";      // Imports the extension's message type
+
+package kittens;
+
+// This defines the extension field.
+extend media.UserContent {
+  repeated Video kitten_videos = 126;
+}
+

The extend block ties the new kitten_videos field back to the +media.UserContent message, using the field number 126 that was reserved in +the container.

There is no difference in the wire-format encoding of extension fields as +compared to a standard field with the same field number, type, and cardinality. +Therefore, it is safe to move a standard field out of its container to be an +extension or to move an extension field into its container message as a standard +field so long as the field number, type, and cardinality remain constant.

However, because extensions are defined outside of the container message, no +specialized accessors are generated to get and set specific extension fields. +For our example, the protobuf compiler will not generate AddKittenVideos() +or GetKittenVideos() accessors. Instead, extensions are accessed through +parameterized functions like: HasExtension(), ClearExtension(), +GetExtension(), MutableExtension(), and AddExtension().

In C++, it would look something like:

UserContent user_content;
+user_content.AddExtension(kittens::kitten_videos, new kittens::Video());
+assert(1 == user_content.GetRepeatedExtension(kittens::kitten_videos).size());
+user_content.GetRepeatedExtension(kittens::kitten_videos)[0];
+

Defining Extension Ranges

If you are the owner of a container message, you will need to define an +extension range for the extensions to your message.

Field numbers allocated to extension fields cannot be reused for standard +fields.

It is safe to expand an extension range after it is defined. A good default is +to allocate 1000 relatively small numbers, and densely populate that space using +extension declarations:

message ModernExtendableMessage {
+  // All extensions in this range should use extension declarations.
+  extensions 1000 to 2000 [verification = DECLARATION];
+}
+

When adding a range for extension declarations before the actual extensions, you +should add verification = DECLARATION to enforce that declarations are used +for this new range. This placeholder can be removed once an actual declaration +is added.

It is safe to split an existing extension range into separate ranges that cover +the same total range. This might be necessary for migrating a legacy message +type to +Extension Declarations. +For example, before migration, the range might be defined as:

message LegacyMessage {
+  extensions 1000 to max;
+}
+

And after migration (splitting the range) it can be:

message LegacyMessage {
+  // Legacy range that was using an unverified allocation scheme.
+  extensions 1000 to 524999999 [verification = UNVERIFIED];
+  // Current range that uses extension declarations.
+  extensions 525000000 to max  [verification = DECLARATION];
+}
+

It is not safe to increase the start field number nor decrease the end field +number to move or shrink an extension range. These changes can invalidate an +existing extension.

Prefer using field numbers 1 to 15 for standard fields that are populated in +most instances of your proto. It is not recommended to use these numbers for +extensions.

If your numbering convention might involve extensions having very large field +numbers, you can specify that your extension range goes up to the maximum +possible field number using the max keyword:

message Foo {
+  extensions 1000 to max;
+}
+

max is 229 - 1, or 536,870,911.

Choosing Extension Numbers

Extensions are just fields that can be specified outside of their container +messages. All the same rules for Assigning Field Numbers apply to +extension field numbers. The same +Consequences of Reusing Field Numbers also apply to reusing +extension field numbers.

Choosing unique extension field numbers is simple if the container message uses +extension declarations. +When defining a new extension, choose the lowest field number above all other +declarations from the highest extension range defined in the container message. +For example, if a container message is defined like this:

message Container {
+  // Legacy range that was using an unverified allocation scheme
+  extensions 1000 to 524999999;
+  // Current range that uses extension declarations. (highest extension range)
+  extensions 525000000 to max  [
+    declaration = {
+      number: 525000001,
+      full_name: ".bar.baz_ext",
+      type: ".bar.Baz"
+    }
+    // 525,000,002 is the lowest field number above all other declarations
+  ];
+}
+

The next extension of Container should add a new declaration with the number +525000002.

Unverified Extension Number Allocation (not recommended)

The owner of a container message may choose to forgo extension declarations in +favor of their own unverified extension number allocation strategy.

An unverified allocation scheme uses a mechanism external to the protobuf +ecosystem to allocate extension field numbers within the selected extension +range. One example could be using a monorepo’s commit number. This system is +“unverified” from the protobuf compiler’s point of view since there is no way to +check that an extension is using a properly acquired extension field number.

The benefit of an unverified system over a verified system like extension +declarations is the ability to define an extension without coordinating with the +container message owner.

The downside of an unverified system is that the protobuf compiler cannot +protect participants from reusing extension field numbers.

Unverified extension field number allocation strategies are not recommended +because the Consequences of Reusing Field Numbers fall on all +extenders of a message (not just the developer that didn’t follow the +recommendations). If your use case requires very low coordination, consider +using the +Any message +instead.

Unverified extension field number allocation strategies are limited to the range +1 to 524,999,999. Field numbers 525,000,000 and above can only be used with +extension declarations.

Specifying Extension Types

Extensions can be of any field type except oneofs and maps.

Nested Extensions (not recommended)

You can declare extensions in the scope of another message:

import "common/user_profile.proto";
+
+package puppies;
+
+message Photo {
+  extend common.UserProfile {
+    int32 likes_count = 111;
+  }
+  ...
+}
+

In this case, the C++ code to access this extension is:

UserProfile user_profile;
+user_profile.SetExtension(puppies::Photo::likes_count, 42);
+

In other words, the only effect is that likes_count is defined within the +scope of puppies.Photo.

This is a common source of confusion: Declaring an extend block nested inside +a message type does not imply any relationship between the outer type and the +extended type. In particular, the earlier example does not mean that Photo +is any sort of subclass of UserProfile. All it means is that the symbol +likes_count is declared inside the scope of Photo; it’s simply a static +member.

A common pattern is to define extensions inside the scope of the extension’s +field type - for example, here’s an extension to media.UserContent of type +puppies.Photo, where the extension is defined as part of Photo:

import "media/user_content.proto";
+
+package puppies;
+
+message Photo {
+  extend media.UserContent {
+    Photo puppy_photo = 127;
+  }
+  ...
+}
+

However, there is no requirement that an extension with a message type be +defined inside that type. You can also use the standard definition pattern:

import "media/user_content.proto";
+
+package puppies;
+
+message Photo {
+  ...
+}
+
+// This can even be in a different file.
+extend media.UserContent {
+  Photo puppy_photo = 127;
+}
+

This standard (file-level) syntax is preferred to avoid confusion. The +nested syntax is often mistaken for subclassing by users who are not already +familiar with extensions.

Any

The Any message type lets you use messages as embedded types without having +their .proto definition. An Any contains an arbitrary serialized message as +bytes, along with a URL that acts as a globally unique identifier for and +resolves to that message’s type. To use the Any type, you need to +import google/protobuf/any.proto.

import "google/protobuf/any.proto";
+
+message ErrorStatus {
+  string message = 1;
+  repeated google.protobuf.Any details = 2;
+}
+

The default type URL for a given message type is +type.googleapis.com/_packagename_._messagename_.

Different language implementations will support runtime library helpers to pack +and unpack Any values in a typesafe manner – for example, in Java, the Any +type will have special pack() and unpack() accessors, while in C++ there are +PackFrom() and UnpackTo() methods:

// Storing an arbitrary message type in Any.
+NetworkErrorDetails details = ...;
+ErrorStatus status;
+status.add_details()->PackFrom(details);
+
+// Reading an arbitrary message from Any.
+ErrorStatus status = ...;
+for (const google::protobuf::Any& detail : status.details()) {
+  if (detail.Is<NetworkErrorDetails>()) {
+    NetworkErrorDetails network_error;
+    detail.UnpackTo(&network_error);
+    ... processing network_error ...
+  }
+}
+

If you want to limit contained messages to a small number of types and to +require permission before adding new types to the list, consider using +extensions with +extension declarations +instead of Any message types.

Oneof

If you have a message with many singular fields and where at most one field will +be set at the same time, you can enforce this behavior and save memory by using +the oneof feature.

Oneof fields are like singular fields except all the fields in a oneof share +memory, and at most one field can be set at the same time. Setting any member of +the oneof automatically clears all the other members. You can check which value +in a oneof is set (if any) using a special case() or WhichOneof() method, +depending on your chosen language.

Note that if multiple values are set, the last set value as determined by the +order in the proto will overwrite all previous ones.

Field numbers for oneof fields must be unique within the enclosing message.

Using Oneof

To define a oneof in your .proto you use the oneof keyword followed by your +oneof name, in this case test_oneof:

message SampleMessage {
+  oneof test_oneof {
+    string name = 4;
+    SubMessage sub_message = 9;
+  }
+}
+

You then add your oneof fields to the oneof definition. You can add fields of +any type, except map fields and repeated fields. If you need to add a +repeated field to a oneof, you can use a message containing the repeated field.

In your generated code, oneof fields have the same getters and setters as +regular fields. You also get a special method for checking which value (if any) +in the oneof is set. You can find out more about the oneof API for your chosen +language in the relevant API reference.

Oneof Features

  • Setting a oneof field will automatically clear all other members of the +oneof. So if you set several oneof fields, only the last field you set +will still have a value.

    SampleMessage message;
    +message.set_name("name");
    +CHECK(message.has_name());
    +// Calling mutable_sub_message() will clear the name field and will set
    +// sub_message to a new instance of SubMessage with none of its fields set.
    +message.mutable_sub_message();
    +CHECK(!message.has_name());
    +
  • If the parser encounters multiple members of the same oneof on the wire, +only the last member seen is used in the parsed message. When parsing data +on the wire, starting at the beginning of the bytes, evaluate the next +value, and apply the following parsing rules:

    • First, check if a different field in the same oneof is currently set, +and if so clear it.

    • Then apply the contents as though the field was not in a oneof:

      • A primitive will overwrite any value already set
      • A message will merge into any value already set
  • Extensions are not supported for oneof.

  • A oneof cannot be repeated.

  • Reflection APIs work for oneof fields.

  • If you set a oneof field to the default value (such as setting an int32 +oneof field to 0), the “case” of that oneof field will be set, and the value +will be serialized on the wire.

  • If you’re using C++, make sure your code doesn’t cause memory crashes. The +following sample code will crash because sub_message was already deleted +by calling the set_name() method.

    SampleMessage message;
    +SubMessage* sub_message = message.mutable_sub_message();
    +message.set_name("name");      // Will delete sub_message
    +sub_message->set_...            // Crashes here
    +
  • Again in C++, if you Swap() two messages with oneofs, each message will +end up with the other’s oneof case: in the example below, msg1 will have a +sub_message and msg2 will have a name.

    SampleMessage msg1;
    +msg1.set_name("name");
    +SampleMessage msg2;
    +msg2.mutable_sub_message();
    +msg1.swap(&msg2);
    +CHECK(msg1.has_sub_message());
    +CHECK(msg2.has_name());
    +

Backwards-compatibility issues

Be careful when adding or removing oneof fields. If checking the value of a +oneof returns None/NOT_SET, it could mean that the oneof has not been set or +it has been set to a field in a different version of the oneof. There is no way +to tell the difference, since there’s no way to know if an unknown field on the +wire is a member of the oneof.

Tag Reuse Issues

  • Move singular fields into or out of a oneof: You may lose some of your +information (some fields will be cleared) after the message is serialized +and parsed. However, you can safely move a single field into a new oneof +and may be able to move multiple fields if it is known that only one is ever +set. See Updating A Message Type for further details.
  • Delete a oneof field and add it back: This may clear your currently set +oneof field after the message is serialized and parsed.
  • Split or merge oneof: This has similar issues to moving singular fields.

Maps

If you want to create an associative map as part of your data definition, +protocol buffers provides a handy shortcut syntax:

map<key_type, value_type> map_field = N;
+

…where the key_type can be any integral or string type (so, any +scalar type except for floating point types and bytes). Note that +neither enum nor proto messages are valid for key_type. +The value_type can be any type except another map.

So, for example, if you wanted to create a map of projects where each Project +message is associated with a string key, you could define it like this:

map<string, Project> projects = 3;
+

Maps Features

  • Extensions are not supported for maps.
  • Map fields cannot be repeated.
  • Wire format ordering and map iteration ordering of map values is undefined, +so you cannot rely on your map items being in a particular order.
  • When generating text format for a .proto, maps are sorted by key. Numeric +keys are sorted numerically.
  • When parsing from the wire or when merging, if there are duplicate map keys +the last key seen is used. When parsing a map from text format, parsing may +fail if there are duplicate keys.
  • If you provide a key but no value for a map field, the behavior when the +field is serialized is language-dependent. In C++, Java, Kotlin, and Python +the default value for the type is serialized, while in other languages +nothing is serialized.
  • No symbol FooEntry can exist in the same scope as a map foo, because +FooEntry is already used by the implementation of the map.

The generated map API is currently available for all supported languages. You +can find out more about the map API for your chosen language in the relevant +API reference.

Backwards Compatibility

The map syntax is equivalent to the following on the wire, so protocol buffers +implementations that do not support maps can still handle your data:

message MapFieldEntry {
+  key_type key = 1;
+  value_type value = 2;
+}
+
+repeated MapFieldEntry map_field = N;
+

Any protocol buffers implementation that supports maps must both produce and +accept data that can be accepted by the earlier definition.

Packages

You can add an optional package specifier to a .proto file to prevent name +clashes between protocol message types.

package foo.bar;
+message Open { ... }
+

You can then use the package specifier when defining fields of your message +type:

message Foo {
+  ...
+  foo.bar.Open open = 1;
+  ...
+}
+

The way a package specifier affects the generated code depends on your chosen +language:

  • In C++ the generated classes are wrapped inside a C++ namespace. For +example, Open would be in the namespace foo::bar.
  • In Java and Kotlin, the package is used as the Java package, unless +you explicitly provide an option java_package in your .proto file.
  • In Python, the package directive is ignored, since Python modules are +organized according to their location in the file system.
  • In Go, the package directive is ignored, and the generated .pb.go +file is in the package named after the corresponding go_proto_library +Bazel rule. For open source projects, you must provide either a go_package option or set the Bazel -M flag.
  • In Ruby, the generated classes are wrapped inside nested Ruby +namespaces, converted to the required Ruby capitalization style (first +letter capitalized; if the first character is not a letter, PB_ is +prepended). For example, Open would be in the namespace Foo::Bar.
  • In PHP the package is used as the namespace after converting to +PascalCase, unless you explicitly provide an option php_namespace in your +.proto file. For example, Open would be in the namespace Foo\Bar.
  • In C# the package is used as the namespace after converting to +PascalCase, unless you explicitly provide an option csharp_namespace in +your .proto file. For example, Open would be in the namespace Foo.Bar.

Note that even when the package directive does not directly affect the +generated code, for example in Python, it is still strongly recommended to +specify the package for the .proto file, as otherwise it may lead to naming +conflicts in descriptors and make the proto not portable for other languages.

Packages and Name Resolution

Type name resolution in the protocol buffer language works like C++: first the +innermost scope is searched, then the next-innermost, and so on, with each +package considered to be “inner” to its parent package. A leading ‘.’ (for +example, .foo.bar.Baz) means to start from the outermost scope instead.

The protocol buffer compiler resolves all type names by parsing the imported +.proto files. The code generator for each language knows how to refer to each +type in that language, even if it has different scoping rules.

Defining Services

If you want to use your message types with an RPC (Remote Procedure Call) +system, you can define an RPC service interface in a .proto file and the +protocol buffer compiler will generate service interface code and stubs in your +chosen language. So, for example, if you want to define an RPC service with a +method that takes your SearchRequest and returns a SearchResponse, you can +define it in your .proto file as follows:

service SearchService {
+  rpc Search(SearchRequest) returns (SearchResponse);
+}
+

The most straightforward RPC system to use with protocol buffers is +gRPC: a language- and platform-neutral open source RPC system +developed at Google. gRPC works particularly well with protocol buffers and lets +you generate the relevant RPC code directly from your .proto files using a +special protocol buffer compiler plugin.

If you don’t want to use gRPC, it’s also possible to use protocol buffers with +your own RPC implementation. You can find out more about this in the +Proto2 Language Guide.

There are also a number of ongoing third-party projects to develop RPC +implementations for Protocol Buffers. For a list of links to projects we know +about, see the +third-party add-ons wiki page.

JSON Mapping

The standard protobuf binary wire format is the preferred serialization format +for communication between two systems that use protobufs. For communicating with +systems that use JSON rather than protobuf wire format, Protobuf supports a +canonical encoding in +ProtoJSON.

Options

Individual declarations in a .proto file can be annotated with a number of +options. Options do not change the overall meaning of a declaration, but may +affect the way it is handled in a particular context. The complete list of +available options is defined in /google/protobuf/descriptor.proto.

Some options are file-level options, meaning they should be written at the +top-level scope, not inside any message, enum, or service definition. Some +options are message-level options, meaning they should be written inside message +definitions. Some options are field-level options, meaning they should be +written inside field definitions. Options can also be written on enum types, +enum values, oneof fields, service types, and service methods; however, no +useful options currently exist for any of these.

Here are a few of the most commonly used options:

  • java_package (file option): The package you want to use for your generated +Java/Kotlin classes. If no explicit java_package option is given in the +.proto file, then by default the proto package (specified using the +“package” keyword in the .proto file) will be used. However, proto +packages generally do not make good Java packages since proto packages are +not expected to start with reverse domain names. If not generating Java or +Kotlin code, this option has no effect.

    option java_package = "com.example.foo";
    +
  • java_outer_classname (file option): The class name (and hence the file +name) for the wrapper Java class you want to generate. If no explicit +java_outer_classname is specified in the .proto file, the class name +will be constructed by converting the .proto file name to camel-case (so +foo_bar.proto becomes FooBar.java). If the java_multiple_files option +is disabled, then all other classes/enums/etc. generated for the .proto +file will be generated within this outer wrapper Java class as nested +classes/enums/etc. If not generating Java code, this option has no effect.

    option java_outer_classname = "Ponycopter";
    +
  • java_multiple_files (file option): If false, only a single .java file +will be generated for this .proto file, and all the Java +classes/enums/etc. generated for the top-level messages, services, and +enumerations will be nested inside of an outer class (see +java_outer_classname). If true, separate .java files will be generated +for each of the Java classes/enums/etc. generated for the top-level +messages, services, and enumerations, and the wrapper Java class generated +for this .proto file won’t contain any nested classes/enums/etc. This is a +Boolean option which defaults to false. If not generating Java code, this +option has no effect. This was removed in edition 2024 and replaced with +features.(pb.java).nest_in_file_class

    option java_multiple_files = true;
    +
  • optimize_for (file option): Can be set to SPEED, CODE_SIZE, or +LITE_RUNTIME. This affects the C++ and Java code generators (and possibly +third-party generators) in the following ways:

    • SPEED (default): The protocol buffer compiler will generate code for +serializing, parsing, and performing other common operations on your +message types. This code is highly optimized.
    • CODE_SIZE: The protocol buffer compiler will generate minimal classes +and will rely on shared, reflection-based code to implement +serialization, parsing, and various other operations. The generated code +will thus be much smaller than with SPEED, but operations will be +slower. Classes will still implement exactly the same public API as they +do in SPEED mode. This mode is most useful in apps that contain a very +large number of .proto files and do not need all of them to be +blindingly fast.
    • LITE_RUNTIME: The protocol buffer compiler will generate classes that +depend only on the “lite” runtime library (libprotobuf-lite instead of +libprotobuf). The lite runtime is much smaller than the full library +(around an order of magnitude smaller) but omits certain features like +descriptors and reflection. This is particularly useful for apps running +on constrained platforms like mobile phones. The compiler will still +generate fast implementations of all methods as it does in SPEED mode. +Generated classes will only implement the MessageLite interface in +each language, which provides only a subset of the methods of the full +Message interface.
    option optimize_for = CODE_SIZE;
    +
  • cc_generic_services, java_generic_services, py_generic_services (file +options): Generic services are deprecated. Whether or not the protocol +buffer compiler should generate abstract service code based on +services definitions in C++, Java, and Python, respectively. +For legacy reasons, these default to true. However, as of version 2.3.0 +(January 2010), it is considered preferable for RPC implementations to +provide +code generator plugins +to generate code more specific to each system, rather than rely on the +“abstract” services.

    // This file relies on plugins to generate service code.
    +option cc_generic_services = false;
    +option java_generic_services = false;
    +option py_generic_services = false;
    +
  • cc_enable_arenas (file option): Enables +arena allocation for C++ +generated code.

  • objc_class_prefix (file option): Sets the Objective-C class prefix which +is prepended to all Objective-C generated classes and enums from this +.proto. There is no default. You should use prefixes that are between 3-5 +uppercase characters as +recommended by Apple. +Note that all 2 letter prefixes are reserved by Apple.

  • packed (field option): In protobuf editions, this option is locked to +true. To use unpacked wireformat, you can override this option using an +editions feature. This provides compatibility with parsers prior to version +2.3.0 (rarely needed) as shown in the following example:

    repeated int32 samples = 4 [features.repeated_field_encoding = EXPANDED];
    +
  • deprecated (field option): If set to true, indicates that the field is +deprecated and should not be used by new code. In most languages this has no +actual effect. In Java, this becomes a @Deprecated annotation. For C++, +clang-tidy will generate warnings whenever deprecated fields are used. In +the future, other language-specific code generators may generate deprecation +annotations on the field’s accessors, which will in turn cause a warning to +be emitted when compiling code which attempts to use the field. If the field +is not used by anyone and you want to prevent new users from using it, +consider replacing the field declaration with a reserved +statement.

    int32 old_field = 6 [deprecated = true];
    +

Enum Value Options

Enum value options are supported. You can use the deprecated option to +indicate that a value shouldn’t be used anymore. You can also create custom +options using extensions.

The following example shows the syntax for adding these options:

import "google/protobuf/descriptor.proto";
+
+extend google.protobuf.EnumValueOptions {
+  string string_name = 123456789;
+}
+
+enum Data {
+  DATA_UNSPECIFIED = 0;
+  DATA_SEARCH = 1 [deprecated = true];
+  DATA_DISPLAY = 2 [
+    (string_name) = "display_value"
+  ];
+}
+

The C++ code to read the string_name option might look something like this:

const absl::string_view foo = proto2::GetEnumDescriptor<Data>()
+    ->FindValueByName("DATA_DISPLAY")->options().GetExtension(string_name);
+

See Custom Options to see how to apply custom options to enum +values and to fields.

Custom Options

Protocol Buffers also allows you to define and use your own options. Note that +this is an advanced feature which most people don’t need. If you do think +you need to create your own options, see the +Proto2 Language Guide +for details. Note that creating custom options uses +extensions.

Starting in edition 2024, import custom option definitions using import option. See Importing.

Option Retention

Options have a notion of retention, which controls whether an option is +retained in the generated code. Options have runtime retention by default, +meaning that they are retained in the generated code and are thus visible at +runtime in the generated descriptor pool. However, you can set retention = RETENTION_SOURCE to specify that an option (or field within an option) must not +be retained at runtime. This is called source retention.

Option retention is an advanced feature that most users should not need to worry +about, but it can be useful if you would like to use certain options without +paying the code size cost of retaining them in your binaries. Options with +source retention are still visible to protoc and protoc plugins, so code +generators can use them to customize their behavior.

Retention can be set directly on an option, like this:

extend google.protobuf.FileOptions {
+  int32 source_retention_option = 1234
+      [retention = RETENTION_SOURCE];
+}
+

It can also be set on a plain field, in which case it takes effect only when +that field appears inside an option:

message OptionsMessage {
+  int32 source_retention_field = 1 [retention = RETENTION_SOURCE];
+}
+

You can set retention = RETENTION_RUNTIME if you like, but this has no effect +since it is the default behavior. When a message field is marked +RETENTION_SOURCE, its entire contents are dropped; fields inside it cannot +override that by trying to set RETENTION_RUNTIME.

Option Targets

Fields have a targets option which controls the types of entities that the +field may apply to when used as an option. For example, if a field has +targets = TARGET_TYPE_MESSAGE then that field cannot be set in a custom option +on an enum (or any other non-message entity). Protoc enforces this and will +raise an error if there is a violation of the target constraints.

At first glance, this feature may seem unnecessary given that every custom +option is an extension of the options message for a specific entity, which +already constrains the option to that one entity. However, option targets are +useful in the case where you have a shared options message applied to multiple +entity types and you want to control the usage of individual fields in that +message. For example:

message MyOptions {
+  string file_only_option = 1 [targets = TARGET_TYPE_FILE];
+  int32 message_and_enum_option = 2 [targets = TARGET_TYPE_MESSAGE,
+                                     targets = TARGET_TYPE_ENUM];
+}
+
+extend google.protobuf.FileOptions {
+  MyOptions file_options = 50000;
+}
+
+extend google.protobuf.MessageOptions {
+  MyOptions message_options = 50000;
+}
+
+extend google.protobuf.EnumOptions {
+  MyOptions enum_options = 50000;
+}
+
+// OK: this field is allowed on file options
+option (file_options).file_only_option = "abc";
+
+message MyMessage {
+  // OK: this field is allowed on both message and enum options
+  option (message_options).message_and_enum_option = 42;
+}
+
+enum MyEnum {
+  MY_ENUM_UNSPECIFIED = 0;
+  // Error: file_only_option cannot be set on an enum.
+  option (enum_options).file_only_option = "xyz";
+}
+

Generating Your Classes

To generate the Java, Kotlin, Python, C++, Go, Ruby, Objective-C, or C# code +that you need to work with the message types defined in a .proto file, you +need to run the protocol buffer compiler protoc on the .proto file. If you +haven’t installed the compiler, +download the package and follow the +instructions in the README. For Go, you also need to install a special code +generator plugin for the compiler; you can find this and installation +instructions in the golang/protobuf +repository on GitHub.

The Protocol Compiler is invoked as follows:

protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR --go_out=DST_DIR --ruby_out=DST_DIR --objc_out=DST_DIR --csharp_out=DST_DIR path/to/file.proto
+
  • IMPORT_PATH specifies a directory in which to look for .proto files when +resolving import directives. If omitted, the current directory is used. +Multiple import directories can be specified by passing the --proto_path +option multiple times; they will be searched in order. -I=_IMPORT_PATH_ +can be used as a short form of --proto_path.

Note: File paths relative to their proto_path must be globally unique in a +given binary. For example, if you have proto/lib1/data.proto and +proto/lib2/data.proto, those two files cannot be used together with +-I=proto/lib1 -I=proto/lib2 because it would be ambiguous which file import "data.proto" will mean. Instead -Iproto/ should be used and the global names +will be lib1/data.proto and lib2/data.proto.

If you are publishing a library and other users may use your messages directly, +you should include a unique library name in the path that they are expected to +be used under to avoid file name collisions. If you have multiple directories in +one project, it is best practice to prefer setting one -I to a top level +directory of the project.

  • You can provide one or more output directives:

    As an extra convenience, if the DST_DIR ends in .zip or .jar, the +compiler will write the output to a single ZIP-format archive file with the +given name. .jar outputs will also be given a manifest file as required by +the Java JAR specification. Note that if the output archive already exists, +it will be overwritten.

  • You must provide one or more .proto files as input. Multiple .proto +files can be specified at once. Although the files are named relative to the +current directory, each file must reside in one of the IMPORT_PATHs so +that the compiler can determine its canonical name.

File location

Prefer not to put .proto files in the same +directory as other language sources. Consider +creating a subpackage proto for .proto files, under the root package for +your project.

Location Should be Language-agnostic

When working with Java code, it’s handy to put related .proto files in the +same directory as the Java source. However, if any non-Java code ever uses the +same protos, the path prefix will no longer make sense. So in +general, put the protos in a related language-agnostic directory such as +//myteam/mypackage.

The exception to this rule is when it’s clear that the protos will be used only +in a Java context, such as for testing.

Supported Platforms

For information about:

\ No newline at end of file diff --git a/programming-guides/encoding/index.html b/programming-guides/encoding/index.html new file mode 100644 index 000000000..88d85de76 --- /dev/null +++ b/programming-guides/encoding/index.html @@ -0,0 +1,264 @@ +Encoding | Protocol Buffers Documentation +

Encoding

Explains how Protocol Buffers encodes data to files or to the wire.

This document describes the protocol buffer wire format, which defines the +details of how your message is sent on the wire and how much space it consumes +on disk. You probably don’t need to understand this to use protocol buffers in +your application, but it’s useful information for doing optimizations.

If you already know the concepts but want a reference, skip to the +Condensed reference card section.

Protoscope is a very simple +language for describing snippets of the low-level wire format, which we’ll use +to provide a visual reference for the encoding of various messages. Protoscope’s +syntax consists of a sequence of tokens that each encode down to a specific +byte sequence.

For example, backticks denote a raw hex literal, like `70726f746f6275660a`. This encodes into the exact bytes denoted as hex in the literal. Quotes +denote UTF-8 strings, like "Hello, Protobuf!". This literal is synonymous with +`48656c6c6f2c2050726f746f62756621` (which, if you observe closely, is +composed of ASCII bytes). We’ll introduce more of the Protoscope language as we +discuss aspects of the wire format.

The Protoscope tool can also dump encoded protocol buffers as text. See +https://github.com/protocolbuffers/protoscope/tree/main/testdata for examples.

All examples in this topic assume that you are using Edition 2023 or later.

A Simple Message

Let’s say you have the following very simple message definition:

message Test1 {
+  int32 a = 1;
+}
+

In an application, you create a Test1 message and set a to 150. You then +serialize the message to an output stream. If you were able to examine the +encoded message, you’d see three bytes:

08 96 01
+

So far, so small and numeric – but what does it mean? If you use the Protoscope +tool to dump those bytes, you’d get something like 1: 150. How does it know +this is the contents of the message?

Base 128 Varints

Variable-width integers, or varints, are at the core of the wire format. They +allow encoding unsigned 64-bit integers using anywhere between one and ten +bytes, with small values using fewer bytes.

Each byte in the varint has a continuation bit that indicates if the byte that +follows it is part of the varint. This is the most significant bit (MSB) of +the byte (sometimes also called the sign bit). The lower 7 bits are a payload; +the resulting integer is built by appending together the 7-bit payloads of its +constituent bytes.

So, for example, here is the number 1, encoded as `01` – it’s a single +byte, so the MSB is not set:

0000 0001
+^ msb
+

And here is 150, encoded as `9601` – this is a bit more complicated:

10010110 00000001
+^ msb    ^ msb
+

How do you figure out that this is 150? First you drop the MSB from each byte, +as this is just there to tell us whether we’ve reached the end of the number (as +you can see, it’s set in the first byte as there is more than one byte in the +varint). These 7-bit payloads are in little-endian order. Convert to big-endian +order, concatenate, and interpret as an unsigned 64-bit integer:

10010110 00000001        // Original inputs.
+ 0010110  0000001        // Drop continuation bits.
+ 0000001  0010110        // Convert to big-endian.
+   00000010010110        // Concatenate.
+ 128 + 16 + 4 + 2 = 150  // Interpret as an unsigned 64-bit integer.
+

Because varints are so crucial to protocol buffers, in protoscope syntax, we +refer to them as plain integers. 150 is the same as `9601`.

Message Structure

A protocol buffer message is a series of key-value pairs. The binary version of +a message just uses the field’s number as the key – the name and declared type +for each field can only be determined on the decoding end by referencing the +message type’s definition (i.e. the .proto file). Protoscope does not have +access to this information, so it can only provide the field numbers.

When a message is encoded, each key-value pair is turned into a record +consisting of the field number, a wire type and a payload. The wire type tells +the parser how big the payload after it is. This allows old parsers to skip over +new fields they don’t understand. This type of scheme is sometimes called +Tag-Length-Value, +or TLV.

There are six wire types: VARINT, I64, LEN, SGROUP, EGROUP, and I32

IDNameUsed For
0VARINTint32, int64, uint32, uint64, sint32, sint64, bool, enum
1I64fixed64, sfixed64, double
2LENstring, bytes, embedded messages, packed repeated fields
3SGROUPgroup start (deprecated)
4EGROUPgroup end (deprecated)
5I32fixed32, sfixed32, float

The “tag” of a record is encoded as a varint formed from the field number and +the wire type via the formula (field_number << 3) | wire_type. In other words, +after decoding the varint representing a field, the low 3 bits tell us the wire +type, and the rest of the integer tells us the field number.

Now let’s look at our simple example again. You now know that the first number +in the stream is always a varint key, and here it’s `08`, or (dropping the +MSB):

000 1000
+

You take the last three bits to get the wire type (0) and then right-shift by +three to get the field number (1). Protoscope represents a tag as an integer +followed by a colon and the wire type, so we can write the above bytes as +1:VARINT.

Because the wire type is 0, or VARINT, we know that we need to decode a varint +to get the payload. As we saw above, the bytes `9601` varint-decode to +150, giving us our record. We can write it in Protoscope as 1:VARINT 150.

Protoscope can infer the type for a tag if there is whitespace after the :. It +does so by looking ahead at the next token and guessing what you meant (the +rules are documented in detail in +Protoscope’s language.txt). +For example, in 1: 150, there is a varint immediately after the untyped tag, +so Protoscope infers its type to be VARINT. If you wrote 2: {}, it would see +the { and guess LEN; if you wrote 3: 5i32 it would guess I32, and so on.

More Integer Types

Bools and Enums

Bools and enums are both encoded as if they were int32s. Bools, in particular, +always encode as either `00` or `01`. In Protoscope, false and +true are aliases for these byte strings.

Signed Integers

As you saw in the previous section, all the protocol buffer types associated +with wire type 0 are encoded as varints. However, varints are unsigned, so the +different signed types, sint32 and sint64 vs int32 or int64, encode +negative integers differently.

The intN types encode negative numbers as two’s complement, which means that, +as unsigned, 64-bit integers, they have their highest bit set. As a result, this +means that all ten bytes must be used. For example, -2 is converted by +protoscope into

11111110 11111111 11111111 11111111 11111111
+11111111 11111111 11111111 11111111 00000001
+

This is the two’s complement of 2, defined in unsigned arithmetic as ~0 - 2 + 1, where ~0 is the all-ones 64-bit integer. It is a useful exercise to +understand why this produces so many ones.

sintN uses the “ZigZag” encoding instead of two’s complement to encode +negative integers. Positive integers p are encoded as 2 * p (the even +numbers), while negative integers n are encoded as 2 * |n| - 1 (the odd +numbers). The encoding thus “zig-zags” between positive and negative numbers. +For example:

Signed OriginalEncoded As
00
-11
12
-23
0x7fffffff0xfffffffe
-0x800000000xffffffff

In other words, each value n is encoded using

(n << 1) ^ (n >> 31)
+

for sint32s, or

(n << 1) ^ (n >> 63)
+

for the 64-bit version.

When the sint32 or sint64 is parsed, its value is decoded back to the +original, signed version.

In protoscope, suffixing an integer with a z will make it encode as ZigZag. +For example, -500z is the same as the varint 999.

Non-varint Numbers

Non-varint numeric types are simple. double and fixed64 have wire type +I64, which tells the parser to expect a fixed eight-byte lump of data. +double values are encoded in IEEE 754 double-precision format. We can specify +a double record by writing 5: 25.4, or a fixed64 record with 6: 200i64.

Similarly float and fixed32 have wire type I32, which tells it to expect +four bytes instead. float values are encoded in IEEE 754 single-precision +format. The syntax for these consists of adding an i32 suffix. 25.4i32 will +emit four bytes, as will 200i32. Tag types are inferred as I32.

Length-Delimited Records

Length prefixes are another major concept in the wire format. The LEN wire +type has a dynamic length, specified by a varint immediately after the tag, +which is followed by the payload as usual.

Consider this message schema:

message Test2 {
+  string b = 2;
+}
+

A record for the field b is a string, and strings are LEN-encoded. If we set +b to "testing", we encoded as a LEN record with field number 2 containing +the ASCII string "testing". The result is `120774657374696e67`. Breaking +up the bytes,

12 07 [74 65 73 74 69 6e 67]
+

we see that the tag, `12`, is 00010 010, or 2:LEN. The byte that +follows is the int32 varint 7, and the next seven bytes are the UTF-8 +encoding of "testing". The int32 varint means that the max length of a string +is 2GB.

In Protoscope, this is written as 2:LEN 7 "testing". However, it can be +inconvenient to repeat the length of the string (which, in Protoscope text, is +already quote-delimited). Wrapping Protoscope content in braces will generate a +length prefix for it: {"testing"} is a shorthand for 7 "testing". {} is +always inferred by fields to be a LEN record, so we can write this record +simply as 2: {"testing"}.

bytes fields are encoded in the same way.

Submessages

Submessage fields also use the LEN wire type. Here’s a message definition with +an embedded message of our original example message, Test1:

message Test3 {
+  Test1 c = 3;
+}
+

If Test1’s a field (i.e., Test3’s c.a field) is set to 150, we get ``1a03089601``. Breaking it up:

 1a 03 [08 96 01]
+

The last three bytes (in []) are exactly the same ones from our +very first example. These bytes are preceded by a LEN-typed tag, +and a length of 3, exactly the same way as strings are encoded.

In Protoscope, submessages are quite succinct. ``1a03089601`` can be written +as 3: {1: 150}.

Missing Elements

Missing fields are easy to encode: we just leave out the record if +it’s not present. This means that “huge” protos with only a few fields set are +quite sparse.

Repeated Elements

Starting in Edition 2023, repeated fields of a primitive type +(any scalar type +that is not string or bytes) are “packed” by default.

Packed repeated fields, instead of being encoded as one +record per entry, are encoded as a single LEN record that contains each +element concatenated. To decode, elements are decoded from the LEN record one +by one until the payload is exhausted. The start of the next element is +determined by the length of the previous, which itself depends on the type of +the field. Thus, if we have:

message Test4 {
+  string d = 4;
+  repeated int32 e = 6;
+}
+

and we construct a Test4 message with d set to "hello", and e set to +1, 2, and 3, this could be encoded as `3206038e029ea705`, or +written out as Protoscope,

4: {"hello"}
+6: {3 270 86942}
+

However, if the repeated field is set to expanded (overriding the default packed +state) or is not packable (strings and messages) then an entry for each +individual value is encoded. Also, records for e do not need to appear +consecutively, and can be interleaved with other fields; only the order of +records for the same field with respect to each other is preserved. Thus, this +could look like the following:

6: 1
+6: 2
+4: {"hello"}
+6: 3
+

Only repeated fields of primitive numeric types can be declared “packed”. These +are types that would normally use the VARINT, I32, or I64 wire types.

Note that although there’s usually no reason to encode more than one key-value +pair for a packed repeated field, parsers must be prepared to accept multiple +key-value pairs. In this case, the payloads should be concatenated. Each pair +must contain a whole number of elements. The following is a valid encoding of +the same message above that parsers must accept:

6: {3 270}
+6: {86942}
+

Protocol buffer parsers must be able to parse repeated fields that were compiled +as packed as if they were not packed, and vice versa. This permits adding +[packed=true] to existing fields in a forward- and backward-compatible way.

Oneofs

Oneof fields are +encoded the same as if the fields were not in a oneof. The rules that apply to +oneofs are independent of how they are represented on the wire.

Last One Wins

Normally, an encoded message would never have more than one instance of a +non-repeated field. However, parsers are expected to handle the case in which +they do. For numeric types and strings, if the same field appears multiple +times, the parser accepts the last value it sees. For embedded message fields, +the parser merges multiple instances of the same field, as if with the +Message::MergeFrom method – that is, all singular scalar fields in the latter +instance replace those in the former, singular embedded messages are merged, and +repeated fields are concatenated. The effect of these rules is that parsing +the concatenation of two encoded messages produces exactly the same result as if +you had parsed the two messages separately and merged the resulting objects. +That is, this:

MyMessage message;
+message.ParseFromString(str1 + str2);
+

is equivalent to this:

MyMessage message, message2;
+message.ParseFromString(str1);
+message2.ParseFromString(str2);
+message.MergeFrom(message2);
+

This property is occasionally useful, as it allows you to merge two messages (by +concatenation) even if you do not know their types.

Maps

Map fields are just a shorthand for a special kind of repeated field. If we have

message Test6 {
+  map<string, int32> g = 7;
+}
+

this is actually the same as

message Test6 {
+  message g_Entry {
+    string key = 1;
+    int32 value = 2;
+  }
+  repeated g_Entry g = 7;
+}
+

Thus, maps are encoded almost exactly like a repeated message field: as a +sequence of LEN-typed records, with two fields each. The exception is that +order is not guaranteed to be preserved with maps during serialization.

Groups

Groups are a deprecated feature that should not be used, but they remain in the +wire format, and deserve a passing mention.

A group is a bit like a submessage, but it is delimited by special tags rather +than by a LEN prefix. Each group in a message has a field number, which is +used on these special tags.

A group with field number 8 begins with an 8:SGROUP tag. SGROUP records +have empty payloads, so all this does is denote the start of the group. Once all +the fields in the group are listed, a corresponding 8:EGROUP tag denotes its +end. EGROUP records also have no payload, so 8:EGROUP is the entire record. +Group field numbers need to match up. If we encounter 7:EGROUP where we expect +8:EGROUP, the message is mal-formed.

Protoscope provides a convenient syntax for writing groups. Instead of writing

8:SGROUP
+  1: 2
+  3: {"foo"}
+8:EGROUP
+

Protoscope allows

8: !{
+  1: 2
+  3: {"foo"}
+}
+

This will generate the appropriate start and end group markers. The !{} syntax +can only occur immediately after an un-typed tag expression, like 8:.

Field Order

Field numbers may be declared in any order in a .proto file. The order chosen +has no effect on how the messages are serialized.

When a message is serialized, there is no guaranteed order for how its known or +unknown fields +will be written. Serialization order is an implementation detail, and the +details of any particular implementation may change in the future. Therefore, +protocol buffer parsers must be able to parse fields in any order.

Implications

  • Do not assume the byte output of a serialized message is stable. This is +especially true for messages with transitive bytes fields representing other +serialized protocol buffer messages.
  • By default, repeated invocations of serialization methods on the same +protocol buffer message instance may not produce the same byte output. That +is, the default serialization is not deterministic.
    • Deterministic serialization only guarantees the same byte output for a +particular binary. The byte output may change across different versions +of the binary.
  • The following checks may fail for a protocol buffer message instance foo:
    • foo.SerializeAsString() == foo.SerializeAsString()
    • Hash(foo.SerializeAsString()) == Hash(foo.SerializeAsString())
    • CRC(foo.SerializeAsString()) == CRC(foo.SerializeAsString())
    • FingerPrint(foo.SerializeAsString()) == FingerPrint(foo.SerializeAsString())
  • Here are a few example scenarios where logically equivalent protocol buffer +messages foo and bar may serialize to different byte outputs:
    • bar is serialized by an old server that treats some fields as unknown.
    • bar is serialized by a server that is implemented in a different +programming language and serializes fields in different order.
    • bar has a field that serializes in a non-deterministic manner.
    • bar has a field that stores a serialized byte output of a protocol +buffer message which is serialized differently.
    • bar is serialized by a new server that serializes fields in a +different order due to an implementation change.
    • foo and bar are concatenations of the same individual messages in a +different order.

Encoded Proto Size Limitations

Protos must be smaller than 2 GiB when serialized. Many proto implementations +will refuse to serialize or parse messages that exceed this limit.

Condensed Reference Card

The following provides the most prominent parts of the wire format in an +easy-to-reference format.

message    := (tag value)*
+
+tag        := (field << 3) bit-or wire_type;
+                encoded as uint32 varint
+value      := varint      for wire_type == VARINT,
+              i32         for wire_type == I32,
+              i64         for wire_type == I64,
+              len-prefix  for wire_type == LEN,
+              <empty>     for wire_type == SGROUP or EGROUP
+
+varint     := int32 | int64 | uint32 | uint64 | bool | enum | sint32 | sint64;
+                encoded as varints (sintN are ZigZag-encoded first)
+i32        := sfixed32 | fixed32 | float;
+                encoded as 4-byte little-endian (float is IEEE 754
+                single-precision); memcpy of the equivalent C types (u?int32_t,
+                float)
+i64        := sfixed64 | fixed64 | double;
+                encoded as 8-byte little-endian (double is IEEE 754
+                double-precision); memcpy of the equivalent C types (u?int64_t,
+                double)
+
+len-prefix := size (message | string | bytes | packed);
+                size encoded as int32 varint
+string     := valid UTF-8 string (e.g. ASCII);
+                max 2GB of bytes
+bytes      := any sequence of 8-bit bytes;
+                max 2GB of bytes
+packed     := varint* | i32* | i64*,
+                consecutive values of the type specified in `.proto`
+

See also the +Protoscope Language Reference.

Key

message := (tag value)*
A message is encoded as a sequence of zero or more pairs of tags and values.
tag := (field << 3) bit-or wire_type
A tag is a combination of a wire_type, stored in the least significant +three bits, and the field number that is defined in the .proto file.
value := varint for wire_type == VARINT, ...
A value is stored differently depending on the wire_type specified in the +tag.
varint := int32 | int64 | uint32 | uint64 | bool | enum | sint32 | sint64
You can use varint to store any of the listed data types.
i32 := sfixed32 | fixed32 | float
You can use fixed32 to store any of the listed data types.
i64 := sfixed64 | fixed64 | double
You can use fixed64 to store any of the listed data types.
len-prefix := size (message | string | bytes | packed)
A length-prefixed value is stored as a length (encoded as a varint), and +then one of the listed data types.
string := valid UTF-8 string (e.g. ASCII)
As described, a string must use UTF-8 character encoding. A string cannot +exceed 2GB.
bytes := any sequence of 8-bit bytes
As described, bytes can store custom data types, up to 2GB in size.
packed := varint* | i32* | i64*
Use the packed data type when you are storing consecutive values of the +type described in the protocol definition. The tag is dropped for values +after the first, which amortizes the costs of tags to one per field, rather +than per element.
\ No newline at end of file diff --git a/programming-guides/enum/index.html b/programming-guides/enum/index.html new file mode 100644 index 000000000..fa6e8fd37 --- /dev/null +++ b/programming-guides/enum/index.html @@ -0,0 +1,104 @@ +Enum Behavior | Protocol Buffers Documentation +

Enum Behavior

Explains how enums currently work in Protocol Buffers vs. how they should work.

Enums behave differently in different language libraries. This topic covers the +different behaviors as well as the plans to move protobufs to a state where they +are consistent across all languages. If you’re looking for information on how to +use enums in general, see the corresponding sections in the +proto2, +proto3, and +editions 2023 +language guide topics.

Definitions

Enums have two distinct flavors (open and closed). They behave identically +except in their handling of unknown values. Practically, this means that simple +cases work the same, but some corner cases have interesting implications.

For the purpose of explanation, let us assume we have the following .proto +file (we are deliberately not specifying if this is a syntax = "proto2", +syntax = "proto3", or edition = "2023" file right now):

enum Enum {
+  A = 0;
+  B = 1;
+}
+
+message Msg {
+  optional Enum enum = 1;
+}
+

The distinction between open and closed can be encapsulated in a single +question:

What happens when a program parses binary data that contains field 1 with the +value 2?

  • Open enums will parse the value 2 and store it directly in the field. +Accessor will report the field as being set and will return something that +represents 2.
  • Closed enums will parse the value 2 and store it in the message’s +unknown field set. Accessors will report the field as being unset and will +return the enum’s default value.

Implications of Closed Enums

The behavior of closed enums has unexpected consequences when parsing a +repeated field. When a repeated Enum field is parsed, all unknown values will +be placed in the +unknown field +set. When it is serialized those unknown values will be written again, but not +in their original place in the list. For example, given the .proto file:

enum Enum {
+  A = 0;
+  B = 1;
+}
+
+message Msg {
+  repeated Enum r = 1;
+}
+

A wire format containing the values [0, 2, 1, 2] for field 1 will parse so +that the repeated field contains [0, 1] and the value [2, 2] will end up +stored as an unknown field. After reserializing the message, the wire format +will correspond to [0, 1, 2, 2].

Similarly, maps with closed enums for their value will place entire entries +(key and value) in the unknown fields whenever the value is unknown.

History

Prior to the introduction of syntax = "proto3" all enums were closed. Proto3 +and editions use open enums specifically because of the unexpected behavior +that closed enums cause. You can use +features.enum_type to +explicitly set editions enums to closed, if needed.

Specification

The following specifies the behavior of conformant implementations for protobuf. +Because this is subtle, many implementations are out of conformance. See +Known Issues for details on how different implementations +behave.

  • When a proto2 file imports an enum defined in a proto2 file, that enum +should be treated as closed.
  • When a proto3 file imports an enum defined in a proto3 file, that enum +should be treated as open.
  • When a proto3 file imports an enum defined in a proto2 file, the +protoc compiler will produce an error.
  • When a proto2 file imports an enum defined in a proto3 file, that enum +should be treated as open.

Editions honor whatever behavior the enum had in the file being imported from. +Proto2 enums are always treated as closed, proto3 enums are always treated as +open, and when importing from another editions file it uses the feature setting.

Known Issues

C++

All known C++ releases are out of conformance. When a proto2 file imports an +enum defined in a proto3 file, C++ treats that field as a closed enum. +Under editions, this behavior is represented by the deprecated field feature +features.(pb.cpp).legacy_closed_enum. +There are two options for moving to conformant behavior:

  • Remove the field feature. This is the recommended approach, but may cause +runtime behavior changes. Without the feature, unrecognized integers will +end up stored in the field cast to the enum type instead of being put into +the unknown field set.
  • Change the enum to closed. This is discouraged, and can cause runtime +behavior changes if anybody else is using the enum. Unrecognized integers +will end up in the unknown field set instead of those fields.

C#

All known C# releases are out of conformance. C# treats all enums as open.

Java

All known Java releases are out of conformance. When a proto2 file imports an +enum defined in a proto3 file, Java treats that field as a closed enum.

Under editions, this behavior is represented by the deprecated field feature +features.(pb.java).legacy_closed_enum). +There are two options for moving to conformant behavior:

  • Remove the field feature. This may cause runtime behavior changes. Without +the feature, unrecognized integers will end up stored in the field and the +UNRECOGNIZED value will be returned by the enum getter. Before, these +values would be put into the unknown field set.
  • Change the enum to closed. If anybody else is using it they may see +runtime behavior changes. Unrecognized integers will end up in the unknown +field set instead of those fields.

NOTE: Java’s handling of open enums has surprising edge cases. Given +the following definitions:

syntax = "proto3";
+
+enum Enum {
+  A = 0;
+  B = 1;
+}
+
+message Msg {
+  repeated Enum name = 1;
+}
+

Java will generate the methods Enum getName() and int getNameValue(). The +method getName will return Enum.UNRECOGNIZED for values outside the known +set (such as 2), whereas getNameValue will return 2.

Similarly, Java will generate methods Builder setName(Enum value) and +Builder setNameValue(int value). The method setName will throw an +exception when passed Enum.UNRECOGNIZED, whereas setNameValue will accept +2.

Kotlin

All known Kotlin releases are out of conformance. When a proto2 file imports +an enum defined in a proto3 file, Kotlin treats that field as a closed +enum.

Kotlin is built on Java and shares all of its oddities.

Go

All known Go releases are out of conformance. Go treats all enums as open.

JSPB

All known JSPB releases are out of conformance. JSPB treats all enums as +open.

PHP

PHP is conformant.

Python

Python is conformant in versions above 4.22.0 (released 2023 Q1).

Older versions which are no longer supported are out of conformance. When a +proto2 file imports an enum defined in a proto3 file, non-conformant Python +versions treat that field as a closed enum.

Ruby

All known Ruby releases are out of conformance. Ruby treats all enums as +open.

Objective-C

Objective-C is conformant in versions above 3.22.0 (released 2023 Q1).

Older versions which are no longer supported and are out of conformance. When a +proto2 file imports an enum defined in a proto3 file, non-conformant ObjC +versions treat that field as a closed enum.

Swift

Swift is conformant.

Dart

Dart treats all enums as closed.

\ No newline at end of file diff --git a/programming-guides/extension_declarations/index.html b/programming-guides/extension_declarations/index.html new file mode 100644 index 000000000..3240eb871 --- /dev/null +++ b/programming-guides/extension_declarations/index.html @@ -0,0 +1,137 @@ +Extension Declarations | Protocol Buffers Documentation +

Extension Declarations

Describes in detail what extension declarations are, why we need them, and how we use them.

Introduction

This page describes in detail what extension declarations are, why we need them, +and how we use them.

If you need an introduction to extensions, read this +extensions guide

Motivation

Extension declarations aim to strike a happy medium between regular fields and +extensions. Like extensions, they avoid creating a dependency on the message +type of the field, which therefore results in a leaner build graph and smaller +binaries in environments where unused messages are difficult or impossible to +strip. Like regular fields, the field name/number appear in the enclosing +message, which makes it easier to avoid conflicts and see a convenient listing +of what fields are declared.

Listing the occupied extension numbers with extension declarations makes it +easier for users to pick an available extension number and to avoid conflicts.

Usage

Extension declarations are an option of extension ranges. Like forward +declarations in C++, you can declare the field type, field name, and cardinality +(singular or repeated) of an extension field without importing the .proto file +containing the full extension definition:

edition = "2023";
+
+message Foo {
+  extensions 4 to 1000 [
+    declaration = {
+      number: 4,
+      full_name: ".my.package.event_annotations",
+      type: ".logs.proto.ValidationAnnotations",
+      repeated: true },
+    declaration = {
+      number: 999,
+      full_name: ".foo.package.bar",
+      type: "int32"}];
+}
+

This syntax has the following semantics:

  • Multiple declarations with distinct extension numbers can be defined in a +single extension range if the size of the range allows.
  • If there is any declaration for the extension range, all extensions of the +range must also be declared. This prevents non-declared extensions from +being added, and enforces that any new extensions use declarations for the +range.
  • The given message type (.logs.proto.ValidationAnnotations) does not need +to have been previously defined or imported. We check only that it is a +valid name that could potentially be defined in another .proto file.
  • When this or another .proto file defines an extension of this message +(Foo) with this name or number, we enforce that the number, type, and full +name of the extension match what is forward-declared here.

The extension declarations expect two extension fields with different packages:

package my.package;
+extend Foo {
+  repeated logs.proto.ValidationAnnotations event_annotations = 4;
+}
+
package foo.package;
+extend Foo {
+  optional int32 bar = 999;
+}
+

Reserved Declarations

An extension declaration can be marked reserved: true to indicate that it is +no longer actively used and the extension definition has been deleted. Do not +delete the extension declaration or edit its type or full_name value.

This reserved tag is separate from the reserved keyword for regular fields and +does not require breaking up the extension range.

edition = "2023";
+
+message Foo {
+  extensions 4 to 1000 [
+    declaration = {
+      number: 500,
+      full_name: ".my.package.event_annotations",
+      type: ".logs.proto.ValidationAnnotations",
+      reserved: true }];
+}
+

An extension field definition using a number that is reserved in the +declaration will fail to compile.

Representation in descriptor.proto

Extension declaration is represented in descriptor.proto as fields in +proto2.ExtensionRangeOptions:

message ExtensionRangeOptions {
+  message Declaration {
+    optional int32 number = 1;
+    optional string full_name = 2;
+    optional string type = 3;
+    optional bool reserved = 5;
+    optional bool repeated = 6;
+  }
+  repeated Declaration declaration = 2;
+}
+

Reflection Field Lookup

Extension declarations are not returned from the normal field lookup functions +like Descriptor::FindFieldByName() or Descriptor::FindFieldByNumber(). Like +extensions, they are discoverable by extension lookup routines like +DescriptorPool::FindExtensionByName(). This is an explicit choice that +reflects the fact that declarations are not definitions and do not have enough +information to return a full FieldDescriptor.

Declared extensions still behave like regular extensions from the perspective of +TextFormat and JSON. It also means that migrating an existing field to a +declared extension will require first migrating any reflective use of that +field.

Use Extension Declarations to Allocate Numbers

Extensions use field numbers just like ordinary fields do, so it is important +for each extension to be assigned a number that is unique within the parent +message. We recommend using extension +declarations to declare the field +number and type for each extension in the parent message. The extension +declarations serve as a registry of all the parent message’s extensions, and +protoc will enforce that there are no field number conflicts. When you add a new +extension, choose the next available number usually by just incrementing by one +the previously added extension number.

TIP: There is a special guidance for +MessageSet which provides a script to help pick +the next available number.

Whenever you delete an extension, make sure to mark the field number reserved +to eliminate the risk of accidentally reusing +it.

This convention is only a recommendation–the protobuf team does not have the +ability or desire to force anyone to adhere to it for every extendable message. +If you as the owner of an extendable proto do not want to coordinate extension +numbers through extension declarations, you can choose to provide coordination +through other means. Be very careful, though, +because accidental reuse of an extension number can cause serious problems.

One way to sidestep the issue would be to avoid extensions entirely and use +google.protobuf.Any +instead. This could be a good choice for APIs that front storage or for +pass-through systems where the client cares about the contents of the proto but +the system receiving it does not.

Consequences of Reusing an Extension Number

An extension is a field defined outside the container message; usually in a +separate .proto file. This distribution of definitions makes it easy for two +developers to accidentally create different definitions for the same extension +field number.

The consequences of changing an extension definition are the same for extensions +and standard fields. Reusing a field number introduces an ambiguity in how a +proto should be decoded from the wire format. The protobuf wire format is lean +and doesn’t provide a good way to detect fields encoded using one definition and +decoded using another.

This ambiguity can manifest in a short time frame, such as a client using one +extension definition and a server using another communicating +.

This ambiguity can also manifest over a longer time frame, such as storing data +encoded using one extension definition and later retrieving and decoding using +the second extension definition. This long-term case can be difficult to +diagnose if the first extension definition was deleted after the data was +encoded and stored.

The outcome of this can be:

  1. A parse error (best case scenario).
  2. Leaked PII / SPII – if PII or SPII is written using one extension definition +and read using another extension definition.
  3. Data Corruption – if data is read using the “wrong” definition, modified and +rewritten.

Data definition ambiguity is almost certainly going to cost someone time for +debugging at a minimum. It could also cause data leaks or corruption that takes +months to clean up.

Usage Tips

Never Delete an Extension Declaration

Deleting an extension declaration opens the door to accidental reuse in the +future. If the extension is no longer processed and the definition is deleted, +the extension declaration can be marked reserved.

Never Use a Field Name or Number from the reserved List for a New Extension Declaration

Reserved numbers may have been used for fields or other extensions in the past.

Using the full_name of a reserved field +is not recommended +due +to the possibility of ambiguity when using textproto.

Never change the type of an existing extension declaration

Changing the extension field’s type can result in data corruption.

If the extension field is of an enum or message type, and that enum or message +type is being renamed, updating the declaration name is required and safe. To +avoid breakages, the update of the type, the extension field definition, and +extension declaration should all happen in a single +commit.

Use Caution When Renaming an Extension Field

While renaming an extension field is fine for the wire format, it can break JSON +and TextFormat parsing.

\ No newline at end of file diff --git a/programming-guides/field_presence/index.html b/programming-guides/field_presence/index.html new file mode 100644 index 000000000..454b005fa --- /dev/null +++ b/programming-guides/field_presence/index.html @@ -0,0 +1,317 @@ +Application Note: Field Presence | Protocol Buffers Documentation +

Application Note: Field Presence

Explains the various presence-tracking disciplines for protobuf fields. It also explains the behavior of explicit presence-tracking for singular proto3 fields with basic types.

Background

Field presence is the notion of whether a protobuf field has a value. There +are two different manifestations of presence for protobufs: implicit presence, +where the generated message API stores field values (only), and explicit +presence, where the API also stores whether or not a field has been set.

Presence Disciplines

Presence disciplines define the semantics for translating between the API +representation and the serialized representation. The implicit presence +discipline relies upon the field value itself to make decisions at +(de)serialization time, while the explicit presence discipline relies upon the +explicit tracking state instead.

Presence in Tag-value stream (Wire Format) Serialization

The wire format is a stream of tagged, self-delimiting values. By definition, +the wire format represents a sequence of present values. In other words, every +value found within a serialization represents a present field; furthermore, +the serialization contains no information about not-present values.

The generated API for a proto message includes (de)serialization definitions +which translate between API types and a stream of definitionally present (tag, +value) pairs. This translation is designed to be forward- and +backward-compatible across changes to the message definition; however, this +compatibility introduces some (perhaps surprising) considerations when +deserializing wire-formatted messages:

  • When serializing, fields with implicit presence are not serialized if they +contain their default value.
    • For numeric types, the default is 0.
    • For enums, the default is the zero-valued enumerator.
    • For strings, bytes, and repeated fields, the default is the zero-length +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 +presence, then these values may not be re-serialized; i.e., the empty field +may be “not present” after a serialization round-trip.
  • When deserializing, duplicate field values may be handled in different ways +depending on the field definition.
    • Duplicate repeated fields are typically appended to the field’s API +representation. (Note that serializing a packed repeated field +produces only one, length-delimited value in the tag stream.)
    • Duplicate optional field values follow the rule that “the last one +wins.”
  • oneof fields expose the API-level invariant that only one field is set at +a time. However, the wire format may include multiple (tag, value) pairs +which notionally belong to the oneof. Similar to optional fields, the +generated API follows the “last one wins” rule.
  • Out-of-range values are not returned for enum fields in generated proto2 +APIs. However, out-of-range values may be stored as unknown fields in the +API, even though the wire-format tag was recognized.

Presence in Named-field Mapping Formats

Protobufs can be represented in human-readable, textual forms. Two notable +formats are TextFormat (the output format produced by generated message +DebugString methods) and JSON.

These formats have correctness requirements of their own, and are generally +stricter than tagged-value stream formats. However, TextFormat more closely +mimics the semantics of the wire format, and does, in certain cases, provide +similar semantics (for example, appending repeated name-value mappings to a +repeated field). In particular, similar to the wire format, TextFormat only +includes fields which are present.

JSON is a much stricter format, however, and cannot validly represent some +semantics of the wire format or TextFormat.

  • Notably, JSON elements are semantically unordered, and each member must +have a unique name. This is different from TextFormat rules for repeated +fields.
  • JSON may include fields that are “not present,” unlike the implicit +presence discipline for other formats:
    • JSON defines a null value, which may be used to represent a defined +but not-present field.
    • Repeated field values may be included in the formatted output, even if +they are equal to the default (an empty list).
  • Because JSON elements are unordered, there is no way to unambiguously +interpret the “last one wins” rule.
    • In most cases, this is fine: JSON elements must have unique names: +repeated field values are not valid JSON, so they do not need to be +resolved as they are for TextFormat.
    • However, this means that it may not be possible to interpret oneof +fields unambiguously: if multiple cases are present, they are unordered.

In theory, JSON can represent presence in a semantic-preserving fashion. In +practice, however, presence correctness can vary depending upon implementation +choices, especially if JSON was chosen as a means to interoperate with clients +not using protobufs.

Presence in Proto2 APIs

This table outlines whether presence is tracked for fields in proto2 APIs (both +for generated APIs and using dynamic reflection):

Field typeExplicit Presence
Singular numeric (integer or floating point)✔️
Singular enum✔️
Singular string or bytes✔️
Singular message✔️
Repeated
Oneofs✔️
Maps

Singular fields (of all types) track presence explicitly in the generated API. +The generated message interface includes methods to query presence of fields. +For example, the field foo has a corresponding has_foo method. (The specific +name follows the same language-specific naming convention as the field +accessors.) These methods are sometimes referred to as “hazzers” within the +protobuf implementation.

Similar to singular fields, oneof fields explicitly track which one of the +members, if any, contains a value. For example, consider this example oneof:

oneof foo {
+  int32 a = 1;
+  float b = 2;
+}
+

Depending on the target language, the generated API would generally include +several methods:

  • A hazzer for the oneof: has_foo
  • A oneof case method: foo
  • Hazzers for the members: has_a, has_b
  • Getters for the members: a, b

Repeated fields and maps do not track presence: there is no distinction between +an empty and a not-present repeated field.

Presence in Proto3 APIs

This table outlines whether presence is tracked for fields in proto3 APIs (both +for generated APIs and using dynamic reflection):

Field typeoptionalExplicit Presence
Singular numeric (integer or floating point)No
Singular numeric (integer or floating point)Yes✔️
Singular enumNo
Singular enumYes✔️
Singular string or bytesNo
Singular string or bytesYes✔️
Singular messageNo✔️
Singular messageYes✔️
RepeatedN/A
OneofsN/A✔️
MapsN/A

Similar to proto2 APIs, proto3 does not track presence explicitly for repeated +fields. Without the optional label, proto3 APIs do not track presence for +basic types (numeric, string, bytes, and enums), either. Oneof fields +affirmatively expose presence, although the same set of hazzer methods may not +generated as in proto2 APIs.

This default behavior of not tracking presence without the optional label is +different from the proto2 behavior. We recommend using the optional label with +proto3 unless you have a specific reason not to.

Under the implicit presence discipline, the default value is synonymous with +“not present” for purposes of serialization. To notionally “clear” a field (so +it won’t be serialized), an API user would set it to the default value.

The default value for enum-typed fields under implicit presence is the +corresponding 0-valued enumerator. Under proto3 syntax rules, all enum types are +required to have an enumerator value which maps to 0. By convention, this is an +UNKNOWN or similarly-named enumerator. If the zero value is notionally outside +the domain of valid values for the application, this behavior can be thought of +as tantamount to explicit presence.

Presence in Editions APIs

This table outlines whether presence is tracked for fields in editions APIs +(both for generated APIs and using dynamic reflection):

Field typeExplicit Presence
Singular numeric (integer or floating point)✔️
Singular enum✔️
Singular string or bytes✔️
Singular message†✔️
Repeated
Oneofs†✔️
Maps

† Messages and oneofs have never had implicit presence, and editions +doesn’t allow you to set field_presence = IMPLICIT.

Editions-based APIs track field presence explicitly, similarly to proto2, unless +features.field_presence is set to IMPLICIT. Similar to proto2 APIs, +editions-based APIs do not track presence explicitly for repeated fields.

Semantic Differences

The implicit presence serialization discipline results in visible differences +from the explicit presence tracking discipline, when the default value is set. +For a singular field with numeric, enum, or string type:

  • Implicit presence discipline:
    • Default values are not serialized.
    • Default values are not merged-from.
    • To “clear” a field, it is set to its default value.
    • The default value may mean:
      • the field was explicitly set to its default value, which is valid in +the application-specific domain of values;
      • the field was notionally “cleared” by setting its default; or
      • the field was never set.
    • has_ methods are not generated (but see note after this list)
  • Explicit presence discipline:
    • Explicitly set values are always serialized, including default values.
    • Un-set fields are never merged-from.
    • Explicitly set fields – including default values – are merged-from.
    • A generated has_foo method indicates whether or not the field foo +has been set (and not cleared).
    • A generated clear_foo method must be used to clear (i.e., un-set) the +value.

Considerations for Merging

Under the implicit presence rules, it is effectively impossible for a target +field to merge-from its default value (using the protobuf’s API merging +functions). This is because default values are skipped, similar to the implicit +presence serialization discipline. Merging only updates the target (merged-to) +message using the non-skipped values from the update (merged-from) message.

The difference in merging behavior has further implications for protocols which +rely on partial “patch” updates. If field presence is not tracked, then an +update patch alone cannot represent an update to the default value, because only +non-default values are merged-from.

Updating to set a default value in this case requires some external mechanism, +such as FieldMask. However, if presence is tracked, then all explicitly-set +values – even default values – will be merged into the target.

Considerations for change-compatibility

Changing a field between explicit presence and implicit presence is a +binary-compatible change for serialized values in wire format. However, the +serialized representation of the message may differ, depending on which version +of the message definition was used for serialization. Specifically, when a +“sender” explicitly sets a field to its default value:

  • The serialized value following implicit presence discipline does not +contain the default value, even though it was explicitly set.
  • The serialized value following explicit presence discipline contains every +“present” field, even if it contains the default value.

This change may or may not be safe, depending on the application’s semantics. +For example, consider two clients with different versions of a message +definition.

Client A uses this definition of the message, which follows the explicit +presence serialization discipline for field foo:

syntax = "proto3";
+message Msg {
+  optional int32 foo = 1;
+}
+

Client B uses a definition of the same message, except that it follows the no +presence discipline:

syntax = "proto3";
+message Msg {
+  int32 foo = 1;
+}
+

Now, consider a scenario where client A observes foo’s presence as the clients +repeatedly exchange the “same” message by deserializing and reserializing:

// Client A:
+Msg m_a;
+m_a.set_foo(1);                  // non-default value
+assert(m_a.has_foo());           // OK
+Send(m_a.SerializeAsString());   // to client B
+
+// Client B:
+Msg m_b;
+m_b.ParseFromString(Receive());  // from client A
+assert(m_b.foo() == 1);          // OK
+Send(m_b.SerializeAsString());   // to client A
+
+// Client A:
+m_a.ParseFromString(Receive());  // from client B
+assert(m_a.foo() == 1);          // OK
+assert(m_a.has_foo());           // OK
+m_a.set_foo(0);                  // default value
+Send(m_a.SerializeAsString());   // to client B
+
+// Client B:
+Msg m_b;
+m_b.ParseFromString(Receive());  // from client A
+assert(m_b.foo() == 0);          // OK
+Send(m_b.SerializeAsString());   // to client A
+
+// Client A:
+m_a.ParseFromString(Receive());  // from client B
+assert(m_a.foo() == 0);          // OK
+assert(m_a.has_foo());           // FAIL
+

If client A depends on explicit presence for foo, then a “round trip” +through client B will be lossy from the perspective of client A. In the example, +this is not a safe change: client A requires (by assert) that the field is +present; even without any modifications through the API, that requirement fails +in a value- and peer-dependent case.

How to Enable Explicit Presence in Proto3

These are the general steps to use field tracking support for proto3:

  1. Add an optional field to a .proto file.
  2. Run protoc (at least v3.15, or v3.12 using +--experimental_allow_proto3_optional flag).
  3. Use the generated “hazzer” methods and “clear” methods in application code, +instead of comparing or setting default values.

.proto File Changes

This is an example of a proto3 message with fields which follow both no +presence and explicit presence semantics:

syntax = "proto3";
+package example;
+
+message MyMessage {
+  // implicit presence:
+  int32 not_tracked = 1;
+
+  // Explicit presence:
+  optional int32 tracked = 2;
+}
+

protoc Invocation

Presence tracking for proto3 messages is enabled by default +since v3.15.0 +release, formerly up until +v3.12.0 the +--experimental_allow_proto3_optional flag was required when using presence +tracking with protoc.

Using the Generated Code

The generated code for proto3 fields with explicit presence (the optional +label) will be the same as it would be in a proto2 file.

This is the definition used in the “implicit presence” examples below:

syntax = "proto3";
+package example;
+message Msg {
+  int32 foo = 1;
+}
+

This is the definition used in the “explicit presence” examples below:

syntax = "proto3";
+package example;
+message Msg {
+  optional int32 foo = 1;
+}
+

In the examples, a function GetProto constructs and returns a message of type +Msg with unspecified contents.

C++ Example

Implicit presence:

Msg m = GetProto();
+if (m.foo() != 0) {
+  // "Clear" the field:
+  m.set_foo(0);
+} else {
+  // Default value: field may not have been present.
+  m.set_foo(1);
+}
+

Explicit presence:

Msg m = GetProto();
+if (m.has_foo()) {
+  // Clear the field:
+  m.clear_foo();
+} else {
+  // Field is not present, so set it.
+  m.set_foo(1);
+}
+

C# Example

Implicit presence:

var m = GetProto();
+if (m.Foo != 0) {
+  // "Clear" the field:
+  m.Foo = 0;
+} else {
+  // Default value: field may not have been present.
+  m.Foo = 1;
+}
+

Explicit presence:

var m = GetProto();
+if (m.HasFoo) {
+  // Clear the field:
+  m.ClearFoo();
+} else {
+  // Field is not present, so set it.
+  m.Foo = 1;
+}
+

Go Example

Implicit presence:

m := GetProto()
+if m.Foo != 0 {
+  // "Clear" the field:
+  m.Foo = 0
+} else {
+  // Default value: field may not have been present.
+  m.Foo = 1
+}
+

Explicit presence:

m := GetProto()
+if m.Foo != nil {
+  // Clear the field:
+  m.Foo = nil
+} else {
+  // Field is not present, so set it.
+  m.Foo = proto.Int32(1)
+}
+

Java Example

These examples use a Builder to demonstrate clearing. Simply checking presence +and getting values from a Builder follows the same API as the message type.

Implicit presence:

Msg.Builder m = GetProto().toBuilder();
+if (m.getFoo() != 0) {
+  // "Clear" the field:
+  m.setFoo(0);
+} else {
+  // Default value: field may not have been present.
+  m.setFoo(1);
+}
+

Explicit presence:

Msg.Builder m = GetProto().toBuilder();
+if (m.hasFoo()) {
+  // Clear the field:
+  m.clearFoo()
+} else {
+  // Field is not present, so set it.
+  m.setFoo(1);
+}
+

Python Example

Implicit presence:

m = example.Msg()
+if m.foo != 0:
+  # "Clear" the field:
+  m.foo = 0
+else:
+  # Default value: field may not have been present.
+  m.foo = 1
+

Explicit presence:

m = example.Msg()
+if m.HasField('foo'):
+  # Clear the field:
+  m.ClearField('foo')
+else:
+  # Field is not present, so set it.
+  m.foo = 1
+

Ruby Example

Implicit presence:

m = Msg.new
+if m.foo != 0
+  # "Clear" the field:
+  m.foo = 0
+else
+  # Default value: field may not have been present.
+  m.foo = 1
+end
+

Explicit presence:

m = Msg.new
+if m.has_foo?
+  # Clear the field:
+  m.clear_foo
+else
+  # Field is not present, so set it.
+  m.foo = 1
+end
+

Javascript Example

Implicit presence:

var m = new Msg();
+if (m.getFoo() != 0) {
+  // "Clear" the field:
+  m.setFoo(0);
+} else {
+  // Default value: field may not have been present.
+  m.setFoo(1);
+}
+

Explicit presence:

var m = new Msg();
+if (m.hasFoo()) {
+  // Clear the field:
+  m.clearFoo()
+} else {
+  // Field is not present, so set it.
+  m.setFoo(1);
+}
+

Objective-C Example

Implicit presence:

Msg *m = [Msg message];
+if (m.foo != 0) {
+  // "Clear" the field:
+  m.foo = 0;
+} else {
+  // Default value: field may not have been present.
+  m.foo = 1;
+}
+

Explicit presence:

Msg *m = [Msg message];
+if ([m hasFoo]) {
+  // Clear the field:
+  [m clearFoo];
+} else {
+  // Field is not present, so set it.
+  m.foo = 1;
+}
+

Cheat sheet

Proto2:

Is field presence tracked?

Field typeTracked?
Singular fieldyes
Singular message fieldyes
Field in a oneofyes
Repeated field & mapno

Proto3:

Is field presence tracked?

Field typeTracked?
Other singular fieldif defined as optional
Singular message fieldyes
Field in a oneofyes
Repeated field & mapno

Edition 2023:

Is field presence tracked?

Field type (in descending prescendence)Tracked?
Repeated field & mapno
Message and Oneof fieldsyes
Other singular fields if features.field_presence set to IMPLICITno
All other fieldsyes
\ No newline at end of file diff --git a/programming-guides/index.html b/programming-guides/index.html new file mode 100644 index 000000000..43e30551d --- /dev/null +++ b/programming-guides/index.html @@ -0,0 +1,8 @@ +Programming Guides | Protocol Buffers Documentation +

Programming Guides

Learn how to use Protocol Buffers in your projects.

Language Guide (editions)

Covers how to use the editions revisions of the Protocol Buffers language in your project.

Language Guide (proto 2)

Covers how to use the proto2 revision of Protocol Buffers language in your project.

Language Guide (proto 3)

Covers how to use the proto3 revision of the Protocol Buffers language in your project.

Proto Limits

Covers the limits to number of supported elements in proto schemas.

Style Guide

Provides direction for how best to structure your proto definitions.

Enum Behavior

Explains how enums currently work in Protocol Buffers vs. how they should work.

Encoding

Explains how Protocol Buffers encodes data to files or to the wire.

ProtoJSON Format

Describes the spec details of the canonical JSON representation for Protobuf messages.

Techniques

Describes some commonly-used design patterns for dealing with Protocol Buffers.

Third-Party Add-ons

Links out to many open source projects that seek to add useful functionality on top of Protocol Buffers.

Extension Declarations

Describes in detail what extension declarations are, why we need them, and how we use them.

Application Note: Field Presence

Explains the various presence-tracking disciplines for protobuf fields. It also explains the behavior of explicit presence-tracking for singular proto3 fields with basic types.

Symbol Visibility

Explains the terminology and functionality of visibility, introduced in edition 2024.

Proto Serialization Is Not Canonical

Explains how serialization works and why it is not canonical.

Deserializing Debug Proto Representations

How to log debugging information in Protocol Buffers.

\ No newline at end of file diff --git a/programming-guides/index.xml b/programming-guides/index.xml new file mode 100644 index 000000000..e05105a3f --- /dev/null +++ b/programming-guides/index.xml @@ -0,0 +1,28 @@ +Programming Guides on Protocol Buffers Documentationhttps://protobuf.dev/programming-guides/Recent content in Programming Guides on Protocol Buffers DocumentationHugoenLanguage Guide (editions)https://protobuf.dev/programming-guides/editions/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/editions/This guide describes how to use the protocol buffer language to structure your protocol buffer data, including .proto file syntax and how to generate data access classes from your .proto files. It covers edition 2023 to edition 2024 of the protocol buffers language. For information about how editions differ from proto2 and proto3 conceptually, see Protobuf Editions Overview. +For information on the proto2 syntax, see the Proto2 Language Guide. +For information on proto3 syntax, see the Proto3 Language Guide.Language Guide (proto 2)https://protobuf.dev/programming-guides/proto2/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/proto2/This guide describes how to use the protocol buffer language to structure your protocol buffer data, including .proto file syntax and how to generate data access classes from your .proto files. It covers the proto2 revision of the protocol buffers language. +For information on editions syntax, see the Protobuf Editions Language Guide. +For information on proto3 syntax, see the Proto3 Language Guide. +This is a reference guide – for a step by step example that uses many of the features described in this document, see the tutorial for your chosen language.Language Guide (proto 3)https://protobuf.dev/programming-guides/proto3/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/proto3/This guide describes how to use the protocol buffer language to structure your protocol buffer data, including .proto file syntax and how to generate data access classes from your .proto files. It covers the proto3 revision of the protocol buffers language. +For information on editions syntax, see the Protobuf Editions Language Guide. +For information on the proto2 syntax, see the Proto2 Language Guide. +This is a reference guide – for a step by step example that uses many of the features described in this document, see the tutorial for your chosen language.Proto Limitshttps://protobuf.dev/programming-guides/proto-limits/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/proto-limits/This topic documents the limits to the number of supported elements (fields, enum values, and so on) in proto schemas. +This information is a collection of discovered limitations by many engineers, but is not exhaustive and may be incorrect/outdated in some areas. As you discover limitations in your work, contribute those to this document to help others. +Number of Fields All messages are limited to 65,535 fields. +Message with only singular proto fields (such as Boolean):Style Guidehttps://protobuf.dev/programming-guides/style/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/style/This document provides a style guide for .proto files. By following these conventions, you&rsquo;ll make your protocol buffer message definitions and their corresponding classes consistent and easy to read. +Enforcement of the following style guidelines is controlled via enforce_naming_style. +Standard File Formatting Keep the line length to 80 characters. Use an indent of 2 spaces. Prefer the use of double quotes for strings. File Structure Files should be named lower_snake_case.proto.Enum Behaviorhttps://protobuf.dev/programming-guides/enum/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/enum/Enums behave differently in different language libraries. This topic covers the different behaviors as well as the plans to move protobufs to a state where they are consistent across all languages. If you&rsquo;re looking for information on how to use enums in general, see the corresponding sections in the proto2, proto3, and editions 2023 language guide topics. +Definitions Enums have two distinct flavors (open and closed). They behave identically except in their handling of unknown values.Encodinghttps://protobuf.dev/programming-guides/encoding/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/encoding/This document describes the protocol buffer wire format, which defines the details of how your message is sent on the wire and how much space it consumes on disk. You probably don&rsquo;t need to understand this to use protocol buffers in your application, but it&rsquo;s useful information for doing optimizations. +If you already know the concepts but want a reference, skip to the Condensed reference card section. +Protoscope is a very simple language for describing snippets of the low-level wire format, which we&rsquo;ll use to provide a visual reference for the encoding of various messages.ProtoJSON Formathttps://protobuf.dev/programming-guides/json/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/json/Protobuf supports a canonical encoding in JSON, making it easier to share data with systems that do not support the standard protobuf binary wire format. +This page specifies the format, but a number of additional edge cases which define a conformant ProtoJSON parser are covered in the Protobuf Conformance Test Suite and are not exhaustively detailed here. +Non-goals of the Format Cannot Represent Some JSON schemas The ProtoJSON format is designed to be a JSON representation of schemas which are expressible in the Protobuf schema language.Techniqueshttps://protobuf.dev/programming-guides/techniques/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/techniques/You can also send design and usage questions to the Protocol Buffers discussion group. +Common Filename Suffixes It is fairly common to write messages to files in several different formats. We recommend using the following file extensions for these files. +Content Extension Text Format .txtpb Wire Format .binpb JSON Format .json For Text Format specifically, .textproto is also fairly common, but we recommend .txtpb for its brevity. +Streaming Multiple Messages If you want to write multiple messages to a single file or stream, it is up to you to keep track of where one message ends and the next begins.Third-Party Add-onshttps://protobuf.dev/programming-guides/addons/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/addons/Many open source projects seek to add useful functionality on top of Protocol Buffers. For a list of links to projects we know about, see the third-party add-ons wiki page.Extension Declarationshttps://protobuf.dev/programming-guides/extension_declarations/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/extension_declarations/Introduction This page describes in detail what extension declarations are, why we need them, and how we use them. +Note Proto3 does not support extensions (except for declaring custom options). Extensions are fully supported in proto2 and editions though. If you need an introduction to extensions, read this extensions guide +Motivation Extension declarations aim to strike a happy medium between regular fields and extensions. Like extensions, they avoid creating a dependency on the message type of the field, which therefore results in a leaner build graph and smaller binaries in environments where unused messages are difficult or impossible to strip.Application Note: Field Presencehttps://protobuf.dev/programming-guides/field_presence/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/field_presence/Background Field presence is the notion of whether a protobuf field has a value. There are two different manifestations of presence for protobufs: implicit presence, where the generated message API stores field values (only), and explicit presence, where the API also stores whether or not a field has been set. +Note We recommend always adding the optional label for proto3 basic types. This provides a smoother path to editions, which uses explicit presence by default.Symbol Visibilityhttps://protobuf.dev/programming-guides/symbol_visibility/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/symbol_visibility/This document describes the terminology and functionality of the symbol visibility system introduced in proto edition = &quot;2024&quot; +Glossary Symbol: Any of message, enum, service or extend &lt;type&gt;, the allowed Top-Level types in a .proto file. Top-Level: A Symbol defined at the root of a .proto file. This includes all service definitions and any message, enum, or extend block not nested in message. Visibility: Property of a Symbol that controls whether it can be imported into another .Proto Serialization Is Not Canonicalhttps://protobuf.dev/programming-guides/serialization-not-canonical/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/serialization-not-canonical/Many people want a serialized proto to canonically represent the contents of that proto. Use cases include: +using a serialized proto as a key in a hash table taking a fingerprint or checksum of a serialized proto comparing serialized payloads as a way of checking message equality Unfortunately, protobuf serialization is not (and cannot be) canonical. There are a few notable exceptions, such as MapReduce, but in general you should generally think of proto serialization as unstable.Deserializing Debug Proto Representationshttps://protobuf.dev/programming-guides/deserialize-debug/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/programming-guides/deserialize-debug/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. +Unlike the Protobuf DebugString output format, the new debugging format automatically redacts sensitive fields by replacing their values with the string &ldquo;[REDACTED]&rdquo; (without the quotation marks). \ No newline at end of file diff --git a/programming-guides/json/index.html b/programming-guides/json/index.html new file mode 100644 index 000000000..8b692905d --- /dev/null +++ b/programming-guides/json/index.html @@ -0,0 +1,200 @@ +ProtoJSON Format | Protocol Buffers Documentation +

ProtoJSON Format

Describes the spec details of the canonical JSON representation for Protobuf messages.

Protobuf supports a canonical encoding in JSON, making it easier to share data +with systems that do not support the standard protobuf binary wire format.

This page specifies the format, but a number of additional edge cases which +define a conformant ProtoJSON parser are covered in the Protobuf Conformance +Test Suite and are not exhaustively detailed here.

Non-goals of the Format

Cannot Represent Some JSON schemas

The ProtoJSON format is designed to be a JSON representation of schemas which +are expressible in the Protobuf schema language.

It may be possible to represent many pre-existing JSON schemas as a Protobuf +schema and parse it using ProtoJSON, but it is not designed to be able to +represent arbitrary JSON schemas.

For example, there is no way to express in Protobuf schema to write types that +may be common in JSON schemas like number[][] or number|string.

It is possible to use google.protobuf.Struct and google.protobuf.Value types +to allow arbitrary JSON to be parsed into a Protobuf schema, but these only +allow you to capture the values as schemaless unordered key-value maps.

Not as efficient as the binary wire format

ProtoJSON Format is not as efficient as binary wire format and never will be.

The converter uses more CPU to encode and decode messages and (except in rare +cases) encoded messages consume more space.

Does not have as good schema-evolution guarantees as binary wire format

ProtoJSON format does not support unknown fields, and it puts field and enum +value names into encoded messages which makes it much harder to change those +names later. Removing fields is a breaking change that will trigger a parsing +error.

See JSON Wire Safety below for more details.

Format Description

Representation of each type

The following table shows how data is represented in JSON files.

Protobuf typeJSONJSON exampleNotes
messageobject{"fooBar": v, "g": null, ...}Generates JSON objects.

Keys are serialized as lowerCamelCase of field name. See +Field Names for more special cases regarding mapping of field names +to object keys.

Well-known types have special representations, as described in the Well-known types table.

null is valid for any field and leaves the field unset. See Null Values for clarification about the semantic behavior of null values.

enumstring"FOO_BAR"The name of the enum value as specified in proto is used. Parsers +accept both enum names and integer values.
map<K,V>object{"k": v, ...}All keys are converted to strings (object keys in JSON can only be strings).
repeated Varray[v, ...]
booltrue, falsetrue, false
stringstring"Hello World!"
bytesbase64 string"YWJjMTIzIT8kKiYoKSctPUB+"JSON value will be the data encoded as a string using standard base64 +encoding with paddings. Either standard or URL-safe base64 encoding +with/without paddings are accepted.
int32, fixed32, uint32number1, -10, 0JSON value will be a number. Either numbers or strings are +accepted. Empty strings are invalid. Exponent notation (such as 1e2) is +accepted in both quoted and unquoted forms.
int64, fixed64, uint64string"1", "-10"JSON value will be a decimal string. Either numbers or strings are +accepted. Empty strings are invalid. Exponent notation (such as 1e2) is +accepted in both quoted and unquoted forms. See Strings for int64s +for the explanation why strings are used for int64s.
float, doublenumber1.1, -10.0, 0, "NaN", "Infinity"JSON value will be a number or one of the special string values "NaN", +"Infinity", and "-Infinity". Either numbers or strings are accepted. +Empty strings are invalid. Exponent notation is also accepted.

Well-Known Types

Some messages in the google.protobuf package have a special representation +when represented in JSON.

No message type outside of the google.protobuf package has a special ProtoJSON +handling; for example, types in google.types package are represented with the +neutral representation.

Message typeJSONJSON exampleNotes
Anyobject{"@type": "url", "f": v, ... }See Any
Timestampstring"1972-01-01T10:00:20.021Z"Uses RFC 3339 (see clarification). Generated output will always be Z-normalized +with 0, 3, 6 or 9 fractional digits. Offsets other than "Z" are +also accepted.
Durationstring"1.000340012s", "1s"Generated output always contains 0, 3, 6, or 9 fractional digits, +depending on required precision, followed by the suffix "s". Accepted +are any fractional digits (also none) as long as they fit into +nanoseconds precision and the suffix "s" is required. This is not RFC 3339 +'duration' format (see Durations for clarification).
Structobject{ ... }Any JSON object. See struct.proto.
Wrapper typesvarious types2, "2", "foo", true, "true", null, 0, ...Wrappers use the same representation in JSON as the wrapped primitive +type, except that null is allowed and preserved during data +conversion and transfer.
FieldMaskstring"f.fooBar,h"See field_mask.proto.
ListValuearray[foo, bar, ...]
ValuevalueAny JSON value. Check +google.protobuf.Value +for details.
NullValuenullJSON null. Special case of the null parsing behavior.
Emptyobject{} (not special cased)An empty JSON object

Field names as JSON keys

Message field names are mapped to lowerCamelCase to be used as JSON object keys. +If the json_name field option is specified, the specified value will be used +as the key instead.

Parsers accept both the lowerCamelCase name (or the one specified by the +json_name option) and the original proto field name. This allows for a +serializer option to choose to print using the original field name (see +JSON Options) and have the resulting output still be parsed +back by all spec parsers.

\0 (nul) is not allowed within a json_name value. For more on why, see +Stricter validation +for json_name. Note that \0 is still considered a legal character within +the value of a string field.

Presence and default-values

When generating JSON-encoded output from a protocol buffer, if a field supports +presence, serializers must emit the field value if and only if the corresponding +hazzer would return true.

If the field doesn’t support field presence and has the default value (for +example any empty repeated field) serializers should omit it from the output. An +implementation may provide options to include fields with default values in the +output.

Null values

Serializers should not emit null values.

Parsers accept null as a legal value for any field, with the following +behavior:

  • Any key validity checking should still occur (disallowing unknown fields).
  • The field should remain unset, as though it was not present in the input at +all (hazzers should still return false where applicable).

The implication of this is that a null value for an implicit presence field +will behave the identically to the behavior to the default value of that field, +since there are no hazzers for those fields. For example, a value of null or +[] for a repeated field will cause key-validation checks, but both will +otherwise behave the same as if the field was not present in the JSON at all.

null values are not allowed within repeated fields.

google.protobuf.NullValue is a special exception to this behavior: null is +handled as a sentinel-present value for this type, and so a field of this type +must be handled by serializers and parsers under the standard presence behavior. +This behavior correspondingly allows google.protobuf.Struct and +google.protobuf.Value to losslessly round trip arbitrary JSON.

Duplicate values

Serializers must never serialize the same field multiple times, nor multiple +different cases in the same oneof in the same JSON object.

Parsers should accept the same field being duplicated, and the last value +provided should be retained. This also applies to “alternate spellings” of the +same field name.

If implementations cannot maintain the necessary information about field order +it is preferred to reject inputs with duplicate keys rather than have an +arbitrary value win. In some implementations maintaining field order of objects +may be impractical or infeasible, so it is strongly recommended that systems +avoid relying on specific behavior for duplicate fields in ProtoJSON where +possible.

Out of range numeric values

When parsing a numeric value, if the number that is is parsed from the wire +doesn’t fit in the corresponding type, the parser should fail to parse.

This includes any negative number for uint32, and numbers less than INT_MIN +or larger than INT_MAX for int32.

Values with nonzero fractional portions are not allowed for integer-typed +fields. Zero fractional portions are accepted. For example 1.0 is valid for an +int32 field, but 1.5 is not.

Strings for int64

Unfortunately, the json.org spec does not speak to the +intended precision limits of numbers. Many implementations follow the original +JS behavior that JSON was derived from and interpret all numbers as binary64 +(double precision) and are silently lossy if a number is an integer larger than +2**53. Other implementations may support unlimited precision bigints, int64s, or +even bigfloats with unlimited fractional precision.

This creates a situation where if the JSON contains a number that is not exactly +representable by double precision, different parsers will behave differently, +including silent precision loss in many languages.

To avoid these problems, ProtoJSON serializers emit int64s as strings to ensure +no precision loss will occur on large int64s by any implementation.

When parsing a bare number when expecting an int64, the implementation should +coerce that value to double-precision even if the corresponding language’s +built-in JSON parser supports parsing of JSON numbers as bigints. This ensures a +consistent interpretation of the same data, regardless of language used.

This design follows established best practices in how to handle large numbers in +JSON when prioritizing interoperability, including:

  • RFC8259 includes +a note that software that intends good interoperability should only presume +double precision on all numbers.

  • OpenAPI int64 +documentation recommends using a JSON string instead of a number when +precision beyond 2**53 is desired.

Any

Normal messages

For any message that is not a well-known type with a special JSON +representation, the message contained inside the Any is turned into a JSON +object with an additional "@type" field inserted that contains the type_url +that was set on the Any.

For example, if you have this message definition:

package x;
+message Child { int32 x = 1; string y = 2; }
+

When an instance of Child is packed into an Any, the JSON representation is:

{
+  "@type": "type.googleapis.com/x.Child",
+  "x": 1,
+  "y": "hello world"
+}
+

Special-cased well-known types

If the Any contains a well-known type that has a special JSON mapping, the +message is converted into the special representation and set as a field with key +“value”.

For example, a google.protobuf.Duration that represents 3.1 seconds will be +represented by the string "3.1s" in the special case handling. When that +Duration is packed into an Any it will be serialized as:

{
+  "@type": "type.googleapis.com/google.protobuf.Duration",
+  "value": "3.1s"
+}
+

Message types with special JSON encodings include:

  • google.protobuf.Any
  • google.protobuf.BoolValue
  • google.protobuf.BytesValue
  • google.protobuf.DoubleValue
  • google.protobuf.Duration
  • google.protobuf.FieldMask
  • google.protobuf.FloatValue
  • google.protobuf.Int32Value
  • google.protobuf.Int64Value
  • google.protobuf.ListValue
  • google.protobuf.StringValue
  • google.protobuf.Struct
  • google.protobuf.Timestamp
  • google.protobuf.UInt32Value
  • google.protobuf.UInt64Value
  • google.protobuf.Value

Note that google.protobuf.Empty is not considered to have any special JSON +mapping; it is simply a normal message that has zero fields. This means the +expected representation of an Empty packed into an Any is {"@type": "type.googleapis.com/google.protobuf.Empty"} and not {"@type": "type.googleapis.com/google.protobuf.Empty", "value": {}}.

ProtoJSON Wire Safety

When using ProtoJSON, only some schema changes are safe to make in a distributed +system. This contrasts with the same concepts applied to the +the binary wire format.

JSON Wire-unsafe Changes

Wire-unsafe changes are schema changes that will break if you parse data that +was serialized using the old schema with a parser that is using the new schema +(or vice versa). You should almost never do this shape of schema change.

  • Changing a field to or from an extension of same number and type is not +safe.
  • Changing a field between string and bytes is not safe.
  • Changing a field between a message type and bytes is not safe.
  • Changing any field from optional to repeated is not safe.
  • Changing a field between a map<K, V> and the corresponding repeated +message field is not safe.
  • Moving fields into an existing oneof is not safe.

JSON Wire-safe Changes

Wire-safe changes are ones where it is fully safe to evolve the schema in this +way without risk of data loss or new parse failures.

Note that nearly all wire-safe changes may be a breaking change to application +code. For example, adding a value to a preexisting enum would be a compilation +break for any code with an exhaustive switch on that enum. For that reason, +Google may avoid making some of these types of changes on public messages. The +AIPs contain guidance for which of these changes are safe to make there.

  • Changing a single optional field into a member of a new oneof is +safe.
  • Changing a oneof which contains only one field to an optional field is +safe.
  • Changing a field between any of int32, sint32, sfixed32, fixed32 is +safe.
  • Changing a field between any of int64, sint64, sfixed64, fixed64 is +safe.
  • Changing a field number is safe (as the field numbers are not used in the +ProtoJSON format), but still strongly discouraged since it is very unsafe in +the binary wire format.
  • Adding values to an enum is safe if the “Emit enum values as integers” is +set on all relevant clients (see options)

JSON Wire-compatible Changes (Conditionally safe)

Unlike wire-safe changes, wire-compatible means that the same data can be parsed +both before and after a given change. However, a client that reads it will get +lossy data under this shape of change. For example, changing an int32 to an +int64 is a compatible change, but if a value larger than INT32_MAX is written, a +client that reads it as an int32 will discard the high order bits.

You can make compatible changes to your schema only if you manage the roll out +to your system carefully. For example, you may change an int32 to an int64 but +ensure you continue to only write legal int32 values until the new schema is +deployed to all endpoints, and then start writing larger values after that.

Compatible But With Unknown Field Handling Problems

Unlike the binary wire format, ProtoJSON implementations generally do not +propagate unknown fields. This means that adding to schemas is generally +compatible but will result in parse failures if a client using the old schema +observes the new content.

This means you can add to your schema, but you cannot safely start writing them +until you know the schema has been deployed to the relevant client or server (or +that the relevant clients set an Ignore Unknown Fields flag, discussed +below).

  • Adding and removing fields is considered compatible with this caveat.
  • Removing enum values is considered compatible with this caveat.

Compatible But Potentially Lossy

  • Changing between any of the 32-bit integers (int32, uint32, sint32, +sfixed32, fixed32) and any of the 64-bit integers ( int64, uint64, +sint64, sfixed32) is a compatible change.
    • If a number is parsed from the wire that doesn’t fit in the +corresponding type, a parse failure will occur.
    • Unlike binary wire format, bool is not compatible with integers.
    • Note that the int64 and uint64 types are quoted by default to avoid +precision loss when handled as a double or JavaScript number, and the 32 +bit types are unquoted by default. Conformant parsers will accept either +quoted or unquoted for all integer types, but nonconformant +implementations may mishandle this case and not handle quoted-int32s or +unquoted-int64s, so caution should be taken.
  • enum may be conditionally compatible with string
    • If “enums-as-ints” flag is used by any client, then enums will instead +be compatible with the integer types instead.

RFC 3339 Clarifications

Timestamps

ProtoJSON timestamps use the RFC 3339 timestamp format. Unfortunately, some +ambiguity in the RFC 3339 spec has created a few edge cases where various other +RFC 3339 implementations do not agree on whether or not the format is legal.

RFC 3339 intends to declare a strict +subset of ISO-8601 format, and some additional ambiguity was created since RFC +3339 was published in 2002 and then ISO-8601 was subsequently revised without +any corresponding revisions of RFC 3339.

Most notably, ISO-8601-1988 contains this note:

In date and time representations lower case characters may be used when upper +case characters are not available.

It is ambiguous whether this note is suggesting that parsers should accept +lowercase letters in general, or if it is only suggesting that lowercase letters +may be used as a substitute in environments where uppercase cannot be +technically used. RFC 3339 contains a note that intends to clarify the +interpretation to be that lowercase letters should be accepted in general.

ISO-8601-2019 does not contain the corresponding note and is unambiguous that +lowercase letters are not allowed.

This created some confusion for all libraries that declare they support RFC +3339: today RFC 3339 declares it is a profile of ISO-8601 but contains a +clarifying note referencing text that is not present in the latest ISO-8601 +spec.

ProtoJSON spec takes the decision that the timestamp format is the stricter +definition of “RFC 3339 as a profile of ISO-8601-2019”. Some Protobuf +implementations may be non-conformant by using a timestamp parsing +implementation that is implemented as “RFC 3339 as a profile of ISO-8601-1988,” +which will accept a few additional edge cases.

For consistent interoperability, parsers should only accept the stricter subset +format where possible. When using a non-conformant implementation that accepts +the laxer definition, strongly avoid relying on the additional edge cases being +accepted.

Durations

RFC 3339 also defines a duration format, but unfortunately the RFC 3339 duration +format does not have any way to express sub-second resolution.

The ProtoJSON duration encoding is directly inspired by RFC 3339 dur-seconds +representation, but it is able to encode nanosecond precision. For integer +number of seconds the two representations may match (like 10s), but the +ProtoJSON durations accept fractional values and conformant implementations must +precisely represent nanosecond precision (like 10.500000001s).

JSON Options

A conformant protobuf JSON implementation may provide the following options:

  • Always emit fields without presence: Fields that don’t support presence +and that have their default value are omitted by default in JSON output (for +example, an implicit presence integer with a 0 value, implicit presence +string fields that are empty strings, and empty repeated and map fields). An +implementation may provide an option to override this behavior and output +fields with their default values.

    As of v25.x, the C++, Java, and Python implementations are nonconformant, as +this flag affects proto2 optional fields but not proto3 optional fields. +A fix is planned for a future release.

  • Ignore unknown fields: The protobuf JSON parser should reject unknown +fields by default but may provide an option to ignore unknown fields in +parsing.

  • Use proto field name instead of lowerCamelCase name: By default the +protobuf JSON printer should convert the field name to lowerCamelCase and +use that as the JSON name. An implementation may provide an option to use +proto field name as the JSON name instead. Protobuf JSON parsers are +required to accept both the converted lowerCamelCase name and the proto +field name.

  • Emit enum values as integers instead of strings: The name of an enum +value is used by default in JSON output. An option may be provided to use +the numeric value of the enum value instead.

\ No newline at end of file diff --git a/programming-guides/migration/index.html b/programming-guides/migration/index.html new file mode 100644 index 000000000..faf4253ee --- /dev/null +++ b/programming-guides/migration/index.html @@ -0,0 +1,2 @@ +https://protobuf.dev/support/migration/ + \ No newline at end of file diff --git a/programming-guides/nullable-getters-setters/index.html b/programming-guides/nullable-getters-setters/index.html new file mode 100644 index 000000000..f3a5ad3a0 --- /dev/null +++ b/programming-guides/nullable-getters-setters/index.html @@ -0,0 +1,2 @@ +https://protobuf.dev/design-decisions/nullable-getters-setters/ + \ No newline at end of file diff --git a/programming-guides/proto-limits/index.html b/programming-guides/proto-limits/index.html new file mode 100644 index 000000000..19c9372a6 --- /dev/null +++ b/programming-guides/proto-limits/index.html @@ -0,0 +1,23 @@ +Proto Limits | Protocol Buffers Documentation +

Proto Limits

Covers the limits to number of supported elements in proto schemas.

This topic documents the limits to the number of supported elements (fields, +enum values, and so on) in proto schemas.

This information is a collection of discovered limitations by many engineers, +but is not exhaustive and may be incorrect/outdated in some areas. As you +discover limitations in your work, contribute those to this document to help +others.

Number of Fields

All messages are limited to 65,535 fields.

Message with only singular proto fields (such as Boolean):

  • ~2100 fields (proto2)
  • ~3100 (proto3 without using optional fields)

Empty message extended by singular fields (such as Boolean):

  • ~4100 fields (proto2)

Extensions are not supported in proto3.

To test this limitation, create a proto message with more than the upper bound +number of fields and compile using a Java proto rule. The limit comes from JVM +specs.

Number of Values in an Enum

The lowest limit is ~1700 values, in Java +. Other languages have different +limits.

Total Size of the Message

Any proto in serialized form must be <2GiB, as that is the maximum size +supported by all implementations. It’s recommended to bound request and response +sizes.

Depth Limit for Proto Unmarshaling

  • Java: +100
  • C++: +100
  • Go: +10000 +(there is a plan to reduce this to 100)

If you try to unmarshal a message that is nested deeper than the depth limit, +the unmarshaling will fail.

\ No newline at end of file diff --git a/programming-guides/proto/index.html b/programming-guides/proto/index.html new file mode 100644 index 000000000..212a5b793 --- /dev/null +++ b/programming-guides/proto/index.html @@ -0,0 +1,2 @@ +https://protobuf.dev/programming-guides/proto2/ + \ No newline at end of file diff --git a/programming-guides/proto2/index.html b/programming-guides/proto2/index.html new file mode 100644 index 000000000..578d89d7a --- /dev/null +++ b/programming-guides/proto2/index.html @@ -0,0 +1,1274 @@ +Language Guide (proto 2) | Protocol Buffers Documentation +

Language Guide (proto 2)

Covers how to use the proto2 revision of Protocol Buffers language in your project.

This guide describes how to use the protocol buffer language to structure your +protocol buffer data, including .proto file syntax and how to generate data +access classes from your .proto files. It covers the proto2 revision of +the protocol buffers language.

For information on editions syntax, see the +Protobuf Editions Language Guide.

For information on proto3 syntax, see the +Proto3 Language Guide.

This is a reference guide – for a step by step example that uses many of the +features described in this document, see the +tutorial +for your chosen language.

Defining A Message Type

First let’s look at a very simple example. Let’s say you want to define a search +request message format, where each search request has a query string, the +particular page of results you are interested in, and a number of results per +page. Here’s the .proto file you use to define the message type.

syntax = "proto2";
+
+message SearchRequest {
+  optional string query = 1;
+  optional int32 page_number = 2;
+  optional int32 results_per_page = 3;
+}
+
  • The first line of the file specifies that you’re using the proto2 revision +of the protobuf language spec.

    • The syntax must be the first non-empty, non-comment line of the file.
    • If no syntax is specified, the protocol buffer compiler will assume +you are using proto2.
  • The SearchRequest message definition specifies three fields (name/value +pairs), one for each piece of data that you want to include in this type of +message. Each field has a name and a type.

Specifying Field Types

In the earlier example, all the fields are scalar types: two integers +(page_number and results_per_page) and a string (query). You can also +specify enumerations and composite types like other message types for +your field.

Assigning Field Numbers

You must give each field in your message definition a number between 1 and +536,870,911 with the following restrictions:

  • The given number must be unique among all fields for that message.
  • Field numbers 19,000 to 19,999 are reserved for the Protocol Buffers +implementation. The protocol buffer compiler will complain if you use one of +these reserved field numbers in your message.
  • You cannot use any previously reserved field numbers or +any field numbers that have been allocated to extensions.

This number cannot be changed once your message type is in use because it +identifies the field in the +message wire format. +“Changing” a field number is equivalent to deleting that field and creating a +new field with the same type but a new number. See Deleting Fields +for how to do this properly.

Field numbers should never be reused. Never take a field number out of the +reserved list for reuse with a new field definition. See +Consequences of Reusing Field Numbers.

You should use the field numbers 1 through 15 for the most-frequently-set +fields. Lower field number values take less space in the wire format. For +example, field numbers in the range 1 through 15 take one byte to encode. Field +numbers in the range 16 through 2047 take two bytes. You can find out more about +this in +Protocol Buffer Encoding.

Consequences of Reusing Field Numbers

Reusing a field number makes decoding wire-format messages ambiguous.

The protobuf wire format is lean and doesn’t provide a way to detect fields +encoded using one definition and decoded using another.

Encoding a field using one definition and then decoding that same field with a +different definition can lead to:

  • Developer time lost to debugging
  • A parse/merge error (best case scenario)
  • Leaked PII/SPII
  • Data corruption

Common causes of field number reuse:

  • renumbering fields (sometimes done to achieve a more aesthetically pleasing +number order for fields). Renumbering effectively deletes and re-adds all +the fields involved in the renumbering, resulting in incompatible +wire-format changes.

  • deleting a field and not reserving the number to prevent +future reuse.

The field number is limited to 29 bits rather than 32 bits because three bits +are used to specify the field’s wire format. For more on this, see the +Encoding topic.

Specifying Field Cardinality

Message fields can be one of the following:

  • Singular:

    In proto2, there are two types of singular fields:

    • optional: (recommended) An optional field is in one of two possible +states:

      • the field is set, and contains a value that was explicitly set or +parsed from the wire. It will be serialized to the wire.
      • the field is unset, and will return the default value. It will not +be serialized to the wire.

      You can check to see if the value was explicitly set.

    • required: Do not use. Required fields are so problematic they were +removed from proto3 and editions. Semantics for required field should be +implemented at the application layer. +When it is used, a +well-formed message must have exactly one of this field.

  • repeated: this field type can be repeated zero or more times in a +well-formed message. The order of the repeated values will be preserved.

  • map: this is a paired key/value field type. See +Maps for more on +this field type.

Use Packed Encoding for New Repeated Fields

For historical reasons, repeated fields of scalar numeric types (for example, +int32, int64, enum) aren’t encoded as efficiently as they could be. New +code should use the special option [packed = true] to get a more efficient +encoding. For example:

repeated int32 samples = 4 [packed = true];
+repeated ProtoEnum results = 5 [packed = true];
+

You can find out more about packed encoding in +Protocol Buffer Encoding.

Required is Strongly Deprecated

A second issue with required fields appears when someone adds a value to an +enum. In this case, the unrecognized enum value is treated as if it were +missing, which also causes the required value check to fail.

Well-formed Messages

The term “well-formed,” when applied to protobuf messages, refers to the bytes +serialized/deserialized. The protoc parser validates that a given proto +definition file is parseable.

Singular fields can appear more than once in wire-format bytes. The parser will +accept the input, but only the last instance of that field will be accessible +through the generated bindings. See +Last One Wins +for more on this topic.

Adding More Message Types

Multiple message types can be defined in a single .proto file. This is useful +if you are defining multiple related messages – so, for example, if you wanted +to define the reply message format that corresponds to your SearchResponse +message type, you could add it to the same .proto:

message SearchRequest {
+  optional string query = 1;
+  optional int32 page_number = 2;
+  optional int32 results_per_page = 3;
+}
+
+message SearchResponse {
+ ...
+}
+

Combining Messages leads to bloat While multiple message types (such as +message, enum, and service) can be defined in a single .proto file, it can +also lead to dependency bloat when large numbers of messages with varying +dependencies are defined in a single file. It’s recommended to include as few +message types per .proto file as possible.

Adding Comments

To add comments to your .proto files:

  • Prefer C/C++/Java line-end-style comments ‘//’ on the line before the .proto +code element

  • C-style inline/multi-line comments /* ... */ are also accepted.

    • When using multi-line comments, a margin line of ‘*’ is preferred.
/**
+ * SearchRequest represents a search query, with pagination options to
+ * indicate which results to include in the response.
+ */
+message SearchRequest {
+  optional string query = 1;
+
+  // Which page number do we want?
+  optional int32 page_number = 2;
+
+  // Number of results to return per page.
+  optional int32 results_per_page = 3;
+}
+

Deleting Fields

Deleting fields can cause serious problems if not done properly.

Do not delete required fields. This is almost impossible to do safely. If +you must delete a required field, you should first mark the field optional +and deprecated and ensure that all systems which in any way observe the +message have been deployed with the new schema. Then you can consider removing +the field (but note that this is still an error-prone process).

When you no longer need a field that is not required, first delete all +references to the field from client code, and then delete the field definition +from the message. However, you must +reserve the deleted field number. If you do not reserve the +field number, it is possible for a developer to reuse that number in the future +and cause a breakage.

You should also reserve the field name to allow JSON and TextFormat encodings of +your message to continue to parse.

Reserved Field Numbers

If you update a message type by entirely deleting a field, or +commenting it out, future developers can reuse the field number when making +their own updates to the type. This can cause severe issues, as described in +Consequences of Reusing Field Numbers. To make sure this +doesn’t happen, add your deleted field number to the reserved list.

The protoc compiler will generate error messages if any future developers try to +use these reserved field numbers.

message Foo {
+  reserved 2, 15, 9 to 11;
+}
+

Reserved field number ranges are inclusive (9 to 11 is the same as 9, 10, 11).

Reserved Field Names

Reusing an old field name later is generally safe, except when using TextProto +or JSON encodings where the field name is serialized. To avoid this risk, you +can add the deleted field name to the reserved list.

Reserved names affect only the protoc compiler behavior and not runtime +behavior, with one exception: TextProto implementations may discard unknown +fields (without raising an error like with other unknown fields) with reserved +names at parse time (only the C++ and Go implementations do so today). Runtime +JSON parsing is not affected by reserved names.

message Foo {
+  reserved 2, 15, 9 to 11;
+  reserved "foo", "bar";
+}
+

Note that you can’t mix field names and field numbers in the same reserved +statement.

What’s Generated from Your .proto?

When you run the protocol buffer compiler on a .proto, the +compiler generates the code in your chosen language you’ll need to work with the +message types you’ve described in the file, including getting and setting field +values, serializing your messages to an output stream, and parsing your messages +from an input stream.

  • For C++, the compiler generates a .h and .cc file from each +.proto, with a class for each message type described in your file.
  • For Java, the compiler generates a .java file with a class for each +message type, as well as a special Builder class for creating message +class instances.
  • For Kotlin, in addition to the Java generated code, the compiler +generates a .kt file for each message type with an improved Kotlin API. +This includes a DSL that simplifies creating message instances, a nullable +field accessor, and a copy function.
  • Python is a little different — the Python compiler generates a module +with a static descriptor of each message type in your .proto, which is +then used with a metaclass to create the necessary Python data access +class at runtime.
  • For Go, the compiler generates a .pb.go file with a type for each +message type in your file.
  • For Ruby, the compiler generates a .rb file with a Ruby module +containing your message types.
  • For Objective-C, the compiler generates a pbobjc.h and pbobjc.m file +from each .proto, with a class for each message type described in your +file.
  • For C#, the compiler generates a .cs file from each .proto, with a +class for each message type described in your file.
  • For PHP, the compiler generates a .php message file for each message +type described in your file, and a .php metadata file for each .proto +file you compile. The metadata file is used to load the valid message types +into the descriptor pool.
  • For Dart, the compiler generates a .pb.dart file with a class for each +message type in your file.

You can find out more about using the APIs for each language by following the +tutorial for your chosen language. For even more API +details, see the relevant API reference.

Scalar Value Types

A scalar message field can have one of the following types – the table shows the +type specified in the .proto file, and the corresponding type in the +automatically generated class:

Proto TypeNotes
double
float
int32Uses variable-length encoding. Inefficient for encoding negative +numbers – if your field is likely to have negative values, use sint32 +instead.
int64Uses variable-length encoding. Inefficient for encoding negative +numbers – if your field is likely to have negative values, use sint64 +instead.
uint32Uses variable-length encoding.
uint64Uses variable-length encoding.
sint32Uses variable-length encoding. Signed int value. These more +efficiently encode negative numbers than regular int32s.
sint64Uses variable-length encoding. Signed int value. These more +efficiently encode negative numbers than regular int64s.
fixed32Always four bytes. More efficient than uint32 if values are often +greater than 228.
fixed64Always eight bytes. More efficient than uint64 if values are often +greater than 256.
sfixed32Always four bytes.
sfixed64Always eight bytes.
bool
stringA string must always contain UTF-8 encoded or 7-bit ASCII text, and cannot +be longer than 232.
bytesMay contain any arbitrary sequence of bytes no longer than 232.
Proto TypeC++ TypeJava/Kotlin Type[1]Python Type[3]Go TypeRuby TypeC# TypePHP TypeDart TypeRust Type
doubledoubledoublefloat*float64Floatdoublefloatdoublef64
floatfloatfloatfloat*float32Floatfloatfloatdoublef32
int32int32_tintintint32Fixnum or Bignum (as required)intinteger*int32i32
int64int64_tlongint/long[4]*int64Bignumlonginteger/string[6]Int64i64
uint32uint32_tint[2]int/long[4]*uint32Fixnum or Bignum (as required)uintintegerintu32
uint64uint64_tlong[2]int/long[4]*uint64Bignumulonginteger/string[6]Int64u64
sint32int32_tintintint32Fixnum or Bignum (as required)intinteger*int32i32
sint64int64_tlongint/long[4]*int64Bignumlonginteger/string[6]Int64i64
fixed32uint32_tint[2]int/long[4]*uint32Fixnum or Bignum (as required)uintintegerintu32
fixed64uint64_tlong[2]int/long[4]*uint64Bignumulonginteger/string[6]Int64u64
sfixed32int32_tintint*int32Fixnum or Bignum (as required)intintegerinti32
sfixed64int64_tlongint/long[4]*int64Bignumlonginteger/string[6]Int64i64
boolboolbooleanbool*boolTrueClass/FalseClassboolbooleanboolbool
stringstringStringunicode (Python 2), str (Python 3)*stringString (UTF-8)stringstringStringProtoString
bytesstringByteStringbytes[]byteString (ASCII-8BIT)ByteStringstringListProtoBytes

[1] Kotlin uses the corresponding types from Java, even for unsigned +types, to ensure compatibility in mixed Java/Kotlin codebases.

[2] In Java, unsigned 32-bit and 64-bit integers are represented +using their signed counterparts, with the top bit simply being stored in the +sign bit.

[3] In all cases, setting values to a field will perform type +checking to make sure it is valid.

[4] 64-bit or unsigned 32-bit integers are always represented as long +when decoded, but can be an int if an int is given when setting the field. In +all cases, the value must fit in the type represented when set. See [2].

[5] Proto2 typically doesn’t ever check the UTF-8 validity of string +fields. Behavior varies between languages though, and invalid UTF-8 data should +not be stored in string fields.

[6] Integer is used on 64-bit machines and string is used on 32-bit +machines.

You can find out more about how these types are encoded when you serialize your +message in +Protocol Buffer Encoding.

Default Field Values

When a message is parsed, if the encoded message bytes do not contain a +particular field, accessing that field in the parsed object returns the default +value for that field. The default values are type-specific:

  • For strings, the default value is the empty string.
  • For bytes, the default value is empty bytes.
  • For bools, the default value is false.
  • For numeric types, the default value is zero.
  • For message fields, the field is not set. Its exact value is +language-dependent. See the +generated code guide for your language +for details.
  • For enums, the default value is the first defined enum value, which +should be 0 (recommended for compatibility with open enums). See +Enum Default Value.

The default value for repeated fields is empty (generally an empty list in the +appropriate language).

The default value for map fields is empty (generally an empty map in the +appropriate language).

Overriding Default Scalar Values

In proto2, you can specify explicit default values for singular non-message +fields. For example, let’s say you want to provide a default value of 10 for the +SearchRequest.results_per_page field:

optional int32 results_per_page = 3 [default = 10];
+

If the sender does not specify results_per_page, the receiver will observe the +following state:

  • The results_per_page field is not present. That is, the +has_results_per_page() (hazzer method) method would return false.
  • The value of results_per_page (returned from the “getter”) is 10.

If the sender does send a value for results_per_page the default value of 10 +is ignored and the sender’s value is returned from the “getter”.

See the generated code guide for your +chosen language for more details about how defaults work in generated code.

Because the default value for enums is the first defined enum value, take care +when adding a value to the beginning of an enum value list. See the +Updating a Message Type section for guidelines on how to safely +change definitions.

Enumerations

When you’re defining a message type, you might want one of its fields to only +have one of a predefined list of values. For example, let’s say you want to add +a corpus field for each SearchRequest, where the corpus can be UNIVERSAL, +WEB, IMAGES, LOCAL, NEWS, PRODUCTS or VIDEO. You can do this very +simply by adding an enum to your message definition with a constant for each +possible value.

In the following example we’ve added an enum called Corpus with all the +possible values, and a field of type Corpus:

enum Corpus {
+  CORPUS_UNSPECIFIED = 0;
+  CORPUS_UNIVERSAL = 1;
+  CORPUS_WEB = 2;
+  CORPUS_IMAGES = 3;
+  CORPUS_LOCAL = 4;
+  CORPUS_NEWS = 5;
+  CORPUS_PRODUCTS = 6;
+  CORPUS_VIDEO = 7;
+}
+
+message SearchRequest {
+  optional string query = 1;
+  optional int32 page_number = 2;
+  optional int32 results_per_page = 3;
+  optional Corpus corpus = 4;
+}
+

Prefixing Enum Values

When prefixing enum values, the remainder of the name with the prefix stripped +should still be a legal and style-conformant enum name. For example, avoid the +following:

enum DeviceTier {
+  DEVICE_TIER_UNKNOWN = 0;
+  DEVICE_TIER_1 = 1;
+  DEVICE_TIER_2 = 2;
+}
+

Instead, use a value name like DEVICE_TIER_TIER1, where the DEVICE_TIER_ +portion is viewed as scoping the enum value rather than as part of the +individual enum value name. Some Protobuf implementations automatically strip +the prefix that matches the containing enum name where it is safe to do so, but +could not in this example since a bare 1 is not a legal enum value name.

We plan for a future Edition to add support for scoped enums, which will +eliminate the need to manually prefix each enum value and enable this to be +written succinctly as TIER1 = 1.

Enum Default Value

The default value for the SearchRequest.corpus field is CORPUS_UNSPECIFIED +because that is the first value defined in the enum.

It is strongly recommended to define the first value of every enum as +ENUM_TYPE_NAME_UNSPECIFIED = 0; or ENUM_TYPE_NAME_UNKNOWN = 0;. This is +because of the way proto2 handles unknown values for enum fields.

It is also recommended that this first, default value have no semantic meaning +other than “this value was unspecified”.

The default value for an enum field like SearchRequest.corpus field can be +explicitly overridden like this:

  optional Corpus corpus = 4 [default = CORPUS_UNIVERSAL];
+

Enum Value Aliases

You can define aliases by assigning the same value to different enum constants. +To do this you need to set the allow_alias option to true. Otherwise, the +protocol buffer compiler generates a warning message when aliases are +found. Though all alias values are valid for serialization, only the first value +is used when deserializing.

enum EnumAllowingAlias {
+  option allow_alias = true;
+  EAA_UNSPECIFIED = 0;
+  EAA_STARTED = 1;
+  EAA_RUNNING = 1;
+  EAA_FINISHED = 2;
+}
+
+enum EnumNotAllowingAlias {
+  ENAA_UNSPECIFIED = 0;
+  ENAA_STARTED = 1;
+  // ENAA_RUNNING = 1;  // Uncommenting this line will cause a warning message.
+  ENAA_FINISHED = 2;
+}
+

Enumerator constants must be in the range of a 32-bit integer. Since enum +values use +varint encoding on the +wire, negative values are inefficient and thus not recommended. You can define +enums within a message definition, as in the earlier example, or outside – +these enums can be reused in any message definition in your .proto file. You +can also use an enum type declared in one message as the type of a field in a +different message, using the syntax _MessageType_._EnumType_.

When you run the protocol buffer compiler on a .proto that uses an enum, the +generated code will have a corresponding enum for Java, Kotlin, or C++, or a +special EnumDescriptor class for Python that’s used to create a set of +symbolic constants with integer values in the runtime-generated class.

Removing enum values is a breaking change for persisted protos. Instead of +removing a value, mark the value with the reserved keyword to prevent the enum +value from being code-generated, or keep the value but indicate that it will be +removed later by using the deprecated field option:

enum PhoneType {
+  PHONE_TYPE_UNSPECIFIED = 0;
+  PHONE_TYPE_MOBILE = 1;
+  PHONE_TYPE_HOME = 2;
+  PHONE_TYPE_WORK = 3 [deprecated = true];
+  reserved 4,5;
+}
+

For more information about how to work with message enums in your +applications, see the generated code guide +for your chosen language.

Reserved Values

If you update an enum type by entirely removing an enum entry, or +commenting it out, future users can reuse the numeric value when making their +own updates to the type. This can cause severe issues if they later load old +instances of the same .proto, including data corruption, privacy bugs, and so +on. One way to make sure this doesn’t happen is to specify that the numeric +values (and/or names, which can also cause issues for JSON serialization) of +your deleted entries are reserved. The protocol buffer compiler will complain +if any future users try to use these identifiers. You can specify that your +reserved numeric value range goes up to the maximum possible value using the +max keyword.

enum Foo {
+  reserved 2, 15, 9 to 11, 40 to max;
+  reserved "FOO", "BAR";
+}
+

Note that you can’t mix field names and numeric values in the same reserved +statement.

Using Other Message Types

You can use other message types as field types. For example, let’s say you +wanted to include Result messages in each SearchResponse message – to do +this, you can define a Result message type in the same .proto and then +specify a field of type Result in SearchResponse:

message SearchResponse {
+  repeated Result results = 1;
+}
+
+message Result {
+  optional string url = 1;
+  optional string title = 2;
+  repeated string snippets = 3;
+}
+

Importing Definitions

In the earlier example, the Result message type is defined in the same file as +SearchResponse – what if the message type you want to use as a field type is +already defined in another .proto file?

You can use definitions from other .proto files by importing them. To import +another .proto’s definitions, you add an import statement to the top of your +file:

import "myproject/other_protos.proto";
+

By default, you can use definitions only from directly imported .proto files. +However, sometimes you may need to move a .proto file to a new location. +Instead of moving the .proto file directly and updating all the call sites in +a single change, you can put a placeholder .proto file in the old location to +forward all the imports to the new location using the import public notion.

Note that the public import functionality is not available in Java, Kotlin, +TypeScript, JavaScript or GCL.

import public dependencies can be transitively relied upon by any code +importing the proto containing the import public statement. For example:

// new.proto
+// All definitions are moved here
+
// old.proto
+// This is the proto that all clients are importing.
+import public "new.proto";
+import "other.proto";
+
// client.proto
+import "old.proto";
+// You use definitions from old.proto and new.proto, but not other.proto
+

The protocol compiler searches for imported files in a set of directories +specified on the protocol compiler command line using the -I/--proto_path +flag. If no flag was given, it looks in the directory in which the compiler was +invoked. In general you should set the --proto_path flag to the root of your +project and use fully qualified names for all imports.

Using proto3 Message Types

It’s possible to import +proto3 and +edition 2023 message +types and use them in your proto2 messages, and vice versa. However, proto2 +enums cannot be used directly in proto3 syntax (it’s okay if an imported proto2 +message uses them).

Nested Types

You can define and use message types inside other message types, as in the +following example – here the Result message is defined inside the +SearchResponse message:

message SearchResponse {
+  message Result {
+    optional string url = 1;
+    optional string title = 2;
+    repeated string snippets = 3;
+  }
+  repeated Result results = 1;
+}
+

If you want to reuse this message type outside its parent message type, you +refer to it as _Parent_._Type_:

message SomeOtherMessage {
+  optional SearchResponse.Result result = 1;
+}
+

You can nest messages as deeply as you like. In the example below, note that the +two nested types named Inner are entirely independent, since they are defined +within different messages:

message Outer {       // Level 0
+  message MiddleAA {  // Level 1
+    message Inner {   // Level 2
+      optional int64 ival = 1;
+      optional bool  booly = 2;
+    }
+  }
+  message MiddleBB {  // Level 1
+    message Inner {   // Level 2
+      optional int32  ival = 1;
+      optional bool   booly = 2;
+    }
+  }
+}
+

Groups

Note that the groups feature is deprecated and should not be used when +creating new message types. Use nested message types instead.

Groups are another way to nest information in your message definitions. For +example, another way to specify a SearchResponse containing a number of +Results is as follows:

message SearchResponse {
+  repeated group Result = 1 {
+    optional string url = 1;
+    optional string title = 2;
+    repeated string snippets = 3;
+  }
+}
+

A group simply combines a nested message type and a field into a single +declaration. In your code, you can treat this message just as if it had a +Result type field called result (the latter name is converted to lower-case +so that it does not conflict with the former). Therefore, this example is +exactly equivalent to the SearchResponse earlier, except that the message has +a different wire format.

Updating a Message Type

If an existing message type no longer meets all your needs – for example, you’d +like the message format to have an extra field – but you’d still like to use +code created with the old format, don’t worry! It’s very simple to update +message types without breaking any of your existing code when you use the binary +wire format.

Check +Proto Best Practices and the +following rules:

Binary Wire-unsafe Changes

Wire-unsafe changes are schema changes that will break if you use parse data +that was serialized using the old schema with a parser that is using the new +schema (or vice versa). Only make wire-unsafe changes if you know that all +serializers and deserializers of the data are using the new schema.

  • Changing field numbers for any existing field is not safe.
    • Changing the field number is equivalent to deleting the field and adding +a new field with the same type. If you want to renumber a field, see the +instructions for deleting a field.
  • Moving fields into an existing oneof is not safe.

Binary Wire-safe Changes

Wire-safe changes are ones where it is fully safe to evolve the schema in this +way without risk of data loss or new parse failures.

Note that any wire-safe changes may be a breaking change to application code in +a given language. For example, adding a value to a preexisting enum would be a +compilation break for any code with an exhaustive switch on that enum. For that +reason, Google may avoid making some of these types of changes on public +messages: the AIPs contain guidance for which of these changes are safe to make +there.

  • Adding new fields is safe.
    • If you add new fields, any messages serialized by code using your “old” +message format can still be parsed by your new generated code. You +should keep in mind the default values for these elements so +that new code can properly interact with messages generated by old code. +Similarly, messages created by your new code can be parsed by your old +code: old binaries simply ignore the new field when parsing. See the +Unknown Fields section for details.
  • Removing fields is safe.
    • The same field number must not used again in your updated message type. +You may want to rename the field instead, perhaps adding the prefix +“OBSOLETE_”, or make the field number reserved, so +that future users of your .proto can’t accidentally reuse the number.
  • Adding additional values to an enum is safe.
  • Changing a single explicit presence field or extension into a member of a +new oneof is safe.
  • Changing a oneof which contains only one field to an explicit presence +field is safe.
  • Changing a field into an extension of same number and type is safe.

Binary Wire-compatible Changes (Conditionally Safe)

Unlike Wire-safe changes, wire-compatible means that the same data can be parsed +both before and after a given change. However, a parse of the data may be lossy +under this shape of change. For example, changing an int32 to an int64 is a +compatible change, but if a value larger than INT32_MAX is written, a client +that reads it as an int32 will discard the high order bits of the number.

You can make compatible changes to your schema only if you manage the roll out +to your system carefully. For example, you may change an int32 to an int64 but +ensure you continue to only write legal int32 values until the new schema is +deployed to all endpoints, and then subsequently start writing larger values +after that.

If your schema is published outside of your organization, you should generally +not make wire-compatible changes, as you cannot manage the deployment of the new +schema to know when the different range of values may be safe to use.

  • int32, uint32, int64, uint64, and bool are all compatible.
    • If a number is parsed from the wire which doesn’t fit in the +corresponding type, you will get the same effect as if you had cast the +number to that type in C++ (for example, if a 64-bit number is read as +an int32, it will be truncated to 32 bits).
  • sint32 and sint64 are compatible with each other but are not +compatible with the other integer types.
    • If the value written was between INT_MIN and INT_MAX inclusive it will +parse as the same value with either type. If an sint64 value was written +outside of that range and parsed as an sint32, the varint is truncated +to 32 bits and then zigzag decoding occurs (which will cause a different +value to be observed).
  • string and bytes are compatible as long as the bytes are valid UTF-8.
  • Embedded messages are compatible with bytes if the bytes contain an +encoded instance of the message.
  • fixed32 is compatible with sfixed32, and fixed64 with sfixed64.
  • For string, bytes, and message fields, singular is compatible with +repeated.
    • Given serialized data of a repeated field as input, clients that expect +this field to be singular will take the last input value if it’s a +primitive type field or merge all input elements if it’s a message type +field. Note that this is not generally safe for numeric types, +including bools and enums. Repeated fields of numeric types are +serialized in the +packed +format by default, which will not be parsed correctly when a singular +field is expected.
  • enum is compatible with int32, uint32, int64, and uint64
    • Be aware that client code may treat them differently when the message is +deserialized: for example, unrecognized proto3 enum values will be +preserved in the message, but how this is represented when the message +is deserialized is language-dependent.
  • Changing a field between a map<K, V> and the corresponding repeated +message field is binary compatible (see Maps, below, for the +message layout and other restrictions).
    • However, the safety of the change is application-dependent: when +deserializing and reserializing a message, clients using the repeated +field definition will produce a semantically identical result; however, +clients using the map field definition may reorder entries and drop +entries with duplicate keys.

Unknown Fields

Unknown fields are well-formed protocol buffer serialized data representing +fields that the parser does not recognize. For example, when an old binary +parses data sent by a new binary with new fields, those new fields become +unknown fields in the old binary.

Proto2 messages preserve unknown fields and include them during parsing and in +the serialized output.

Retaining Unknown Fields

Some actions can cause unknown fields to be lost. For example, if you do one of +the following, unknown fields are lost:

  • Serialize a proto to JSON.
  • Iterate over all of the fields in a message to populate a new message.

To avoid losing unknown fields, do the following:

  • Use binary; avoid using text formats for data exchange.
  • Use message-oriented APIs, such as CopyFrom() and MergeFrom(), to copy data +rather than copying field-by-field

TextFormat is a bit of a special case. Serializing to TextFormat prints unknown +fields using their field numbers. But parsing TextFormat data back into a binary +proto fails if there are entries that use field numbers.

Extensions

An extension is a field defined outside of its container message; usually in a +.proto file separate from the container message’s .proto file.

Why Use Extensions?

There are two main reasons to use extensions:

  • The container message’s .proto file will have fewer imports/dependencies. +This can improve build times, break circular dependencies, and otherwise +promote loose coupling. Extensions are very good for this.
  • Allow systems to attach data to a container message with minimal dependency +and coordination. Extensions are not a great solution for this because of +the limited field number space and the +Consequences of Reusing Field Numbers. If your use case +requires very low coordination for a large number of extensions, consider +using the +Any message type +instead.

Example Extension

Let’s look at an example extension:

// file kittens/video_ext.proto
+
+import "kittens/video.proto";
+import "media/user_content.proto";
+
+package kittens;
+
+// This extension allows kitten videos in a media.UserContent message.
+extend media.UserContent {
+  // Video is a message imported from kittens/video.proto
+  repeated Video kitten_videos = 126;
+}
+

Note that the file defining the extension (kittens/video_ext.proto) imports +the container message’s file (media/user_content.proto).

The container message must reserve a subset of its field numbers for extensions.

// file media/user_content.proto
+
+package media;
+
+// A container message to hold stuff that a user has created.
+message UserContent {
+  // Set verification to `DECLARATION` to enforce extension declarations for all
+  // extensions in this range.
+  extensions 100 to 199 [verification = DECLARATION];
+}
+

The container message’s file (media/user_content.proto) defines the message +UserContent, which reserves field numbers [100 to 199] for extensions. It is +recommended to set verification = DECLARATION for the range to require +declarations for all its extensions.

When the new extension (kittens/video_ext.proto) is added, a corresponding +declaration should be added to UserContent and verification should be +removed.

// A container message to hold stuff that a user has created.
+message UserContent {
+  extensions 100 to 199 [
+    declaration = {
+      number: 126,
+      full_name: ".kittens.kitten_videos",
+      type: ".kittens.Video",
+      repeated: true
+    }
+  ];
+}
+

UserContent declares that field number 126 will be used by a repeated +extension field with the fully-qualified name .kittens.kitten_videos and the +fully-qualified type .kittens.Video. To learn more about extension +declarations see +Extension Declarations.

Note that the container message’s file (media/user_content.proto) does not +import the kitten_video extension definition (kittens/video_ext.proto)

There is no difference in the wire-format encoding of extension fields as +compared to a standard field with the same field number, type, and cardinality. +Therefore, it is safe to move a standard field out of its container to be an +extension or to move an extension field into its container message as a standard +field so long as the field number, type, and cardinality remain constant.

However, because extensions are defined outside of the container message, no +specialized accessors are generated to get and set specific extension fields. +For our example, the protobuf compiler will not generate AddKittenVideos() +or GetKittenVideos() accessors. Instead, extensions are accessed through +parameterized functions like: HasExtension(), ClearExtension(), +GetExtension(), MutableExtension(), and AddExtension().

In C++, it would look something like:

UserContent user_content;
+user_content.AddExtension(kittens::kitten_videos, new kittens::Video());
+assert(1 == user_content.GetExtensionCount(kittens::kitten_videos));
+user_content.GetExtension(kittens::kitten_videos, 0);
+

Defining Extension Ranges

If you are the owner of a container message, you will need to define an +extension range for the extensions to your message.

Field numbers allocated to extension fields cannot be reused for standard +fields.

It is safe to expand an extension range after it is defined. A good default is +to allocate 1000 relatively small numbers, and densely populate that space using +extension declarations:

message ModernExtendableMessage {
+  // All extensions in this range should use extension declarations.
+  extensions 1000 to 2000 [verification = DECLARATION];
+}
+

When adding a range for extension declarations before the actual extensions, you +should add verification = DECLARATION to enforce that declarations are used +for this new range. This placeholder can be removed once an actual declaration +is added.

It is safe to split an existing extension range into separate ranges that cover +the same total range. This might be necessary for migrating a legacy message +type to +Extension Declarations. +For example, before migration, the range might be defined as:

message LegacyMessage {
+  extensions 1000 to max;
+}
+

And after migration (splitting the range) it can be:

message LegacyMessage {
+  // Legacy range that was using an unverified allocation scheme.
+  extensions 1000 to 524999999 [verification = UNVERIFIED];
+  // Current range that uses extension declarations.
+  extensions 525000000 to max  [verification = DECLARATION];
+}
+

It is not safe to increase the start field number nor decrease the end field +number to move or shrink an extension range. These changes can invalidate an +existing extension.

Prefer using field numbers 1 to 15 for standard fields that are populated in +most instances of your proto. It is not recommended to use these numbers for +extensions.

If your numbering convention might involve extensions having very large field +numbers, you can specify that your extension range goes up to the maximum +possible field number using the max keyword:

message Foo {
+  extensions 1000 to max;
+}
+

max is 229 - 1, or 536,870,911.

Choosing Extension Numbers

Extensions are just fields that can be specified outside of their container +messages. All the same rules for Assigning Field Numbers apply to +extension field numbers. The same +Consequences of Reusing Field Numbers also apply to reusing +extension field numbers.

Choosing unique extension field numbers is simple if the container message uses +extension declarations. +When defining a new extension, choose the lowest field number above all other +declarations from the highest extension range defined in the container message. +For example, if a container message is defined like this:

message Container {
+  // Legacy range that was using an unverified allocation scheme
+  extensions 1000 to 524999999;
+  // Current range that uses extension declarations. (highest extension range)
+  extensions 525000000 to max  [
+    declaration = {
+      number: 525000001,
+      full_name: ".bar.baz_ext",
+      type: ".bar.Baz"
+    }
+    // 525,000,002 is the lowest field number above all other declarations
+  ];
+}
+

The next extension of Container should add a new declaration with the number +525000002.

Unverified Extension Number Allocation (not recommended)

The owner of a container message may choose to forgo extension declarations in +favor of their own unverified extension number allocation strategy.

An unverified allocation scheme uses a mechanism external to the protobuf +ecosystem to allocate extension field numbers within the selected extension +range. One example could be using a monorepo’s commit number. This system is +“unverified” from the protobuf compiler’s point of view since there is no way to +check that an extension is using a properly acquired extension field number.

The benefit of an unverified system over a verified system like extension +declarations is the ability to define an extension without coordinating with the +container message owner.

The downside of an unverified system is that the protobuf compiler cannot +protect participants from reusing extension field numbers.

Unverified extension field number allocation strategies are not recommended +because the Consequences of Reusing Field Numbers fall on all +extenders of a message (not just the developer that didn’t follow the +recommendations). If your use case requires very low coordination, consider +using the +Any message +instead.

Unverified extension field number allocation strategies are limited to the range +1 to 524,999,999. Field numbers 525,000,000 and above can only be used with +extension declarations.

Specifying Extension Types

Extensions can be of any field type except oneofs and maps.

Nested Extensions (not recommended)

You can declare extensions in the scope of another message:

import "common/user_profile.proto";
+
+package puppies;
+
+message Photo {
+  extend common.UserProfile {
+    optional int32 likes_count = 111;
+  }
+  ...
+}
+

In this case, the C++ code to access this extension is:

UserProfile user_profile;
+user_profile.SetExtension(puppies::Photo::likes_count, 42);
+

In other words, the only effect is that likes_count is defined within the +scope of puppies.Photo.

This is a common source of confusion: Declaring an extend block nested inside +a message type does not imply any relationship between the outer type and the +extended type. In particular, the earlier example does not mean that Photo +is any sort of subclass of UserProfile. All it means is that the symbol +likes_count is declared inside the scope of Photo; it’s simply a static +member.

A common pattern is to define extensions inside the scope of the extension’s +field type - for example, here’s an extension to media.UserContent of type +puppies.Photo, where the extension is defined as part of Photo:

import "media/user_content.proto";
+
+package puppies;
+
+message Photo {
+  extend media.UserContent {
+    optional Photo puppy_photo = 127;
+  }
+  ...
+}
+

However, there is no requirement that an extension with a message type be +defined inside that type. You can also use the standard definition pattern:

import "media/user_content.proto";
+
+package puppies;
+
+message Photo {
+  ...
+}
+
+// This can even be in a different file.
+extend media.UserContent {
+  optional Photo puppy_photo = 127;
+}
+

This standard (file-level) syntax is preferred to avoid confusion. The +nested syntax is often mistaken for subclassing by users who are not already +familiar with extensions.

Any

The Any message type lets you use messages as embedded types without having +their .proto definition. An Any contains an arbitrary serialized message as +bytes, along with a URL that acts as a globally unique identifier for and +resolves to that message’s type. To use the Any type, you need to +import google/protobuf/any.proto.

import "google/protobuf/any.proto";
+
+message ErrorStatus {
+  string message = 1;
+  repeated google.protobuf.Any details = 2;
+}
+

The default type URL for a given message type is +type.googleapis.com/_packagename_._messagename_.

Different language implementations will support runtime library helpers to pack +and unpack Any values in a typesafe manner – for example, in Java, the Any +type will have special pack() and unpack() accessors, while in C++ there are +PackFrom() and UnpackTo() methods:

// Storing an arbitrary message type in Any.
+NetworkErrorDetails details = ...;
+ErrorStatus status;
+status.add_details()->PackFrom(details);
+
+// Reading an arbitrary message from Any.
+ErrorStatus status = ...;
+for (const google::protobuf::Any& detail : status.details()) {
+  if (detail.Is<NetworkErrorDetails>()) {
+    NetworkErrorDetails network_error;
+    detail.UnpackTo(&network_error);
+    ... processing network_error ...
+  }
+}
+

If you want to limit contained messages to a small number of types and to +require permission before adding new types to the list, consider using +extensions with +extension declarations +instead of Any message types.

Oneof

If you have a message with many optional fields and where at most one field will +be set at the same time, you can enforce this behavior and save memory by using +the oneof feature.

Oneof fields are like optional fields except all the fields in a oneof share +memory, and at most one field can be set at the same time. Setting any member of +the oneof automatically clears all the other members. You can check which value +in a oneof is set (if any) using a special case() or WhichOneof() method, +depending on your chosen language.

Note that if multiple values are set, the last set value as determined by the +order in the proto will overwrite all previous ones.

Field numbers for oneof fields must be unique within the enclosing message.

Using Oneof

To define a oneof in your .proto you use the oneof keyword followed by your +oneof name, in this case test_oneof:

message SampleMessage {
+  oneof test_oneof {
+     string name = 4;
+     SubMessage sub_message = 9;
+  }
+}
+

You then add your oneof fields to the oneof definition. You can add fields of +any type except map fields, but you cannot use the required, optional, or +repeated keywords. If you need to add a repeated field to a oneof, you can use +a message containing the repeated field.

In your generated code, oneof fields have the same getters and setters as +regular optional fields. You also get a special method for checking which +value (if any) in the oneof is set. You can find out more about the oneof API +for your chosen language in the relevant +API reference.

Oneof Features

  • Setting a oneof field will automatically clear all other members of the +oneof. So if you set several oneof fields, only the last field you set +will still have a value.

    SampleMessage message;
    +message.set_name("name");
    +CHECK(message.has_name());
    +// Calling mutable_sub_message() will clear the name field and will set
    +// sub_message to a new instance of SubMessage with none of its fields set.
    +message.mutable_sub_message();
    +CHECK(!message.has_name());
    +
  • If the parser encounters multiple members of the same oneof on the wire, +only the last member seen is used in the parsed message. When parsing data +on the wire, starting at the beginning of the bytes, evaluate the next +value, and apply the following parsing rules:

    • First, check if a different field in the same oneof is currently set, +and if so clear it.

    • Then apply the contents as though the field was not in a oneof:

      • A primitive will overwrite any value already set
      • A message will merge into any value already set
  • Extensions are not supported for oneof.

  • A oneof cannot be repeated.

  • Reflection APIs work for oneof fields.

  • If you set a oneof field to the default value (such as setting an int32 +oneof field to 0), the “case” of that oneof field will be set, and the value +will be serialized on the wire.

  • If you’re using C++, make sure your code doesn’t cause memory crashes. The +following sample code will crash because sub_message was already deleted +by calling the set_name() method.

    SampleMessage message;
    +SubMessage* sub_message = message.mutable_sub_message();
    +message.set_name("name");      // Will delete sub_message
    +sub_message->set_...            // Crashes here
    +
  • Again in C++, if you Swap() two messages with oneofs, each message will +end up with the other’s oneof case: in the example below, msg1 will have a +sub_message and msg2 will have a name.

    SampleMessage msg1;
    +msg1.set_name("name");
    +SampleMessage msg2;
    +msg2.mutable_sub_message();
    +msg1.swap(&msg2);
    +CHECK(msg1.has_sub_message());
    +CHECK(msg2.has_name());
    +

Backwards-compatibility issues

Be careful when adding or removing oneof fields. If checking the value of a +oneof returns None/NOT_SET, it could mean that the oneof has not been set or +it has been set to a field in a different version of the oneof. There is no way +to tell the difference, since there’s no way to know if an unknown field on the +wire is a member of the oneof.

Tag Reuse Issues

  • Move optional fields into or out of a oneof: You may lose some of your +information (some fields will be cleared) after the message is serialized +and parsed. However, you can safely move a single field into a new oneof +and may be able to move multiple fields if it is known that only one is ever +set. See Updating A Message Type for further details.
  • Delete a oneof field and add it back: This may clear your currently set +oneof field after the message is serialized and parsed.
  • Split or merge oneof: This has similar issues to moving optional +fields.

Maps

If you want to create an associative map as part of your data definition, +protocol buffers provides a handy shortcut syntax:

map<key_type, value_type> map_field = N;
+

…where the key_type can be any integral or string type (so, any +scalar type except for floating point types and bytes). Note that +neither enum nor proto messages are valid for key_type. +The value_type can be any type except another map.

So, for example, if you wanted to create a map of projects where each Project +message is associated with a string key, you could define it like this:

map<string, Project> projects = 3;
+

Maps Features

  • Extensions are not supported for maps.
  • Maps cannot be repeated, optional, or required.
  • Wire format ordering and map iteration ordering of map values is undefined, +so you cannot rely on your map items being in a particular order.
  • When generating text format for a .proto, maps are sorted by key. Numeric +keys are sorted numerically.
  • When parsing from the wire or when merging, if there are duplicate map keys +the last key seen is used. When parsing a map from text format, parsing may +fail if there are duplicate keys.
  • If you provide a key but no value for a map field, the behavior when the +field is serialized is language-dependent. In C++, Java, Kotlin, and Python +the default value for the type is serialized, while in other languages +nothing is serialized.
  • No symbol FooEntry can exist in the same scope as a map foo, because +FooEntry is already used by the implementation of the map.

The generated map API is currently available for all supported languages. You +can find out more about the map API for your chosen language in the relevant +API reference.

Backwards Compatibility

The map syntax is equivalent to the following on the wire, so protocol buffers +implementations that do not support maps can still handle your data:

message MapFieldEntry {
+  optional key_type key = 1;
+  optional value_type value = 2;
+}
+
+repeated MapFieldEntry map_field = N;
+

Any protocol buffers implementation that supports maps must both produce and +accept data that can be accepted by the earlier definition.

Packages

You can add an optional package specifier to a .proto file to prevent name +clashes between protocol message types.

package foo.bar;
+message Open { ... }
+

You can then use the package specifier when defining fields of your message +type:

message Foo {
+  ...
+  optional foo.bar.Open open = 1;
+  ...
+}
+

The way a package specifier affects the generated code depends on your chosen +language:

  • In C++ the generated classes are wrapped inside a C++ namespace. For +example, Open would be in the namespace foo::bar.
  • In Java and Kotlin, the package is used as the Java package, unless +you explicitly provide an option java_package in your .proto file.
  • In Python, the package directive is ignored, since Python modules are +organized according to their location in the file system.
  • In Go, the package directive is ignored, and the generated .pb.go +file is in the package named after the corresponding go_proto_library +Bazel rule. For open source projects, you must provide either a go_package option or set the Bazel -M flag.
  • In Ruby, the generated classes are wrapped inside nested Ruby +namespaces, converted to the required Ruby capitalization style (first +letter capitalized; if the first character is not a letter, PB_ is +prepended). For example, Open would be in the namespace Foo::Bar.
  • In PHP the package is used as the namespace after converting to +PascalCase, unless you explicitly provide an option php_namespace in your +.proto file. For example, Open would be in the namespace Foo\Bar.
  • In C# the package is used as the namespace after converting to +PascalCase, unless you explicitly provide an option csharp_namespace in +your .proto file. For example, Open would be in the namespace Foo.Bar.

Note that even when the package directive does not directly affect the +generated code, for example in Python, it is still strongly recommended to +specify the package for the .proto file, as otherwise it may lead to naming +conflicts in descriptors and make the proto not portable for other languages.

Packages and Name Resolution

Type name resolution in the protocol buffer language works like C++: first the +innermost scope is searched, then the next-innermost, and so on, with each +package considered to be “inner” to its parent package. A leading ‘.’ (for +example, .foo.bar.Baz) means to start from the outermost scope instead.

The protocol buffer compiler resolves all type names by parsing the imported +.proto files. The code generator for each language knows how to refer to each +type in that language, even if it has different scoping rules.

Defining Services

If you want to use your message types with an RPC (Remote Procedure Call) +system, you can define an RPC service interface in a .proto file and the +protocol buffer compiler will generate service interface code and stubs in your +chosen language. So, for example, if you want to define an RPC service with a +method that takes your SearchRequest and returns a SearchResponse, you can +define it in your .proto file as follows:

service SearchService {
+  rpc Search(SearchRequest) returns (SearchResponse);
+}
+

By default, the protocol compiler will then generate an abstract interface +called SearchService and a corresponding “stub” implementation. The stub +forwards all calls to an RpcChannel, which in turn is an abstract interface +that you must define yourself in terms of your own RPC system. For example, you +might implement an RpcChannel which serializes the message and sends it to a +server via HTTP. In other words, the generated stub provides a type-safe +interface for making protocol-buffer-based RPC calls, without locking you into +any particular RPC implementation. So, in C++, you might end up with code like +this:

using google::protobuf;
+
+protobuf::RpcChannel* channel;
+protobuf::RpcController* controller;
+SearchService* service;
+SearchRequest request;
+SearchResponse response;
+
+void DoSearch() {
+  // You provide classes MyRpcChannel and MyRpcController, which implement
+  // the abstract interfaces protobuf::RpcChannel and protobuf::RpcController.
+  channel = new MyRpcChannel("somehost.example.com:1234");
+  controller = new MyRpcController;
+
+  // The protocol compiler generates the SearchService class based on the
+  // definition given earlier.
+  service = new SearchService::Stub(channel);
+
+  // Set up the request.
+  request.set_query("protocol buffers");
+
+  // Execute the RPC.
+  service->Search(controller, &request, &response,
+                  protobuf::NewCallback(&Done));
+}
+
+void Done() {
+  delete service;
+  delete channel;
+  delete controller;
+}
+

All service classes also implement the Service interface, which provides a way +to call specific methods without knowing the method name or its input and output +types at compile time. On the server side, this can be used to implement an RPC +server with which you could register services.

using google::protobuf;
+
+class ExampleSearchService : public SearchService {
+ public:
+  void Search(protobuf::RpcController* controller,
+              const SearchRequest* request,
+              SearchResponse* response,
+              protobuf::Closure* done) {
+    if (request->query() == "google") {
+      response->add_result()->set_url("http://www.google.com");
+    } else if (request->query() == "protocol buffers") {
+      response->add_result()->set_url("http://protobuf.googlecode.com");
+    }
+    done->Run();
+  }
+};
+
+int main() {
+  // You provide class MyRpcServer.  It does not have to implement any
+  // particular interface; this is just an example.
+  MyRpcServer server;
+
+  protobuf::Service* service = new ExampleSearchService;
+  server.ExportOnPort(1234, service);
+  server.Run();
+
+  delete service;
+  return 0;
+}
+

If you don’t want to plug in your own existing RPC system, you can use +gRPC: a language- and platform-neutral +open source RPC system developed at Google. gRPC works particularly well with +protocol buffers and lets you generate the relevant RPC code directly from your +.proto files using a special protocol buffer compiler plugin. However, as +there are potential compatibility issues between clients and servers generated +with proto2 and proto3, we recommend that you use proto3 or edition 2023 for +defining gRPC services. You can find out more about proto3 syntax in the +Proto3 Language Guide and +about edition 2023 in +Edition 2023 Language Guide.

In addition to gRPC, there are also a number of ongoing third-party projects to +develop RPC implementations for Protocol Buffers. For a list of links to +projects we know about, see the +third-party add-ons wiki page.

JSON Mapping

The standard protobuf binary wire format is the preferred serialization format +for communication between two systems that use protobufs. For communicating with +systems that use JSON rather than protobuf wire format, Protobuf supports a +canonical encoding in JSON.

Options

Individual declarations in a .proto file can be annotated with a number of +options. Options do not change the overall meaning of a declaration, but may +affect the way it is handled in a particular context. The complete list of +available options is defined in /google/protobuf/descriptor.proto.

Some options are file-level options, meaning they should be written at the +top-level scope, not inside any message, enum, or service definition. Some +options are message-level options, meaning they should be written inside message +definitions. Some options are field-level options, meaning they should be +written inside field definitions. Options can also be written on enum types, +enum values, oneof fields, service types, and service methods; however, no +useful options currently exist for any of these.

Here are a few of the most commonly used options:

  • java_package (file option): The package you want to use for your generated +Java/Kotlin classes. If no explicit java_package option is given in the +.proto file, then by default the proto package (specified using the +“package” keyword in the .proto file) will be used. However, proto +packages generally do not make good Java packages since proto packages are +not expected to start with reverse domain names. If not generating Java or +Kotlin code, this option has no effect.

    option java_package = "com.example.foo";
    +
  • java_outer_classname (file option): The class name (and hence the file +name) for the wrapper Java class you want to generate. If no explicit +java_outer_classname is specified in the .proto file, the class name +will be constructed by converting the .proto file name to camel-case (so +foo_bar.proto becomes FooBar.java). If the java_multiple_files option +is disabled, then all other classes/enums/etc. generated for the .proto +file will be generated within this outer wrapper Java class as nested +classes/enums/etc. If not generating Java code, this option has no effect.

    option java_outer_classname = "Ponycopter";
    +
  • java_multiple_files (file option): If false, only a single .java file +will be generated for this .proto file, and all the Java +classes/enums/etc. generated for the top-level messages, services, and +enumerations will be nested inside of an outer class (see +java_outer_classname). If true, separate .java files will be generated +for each of the Java classes/enums/etc. generated for the top-level +messages, services, and enumerations, and the wrapper Java class generated +for this .proto file won’t contain any nested classes/enums/etc. This is a +Boolean option which defaults to false. If not generating Java code, this +option has no effect.

    option java_multiple_files = true;
    +
  • optimize_for (file option): Can be set to SPEED, CODE_SIZE, or +LITE_RUNTIME. This affects the C++ and Java code generators (and possibly +third-party generators) in the following ways:

    • SPEED (default): The protocol buffer compiler will generate code for +serializing, parsing, and performing other common operations on your +message types. This code is highly optimized.
    • CODE_SIZE: The protocol buffer compiler will generate minimal classes +and will rely on shared, reflection-based code to implement +serialization, parsing, and various other operations. The generated code +will thus be much smaller than with SPEED, but operations will be +slower. Classes will still implement exactly the same public API as they +do in SPEED mode. This mode is most useful in apps that contain a very +large number of .proto files and do not need all of them to be +blindingly fast.
    • LITE_RUNTIME: The protocol buffer compiler will generate classes that +depend only on the “lite” runtime library (libprotobuf-lite instead of +libprotobuf). The lite runtime is much smaller than the full library +(around an order of magnitude smaller) but omits certain features like +descriptors and reflection. This is particularly useful for apps running +on constrained platforms like mobile phones. The compiler will still +generate fast implementations of all methods as it does in SPEED mode. +Generated classes will only implement the MessageLite interface in +each language, which provides only a subset of the methods of the full +Message interface.
    option optimize_for = CODE_SIZE;
    +
  • cc_generic_services, java_generic_services, py_generic_services (file +options): Generic services are deprecated. Whether or not the protocol +buffer compiler should generate abstract service code based on +services definitions in C++, Java, and Python, respectively. +For legacy reasons, these default to true. However, as of version 2.3.0 +(January 2010), it is considered preferable for RPC implementations to +provide +code generator plugins +to generate code more specific to each system, rather than rely on the +“abstract” services.

    // This file relies on plugins to generate service code.
    +option cc_generic_services = false;
    +option java_generic_services = false;
    +option py_generic_services = false;
    +
  • cc_enable_arenas (file option): Enables +arena allocation for C++ +generated code.

  • objc_class_prefix (file option): Sets the Objective-C class prefix which +is prepended to all Objective-C generated classes and enums from this +.proto. There is no default. You should use prefixes that are between 3-5 +uppercase characters as +recommended by Apple. +Note that all 2 letter prefixes are reserved by Apple.

  • message_set_wire_format (message option): If set to true, the message +uses a different binary format intended to be compatible with an old format +used inside Google called MessageSet. Users outside Google will probably +never need to use this option. The message must be declared exactly as +follows:

    message Foo {
    +  option message_set_wire_format = true;
    +  extensions 4 to max;
    +}
    +
  • packed (field option): If set to true on a repeated field of a basic +numeric type, it causes a more compact +encoding to be +used. The only reason to not use this option is if you need compatibility +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.

    repeated int32 samples = 4 [packed = true];
    +
  • deprecated (field option): If set to true, indicates that the field is +deprecated and should not be used by new code. In most languages this has no +actual effect. In Java, this becomes a @Deprecated annotation. For C++, +clang-tidy will generate warnings whenever deprecated fields are used. In +the future, other language-specific code generators may generate deprecation +annotations on the field’s accessors, which will in turn cause a warning to +be emitted when compiling code which attempts to use the field. If the field +is not used by anyone and you want to prevent new users from using it, +consider replacing the field declaration with a reserved +statement.

    optional int32 old_field = 6 [deprecated = true];
    +

Enum Value Options

Enum value options are supported. You can use the deprecated option to +indicate that a value shouldn’t be used anymore. You can also create custom +options using extensions.

The following example shows the syntax for adding these options:

import "google/protobuf/descriptor.proto";
+
+extend google.protobuf.EnumValueOptions {
+  optional string string_name = 123456789;
+}
+
+enum Data {
+  DATA_UNSPECIFIED = 0;
+  DATA_SEARCH = 1 [deprecated = true];
+  DATA_DISPLAY = 2 [
+    (string_name) = "display_value"
+  ];
+}
+

The C++ code to read the string_name option might look something like this:

const absl::string_view foo = proto2::GetEnumDescriptor<Data>()
+    ->FindValueByName("DATA_DISPLAY")->options().GetExtension(string_name);
+

See Custom Options to see how to apply custom options to enum +values and to fields.

Custom Options

Protocol Buffers also allows you to define and use your own options. Note that +this is an advanced feature which most people don’t need. Since options are +defined by the messages defined in google/protobuf/descriptor.proto (like +FileOptions or FieldOptions), defining your own options is simply a matter +of extending those messages. For example:

import "google/protobuf/descriptor.proto";
+
+extend google.protobuf.MessageOptions {
+  optional string my_option = 51234;
+}
+
+message MyMessage {
+  option (my_option) = "Hello world!";
+}
+

Here we have defined a new message-level option by extending MessageOptions. +When we then use the option, the option name must be enclosed in parentheses to +indicate that it is an extension. We can now read the value of my_option in +C++ like so:

string value = MyMessage::descriptor()->options().GetExtension(my_option);
+

Here, MyMessage::descriptor()->options() returns the MessageOptions protocol +message for MyMessage. Reading custom options from it is just like reading any +other extension.

Similarly, in Java we would write:

String value = MyProtoFile.MyMessage.getDescriptor().getOptions()
+  .getExtension(MyProtoFile.myOption);
+

In Python it would be:

value = my_proto_file_pb2.MyMessage.DESCRIPTOR.GetOptions()
+  .Extensions[my_proto_file_pb2.my_option]
+

Custom options can be defined for every kind of construct in the Protocol +Buffers language. Here is an example that uses every kind of option:

import "google/protobuf/descriptor.proto";
+
+extend google.protobuf.FileOptions {
+  optional string my_file_option = 50000;
+}
+extend google.protobuf.MessageOptions {
+  optional int32 my_message_option = 50001;
+}
+extend google.protobuf.FieldOptions {
+  optional float my_field_option = 50002;
+}
+extend google.protobuf.OneofOptions {
+  optional int64 my_oneof_option = 50003;
+}
+extend google.protobuf.EnumOptions {
+  optional bool my_enum_option = 50004;
+}
+extend google.protobuf.EnumValueOptions {
+  optional uint32 my_enum_value_option = 50005;
+}
+extend google.protobuf.ServiceOptions {
+  optional MyEnum my_service_option = 50006;
+}
+extend google.protobuf.MethodOptions {
+  optional MyMessage my_method_option = 50007;
+}
+
+option (my_file_option) = "Hello world!";
+
+message MyMessage {
+  option (my_message_option) = 1234;
+
+  optional int32 foo = 1 [(my_field_option) = 4.5];
+  optional string bar = 2;
+  oneof qux {
+    option (my_oneof_option) = 42;
+
+    string quux = 3;
+  }
+}
+
+enum MyEnum {
+  option (my_enum_option) = true;
+
+  FOO = 1 [(my_enum_value_option) = 321];
+  BAR = 2;
+}
+
+message RequestType {}
+message ResponseType {}
+
+service MyService {
+  option (my_service_option) = FOO;
+
+  rpc MyMethod(RequestType) returns(ResponseType) {
+    // Note:  my_method_option has type MyMessage.  We can set each field
+    //   within it using a separate "option" line.
+    option (my_method_option).foo = 567;
+    option (my_method_option).bar = "Some string";
+  }
+}
+

Note that if you want to use a custom option in a package other than the one in +which it was defined, you must prefix the option name with the package name, +just as you would for type names. For example:

// foo.proto
+import "google/protobuf/descriptor.proto";
+package foo;
+extend google.protobuf.MessageOptions {
+  optional string my_option = 51234;
+}
+
// bar.proto
+import "foo.proto";
+package bar;
+message MyMessage {
+  option (foo.my_option) = "Hello world!";
+}
+

One last thing: Since custom options are extensions, they must be assigned field +numbers like any other field or extension. In the examples earlier, we have used +field numbers in the range 50000-99999. This range is reserved for internal use +within individual organizations, so you can use numbers in this range freely for +in-house applications. If you intend to use custom options in public +applications, however, then it is important that you make sure that your field +numbers are globally unique. To obtain globally unique field numbers, send a +request to add an entry to +protobuf global extension registry. +Usually you only need one extension number. You can declare multiple options +with only one extension number by putting them in a sub-message:

message FooOptions {
+  optional int32 opt1 = 1;
+  optional string opt2 = 2;
+}
+
+extend google.protobuf.FieldOptions {
+  optional FooOptions foo_options = 1234;
+}
+
+// usage:
+message Bar {
+  optional int32 a = 1 [(foo_options).opt1 = 123, (foo_options).opt2 = "baz"];
+  // alternative aggregate syntax (uses TextFormat):
+  optional int32 b = 2 [(foo_options) = { opt1: 123 opt2: "baz" }];
+}
+

Also, note that each option type (file-level, message-level, field-level, etc.) +has its own number space, so, for example, you could declare extensions of +FieldOptions and MessageOptions with the same number.

Option Retention

Options have a notion of retention, which controls whether an option is +retained in the generated code. Options have runtime retention by default, +meaning that they are retained in the generated code and are thus visible at +runtime in the generated descriptor pool. However, you can set retention = RETENTION_SOURCE to specify that an option (or field within an option) must not +be retained at runtime. This is called source retention.

Option retention is an advanced feature that most users should not need to worry +about, but it can be useful if you would like to use certain options without +paying the code size cost of retaining them in your binaries. Options with +source retention are still visible to protoc and protoc plugins, so code +generators can use them to customize their behavior.

Retention can be set directly on an option, like this:

extend google.protobuf.FileOptions {
+  optional int32 source_retention_option = 1234
+      [retention = RETENTION_SOURCE];
+}
+

It can also be set on a plain field, in which case it takes effect only when +that field appears inside an option:

message OptionsMessage {
+  optional int32 source_retention_field = 1 [retention = RETENTION_SOURCE];
+}
+

You can set retention = RETENTION_RUNTIME if you like, but this has no effect +since it is the default behavior. When a message field is marked +RETENTION_SOURCE, its entire contents are dropped; fields inside it cannot +override that by trying to set RETENTION_RUNTIME.

Option Targets

Fields have a targets option which controls the types of entities that the +field may apply to when used as an option. For example, if a field has +targets = TARGET_TYPE_MESSAGE then that field cannot be set in a custom option +on an enum (or any other non-message entity). Protoc enforces this and will +raise an error if there is a violation of the target constraints.

At first glance, this feature may seem unnecessary given that every custom +option is an extension of the options message for a specific entity, which +already constrains the option to that one entity. However, option targets are +useful in the case where you have a shared options message applied to multiple +entity types and you want to control the usage of individual fields in that +message. For example:

message MyOptions {
+  optional string file_only_option = 1 [targets = TARGET_TYPE_FILE];
+  optional int32 message_and_enum_option = 2 [targets = TARGET_TYPE_MESSAGE,
+                                              targets = TARGET_TYPE_ENUM];
+}
+
+extend google.protobuf.FileOptions {
+  optional MyOptions file_options = 50000;
+}
+
+extend google.protobuf.MessageOptions {
+  optional MyOptions message_options = 50000;
+}
+
+extend google.protobuf.EnumOptions {
+  optional MyOptions enum_options = 50000;
+}
+
+// OK: this field is allowed on file options
+option (file_options).file_only_option = "abc";
+
+message MyMessage {
+  // OK: this field is allowed on both message and enum options
+  option (message_options).message_and_enum_option = 42;
+}
+
+enum MyEnum {
+  MY_ENUM_UNSPECIFIED = 0;
+  // Error: file_only_option cannot be set on an enum.
+  option (enum_options).file_only_option = "xyz";
+}
+

Generating Your Classes

To generate the Java, Kotlin, Python, C++, Go, Ruby, Objective-C, or C# code +that you need to work with the message types defined in a .proto file, you +need to run the protocol buffer compiler protoc on the .proto file. If you +haven’t installed the compiler, +download the package and follow the +instructions in the README. For Go, you also need to install a special code +generator plugin for the compiler; you can find this and installation +instructions in the golang/protobuf +repository on GitHub.

The Protocol Compiler is invoked as follows:

protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR --go_out=DST_DIR --ruby_out=DST_DIR --objc_out=DST_DIR --csharp_out=DST_DIR path/to/file.proto
+
  • IMPORT_PATH specifies a directory in which to look for .proto files when +resolving import directives. If omitted, the current directory is used. +Multiple import directories can be specified by passing the --proto_path +option multiple times; they will be searched in order. -I=_IMPORT_PATH_ +can be used as a short form of --proto_path.

Note: File paths relative to their proto_path must be globally unique in a +given binary. For example, if you have proto/lib1/data.proto and +proto/lib2/data.proto, those two files cannot be used together with +-I=proto/lib1 -I=proto/lib2 because it would be ambiguous which file import "data.proto" will mean. Instead -Iproto/ should be used and the global names +will be lib1/data.proto and lib2/data.proto.

If you are publishing a library and other users may use your messages directly, +you should include a unique library name in the path that they are expected to +be used under to avoid file name collisions. If you have multiple directories in +one project, it is best practice to prefer setting one -I to a top level +directory of the project.

  • You can provide one or more output directives:

    As an extra convenience, if the DST_DIR ends in .zip or .jar, the +compiler will write the output to a single ZIP-format archive file with the +given name. .jar outputs will also be given a manifest file as required by +the Java JAR specification. Note that if the output archive already exists, +it will be overwritten.

  • You must provide one or more .proto files as input. Multiple .proto +files can be specified at once. Although the files are named relative to the +current directory, each file must reside in one of the IMPORT_PATHs so +that the compiler can determine its canonical name.

File location

Prefer not to put .proto files in the same +directory as other language sources. Consider +creating a subpackage proto for .proto files, under the root package for +your project.

Location Should be Language-agnostic

When working with Java code, it’s handy to put related .proto files in the +same directory as the Java source. However, if any non-Java code ever uses the +same protos, the path prefix will no longer make sense. So in +general, put the protos in a related language-agnostic directory such as +//myteam/mypackage.

The exception to this rule is when it’s clear that the protos will be used only +in a Java context, such as for testing.

Supported Platforms

For information about:

\ No newline at end of file diff --git a/programming-guides/proto3/index.html b/programming-guides/proto3/index.html new file mode 100644 index 000000000..2c98a02e2 --- /dev/null +++ b/programming-guides/proto3/index.html @@ -0,0 +1,877 @@ +Language Guide (proto 3) | Protocol Buffers Documentation +

Language Guide (proto 3)

Covers how to use the proto3 revision of the Protocol Buffers language in your project.

This guide describes how to use the protocol buffer language to structure your +protocol buffer data, including .proto file syntax and how to generate data +access classes from your .proto files. It covers the proto3 revision of +the protocol buffers language.

For information on editions syntax, see the +Protobuf Editions Language Guide.

For information on the proto2 syntax, see the +Proto2 Language Guide.

This is a reference guide – for a step by step example that uses many of the +features described in this document, see the +tutorial +for your chosen language.

Defining A Message Type

First let’s look at a very simple example. Let’s say you want to define a search +request message format, where each search request has a query string, the +particular page of results you are interested in, and a number of results per +page. Here’s the .proto file you use to define the message type.

syntax = "proto3";
+
+message SearchRequest {
+  string query = 1;
+  int32 page_number = 2;
+  int32 results_per_page = 3;
+}
+
  • The first line of the file specifies that you’re using the proto3 revision +of the protobuf language spec.

    • The edition (or syntax for proto2/proto3) must be the first +non-empty, non-comment line of the file.
    • If no edition or syntax is specified, the protocol buffer compiler +will assume you are using +proto2.
  • The SearchRequest message definition specifies three fields (name/value +pairs), one for each piece of data that you want to include in this type of +message. Each field has a name and a type.

Specifying Field Types

In the earlier example, all the fields are scalar types: two integers +(page_number and results_per_page) and a string (query). You can also +specify enumerations and composite types like other message types for +your field.

Assigning Field Numbers

You must give each field in your message definition a number between 1 and +536,870,911 with the following restrictions:

  • The given number must be unique among all fields for that message.
  • Field numbers 19,000 to 19,999 are reserved for the Protocol Buffers +implementation. The protocol buffer compiler will complain if you use one of +these reserved field numbers in your message.
  • You cannot use any previously reserved field numbers or +any field numbers that have been allocated to +extensions.

This number cannot be changed once your message type is in use because it +identifies the field in the +message wire format. +“Changing” a field number is equivalent to deleting that field and creating a +new field with the same type but a new number. See Deleting Fields +for how to do this properly.

Field numbers should never be reused. Never take a field number out of the +reserved list for reuse with a new field definition. See +Consequences of Reusing Field Numbers.

You should use the field numbers 1 through 15 for the most-frequently-set +fields. Lower field number values take less space in the wire format. For +example, field numbers in the range 1 through 15 take one byte to encode. Field +numbers in the range 16 through 2047 take two bytes. You can find out more about +this in +Protocol Buffer Encoding.

Consequences of Reusing Field Numbers

Reusing a field number makes decoding wire-format messages ambiguous.

The protobuf wire format is lean and doesn’t provide a way to detect fields +encoded using one definition and decoded using another.

Encoding a field using one definition and then decoding that same field with a +different definition can lead to:

  • Developer time lost to debugging
  • A parse/merge error (best case scenario)
  • Leaked PII/SPII
  • Data corruption

Common causes of field number reuse:

  • renumbering fields (sometimes done to achieve a more aesthetically pleasing +number order for fields). Renumbering effectively deletes and re-adds all +the fields involved in the renumbering, resulting in incompatible +wire-format changes.
  • deleting a field and not reserving the number to prevent +future reuse.

The field number is limited to 29 bits rather than 32 bits because three bits +are used to specify the field’s wire format. For more on this, see the +Encoding topic.

Specifying Field Cardinality

Message fields can be one of the following:

  • Singular:

    In proto3, there are two types of singular fields:

    • optional: (recommended) An optional field is in one of two possible +states:

      • the field is set, and contains a value that was explicitly set or +parsed from the wire. It will be serialized to the wire.
      • the field is unset, and will return the default value. It will not +be serialized to the wire.

      You can check to see if the value was explicitly set.

      optional is recommended over implicit fields for maximum +compatibility with protobuf editions and proto2.

    • implicit: (not recommended) An implicit field has no explicit +cardinality label and behaves as follows:

      • if the field is a message type, it behaves just like an optional +field.

      • if the field is not a message, it has two states:

        • the field is set to a non-default (non-zero) value that was +explicitly set or parsed from the wire. It will be serialized to +the wire.
        • the field is set to the default (zero) value. It will not be +serialized to the wire. In fact, you cannot determine whether +the default (zero) value was set or parsed from the wire or not +provided at all. For more on this subject, see +Field Presence.
  • repeated: this field type can be repeated zero or more times in a +well-formed message. The order of the repeated values will be preserved.

  • map: this is a paired key/value field type. See +Maps for more on +this field type.

Repeated Fields are Packed by Default

In proto3, repeated fields of scalar numeric types use packed encoding by +default.

You can find out more about packed encoding in +Protocol Buffer Encoding.

Message Type Fields Always Have Field Presence

In proto3, message-type fields already have field presence. Because of this, +adding the optional modifier doesn’t change the field presence for the field.

The definitions for Message2 and Message3 in the following code sample +generate the same code for all languages, and there is no difference in +representation in binary, JSON, and TextFormat:

syntax="proto3";
+
+package foo.bar;
+
+message Message1 {}
+
+message Message2 {
+  Message1 foo = 1;
+}
+
+message Message3 {
+  optional Message1 bar = 1;
+}
+

Well-formed Messages

The term “well-formed,” when applied to protobuf messages, refers to the bytes +serialized/deserialized. The protoc parser validates that a given proto +definition file is parseable.

Singular fields can appear more than once in wire-format bytes. The parser will +accept the input, but only the last instance of that field will be accessible +through the generated bindings. See +Last One Wins +for more on this topic.

Adding More Message Types

Multiple message types can be defined in a single .proto file. This is useful +if you are defining multiple related messages – so, for example, if you wanted +to define the reply message format that corresponds to your SearchResponse +message type, you could add it to the same .proto:

message SearchRequest {
+  string query = 1;
+  int32 page_number = 2;
+  int32 results_per_page = 3;
+}
+
+message SearchResponse {
+ ...
+}
+

Combining Messages leads to bloat While multiple message types (such as +message, enum, and service) can be defined in a single .proto file, it can +also lead to dependency bloat when large numbers of messages with varying +dependencies are defined in a single file. It’s recommended to include as few +message types per .proto file as possible.

Adding Comments

To add comments to your .proto files:

  • Prefer C/C++/Java line-end-style comments ‘//’ on the line before the .proto +code element

  • C-style inline/multi-line comments /* ... */ are also accepted.

    • When using multi-line comments, a margin line of ‘*’ is preferred.
/**
+ * SearchRequest represents a search query, with pagination options to
+ * indicate which results to include in the response.
+ */
+message SearchRequest {
+  string query = 1;
+
+  // Which page number do we want?
+  int32 page_number = 2;
+
+  // Number of results to return per page.
+  int32 results_per_page = 3;
+}
+

Deleting Fields

Deleting fields can cause serious problems if not done properly.

When you no longer need a field and all references have been deleted from client +code, you may delete the field definition from the message. However, you +must reserve the deleted field number. If you do not +reserve the field number, it is possible for a developer to reuse that number in +the future.

You should also reserve the field name to allow JSON and TextFormat encodings of +your message to continue to parse.

Reserved Field Numbers

If you update a message type by entirely deleting a field, or +commenting it out, future developers can reuse the field number when making +their own updates to the type. This can cause severe issues, as described in +Consequences of Reusing Field Numbers. To make sure this +doesn’t happen, add your deleted field number to the reserved list.

The protoc compiler will generate error messages if any future developers try to +use these reserved field numbers.

message Foo {
+  reserved 2, 15, 9 to 11;
+}
+

Reserved field number ranges are inclusive (9 to 11 is the same as 9, 10, 11).

Reserved Field Names

Reusing an old field name later is generally safe, except when using TextProto +or JSON encodings where the field name is serialized. To avoid this risk, you +can add the deleted field name to the reserved list.

Reserved names affect only the protoc compiler behavior and not runtime +behavior, with one exception: TextProto implementations may discard unknown +fields (without raising an error like with other unknown fields) with reserved +names at parse time (only the C++ and Go implementations do so today). Runtime +JSON parsing is not affected by reserved names.

message Foo {
+  reserved 2, 15, 9 to 11;
+  reserved "foo", "bar";
+}
+

Note that you can’t mix field names and field numbers in the same reserved +statement.

What’s Generated from Your .proto?

When you run the protocol buffer compiler on a .proto, the +compiler generates the code in your chosen language you’ll need to work with the +message types you’ve described in the file, including getting and setting field +values, serializing your messages to an output stream, and parsing your messages +from an input stream.

  • For C++, the compiler generates a .h and .cc file from each +.proto, with a class for each message type described in your file.
  • For Java, the compiler generates a .java file with a class for each +message type, as well as a special Builder class for creating message +class instances.
  • For Kotlin, in addition to the Java generated code, the compiler +generates a .kt file for each message type with an improved Kotlin API. +This includes a DSL that simplifies creating message instances, a nullable +field accessor, and a copy function.
  • Python is a little different — the Python compiler generates a module +with a static descriptor of each message type in your .proto, which is +then used with a metaclass to create the necessary Python data access +class at runtime.
  • For Go, the compiler generates a .pb.go file with a type for each +message type in your file.
  • For Ruby, the compiler generates a .rb file with a Ruby module +containing your message types.
  • For Objective-C, the compiler generates a pbobjc.h and pbobjc.m file +from each .proto, with a class for each message type described in your +file.
  • For C#, the compiler generates a .cs file from each .proto, with a +class for each message type described in your file.
  • For PHP, the compiler generates a .php message file for each message +type described in your file, and a .php metadata file for each .proto +file you compile. The metadata file is used to load the valid message types +into the descriptor pool.
  • For Dart, the compiler generates a .pb.dart file with a class for each +message type in your file.

You can find out more about using the APIs for each language by following the +tutorial for your chosen language. For even more API +details, see the relevant API reference.

Scalar Value Types

A scalar message field can have one of the following types – the table shows the +type specified in the .proto file, and the corresponding type in the +automatically generated class:

Proto TypeNotes
doubleUses IEEE 754 +double-precision format.
floatUses IEEE 754 +single-precision format.
int32Uses variable-length encoding. Inefficient for encoding negative +numbers – if your field is likely to have negative values, use sint32 +instead.
int64Uses variable-length encoding. Inefficient for encoding negative +numbers – if your field is likely to have negative values, use sint64 +instead.
uint32Uses variable-length encoding.
uint64Uses variable-length encoding.
sint32Uses variable-length encoding. Signed int value. These more +efficiently encode negative numbers than regular int32s.
sint64Uses variable-length encoding. Signed int value. These more +efficiently encode negative numbers than regular int64s.
fixed32Always four bytes. More efficient than uint32 if values are often +greater than 228.
fixed64Always eight bytes. More efficient than uint64 if values are often +greater than 256.
sfixed32Always four bytes.
sfixed64Always eight bytes.
bool
stringA string must always contain UTF-8 encoded or 7-bit ASCII text, and cannot +be longer than 232.
bytesMay contain any arbitrary sequence of bytes no longer than 232.
Proto TypeC++ TypeJava/Kotlin Type[1]Python Type[3]Go TypeRuby TypeC# TypePHP TypeDart TypeRust Type
doubledoubledoublefloatfloat64Floatdoublefloatdoublef64
floatfloatfloatfloatfloat32Floatfloatfloatdoublef32
int32int32_tintintint32Fixnum or Bignum (as required)intintegerinti32
int64int64_tlongint/long[4]int64Bignumlonginteger/string[6]Int64i64
uint32uint32_tint[2]int/long[4]uint32Fixnum or Bignum (as required)uintintegerintu32
uint64uint64_tlong[2]int/long[4]uint64Bignumulonginteger/string[6]Int64u64
sint32int32_tintintint32Fixnum or Bignum (as required)intintegerinti32
sint64int64_tlongint/long[4]int64Bignumlonginteger/string[6]Int64i64
fixed32uint32_tint[2]int/long[4]uint32Fixnum or Bignum (as required)uintintegerintu32
fixed64uint64_tlong[2]int/long[4]uint64Bignumulonginteger/string[6]Int64u64
sfixed32int32_tintintint32Fixnum or Bignum (as required)intintegerinti32
sfixed64int64_tlongint/long[4]int64Bignumlonginteger/string[6]Int64i64
boolboolbooleanboolboolTrueClass/FalseClassboolbooleanboolbool
stringstd::stringStringstr/unicode[5]stringString (UTF-8)stringstringStringProtoString
bytesstd::stringByteStringstr (Python 2), bytes (Python 3)[]byteString (ASCII-8BIT)ByteStringstringListProtoBytes

[1] Kotlin uses the corresponding types from Java, even for unsigned +types, to ensure compatibility in mixed Java/Kotlin codebases.

[2] In Java, unsigned 32-bit and 64-bit integers are represented +using their signed counterparts, with the top bit simply being stored in the +sign bit.

[3] In all cases, setting values to a field will perform type +checking to make sure it is valid.

[4] 64-bit or unsigned 32-bit integers are always represented as long +when decoded, but can be an int if an int is given when setting the field. In +all cases, the value must fit in the type represented when set. See [2].

[5] Python strings are represented as unicode on decode but can be +str if an ASCII string is given (this is subject to change).

[6] Integer is used on 64-bit machines and string is used on 32-bit +machines.

You can find out more about how these types are encoded when you serialize your +message in +Protocol Buffer Encoding.

Default Field Values

When a message is parsed, if the encoded message bytes do not contain a +particular field, accessing that field in the parsed object returns the default +value for that field. The default values are type-specific:

  • For strings, the default value is the empty string.
  • For bytes, the default value is empty bytes.
  • For bools, the default value is false.
  • For numeric types, the default value is zero.
  • For message fields, the field is not set. Its exact value is +language-dependent. See the +generated code guide for details.
  • For enums, the default value is the first defined enum value, which must +be 0. See Enum Default Value.

The default value for repeated fields is empty (generally an empty list in the +appropriate language).

The default value for map fields is empty (generally an empty map in the +appropriate language).

Note that for implicit-presence scalar fields, once a message is parsed there’s +no way of telling whether that field was explicitly set to the default value +(for example whether a boolean was set to false) or just not set at all: you +should bear this in mind when defining your message types. For example, don’t +have a boolean that switches on some behavior when set to false if you don’t +want that behavior to also happen by default. Also note that if a scalar message +field is set to its default, the value will not be serialized on the wire. +If a float or double value is set to +0 it will not be serialized, but -0 is +considered distinct and will be serialized.

See the generated code guide for your +chosen language for more details about how defaults work in generated code.

Enumerations

When you’re defining a message type, you might want one of its fields to only +have one of a predefined list of values. For example, let’s say you want to add +a corpus field for each SearchRequest, where the corpus can be UNIVERSAL, +WEB, IMAGES, LOCAL, NEWS, PRODUCTS or VIDEO. You can do this very +simply by adding an enum to your message definition with a constant for each +possible value.

In the following example we’ve added an enum called Corpus with all the +possible values, and a field of type Corpus:

enum Corpus {
+  CORPUS_UNSPECIFIED = 0;
+  CORPUS_UNIVERSAL = 1;
+  CORPUS_WEB = 2;
+  CORPUS_IMAGES = 3;
+  CORPUS_LOCAL = 4;
+  CORPUS_NEWS = 5;
+  CORPUS_PRODUCTS = 6;
+  CORPUS_VIDEO = 7;
+}
+
+message SearchRequest {
+  string query = 1;
+  int32 page_number = 2;
+  int32 results_per_page = 3;
+  Corpus corpus = 4;
+}
+

Prefixing Enum Values

When prefixing enum values, the remainder of the name with the prefix stripped +should still be a legal and style-conformant enum name. For example, avoid the +following:

enum DeviceTier {
+  DEVICE_TIER_UNKNOWN = 0;
+  DEVICE_TIER_1 = 1;
+  DEVICE_TIER_2 = 2;
+}
+

Instead, use a value name like DEVICE_TIER_TIER1, where the DEVICE_TIER_ +portion is viewed as scoping the enum value rather than as part of the +individual enum value name. Some Protobuf implementations automatically strip +the prefix that matches the containing enum name where it is safe to do so, but +could not in this example since a bare 1 is not a legal enum value name.

We plan for a future Edition to add support for scoped enums, which will +eliminate the need to manually prefix each enum value and enable this to be +written succinctly as TIER1 = 1.

Enum Default Value

The default value for the SearchRequest.corpus field is CORPUS_UNSPECIFIED +because that is the first value defined in the enum.

In proto3, the first value defined in an enum definition must have the value +zero and should have the name ENUM_TYPE_NAME_UNSPECIFIED or +ENUM_TYPE_NAME_UNKNOWN. This is because:

  • There must be a zero value, so that we can use 0 as a numeric +default value.
  • The zero value needs to be the first element, for compatibility with the +proto2 semantics where +the first enum value is the default unless a different value is explicitly +specified.

It is also recommended that this first, default value have no semantic meaning +other than “this value was unspecified”.

Enum Value Aliases

You can define aliases by assigning the same value to different enum constants. +To do this you need to set the allow_alias option to true. Otherwise, the +protocol buffer compiler generates a warning message when aliases are +found. Though all alias values are valid for serialization, only the first value +is used when deserializing.

enum EnumAllowingAlias {
+  option allow_alias = true;
+  EAA_UNSPECIFIED = 0;
+  EAA_STARTED = 1;
+  EAA_RUNNING = 1;
+  EAA_FINISHED = 2;
+}
+
+enum EnumNotAllowingAlias {
+  ENAA_UNSPECIFIED = 0;
+  ENAA_STARTED = 1;
+  // ENAA_RUNNING = 1;  // Uncommenting this line will cause a warning message.
+  ENAA_FINISHED = 2;
+}
+

Enumerator constants must be in the range of a 32-bit integer. Since enum +values use +varint encoding on the +wire, negative values are inefficient and thus not recommended. You can define +enums within a message definition, as in the earlier example, or outside – +these enums can be reused in any message definition in your .proto file. You +can also use an enum type declared in one message as the type of a field in a +different message, using the syntax _MessageType_._EnumType_.

When you run the protocol buffer compiler on a .proto that uses an enum, the +generated code will have a corresponding enum for Java, Kotlin, or C++, or a +special EnumDescriptor class for Python that’s used to create a set of +symbolic constants with integer values in the runtime-generated class.

During deserialization, unrecognized enum values will be preserved in the +message, though how this is represented when the message is deserialized is +language-dependent. In languages that support open enum types with values +outside the range of specified symbols, such as C++ and Go, the unknown enum +value is simply stored as its underlying integer representation. In languages +with closed enum types such as Java, a case in the enum is used to represent an +unrecognized value, and the underlying integer can be accessed with special +accessors. In either case, if the message is serialized the unrecognized value +will still be serialized with the message.

For more information about how to work with message enums in your +applications, see the generated code guide +for your chosen language.

Reserved Values

If you update an enum type by entirely removing an enum entry, or +commenting it out, future users can reuse the numeric value when making their +own updates to the type. This can cause severe issues if they later load old +instances of the same .proto, including data corruption, privacy bugs, and so +on. One way to make sure this doesn’t happen is to specify that the numeric +values (and/or names, which can also cause issues for JSON serialization) of +your deleted entries are reserved. The protocol buffer compiler will complain +if any future users try to use these identifiers. You can specify that your +reserved numeric value range goes up to the maximum possible value using the +max keyword.

enum Foo {
+  reserved 2, 15, 9 to 11, 40 to max;
+  reserved "FOO", "BAR";
+}
+

Note that you can’t mix field names and numeric values in the same reserved +statement.

Using Other Message Types

You can use other message types as field types. For example, let’s say you +wanted to include Result messages in each SearchResponse message – to do +this, you can define a Result message type in the same .proto and then +specify a field of type Result in SearchResponse:

message SearchResponse {
+  repeated Result results = 1;
+}
+
+message Result {
+  string url = 1;
+  string title = 2;
+  repeated string snippets = 3;
+}
+

Importing Definitions

In the earlier example, the Result message type is defined in the same file as +SearchResponse – what if the message type you want to use as a field type is +already defined in another .proto file?

You can use definitions from other .proto files by importing them. To import +another .proto’s definitions, you add an import statement to the top of your +file:

import "myproject/other_protos.proto";
+

The protobuf compiler searches for imported files in a set of directories +specified using the -I/--proto_path flag. The path given in an import +statement is resolved relative to these directories. For more information on +using the compiler, see Generating Your Classes.

For example, consider the following directory structure:

my_project/
+├── protos/
+│   ├── main.proto
+│   └── common/
+│       └── timestamp.proto
+

To use definitions from timestamp.proto within main.proto, you would run the +compiler from the my_project directory and set --proto_path=protos. The +import statement in main.proto would then be:

// Located in my_project/protos/main.proto
+import "common/timestamp.proto";
+

In general you should set the --proto_path flag to the highest-level directory +that contains protos. This is often the root of the project, but in this example +it’s in a separate /protos directory.

By default, you can use definitions only from directly imported .proto files. +However, sometimes you may need to move a .proto file to a new location. +Instead of moving the .proto file directly and updating all the call sites in +a single change, you can put a placeholder .proto file in the old location to +forward all the imports to the new location using the import public notion.

Note: The public import functionality available in Java is most effective +when moving an entire .proto file or when using java_multiple_files = true. In +these cases, generated names remain stable, avoiding the need to update +references in your code. While technically functional when moving a subset of a +.proto file without java_multiple_files = true, doing so requires simultaneous +updates to many references, thus might not significantly ease migration. The +functionality is not available in Kotlin, TypeScript, JavaScript, or GCL.

import public dependencies can be transitively relied upon by any code +importing the proto containing the import public statement. For example:

// new.proto
+// All definitions are moved here
+
// old.proto
+// This is the proto that all clients are importing.
+import public "new.proto";
+import "other.proto";
+
// client.proto
+import "old.proto";
+// You use definitions from old.proto and new.proto, but not other.proto
+

Using proto2 Message Types

It’s possible to import +proto2 message types and +use them in your proto3 messages, and vice versa. However, proto2 enums cannot +be used directly in proto3 syntax (it’s okay if an imported proto2 message uses +them).

Nested Types

You can define and use message types inside other message types, as in the +following example – here the Result message is defined inside the +SearchResponse message:

message SearchResponse {
+  message Result {
+    string url = 1;
+    string title = 2;
+    repeated string snippets = 3;
+  }
+  repeated Result results = 1;
+}
+

If you want to reuse this message type outside its parent message type, you +refer to it as _Parent_._Type_:

message SomeOtherMessage {
+  SearchResponse.Result result = 1;
+}
+

You can nest messages as deeply as you like. In the example below, note that the +two nested types named Inner are entirely independent, since they are defined +within different messages:

message Outer {       // Level 0
+  message MiddleAA {  // Level 1
+    message Inner {   // Level 2
+      int64 ival = 1;
+      bool  booly = 2;
+    }
+  }
+  message MiddleBB {  // Level 1
+    message Inner {   // Level 2
+      int32 ival = 1;
+      bool  booly = 2;
+    }
+  }
+}
+

Updating A Message Type

If an existing message type no longer meets all your needs – for example, you’d +like the message format to have an extra field – but you’d still like to use +code created with the old format, don’t worry! It’s very simple to update +message types without breaking any of your existing code when you use the binary +wire format.

Check +Proto Best Practices and the +following rules:

Binary Wire-unsafe Changes

Wire-unsafe changes are schema changes that will break if you use parse data +that was serialized using the old schema with a parser that is using the new +schema (or vice versa). Only make wire-unsafe changes if you know that all +serializers and deserializers of the data are using the new schema.

  • Changing field numbers for any existing field is not safe.
    • Changing the field number is equivalent to deleting the field and adding +a new field with the same type. If you want to renumber a field, see the +instructions for deleting a field.
  • Moving fields into an existing oneof is not safe.

Binary Wire-safe Changes

Wire-safe changes are ones where it is fully safe to evolve the schema in this +way without risk of data loss or new parse failures.

Note that any wire-safe changes may be a breaking change to application code in +a given language. For example, adding a value to a preexisting enum would be a +compilation break for any code with an exhaustive switch on that enum. For that +reason, Google may avoid making some of these types of changes on public +messages: the AIPs contain guidance for which of these changes are safe to make +there.

  • Adding new fields is safe.
    • If you add new fields, any messages serialized by code using your “old” +message format can still be parsed by your new generated code. You +should keep in mind the default values for these elements so +that new code can properly interact with messages generated by old code. +Similarly, messages created by your new code can be parsed by your old +code: old binaries simply ignore the new field when parsing. See the +Unknown Fields section for details.
  • Removing fields is safe.
    • The same field number must not used again in your updated message type. +You may want to rename the field instead, perhaps adding the prefix +“OBSOLETE_”, or make the field number reserved, so +that future users of your .proto can’t accidentally reuse the number.
  • Adding additional values to an enum is safe.
  • Changing a single explicit presence field or extension into a member of a +new oneof is safe.
  • Changing a oneof which contains only one field to an explicit presence +field is safe.
  • Changing a field into an extension of same number and type is safe.

Binary Wire-compatible Changes (Conditionally Safe)

Unlike Wire-safe changes, wire-compatible means that the same data can be parsed +both before and after a given change. However, a parse of the data may be lossy +under this shape of change. For example, changing an int32 to an int64 is a +compatible change, but if a value larger than INT32_MAX is written, a client +that reads it as an int32 will discard the high order bits of the number.

You can make compatible changes to your schema only if you manage the roll out +to your system carefully. For example, you may change an int32 to an int64 but +ensure you continue to only write legal int32 values until the new schema is +deployed to all endpoints, and then subsequently start writing larger values +after that.

If your schema is published outside of your organization, you should generally +not make wire-compatible changes, as you cannot manage the deployment of the new +schema to know when the different range of values may be safe to use.

  • int32, uint32, int64, uint64, and bool are all compatible.
    • If a number is parsed from the wire which doesn’t fit in the +corresponding type, you will get the same effect as if you had cast the +number to that type in C++ (for example, if a 64-bit number is read as +an int32, it will be truncated to 32 bits).
  • sint32 and sint64 are compatible with each other but are not +compatible with the other integer types.
    • If the value written was between INT_MIN and INT_MAX inclusive it will +parse as the same value with either type. If an sint64 value was written +outside of that range and parsed as an sint32, the varint is truncated +to 32 bits and then zigzag decoding occurs (which will cause a different +value to be observed).
  • string and bytes are compatible as long as the bytes are valid UTF-8.
  • Embedded messages are compatible with bytes if the bytes contain an +encoded instance of the message.
  • fixed32 is compatible with sfixed32, and fixed64 with sfixed64.
  • For string, bytes, and message fields, singular is compatible with +repeated.
    • Given serialized data of a repeated field as input, clients that expect +this field to be singular will take the last input value if it’s a +primitive type field or merge all input elements if it’s a message type +field. Note that this is not generally safe for numeric types, +including bools and enums. Repeated fields of numeric types are +serialized in the +packed +format by default, which will not be parsed correctly when a singular +field is expected.
  • enum is compatible with int32, uint32, int64, and uint64
    • Be aware that client code may treat them differently when the message is +deserialized: for example, unrecognized proto3 enum values will be +preserved in the message, but how this is represented when the message +is deserialized is language-dependent.
  • Changing a field between a map<K, V> and the corresponding repeated +message field is binary compatible (see Maps, below, for the +message layout and other restrictions).
    • However, the safety of the change is application-dependent: when +deserializing and reserializing a message, clients using the repeated +field definition will produce a semantically identical result; however, +clients using the map field definition may reorder entries and drop +entries with duplicate keys.

Unknown Fields

Unknown fields are well-formed protocol buffer serialized data representing +fields that the parser does not recognize. For example, when an old binary +parses data sent by a new binary with new fields, those new fields become +unknown fields in the old binary.

Proto3 messages preserve unknown fields and include them during parsing and in +the serialized output, which matches proto2 behavior.

Retaining Unknown Fields

Some actions can cause unknown fields to be lost. For example, if you do one of +the following, unknown fields are lost:

  • Serialize a proto to JSON.
  • Iterate over all of the fields in a message to populate a new message.

To avoid losing unknown fields, do the following:

  • Use binary; avoid using text formats for data exchange.
  • Use message-oriented APIs, such as CopyFrom() and MergeFrom(), to copy data +rather than copying field-by-field

TextFormat is a bit of a special case. Serializing to TextFormat prints unknown +fields using their field numbers. But parsing TextFormat data back into a binary +proto fails if there are entries that use field numbers.

Any

The Any message type lets you use messages as embedded types without having +their .proto definition. An Any contains an arbitrary serialized message as +bytes, along with a URL that acts as a globally unique identifier for and +resolves to that message’s type. To use the Any type, you need to +import google/protobuf/any.proto.

import "google/protobuf/any.proto";
+
+message ErrorStatus {
+  string message = 1;
+  repeated google.protobuf.Any details = 2;
+}
+

The default type URL for a given message type is +type.googleapis.com/_packagename_._messagename_.

Different language implementations will support runtime library helpers to pack +and unpack Any values in a typesafe manner – for example, in Java, the Any +type will have special pack() and unpack() accessors, while in C++ there are +PackFrom() and UnpackTo() methods:

// Storing an arbitrary message type in Any.
+NetworkErrorDetails details = ...;
+ErrorStatus status;
+status.add_details()->PackFrom(details);
+
+// Reading an arbitrary message from Any.
+ErrorStatus status = ...;
+for (const google::protobuf::Any& detail : status.details()) {
+  if (detail.Is<NetworkErrorDetails>()) {
+    NetworkErrorDetails network_error;
+    detail.UnpackTo(&network_error);
+    ... processing network_error ...
+  }
+}
+

Oneof

If you have a message with many singular fields and where at most one field will +be set at the same time, you can enforce this behavior and save memory by using +the oneof feature.

Oneof fields are like optional fields except all the fields in a oneof share +memory, and at most one field can be set at the same time. Setting any member of +the oneof automatically clears all the other members. You can check which value +in a oneof is set (if any) using a special case() or WhichOneof() method, +depending on your chosen language.

Note that if multiple values are set, the last set value as determined by the +order in the proto will overwrite all previous ones.

Field numbers for oneof fields must be unique within the enclosing message.

Using Oneof

To define a oneof in your .proto you use the oneof keyword followed by your +oneof name, in this case test_oneof:

message SampleMessage {
+  oneof test_oneof {
+    string name = 4;
+    SubMessage sub_message = 9;
+  }
+}
+

You then add your oneof fields to the oneof definition. You can add fields of +any type, except map fields and repeated fields. If you need to add a +repeated field to a oneof, you can use a message containing the repeated field.

In your generated code, oneof fields have the same getters and setters as +regular fields. You also get a special method for checking which value (if any) +in the oneof is set. You can find out more about the oneof API for your chosen +language in the relevant API reference.

Oneof Features

  • Setting a oneof field will automatically clear all other members of the +oneof. So if you set several oneof fields, only the last field you set +will still have a value.

    SampleMessage message;
    +message.set_name("name");
    +CHECK_EQ(message.name(), "name");
    +// Calling mutable_sub_message() will clear the name field and will set
    +// sub_message to a new instance of SubMessage with none of its fields set.
    +message.mutable_sub_message();
    +CHECK(message.name().empty());
    +
  • If the parser encounters multiple members of the same oneof on the wire, +only the last member seen is used in the parsed message. When parsing data +on the wire, starting at the beginning of the bytes, evaluate the next +value, and apply the following parsing rules:

    • First, check if a different field in the same oneof is currently set, +and if so clear it.

    • Then apply the contents as though the field was not in a oneof:

      • A primitive will overwrite any value already set
      • A message will merge into any value already set
  • A oneof cannot be repeated.

  • Reflection APIs work for oneof fields.

  • If you set a oneof field to the default value (such as setting an int32 +oneof field to 0), the “case” of that oneof field will be set, and the value +will be serialized on the wire.

  • If you’re using C++, make sure your code doesn’t cause memory crashes. The +following sample code will crash because sub_message was already deleted +by calling the set_name() method.

    SampleMessage message;
    +SubMessage* sub_message = message.mutable_sub_message();
    +message.set_name("name");      // Will delete sub_message
    +sub_message->set_...            // Crashes here
    +
  • Again in C++, if you Swap() two messages with oneofs, each message will +end up with the other’s oneof case: in the example below, msg1 will have a +sub_message and msg2 will have a name.

    SampleMessage msg1;
    +msg1.set_name("name");
    +SampleMessage msg2;
    +msg2.mutable_sub_message();
    +msg1.swap(&msg2);
    +CHECK(msg1.has_sub_message());
    +CHECK_EQ(msg2.name(), "name");
    +

Backwards-compatibility issues

Be careful when adding or removing oneof fields. If checking the value of a +oneof returns None/NOT_SET, it could mean that the oneof has not been set or +it has been set to a field in a different version of the oneof. There is no way +to tell the difference, since there’s no way to know if an unknown field on the +wire is a member of the oneof.

Tag Reuse Issues

  • Move singular fields into or out of a oneof: You may lose some of your +information (some fields will be cleared) after the message is serialized +and parsed. However, you can safely move a single field into a new oneof +and may be able to move multiple fields if it is known that only one is ever +set. See Updating A Message Type for further details.
  • Delete a oneof field and add it back: This may clear your currently set +oneof field after the message is serialized and parsed.
  • Split or merge oneof: This has similar issues to moving singular fields.

Maps

If you want to create an associative map as part of your data definition, +protocol buffers provides a handy shortcut syntax:

map<key_type, value_type> map_field = N;
+

…where the key_type can be any integral or string type (so, any +scalar type except for floating point types and bytes). Note that +neither enum nor proto messages are valid for key_type. +The value_type can be any type except another map.

So, for example, if you wanted to create a map of projects where each Project +message is associated with a string key, you could define it like this:

map<string, Project> projects = 3;
+

Maps Features

  • Map fields cannot be repeated.
  • Wire format ordering and map iteration ordering of map values is undefined, +so you cannot rely on your map items being in a particular order.
  • When generating text format for a .proto, maps are sorted by key. Numeric +keys are sorted numerically.
  • When parsing from the wire or when merging, if there are duplicate map keys +the last key seen is used. When parsing a map from text format, parsing may +fail if there are duplicate keys.
  • If you provide a key but no value for a map field, the behavior when the +field is serialized is language-dependent. In C++, Java, Kotlin, and Python +the default value for the type is serialized, while in other languages +nothing is serialized.
  • No symbol FooEntry can exist in the same scope as a map foo, because +FooEntry is already used by the implementation of the map.

The generated map API is currently available for all supported languages. You +can find out more about the map API for your chosen language in the relevant +API reference.

Backwards Compatibility

The map syntax is equivalent to the following on the wire, so protocol buffers +implementations that do not support maps can still handle your data:

message MapFieldEntry {
+  key_type key = 1;
+  value_type value = 2;
+}
+
+repeated MapFieldEntry map_field = N;
+

Any protocol buffers implementation that supports maps must both produce and +accept data that can be accepted by the earlier definition.

Packages

You can add an optional package specifier to a .proto file to prevent name +clashes between protocol message types.

package foo.bar;
+message Open { ... }
+

You can then use the package specifier when defining fields of your message +type:

message Foo {
+  ...
+  foo.bar.Open open = 1;
+  ...
+}
+

The way a package specifier affects the generated code depends on your chosen +language:

  • In C++ the generated classes are wrapped inside a C++ namespace. For +example, Open would be in the namespace foo::bar.
  • In Java and Kotlin, the package is used as the Java package, unless +you explicitly provide an option java_package in your .proto file.
  • In Python, the package directive is ignored, since Python modules are +organized according to their location in the file system.
  • In Go, the package directive is ignored, and the generated .pb.go +file is in the package named after the corresponding go_proto_library +Bazel rule. For open source projects, you must provide either a go_package option or set the Bazel -M flag.
  • In Ruby, the generated classes are wrapped inside nested Ruby +namespaces, converted to the required Ruby capitalization style (first +letter capitalized; if the first character is not a letter, PB_ is +prepended). For example, Open would be in the namespace Foo::Bar.
  • In PHP the package is used as the namespace after converting to +PascalCase, unless you explicitly provide an option php_namespace in your +.proto file. For example, Open would be in the namespace Foo\Bar.
  • In C# the package is used as the namespace after converting to +PascalCase, unless you explicitly provide an option csharp_namespace in +your .proto file. For example, Open would be in the namespace Foo.Bar.

Note that even when the package directive does not directly affect the +generated code, for example in Python, it is still strongly recommended to +specify the package for the .proto file, as otherwise it may lead to naming +conflicts in descriptors and make the proto not portable for other languages.

Packages and Name Resolution

Type name resolution in the protocol buffer language works like C++: first the +innermost scope is searched, then the next-innermost, and so on, with each +package considered to be “inner” to its parent package. A leading ‘.’ (for +example, .foo.bar.Baz) means to start from the outermost scope instead.

The protocol buffer compiler resolves all type names by parsing the imported +.proto files. The code generator for each language knows how to refer to each +type in that language, even if it has different scoping rules.

Defining Services

If you want to use your message types with an RPC (Remote Procedure Call) +system, you can define an RPC service interface in a .proto file and the +protocol buffer compiler will generate service interface code and stubs in your +chosen language. So, for example, if you want to define an RPC service with a +method that takes your SearchRequest and returns a SearchResponse, you can +define it in your .proto file as follows:

service SearchService {
+  rpc Search(SearchRequest) returns (SearchResponse);
+}
+

The most straightforward RPC system to use with protocol buffers is +gRPC: a language- and platform-neutral open source RPC system +developed at Google. gRPC works particularly well with protocol buffers and lets +you generate the relevant RPC code directly from your .proto files using a +special protocol buffer compiler plugin.

If you don’t want to use gRPC, it’s also possible to use protocol buffers with +your own RPC implementation. You can find out more about this in the +Proto2 Language Guide.

There are also a number of ongoing third-party projects to develop RPC +implementations for Protocol Buffers. For a list of links to projects we know +about, see the +third-party add-ons wiki page.

JSON Mapping

The standard protobuf binary wire format is the preferred serialization format +for communication between two systems that use protobufs. For communicating with +systems that use JSON rather than protobuf wire format, Protobuf supports a +canonical encoding in JSON.

Options

Individual declarations in a .proto file can be annotated with a number of +options. Options do not change the overall meaning of a declaration, but may +affect the way it is handled in a particular context. The complete list of +available options is defined in /google/protobuf/descriptor.proto.

Some options are file-level options, meaning they should be written at the +top-level scope, not inside any message, enum, or service definition. Some +options are message-level options, meaning they should be written inside message +definitions. Some options are field-level options, meaning they should be +written inside field definitions. Options can also be written on enum types, +enum values, oneof fields, service types, and service methods; however, no +useful options currently exist for any of these.

Here are a few of the most commonly used options:

  • java_package (file option): The package you want to use for your generated +Java/Kotlin classes. If no explicit java_package option is given in the +.proto file, then by default the proto package (specified using the +“package” keyword in the .proto file) will be used. However, proto +packages generally do not make good Java packages since proto packages are +not expected to start with reverse domain names. If not generating Java or +Kotlin code, this option has no effect.

    option java_package = "com.example.foo";
    +
  • java_outer_classname (file option): The class name (and hence the file +name) for the wrapper Java class you want to generate. If no explicit +java_outer_classname is specified in the .proto file, the class name +will be constructed by converting the .proto file name to camel-case (so +foo_bar.proto becomes FooBar.java). If the java_multiple_files option +is disabled, then all other classes/enums/etc. generated for the .proto +file will be generated within this outer wrapper Java class as nested +classes/enums/etc. If not generating Java code, this option has no effect.

    option java_outer_classname = "Ponycopter";
    +
  • java_multiple_files (file option): If false, only a single .java file +will be generated for this .proto file, and all the Java +classes/enums/etc. generated for the top-level messages, services, and +enumerations will be nested inside of an outer class (see +java_outer_classname). If true, separate .java files will be generated +for each of the Java classes/enums/etc. generated for the top-level +messages, services, and enumerations, and the wrapper Java class generated +for this .proto file won’t contain any nested classes/enums/etc. This is a +Boolean option which defaults to false. If not generating Java code, this +option has no effect.

    option java_multiple_files = true;
    +
  • optimize_for (file option): Can be set to SPEED, CODE_SIZE, or +LITE_RUNTIME. This affects the C++ and Java code generators (and possibly +third-party generators) in the following ways:

    • SPEED (default): The protocol buffer compiler will generate code for +serializing, parsing, and performing other common operations on your +message types. This code is highly optimized.
    • CODE_SIZE: The protocol buffer compiler will generate minimal classes +and will rely on shared, reflection-based code to implement +serialization, parsing, and various other operations. The generated code +will thus be much smaller than with SPEED, but operations will be +slower. Classes will still implement exactly the same public API as they +do in SPEED mode. This mode is most useful in apps that contain a very +large number of .proto files and do not need all of them to be +blindingly fast.
    • LITE_RUNTIME: The protocol buffer compiler will generate classes that +depend only on the “lite” runtime library (libprotobuf-lite instead of +libprotobuf). The lite runtime is much smaller than the full library +(around an order of magnitude smaller) but omits certain features like +descriptors and reflection. This is particularly useful for apps running +on constrained platforms like mobile phones. The compiler will still +generate fast implementations of all methods as it does in SPEED mode. +Generated classes will only implement the MessageLite interface in +each language, which provides only a subset of the methods of the full +Message interface.
    option optimize_for = CODE_SIZE;
    +
  • cc_generic_services, java_generic_services, py_generic_services (file +options): Generic services are deprecated. Whether or not the protocol +buffer compiler should generate abstract service code based on +services definitions in C++, Java, and Python, respectively. +For legacy reasons, these default to true. However, as of version 2.3.0 +(January 2010), it is considered preferable for RPC implementations to +provide +code generator plugins +to generate code more specific to each system, rather than rely on the +“abstract” services.

    // This file relies on plugins to generate service code.
    +option cc_generic_services = false;
    +option java_generic_services = false;
    +option py_generic_services = false;
    +
  • cc_enable_arenas (file option): Enables +arena allocation for C++ +generated code.

  • objc_class_prefix (file option): Sets the Objective-C class prefix which +is prepended to all Objective-C generated classes and enums from this +.proto. There is no default. You should use prefixes that are between 3-5 +uppercase characters as +recommended by Apple. +Note that all 2 letter prefixes are reserved by Apple.

  • packed (field option): Defaults to true on a repeated field of a basic +numeric type, causing a more compact +encoding to be +used. To use unpacked wireformat, it can be set to false. This provides +compatibility with parsers prior to version 2.3.0 (rarely needed) as shown +in the following example:

    repeated int32 samples = 4 [packed = false];
    +
  • deprecated (field option): If set to true, indicates that the field is +deprecated and should not be used by new code. In most languages this has no +actual effect. In Java, this becomes a @Deprecated annotation. For C++, +clang-tidy will generate warnings whenever deprecated fields are used. In +the future, other language-specific code generators may generate deprecation +annotations on the field’s accessors, which will in turn cause a warning to +be emitted when compiling code which attempts to use the field. If the field +is not used by anyone and you want to prevent new users from using it, +consider replacing the field declaration with a reserved +statement.

    int32 old_field = 6 [deprecated = true];
    +

Enum Value Options

Enum value options are supported. You can use the deprecated option to +indicate that a value shouldn’t be used anymore. You can also create custom +options using extensions.

The following example shows the syntax for adding these options:

import "google/protobuf/descriptor.proto";
+
+extend google.protobuf.EnumValueOptions {
+  optional string string_name = 123456789;
+}
+
+enum Data {
+  DATA_UNSPECIFIED = 0;
+  DATA_SEARCH = 1 [deprecated = true];
+  DATA_DISPLAY = 2 [
+    (string_name) = "display_value"
+  ];
+}
+

The C++ code to read the string_name option might look something like this:

const absl::string_view foo = proto2::GetEnumDescriptor<Data>()
+    ->FindValueByName("DATA_DISPLAY")->options().GetExtension(string_name);
+

See Custom Options to see how to apply custom options to enum +values and to fields.

Custom Options

Protocol Buffers also allows you to define and use your own options. Note that +this is an advanced feature which most people don’t need. If you do think +you need to create your own options, see the +Proto2 Language Guide +for details. Note that creating custom options uses +extensions, +which are permitted only for custom options in proto3.

Option Retention

Options have a notion of retention, which controls whether an option is +retained in the generated code. Options have runtime retention by default, +meaning that they are retained in the generated code and are thus visible at +runtime in the generated descriptor pool. However, you can set retention = RETENTION_SOURCE to specify that an option (or field within an option) must not +be retained at runtime. This is called source retention.

Option retention is an advanced feature that most users should not need to worry +about, but it can be useful if you would like to use certain options without +paying the code size cost of retaining them in your binaries. Options with +source retention are still visible to protoc and protoc plugins, so code +generators can use them to customize their behavior.

Retention can be set directly on an option, like this:

extend google.protobuf.FileOptions {
+  optional int32 source_retention_option = 1234
+      [retention = RETENTION_SOURCE];
+}
+

It can also be set on a plain field, in which case it takes effect only when +that field appears inside an option:

message OptionsMessage {
+  int32 source_retention_field = 1 [retention = RETENTION_SOURCE];
+}
+

You can set retention = RETENTION_RUNTIME if you like, but this has no effect +since it is the default behavior. When a message field is marked +RETENTION_SOURCE, its entire contents are dropped; fields inside it cannot +override that by trying to set RETENTION_RUNTIME.

Option Targets

Fields have a targets option which controls the types of entities that the +field may apply to when used as an option. For example, if a field has +targets = TARGET_TYPE_MESSAGE then that field cannot be set in a custom option +on an enum (or any other non-message entity). Protoc enforces this and will +raise an error if there is a violation of the target constraints.

At first glance, this feature may seem unnecessary given that every custom +option is an extension of the options message for a specific entity, which +already constrains the option to that one entity. However, option targets are +useful in the case where you have a shared options message applied to multiple +entity types and you want to control the usage of individual fields in that +message. For example:

message MyOptions {
+  string file_only_option = 1 [targets = TARGET_TYPE_FILE];
+  int32 message_and_enum_option = 2 [targets = TARGET_TYPE_MESSAGE,
+                                     targets = TARGET_TYPE_ENUM];
+}
+
+extend google.protobuf.FileOptions {
+  optional MyOptions file_options = 50000;
+}
+
+extend google.protobuf.MessageOptions {
+  optional MyOptions message_options = 50000;
+}
+
+extend google.protobuf.EnumOptions {
+  optional MyOptions enum_options = 50000;
+}
+
+// OK: this field is allowed on file options
+option (file_options).file_only_option = "abc";
+
+message MyMessage {
+  // OK: this field is allowed on both message and enum options
+  option (message_options).message_and_enum_option = 42;
+}
+
+enum MyEnum {
+  MY_ENUM_UNSPECIFIED = 0;
+  // Error: file_only_option cannot be set on an enum.
+  option (enum_options).file_only_option = "xyz";
+}
+

Generating Your Classes

To generate the Java, Kotlin, Python, C++, Go, Ruby, Objective-C, or C# code +that you need to work with the message types defined in a .proto file, you +need to run the protocol buffer compiler protoc on the .proto file. If you +haven’t installed the compiler, +download the package and follow the +instructions in the README. For Go, you also need to install a special code +generator plugin for the compiler; you can find this and installation +instructions in the golang/protobuf +repository on GitHub.

The protobuf compiler is invoked as follows:

protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR --go_out=DST_DIR --ruby_out=DST_DIR --objc_out=DST_DIR --csharp_out=DST_DIR path/to/file.proto
+
  • IMPORT_PATH specifies a directory in which to look for .proto files when +resolving import directives. If omitted, the current directory is used. +Multiple import directories can be specified by passing the --proto_path +option multiple times. -I=_IMPORT_PATH_ can be used as a short form of +--proto_path.

Note: File paths relative to their proto_path must be globally unique in a +given binary. For example, if you have proto/lib1/data.proto and +proto/lib2/data.proto, those two files cannot be used together with +-I=proto/lib1 -I=proto/lib2 because it would be ambiguous which file import "data.proto" will mean. Instead -Iproto/ should be used and the global names +will be lib1/data.proto and lib2/data.proto.

If you are publishing a library and other users may use your messages directly, +you should include a unique library name in the path that they are expected to +be used under to avoid file name collisions. If you have multiple directories in +one project, it is best practice to prefer setting one -I to a top level +directory of the project.

  • You can provide one or more output directives:

    As an extra convenience, if the DST_DIR ends in .zip or .jar, the +compiler will write the output to a single ZIP-format archive file with the +given name. .jar outputs will also be given a manifest file as required by +the Java JAR specification. Note that if the output archive already exists, +it will be overwritten.

  • You must provide one or more .proto files as input. Multiple .proto +files can be specified at once. Although the files are named relative to the +current directory, each file must reside in one of the IMPORT_PATHs so +that the compiler can determine its canonical name.

File location

Prefer not to put .proto files in the same +directory as other language sources. Consider +creating a subpackage proto for .proto files, under the root package for +your project.

Location Should be Language-agnostic

When working with Java code, it’s handy to put related .proto files in the +same directory as the Java source. However, if any non-Java code ever uses the +same protos, the path prefix will no longer make sense. So in +general, put the protos in a related language-agnostic directory such as +//myteam/mypackage.

The exception to this rule is when it’s clear that the protos will be used only +in a Java context, such as for testing.

Supported Platforms

For information about:

\ No newline at end of file diff --git a/programming-guides/serialization-not-canonical/index.html b/programming-guides/serialization-not-canonical/index.html new file mode 100644 index 000000000..176de759a --- /dev/null +++ b/programming-guides/serialization-not-canonical/index.html @@ -0,0 +1,34 @@ +Proto Serialization Is Not Canonical | Protocol Buffers Documentation +

Proto Serialization Is Not Canonical

Explains how serialization works and why it is not canonical.

Many people want a serialized proto to canonically represent the contents of +that proto. Use cases include:

  • using a serialized proto as a key in a hash table
  • taking a fingerprint or checksum of a serialized proto
  • comparing serialized payloads as a way of checking message equality

Unfortunately, protobuf serialization is not (and cannot be) canonical. There +are a few notable exceptions, such as MapReduce, but in general you should +generally think of proto serialization as unstable. This page explains why.

Deterministic is not Canonical

Deterministic serialization is not canonical. The serializer can generate +different output for many reasons, including but not limited to the following +variations:

  1. The protobuf schema changes in any way.
  2. The application being built changes in any way.
  3. The binary is built with different flags (eg. opt vs. debug).
  4. The protobuf library is updated.

This means that hashes of serialized protos are fragile and not stable across +time or space.

There are many reasons why the serialized output can change. The above list is +not exhaustive. Some of them are inherent difficulties in the problem space that +would make it inefficient or impossible to guarantee canonical serialization +even if we wanted to. Others are things we intentionally leave undefined to +allow for optimization opportunities.

Inherent Barriers to Stable Serialization

Protobuf objects preserve unknown fields to provide forward and backward +compatibility. The handling of unknown fields is a primary obstacle to canonical +serialization.

In the wire format, bytes fields and nested sub-messages use the same wire type. +This ambiguity makes it impossible to correctly canonicalize messages stored in +the unknown field set. Since the exact same contents may be either one, it is +impossible to know whether to treat it as a message and recurse down or not.

For efficiency, implementations typically serialize unknown fields after known +fields. Canonical serialization, however, would require interleaving unknown +fields with known fields according to field number. This would impose +significant efficiency and code size costs on all users, even those not +requiring this feature.

Things Intentionally Left Undefined

Even if canonical serialization was feasible (that is, if we could solve the +unknown field problem), we intentionally leave serialization order undefined to +allow for more optimization opportunities:

  1. If we can prove a field is never used in a binary, we can remove it from the +schema completely and process it as an unknown field. This saves substantial +code size and CPU cycles.
  2. There may be opportunities to optimize by serializing vectors of the same +field together, even though this would break field number order.

To leave room for optimizations like this, we want to intentionally scramble +field order in some configurations, so that applications do not inappropriately +depend on field order.

\ No newline at end of file diff --git a/programming-guides/style/index.html b/programming-guides/style/index.html new file mode 100644 index 000000000..58c19f947 --- /dev/null +++ b/programming-guides/style/index.html @@ -0,0 +1,132 @@ +Style Guide | Protocol Buffers Documentation +

Style Guide

Provides direction for how best to structure your proto definitions.

This document provides a style guide for .proto files. By following these +conventions, you’ll make your protocol buffer message definitions and their +corresponding classes consistent and easy to read.

Enforcement of the following style guidelines is controlled via +enforce_naming_style.

Standard File Formatting

  • Keep the line length to 80 characters.
  • Use an indent of 2 spaces.
  • Prefer the use of double quotes for strings.

File Structure

Files should be named lower_snake_case.proto.

All files should be ordered in the following manner:

  1. License header (if applicable)
  2. File overview
  3. Syntax or edition
  4. Package
  5. Imports (sorted)
  6. File options
  7. Everything else

Identifier naming styles

Protobuf identifiers use one of the following naming styles:

  1. TitleCase
    • Contains uppercase letters, lowercase letters, and numbers
    • The initial character is an uppercase letter
    • The initial letter of each word is capitalized
  2. lower_snake_case
    • Contains lowercase letters, underscores, and numbers
    • Words are separated by a single underscore
  3. UPPER_SNAKE_CASE
    • Contains uppercase letters, underscores, and numbers
    • Words are separated by a single underscore
  4. camelCase
    • Contains uppercase letters, lowercase letters, and numbers
    • The initial character is an lowercase letter
    • The initial letter of each subsequent word is capitalized
    • Note: The style guide below does not use camelCase for any +identifier in .proto files; the terminology is only clarified here since +some language’s generated code may transform identifiers into this +style.

In all cases, treat abbreviations as though they are single words: use +GetDnsRequest rather than GetDNSRequest, dns_request rather than +d_n_s_request.

Underscores in Identifiers

Don’t use underscores as the initial or final character of a name. Any +underscore should always be followed by a letter (not a number or a second +underscore).

The motivation for this rule is that each protobuf language implementation may +convert identifiers into the local language style: a name of song_id in a +.proto file may end up having accessors for the field which are capitalized as +SongId, songId or song_id depending on the language.

By using underscores only before letters, it avoids situations where names may +be distinct in one style, but would collide after they are transformed into one +of the other styles.

For example, both DNS2 and DNS_2 would both transform into TitleCase as +Dns2. Allowing either of those names can be lead to painful situations when a +message is used only in some languages where the generated code keeps the +original UPPER_SNAKE_CASE style, becomes widely established, and then is only +later used in a language where names are transformed to TitleCase where they +collide.

When applied, this style rule means that you should use XYZ2 or XYZ_V2 +rather than XYZ_2 or XYZ_2V.

Packages

Packages names should be a dot-delimited sequence of lower_snake_case names. +They should not contain uppercase letters.

Multi-word package names may be lower_snake_case or dot.delimited (dot-delimited +package names are emitted as nested packages/namespaces in most languages).

Package names should attempt to be a short but unique name based on the project +name. The package should not be coupled with the directory path, especially when +the files are in a deeply nested path.

Package names should not be Java packages (com.company.x.y); instead use x.y +as the package and use the java_package option.

Message Names

Use TitleCase for message names.

message SongRequest {
+}
+

Field Names

Use snake_case for field names, including extensions.

Use pluralized names for repeated fields.

string song_name = 1;
+repeated Song songs = 2;
+

Oneof Names

Use lower_snake_case for oneof names.

oneof song_id {
+  string song_human_readable_id = 1;
+  int64 song_machine_id = 2;
+}
+

Enums

Use TitleCase for enum type names.

Use UPPER_SNAKE_CASE for enum value names.

enum FooBar {
+  FOO_BAR_UNSPECIFIED = 0;
+  FOO_BAR_FIRST_VALUE = 1;
+  FOO_BAR_SECOND_VALUE = 2;
+}
+

The first listed value should be a zero value enum and have the suffix of either +_UNSPECIFIED or _UNKNOWN. This value may be used as an unknown/default value +and should be distinct from any of the semantic values you expect to be +explicitly set. For more information on the unspecified enum value, see +the Proto Best Practices page.

Assign the number used for each value densely and sequentially increasing. Gaps +in numbering should only occur when a previously used enum value is removed. +Avoid using negative values.

Enum Value Prefixing

Enum values are semantically considered to not be scoped by their containing +enum name, so the same name in two sibling enums is not allowed. For example, +the following would be rejected by protoc since the SET value defined in the +two enums are considered to be in the same scope:

enum CollectionType {
+  COLLECTION_TYPE_UNSPECIFIED = 0;
+  SET = 1;
+  MAP = 2;
+  ARRAY = 3;
+}
+
+// Won't compile - `SET` enum name will clash
+// with the one defined in `CollectionType` enum.
+enum TennisVictoryType {
+  TENNIS_VICTORY_TYPE_UNSPECIFIED = 0;
+  GAME = 1;
+  SET = 2;
+  MATCH = 3;
+}
+

Name collisions are a high risk when enums are defined at the top level of a +file (not nested inside a message definition); in that case the siblings include +enums defined in other files that set the same package, where protoc may not be +able to detect the collision has occurred at code generation time.

To avoid these risks, it is strongly recommended to do one of:

  • Prefix every value with the enum name (converted to UPPER_SNAKE_CASE)
  • Nest the enum inside a containing message

Either option is enough to mitigate collision risks, but prefer top-level enums +with prefixed values over creating a message simply to mitigate the issue. Since +some languages don’t support an enum being defined inside a “struct” type, +preferring prefixed values ensures a consistent approach across binding +languages.

When prefixing enum values, the remainder of the name with the prefix stripped +should still be a legal and style-conformant enum name. For example, avoid the +following:

enum DeviceTier {
+  DEVICE_TIER_UNKNOWN = 0;
+  DEVICE_TIER_1 = 1;
+  DEVICE_TIER_2 = 2;
+}
+

Instead, use a value name like DEVICE_TIER_TIER1, where the DEVICE_TIER_ +portion is viewed as scoping the enum value rather than as part of the +individual enum value name. Some Protobuf implementations automatically strip +the prefix that matches the containing enum name where it is safe to do so, but +could not in this example since a bare 1 is not a legal enum value name.

A future Edition will add support for scoped enums, which will eliminate the +need to manually prefix each enum value and enable this to be written succinctly +as TIER1 = 1.

Services

Use TitleCase for service names and method names.

service FooService {
+  rpc GetSomething(GetSomethingRequest) returns (GetSomethingResponse);
+  rpc ListSomething(ListSomethingRequest) returns (ListSomethingResponse);
+}
+

Things to Avoid

Avoid confusing relative packages on field types

The .proto syntax allows you to reference types that are defined in a different +package in a relative manner. Resolution will search up the parent packages to +resolve a relative name. For example:

// File: a.proto
+package a.b;
+message C {}
+
// File: x.proto
+package a.x;
+message SomeMsg {
+  // Since we are in a.x.SomeMsg, this name is searched for in this order:
+  //  .a.x.SomeMsg.b.C
+  //  .a.x.b.C
+  //  .a.b.C
+  //  .b.C
+  b.C field3 = 1;
+}
+

Relying on the “relative to a parent package” functionality when referencing +types defined in a different package is supported but can be confusing: in this +example the spelling a.b.C should be used.

Naming other types in the current package (for example, sibling messages) +without writing the package is idiomatic.

You can write a fully qualified name by using a leading period to avoid any +ambiguity concerns, but is commonly omitted in most cases even if the package is +fully written out.

Required Fields

Required fields are a way to enforce that a given field must be set when parsing +wire bytes, and otherwise refuse to parse the message. The required invariant is +generally not enforced on messages constructed in memory. Required fields were +removed in proto3. Proto2 required fields that have been migrated to editions +2023 can use the field_presence feature set to LEGACY_REQUIRED to +accommodate.

While enforcement of required fields at the schema level is intuitively +desirable, one of the primary design goals of protobuf is to support long term +schema evolution. No matter how obviously required a given field seems to be +today, there is a plausible future where the field should no longer be set (e.g. +an int64 user_id may need to migrate to a UserId user_id in the future).

Especially in the case of middleware servers that may forward messages that they +don’t really need to process, the semantics of required has proven too harmful +for those long-term evolution goals, and so is now very strongly discouraged.

See +Required is Strongly Deprecated.

Groups

Groups is an alternate syntax and wire format for nested messages. Groups are +considered deprecated in proto2, were removed from proto3, and are converted to +a delimited representation in edition 2023. You can use a nested message +definition and field of that type instead of using the group syntax, using the +message_encoding +feature for wire-compatibility.

See groups.

\ No newline at end of file diff --git a/programming-guides/symbol_visibility/index.html b/programming-guides/symbol_visibility/index.html new file mode 100644 index 000000000..01253bd40 --- /dev/null +++ b/programming-guides/symbol_visibility/index.html @@ -0,0 +1,178 @@ +Symbol Visibility | Protocol Buffers Documentation +

Symbol Visibility

Explains the terminology and functionality of visibility, introduced in edition 2024.

This document describes the terminology and functionality of the symbol +visibility system introduced in proto edition = "2024"

Glossary

  • Symbol: Any of message, enum, service or extend <type>, the +allowed Top-Level types in a .proto file.
  • Top-Level: A Symbol defined at the root of a .proto file. This +includes all service definitions and any message, enum, or extend +block not nested in message.
  • Visibility: Property of a Symbol that controls whether it can be +imported into another .proto file. Either set explicitly or derived from +file defaults.
  • Entry-Point: A Symbol in a .proto file, which acts as the root of +a local sub-graph of Symbols in that file, through which either +generated code or other .proto files “enter” the file.
  • Symbol Waste: For a given Symbol ‘X’, the set of waste Symbols +are those unreachable from ‘X’, but defined in files which are transitively +imported to satisfy the processing of the file in which ‘X’ is defined.

Introduction

Visibility in Edition 2024 and later provides a way for authors to use access +modifiers for message and enum declarations. The visibility of a symbol +controls the ability to reference that symbol from another .proto file via +import. When a symbol is not visible outside of a given file, then references +to it from another .proto file will fail with a compiler error.

This feature allows authors to control access to their symbols from external +users and encourages smaller files, which may lead to a smaller code footprint +when only a subset of defined symbols are required.

Visibility applies to any message or enum referenced via:

  • message and extend field definitions.
  • extend <symbol>
  • service method request and response types.

Symbol visibility applies only to the proto language, controlling the proto +compiler’s ability to reference that symbol from another proto file. Visibility +must not be reflected into any language-specific generated code.

Detailed Usage

Visibility introduces a set of new file-level options and two new Protobuf +keywords, local and export, which can be prefixed to message and enum +types.

local message MyLocal {...}
+
+export enum MyExported {...}
+

Each .proto file also has a default visibility controlled by the edition’s +defaults or file-level option features.default_symbol_visibility. This +visibility impacts all message and enum definitions in the file.

Values available:

  • EXPORT_ALL: This is the default prior to Edition 2024. All messages and +enums are exported by default.
  • EXPORT_TOP_LEVEL: All top-level symbols default to export; nested +default to local.
  • LOCAL_ALL: All symbols default to local.
  • STRICT: All symbols default to local and visibility keywords are only +valid on top-level message and enum types. Nested types can no longer +use those keywords are are always treated as local

Default behavior per syntax/edition:

Syntax/editionDefault
2024EXPORT_TOP_LEVEL
2023EXPORT_ALL
proto3EXPORT_ALL
proto2EXPORT_ALL

Any top-level message and enum definitions can be annotated with explicit +local or export keywords to indicate their intended use. Symbols nested in +message may allow those keywords.

Example:

// 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
+local 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;
+}
+

STRICT default_symbol_visibility

When default_symbol_visibility is set to STRICT, more restrictive visibility +rules are applied to the file. This mode is intended as a more optimal, but +invasive type of visibility where nested types are not to be used outside their +own file. In STRICT mode:

  1. All symbols default to local.
  2. local and export may be used only on top-level message and enum +declarations.
  3. local and export keywords on nested symbols will result in a syntax +error.

A single carve-out exception to nested visibility keywords is made for specific +wrapper message types used to address C++ namespace pollution. In this case a +export enum is supported iff:

  1. The top-level message is local
  2. All fields are reserved, preventing any field definitions, using reserved 1 to max;

Example:

local message MyNamespaceMessage {
+  export enum Enum {
+    MY_VAL = 1;
+  }
+
+  // Ensure no fields are added to the message.
+  reserved 1 to max;
+}
+

Purpose of Visibility

There are two purposes for the visibility feature. The first introduces access +modifiers, a common feature of many popular programming languages, used to +communicate and enforce the intent of authors about the usage of a given API. +Visibility allows protos to have a limited set of proto-specific access control, +giving proto authors some additional controls about the parts of their API that +can be reused and defining the API’s entry-points.

The second purpose is to encourage limiting the scope of a .proto file to a +narrow set of definitions to reduce the need to process unnecessary definitions. +The protobuf language definition requires that Descriptor type data be bundled +at the FileDescriptorSet and FileDescriptor level. This means that all +definitions in a single file, and its transitive dependencies via imports, are +unconditionally processed whenever that .proto file is processed. In large +definition sets, this can become a significant source of large unused blocks of +definitions that both slow down processing and generate a large set of unused +generated code. The best way to combat this sort of anti-pattern is to keep +.proto files narrowly scoped, containing only the symbols needed for a given +sub-graph located in the same file. With visibility added to message and +enum types, we can enumerate the set of entry-points in a given file and +determine where unrelated definitions can be split into different files to +provide fine-grained dependencies.

Entry-Points

A .proto file entry-point is any symbol that acts as a starting point for a +sub-graph of the full transitive closure of proto symbols processed for a given +file. That sub-graph represents the full transitive closure of types required +for the definition of that entry-point symbol, which is a subset of the symbols +required to process the file in which the entry-point is defined.

There are generally 3 types of entry-points.

Simple-type Entry-Point

message and enum types that have a visibility of export both can act as +entry-points in a symbol graph. In the case of enum, that sub-graph is the +null set, which means any other type definitions in the same file as that +export enum Type {} can be considered ‘waste’ in reference to the symbol graph +required for importing the enum.

For message types the message acts as an entry-point for the full transitive +closure of types for the message’s field definitions and the recursive set of +field definitions of any sub-messages referenced by the entry-point.

Importantly for both enum and message any service or extend definitions +in the same file are unreferencable and can be considered ‘waste’ for users of +those message and enum definitions.

When a .proto file contains multiple local messages with no shared +dependencies, it is possible they can all act as independent entry-points when +used from generated code. The Protobuf compiler and static analysis system have +no way to determine the optimal entry-point layout of such a file. Without that +context we assume that local messages in the same file are optimal for the +intended generated code use-cases.

Service Entry-Points

service definitions act as an entry-point for all symbols referenced +transitively from that service, which includes the full transitive closure of +message and enum types for all rpc method definitions.

Service definitions cannot be referenced in any meaningful way from another +proto, which means when a .proto file is imported and it contains a service +definition, it and its transitive closure of method types can be considered a +waste. This is true even if all method input and output types are referenced +from the importing file.

Extension Entry-Points

extend <symbol> is an Extend type entry-point. Similar to service there is +no way to reference an extension field from a message or enum. An extension +requires import-ing both the Extendee type for an extend ExtendeeType and +the Extender type for ExtenderType my_ext = ..., which requires depending on +the full transitive closure of symbols required for both ExtendeeType and +ExtenderType. The symbols for ExtendeeType can be considered waste to any +other entry-points in the same file as the extend.

Extensions exist to decouple the Extender type from the Extendee type, however +when extensions are defined in the same file as other entry-points this creates +a dependency inversion, forcing the other entry-points in the same file to +depend on the Extendee type.

This dependency inversion can be harmless when the Extendee type is trivial, +containing no imports or non-primitive types, but can also be a source of +tremendous waste if the Extendee has a large transitive dependency set.

In some generated code, nesting extensions inside of a message provides a +useful namespace. This can be accomplished safely with the use of visibility +keywords in one of two ways. Example:

import "expensive/extendee_type.proto";
+
+// You can define a local message for your extension.
+local message ExtenderType {
+  extend expensive.ExtendeeType {
+    ExtenderType ext = 12345;
+  }
+
+  string one = 1;
+  int two = 2;
+}
+

Alternatively, if you have a symbol you both want to use as an extension field +and have that same type be used as a normal field in another messages, then that +message should be defined in its own file and the extend defined in its own +isolated file. You can still provide a friendly namespace, which is especially +useful for languages like C++, for the extension with a local wrapper message +with no fields:

package my.pkg;
+
+import "expensive/extendee_type.proto";
+import "other/foo_type.proto";
+
+// Exclusively used to bind other.FooType as an extension to
+// expensive.ExtendeeType giving it a useful namespaced name
+for `ext` as `my.pkg.WrapperForFooMsg.ext`
+local message WrapperForFooMsg {
+  extend expensive.ExtendeeType {
+    other.FooMsg ext = 45678;
+  }
+
+  // reserve all fields to ensure nothing ever uses this except for wrapping the
+  // extension.
+  reserved 1 to max;
+}
+

Best-Practice: Maintain 1 Entry-Point per File

In general to avoid proto symbol waste striving for a 1:1 ratio between .proto +files and entry-points can ensure that no excess proto compiler processing or +code generation is being performed for any given symbol. This can be further +extended to build systems by ensuring that a build step is only processing a +single .proto file at a time. In Bazel, this would correspond to having only a +single .proto file per proto_library rule.

\ No newline at end of file diff --git a/programming-guides/techniques/index.html b/programming-guides/techniques/index.html new file mode 100644 index 000000000..484ac9c48 --- /dev/null +++ b/programming-guides/techniques/index.html @@ -0,0 +1,54 @@ +Techniques | Protocol Buffers Documentation +

Techniques

Describes some commonly-used design patterns for dealing with Protocol Buffers.

You can also send design and usage questions to +the +Protocol Buffers discussion group.

Common Filename Suffixes

It is fairly common to write messages to files in several different formats. We +recommend using the following file extensions for these files.

ContentExtension
Text Format.txtpb
Wire Format.binpb
JSON Format.json

For Text Format specifically, .textproto is also fairly common, but we +recommend .txtpb for its brevity.

Streaming Multiple Messages

If you want to write multiple messages to a single file or stream, it is up to +you to keep track of where one message ends and the next begins. The Protocol +Buffer wire format is not self-delimiting, so protocol buffer parsers cannot +determine where a message ends on their own. The easiest way to solve this +problem is to write the size of each message before you write the message +itself. When you read the messages back in, you read the size, then read the +bytes into a separate buffer, then parse from that buffer. (If you want to avoid +copying bytes to a separate buffer, check out the CodedInputStream class (in +both C++ and Java) which can be told to limit reads to a certain number of +bytes.)

Large Data Sets

Protocol Buffers are not designed to handle large messages. As a general rule of +thumb, if you are dealing in messages larger than a megabyte each, it may be +time to consider an alternate strategy.

That said, Protocol Buffers are great for handling individual messages within +a large data set. Usually, large data sets are a collection of small pieces, +where each small piece is structured data. Even though Protocol Buffers cannot +handle the entire set at once, using Protocol Buffers to encode each piece +greatly simplifies your problem: now all you need is to handle a set of byte +strings rather than a set of structures.

Protocol Buffers do not include any built-in support for large data sets because +different situations call for different solutions. Sometimes a simple list of +records will do while other times you want something more like a database. Each +solution should be developed as a separate library, so that only those who need +it need pay the costs.

Self-describing Messages

Protocol Buffers do not contain descriptions of their own types. Thus, given +only a raw message without the corresponding .proto file defining its type, it +is difficult to extract any useful data.

However, the contents of a .proto file can itself be represented using protocol +buffers. The file src/google/protobuf/descriptor.proto in the source code +package defines the message types involved. protoc can output a +FileDescriptorSet—which represents a set of .proto files—using the +--descriptor_set_out option. With this, you can define a self-describing +protocol message like so:

syntax = "proto3";
+
+import "google/protobuf/any.proto";
+import "google/protobuf/descriptor.proto";
+
+message SelfDescribingMessage {
+  // Set of FileDescriptorProtos which describe the type and its dependencies.
+  google.protobuf.FileDescriptorSet descriptor_set = 1;
+
+  // The message and its type, encoded as an Any message.
+  google.protobuf.Any message = 2;
+}
+

By using classes like DynamicMessage (available in C++ and Java), you can then +write tools which can manipulate SelfDescribingMessages.

All that said, the reason that this functionality is not included in the +Protocol Buffer library is because we have never had a use for it inside Google.

This technique requires support for dynamic messages using descriptors. Check +that your platforms support this feature before using self-describing messages.

\ No newline at end of file diff --git a/reference/cpp/abseil/index.html b/reference/cpp/abseil/index.html new file mode 100644 index 000000000..b37060dce --- /dev/null +++ b/reference/cpp/abseil/index.html @@ -0,0 +1,36 @@ +Abseil Support | Protocol Buffers Documentation +

Abseil Support

The C++ implementation of Protocol Buffers has an explicit dependency on Abseil.

In version 22.x, C++ protobuf +added an explicit dependency on Abseil.

Bazel Support

If you are using Bazel, to determine the version of Abseil that your protobuf +version supports, you can use the bazel mod command:

$ bazel mod deps abseil-cpp --enable_bzlmod
+<root> (protobuf@30.0-dev)
+└───abseil-cpp@20240722.0
+    ├───bazel_skylib@1.7.1
+    ├───googletest@1.15.2
+    └───platforms@0.0.10
+

bazel mod graph produces the full output:

$ bazel mod graph --enable_bzlmod
+<root> (protobuf@30.0-dev)
+├───abseil-cpp@20240722.0
+│   ├───bazel_skylib@1.7.1 (*)
+│   ├───googletest@1.15.2 (*)
+│   └───platforms@0.0.10 (*)
+├───bazel_features@1.18.0
+│   └───bazel_skylib@1.7.1 (*)
+├───bazel_skylib@1.7.1
+│   ├───platforms@0.0.10 (*)
+│   └───rules_license@1.0.0 (*)
+├───googletest@1.15.2
+│   ├───abseil-cpp@20240722.0 (*)
+│   ├───platforms@0.0.10 (*)
+│   └───re2@2024-07-02
+...
+

CMake Support

Our CMake support is best-effort compared to Bazel. To check for support, try +the following steps:

  1. Run the cmake . command.
  2. Open _deps/absl-src/CMakeLists.txt.

Look for the following line:

project(absl LANGUAGES CXX VERSION 20240722)
+set(ABSL_SOVERSION "2407.0.0")
+include(CTest)
+
\ No newline at end of file diff --git a/reference/cpp/api-docs-link/index.html b/reference/cpp/api-docs-link/index.html new file mode 100644 index 000000000..3573428d7 --- /dev/null +++ b/reference/cpp/api-docs-link/index.html @@ -0,0 +1,4 @@ +C++ API | Protocol Buffers Documentation +
\ No newline at end of file diff --git a/content/reference/cpp/api-docs/_cpptoc.yaml b/reference/cpp/api-docs/_cpptoc.yaml similarity index 100% rename from content/reference/cpp/api-docs/_cpptoc.yaml rename to reference/cpp/api-docs/_cpptoc.yaml diff --git a/reference/cpp/api-docs/google.protobuf.arena/index.html b/reference/cpp/api-docs/google.protobuf.arena/index.html new file mode 100644 index 000000000..c8974b30e --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.arena/index.html @@ -0,0 +1,12 @@ +arena.h | Protocol Buffers Documentation +

arena.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/arena.h>
namespace google::protobuf

This file defines an Arena allocator for better allocation performance.

Classes in this file

ArenaOptions provides optional additional parameters to arena construction that control its block-allocation behavior.
Arena allocator.
Helper typetraits that indicates support for arenas in a type T at compile time.

struct ArenaOptions

#include <google/protobuf/arena.h>
namespace google::protobuf

ArenaOptions provides optional additional parameters to arena construction that control its block-allocation behavior.

Members

size_t
start_block_size
This defines the size of the first block requested from the system malloc. more...
size_t
max_block_size
This defines the maximum block size requested from system malloc (unless an individual arena allocation request occurs with a size larger than this maximum). more...
char *
initial_block
An initial block of memory for the arena to use, or NULL for none. more...
size_t
initial_block_size
The size of the initial block, if provided.
void *(*
block_alloc
A function pointer to an alloc method that returns memory blocks of size requested. more...
void(*
block_dealloc
A function pointer to a dealloc method that takes ownership of the blocks from the arena. more...
ArenaOptions()

size_t ArenaOptions::start_block_size

This defines the size of the first block requested from the system malloc.

Subsequent block sizes will increase in a geometric series up to a maximum.


size_t ArenaOptions::max_block_size

This defines the maximum block size requested from system malloc (unless an individual arena allocation request occurs with a size larger than this maximum).

Requested block sizes increase up to this value, then remain here.


char * ArenaOptions::initial_block

An initial block of memory for the arena to use, or NULL for none.

If provided, the block must live at least as long as the arena itself. The creator of the Arena retains ownership of the block after the Arena is destroyed.


void *(* ArenaOptions::block_alloc

A function pointer to an alloc method that returns memory blocks of size requested.

By default, it contains a ptr to the malloc function.

NOTE: block_alloc and dealloc functions are expected to behave like malloc and free, including Asan poisoning.


void(* ArenaOptions::block_dealloc

A function pointer to a dealloc method that takes ownership of the blocks from the arena.

By default, it contains a ptr to a wrapper function that calls free.

class Arena

#include <google/protobuf/arena.h>
namespace google::protobuf

Arena allocator.

Arena allocation replaces ordinary (heap-based) allocation with new/delete, and improves performance by aggregating allocations into larger blocks and freeing allocations all at once. Protocol messages are allocated on an arena by using Arena::CreateMessage<T>(Arena*), below, and are automatically freed when the arena is destroyed.

This is a thread-safe implementation: multiple threads may allocate from the arena concurrently. Destruction is not thread-safe and the destructing thread must synchronize with users of the arena first.

An arena provides two allocation interfaces: CreateMessage<T>, which works for arena-enabled proto2 message types as well as other types that satisfy the appropriate protocol (described below), and Create<T>, which works for any arbitrary type T. CreateMessage<T> is better when the type T supports it, because this interface (i) passes the arena pointer to the created object so that its sub-objects and internal allocations can use the arena too, and (ii) elides the object's destructor call when possible. Create<T> does not place any special requirements on the type T, and will invoke the object's destructor when the arena is destroyed.

The arena message allocation protocol, required by CreateMessage<T>(Arena* arena, Args&&... args), is as follows:

  • The type T must have (at least) two constructors: a constructor callable with args (without arena), called when a T is allocated on the heap; and a constructor callable with Arena* arena, Args&&... args, called when a T is allocated on an arena. If the second constructor is called with a NULL arena pointer, it must be equivalent to invoking the first (args-only) constructor.
  • The type T must have a particular type trait: a nested type |InternalArenaConstructable_|. This is usually a typedef to |void|. If no such type trait exists, then the instantiation CreateMessage<T> will fail to compile.
  • The type T may have the type trait |DestructorSkippable_|. If this type trait is present in the type, then its destructor will not be called if and only if it was passed a non-NULL arena pointer. If this type trait is not present on the type, then its destructor is always called when the containing arena is destroyed.

This protocol is implemented by all arena-enabled proto2 message classes as well as protobuf container types like RepeatedPtrField and Map. The protocol is internal to protobuf and is not guaranteed to be stable. Non-proto types should not rely on this protocol.

Members

const size_t
kBlockOverhead = = +internal::ThreadSafeArena::kBlockHeaderSize + +internal::ThreadSafeArena::kSerialArenaSize
Block overhead. more...
Arena()
Default constructor with sensible default options, tuned for average use-cases.
Arena(char * initial_block, size_t initial_block_size)
Construct an arena with default options, except for the supplied initial block. more...
explicit
Arena(const ArenaOptions & options)
Arena constructor taking custom options. more...
~Arena()
void
Init(const ArenaOptions & )
uint64
SpaceAllocated() const
The following are routines are for monitoring. more...
uint64
SpaceUsed() const
Returns the total space used by the arena. more...
uint64
Reset()
Frees all storage allocated by this arena after calling destructors registered with OwnDestructor() and freeing objects registered with Own(). more...
template void
Own(T * object)
Adds |object| to a list of heap-allocated objects to be freed with |delete| when the arena is destroyed or reset.
template void
OwnDestructor(T * object)
Adds |object| to a list of objects whose destructors will be manually called when the arena is destroyed or reset. more...
void
OwnCustomDestructor(void * object, void(*)(void *) destruct)
Adds a custom member function on an object to the list of destructors that will be manually called when the arena is destroyed or reset. more...
template static T *
CreateMessage(Arena * arena, Args &&... args)
API to create proto2 message objects on the arena. more...
template static PROTOBUF_NDEBUG_INLINE T *
Create(Arena * arena, Args &&... args)
API to create any objects on the arena. more...
template static PROTOBUF_NDEBUG_INLINE T *
CreateArray(Arena * arena, size_t num_elements)
Create an array of object type T on the arena without invoking the constructor of T. more...
template static Arena *
GetArena(const T * value)
Retrieves the arena associated with |value| if |value| is an arena-capable message, or NULL otherwise. more...

const size_t Arena::kBlockOverhead = = +internal::ThreadSafeArena::kBlockHeaderSize + +internal::ThreadSafeArena::kSerialArenaSize

Block overhead.

Use this as a guide for how much to over-allocate the initial block if you want an allocation of size N to fit inside it.

WARNING: if you allocate multiple objects, it is difficult to guarantee that a series of allocations will fit in the initial block, especially if Arena changes its alignment guarantees in the future!


Arena::Arena(
        char * initial_block,
        size_t initial_block_size)

Construct an arena with default options, except for the supplied initial block.

It is more efficient to use this constructor instead of passing ArenaOptions if the only configuration needed by the caller is supplying an initial block.


explicit Arena::Arena(
        const ArenaOptions & options)

Arena constructor taking custom options.

See ArenaOptions above for descriptions of the options available.


uint64 Arena::SpaceAllocated() const

The following are routines are for monitoring.

They will approximate the total sum allocated and used memory, but the exact value is an implementation deal. For instance allocated space depends on growth policies. Do not use these in unit tests. Returns the total space allocated by the arena, which is the sum of the sizes of the underlying blocks.


uint64 Arena::SpaceUsed() const

Returns the total space used by the arena.

Similar to SpaceAllocated but does not include free space and block overhead. The total space returned may not include space used by other threads executing concurrently with the call to this method.


uint64 Arena::Reset()

Frees all storage allocated by this arena after calling destructors registered with OwnDestructor() and freeing objects registered with Own().

Any objects allocated on this arena are unusable after this call. It also returns the total space used by the arena which is the sums of the sizes of the allocated blocks. This method is not thread-safe.


template void Arena::OwnDestructor(
        T * object)

Adds |object| to a list of objects whose destructors will be manually called when the arena is destroyed or reset.

This differs from Own() in that it does not free the underlying memory with |delete|; hence, it is normally only used for objects that are placement-newed into arena-allocated memory.


void Arena::OwnCustomDestructor(
        void * object,
        void(*)(void *) destruct)

Adds a custom member function on an object to the list of destructors that will be manually called when the arena is destroyed or reset.

This differs from OwnDestructor() in that any member function may be specified, not only the class destructor.


template static T * Arena::CreateMessage(
        Arena * arena,
        Args &&... args)

API to create proto2 message objects on the arena.

If the arena passed in is NULL, then a heap allocated object is returned. Type T must be a message defined in a .proto file with cc_enable_arenas set to true, otherwise a compilation error will occur.

RepeatedField and RepeatedPtrField may also be instantiated directly on an arena with this method.

This function also accepts any type T that satisfies the arena message allocation protocol, documented above.


template static PROTOBUF_NDEBUG_INLINE T *
    Arena::Create(
        Arena * arena,
        Args &&... args)

API to create any objects on the arena.

Note that only the object will be created on the arena; the underlying ptrs (in case of a proto2 message) will be still heap allocated. Proto messages should usually be allocated with CreateMessage<T>() instead.

Note that even if T satisfies the arena message construction protocol (InternalArenaConstructable_ trait and optional DestructorSkippable_ trait), as described above, this function does not follow the protocol; instead, it treats T as a black-box type, just as if it did not have these traits. Specifically, T's constructor arguments will always be only those passed to Create<T>() – no additional arena pointer is implicitly added. Furthermore, the destructor will always be called at arena destruction time (unless the destructor is trivial). Hence, from T's point of view, it is as if the object were allocated on the heap (except that the underlying memory is obtained from the arena).


template static PROTOBUF_NDEBUG_INLINE T *
    Arena::CreateArray(
        Arena * arena,
        size_t num_elements)

Create an array of object type T on the arena without invoking the constructor of T.

If arena is null, then the return value should be freed with delete[] x; (or ::operator delete[](x);). To ensure safe uses, this function checks at compile time (when compiled as C++11) that T is trivially default-constructible and trivially destructible.


template static Arena * Arena::GetArena(
        const T * value)

Retrieves the arena associated with |value| if |value| is an arena-capable message, or NULL otherwise.

If possible, the call resolves at compile time. Note that we can often devirtualize calls to value->GetArena() so usually calling this method is unnecessary.

template class Arena::InternalHelper

#include <google/protobuf/arena.h>
namespace google::protobuf

template <typename >

Members

static Arena *
GetOwningArena(const T * p)
Provides access to protected GetOwningArena to generated messages.
static Arena *
GetArenaForAllocation(const T * p)
Provides access to protected GetArenaForAllocation to generated messages.

template struct Arena::is_arena_constructable

#include <google/protobuf/arena.h>
namespace google::protobuf

template <typename >

Helper typetraits that indicates support for arenas in a type T at compile time.

This is public only to allow construction of higher-level templated utilities.

is_arena_constructable<T>::value is true if the message type T has arena support enabled, and false otherwise.

is_destructor_skippable<T>::value is true if the message type T has told the arena that it is safe to skip the destructor, and false otherwise.

This is inside Arena because only Arena has the friend relationships necessary to see the underlying generated code traits.

Members

template struct Arena::is_destructor_skippable

#include <google/protobuf/arena.h>
namespace google::protobuf

template <typename >

Members

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.common/index.html b/reference/cpp/api-docs/google.protobuf.common/index.html new file mode 100644 index 000000000..905218dc0 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.common/index.html @@ -0,0 +1,8 @@ +common.h | Protocol Buffers Documentation +

common.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/stubs/common.h>
namespace google::protobuf

Contains basic types and utilities used by the rest of the library.

Classes in this file

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.code_generator/index.html b/reference/cpp/api-docs/google.protobuf.compiler.code_generator/index.html new file mode 100644 index 000000000..77c423580 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.code_generator/index.html @@ -0,0 +1,8 @@ +code_generator.h | Protocol Buffers Documentation +

code_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/code_generator.h>
namespace google::protobuf::compiler

Defines the abstract interface implemented by each of the language-specific code generators.

Classes in this file

The abstract interface to a class which generates code implementing a particular proto file in a particular language.
CodeGenerators generate one or more files in a given directory.

File Members

These definitions are not part of any class.
typedef
GeneratorContext OutputDirectory
The type GeneratorContext was once called OutputDirectory. more...
void
ParseGeneratorParameter(const std::string & , std::vector< std::pair< std::string, std::string > > * )
Several code generators treat the parameter argument as holding a list of options separated by commas. more...
std::string
StripProto(const std::string & filename)
Strips ".proto" or ".protodevel" from the end of a filename.

typedef compiler::OutputDirectory

The type GeneratorContext was once called OutputDirectory.

This typedef provides backward compatibility.


void compiler::ParseGeneratorParameter(
        const std::string & ,
        std::vector< std::pair< std::string, std::string > > * )

Several code generators treat the parameter argument as holding a list of options separated by commas.

This helper function parses a set of comma-delimited name/value pairs: e.g., "foo=bar,baz,qux=corge" parses to the pairs:

("foo", "bar"), ("baz", ""), ("qux", "corge")

class CodeGenerator

#include <google/protobuf/compiler/code_generator.h>
namespace google::protobuf::compiler

The abstract interface to a class which generates code implementing a particular proto file in a particular language.

A number of these may be registered with CommandLineInterface to support various languages.

Known subclasses:

Members

enum
Feature
Sync with plugin.proto. more...
CodeGenerator()
virtual
~CodeGenerator()
virtual bool
Generate(const FileDescriptor * file, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const = 0
Generates code for the given proto file, generating one or more files in the given output directory. more...
virtual bool
GenerateAll(const std::vector< const FileDescriptor * > & files, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
Generates code for all given proto files. more...
virtual uint64_t
GetSupportedFeatures() const
Implement this to indicate what features this code generator supports. more...
virtual bool
HasGenerateAll() const
This is no longer used, but this class is part of the opensource protobuf library, so it has to remain to keep vtables the same for the current version of the library. more...

enum CodeGenerator::Feature {
  FEATURE_PROTO3_OPTIONAL = = 1
}

Sync with plugin.proto.

FEATURE_PROTO3_OPTIONAL

virtual bool CodeGenerator::Generate(
        const FileDescriptor * file,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const = 0

Generates code for the given proto file, generating one or more files in the given output directory.

A parameter to be passed to the generator can be specified on the command line. This is intended to be used to pass generator specific parameters. It is empty if no parameter was given. ParseGeneratorParameter (below), can be used to accept multiple parameters within the single parameter command line flag.

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.


virtual bool CodeGenerator::GenerateAll(
        const std::vector< const FileDescriptor * > & files,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const

Generates code for all given proto files.

WARNING: The canonical code generator design produces one or two output files per input .proto file, and we do not wish to encourage alternate designs.

A parameter is given as passed on the command line, as in |Generate()| above.

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.


virtual uint64_t CodeGenerator::GetSupportedFeatures() const

Implement this to indicate what features this code generator supports.

This should be a bitwise OR of features from the Features enum in plugin.proto.


virtual bool CodeGenerator::HasGenerateAll() const

This is no longer used, but this class is part of the opensource protobuf library, so it has to remain to keep vtables the same for the current version of the library.

When protobufs does a api breaking change, the method can be removed.

class GeneratorContext

#include <google/protobuf/compiler/code_generator.h>
namespace google::protobuf::compiler

CodeGenerators generate one or more files in a given directory.

This abstract interface represents the directory to which the CodeGenerator is to write and other information about the context in which the Generator runs.

Members

GeneratorContext()
virtual
~GeneratorContext()
virtual io::ZeroCopyOutputStream *
Open(const std::string & filename) = 0
Opens the given file, truncating it if it exists, and returns a ZeroCopyOutputStream that writes to the file. more...
virtual io::ZeroCopyOutputStream *
OpenForAppend(const std::string & filename)
Similar to Open() but the output will be appended to the file if exists.
virtual io::ZeroCopyOutputStream *
OpenForInsert(const std::string & filename, const std::string & insertion_point)
Creates a ZeroCopyOutputStream which will insert code into the given file at the given insertion point. more...
virtual io::ZeroCopyOutputStream *
OpenForInsertWithGeneratedCodeInfo(const std::string & filename, const std::string & insertion_point, const google::protobuf::GeneratedCodeInfo & info)
Similar to OpenForInsert, but if info is non-empty, will open (or create) filename.pb.meta and insert info at the appropriate place with the necessary shifts. more...
virtual void
ListParsedFiles(std::vector< const FileDescriptor * > * output)
Returns a vector of FileDescriptors for all the files being compiled in this run. more...
virtual void
GetCompilerVersion(Version * version) const
Retrieves the version number of the protocol compiler associated with this GeneratorContext.

virtual io::ZeroCopyOutputStream *
    GeneratorContext::Open(
        const std::string & filename) = 0

Opens the given file, truncating it if it exists, and returns a ZeroCopyOutputStream that writes to the file.

The caller takes ownership of the returned object. This method never fails (a dummy stream will be returned instead).

The filename given should be relative to the root of the source tree. E.g. the C++ generator, when generating code for "foo/bar.proto", will generate the files "foo/bar.pb.h" and "foo/bar.pb.cc"; note that "foo/" is included in these filenames. The filename is not allowed to contain "." or ".." components.


virtual io::ZeroCopyOutputStream *
    GeneratorContext::OpenForInsert(
        const std::string & filename,
        const std::string & insertion_point)

Creates a ZeroCopyOutputStream which will insert code into the given file at the given insertion point.

See plugin.proto (plugin.pb.h) for more information on insertion points. The default implementation assert-fails – it exists only for backwards-compatibility.

WARNING: This feature is currently EXPERIMENTAL and is subject to change.


virtual io::ZeroCopyOutputStream *
    GeneratorContext::OpenForInsertWithGeneratedCodeInfo(
        const std::string & filename,
        const std::string & insertion_point,
        const google::protobuf::GeneratedCodeInfo & info)

Similar to OpenForInsert, but if info is non-empty, will open (or create) filename.pb.meta and insert info at the appropriate place with the necessary shifts.

The default implementation ignores info.

WARNING: This feature will be REMOVED in the near future.


virtual void GeneratorContext::ListParsedFiles(
        std::vector< const FileDescriptor * > * output)

Returns a vector of FileDescriptors for all the files being compiled in this run.

Useful for languages, such as Go, that treat files differently when compiled as a set rather than individually.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.command_line_interface/index.html b/reference/cpp/api-docs/google.protobuf.compiler.command_line_interface/index.html new file mode 100644 index 000000000..03b28d059 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.command_line_interface/index.html @@ -0,0 +1,23 @@ +command_line_interface.h | Protocol Buffers Documentation +

command_line_interface.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/command_line_interface.h>
namespace google::protobuf::compiler

Implements the Protocol Compiler front-end such that it may be reused by custom compilers written to support other languages.

Classes in this file

This class implements the command-line interface to the protocol compiler.

class CommandLineInterface

#include <google/protobuf/compiler/command_line_interface.h>
namespace google::protobuf::compiler

This class implements the command-line interface to the protocol compiler.

It is designed to make it very easy to create a custom protocol compiler supporting the languages of your choice. For example, if you wanted to create a custom protocol compiler binary which includes both the regular C++ support plus support for your own custom output "Foo", you would write a class "FooGenerator" which implements the CodeGenerator interface, then write a main() procedure like this:

int main(int argc, char* argv[]) {
+  google::protobuf::compiler::CommandLineInterface cli;
+
+  // Support generation of C++ source and headers.
+  google::protobuf::compiler::cpp::CppGenerator cpp_generator;
+  cli.RegisterGenerator("--cpp_out", &cpp_generator,
+    "Generate C++ source and header.");
+
+  // Support generation of Foo code.
+  FooGenerator foo_generator;
+  cli.RegisterGenerator("--foo_out", &foo_generator,
+    "Generate Foo file.");
+
+  return cli.Run(argc, argv);
+}

The compiler is invoked with syntax like:

protoc --cpp_out=outdir --foo_out=outdir --proto_path=src src/foo.proto

The .proto file to compile can be specified on the command line using either its physical file path, or a virtual path relative to a directory specified in –proto_path. For example, for src/foo.proto, the following two protoc invocations work the same way:

1. protoc --proto_path=src src/foo.proto (physical file path)
+2. protoc --proto_path=src foo.proto (virtual path relative to src)

If a file path can be interpreted both as a physical file path and as a relative virtual path, the physical file path takes precedence.

For a full description of the command-line syntax, invoke it with –help.

Members

const char *const
kPathSeparator
CommandLineInterface()
~CommandLineInterface()
void
RegisterGenerator(const std::string & flag_name, CodeGenerator * generator, const std::string & help_text)
Register a code generator for a language. more...
void
RegisterGenerator(const std::string & flag_name, const std::string & option_flag_name, CodeGenerator * generator, const std::string & help_text)
Register a code generator for a language. more...
void
AllowPlugins(const std::string & exe_name_prefix)
Enables "plugins". more...
int
Run(int argc, const char *const argv)
Run the Protocol Compiler with the given command-line parameters. more...
void
SetInputsAreProtoPathRelative(bool )
DEPRECATED. more...
void
SetVersionInfo(const std::string & text)
Provides some text which will be printed when the –version flag is used. more...

void CommandLineInterface::RegisterGenerator(
        const std::string & flag_name,
        CodeGenerator * generator,
        const std::string & help_text)

Register a code generator for a language.

Parameters:

  • flag_name: The command-line flag used to specify an output file of this type. The name must start with a '-'. If the name is longer than one letter, it must start with two '-'s.
  • generator: The CodeGenerator which will be called to generate files of this type.
  • help_text: Text describing this flag in the –help output.

Some generators accept extra parameters. You can specify this parameter on the command-line by placing it before the output directory, separated by a colon:

protoc --foo_out=enable_bar:outdir

The text before the colon is passed to CodeGenerator::Generate() as the "parameter".


void CommandLineInterface::RegisterGenerator(
        const std::string & flag_name,
        const std::string & option_flag_name,
        CodeGenerator * generator,
        const std::string & help_text)

Register a code generator for a language.

Besides flag_name you can specify another option_flag_name that could be used to pass extra parameters to the registered code generator. Suppose you have registered a generator by calling:

command_line_interface.RegisterGenerator("--foo_out", "--foo_opt", ...)

Then you could invoke the compiler with a command like:

protoc --foo_out=enable_bar:outdir --foo_opt=enable_baz

This will pass "enable_bar,enable_baz" as the parameter to the generator.


void CommandLineInterface::AllowPlugins(
        const std::string & exe_name_prefix)

Enables "plugins".

In this mode, if a command-line flag ends with "_out" but does not match any registered generator, the compiler will attempt to find a "plugin" to implement the generator. Plugins are just executables. They should live somewhere in the PATH.

The compiler determines the executable name to search for by concatenating exe_name_prefix with the unrecognized flag name, removing "_out". So, for example, if exe_name_prefix is "protoc-" and you pass the flag –foo_out, the compiler will try to run the program "protoc-gen-foo".

The plugin program should implement the following usage:

plugin [--out=OUTDIR] [--parameter=PARAMETER] PROTO_FILES < DESCRIPTORS

–out indicates the output directory (as passed to the –foo_out parameter); if omitted, the current directory should be used. –parameter gives the generator parameter, if any was provided (see below). The PROTO_FILES list the .proto files which were given on the compiler command-line; these are the files for which the plugin is expected to generate output code. Finally, DESCRIPTORS is an encoded FileDescriptorSet (as defined in descriptor.proto). This is piped to the plugin's stdin. The set will include descriptors for all the files listed in PROTO_FILES as well as all files that they import. The plugin MUST NOT attempt to read the PROTO_FILES directly – it must use the FileDescriptorSet.

The plugin should generate whatever files are necessary, as code generators normally do. It should write the names of all files it generates to stdout. The names should be relative to the output directory, NOT absolute names or relative to the current directory. If any errors occur, error messages should be written to stderr. If an error is fatal, the plugin should exit with a non-zero exit code.

Plugins can have generator parameters similar to normal built-in generators. Extra generator parameters can be passed in via a matching "_opt" parameter. For example:

protoc --plug_out=enable_bar:outdir --plug_opt=enable_baz

This will pass "enable_bar,enable_baz" as the parameter to the plugin.


int CommandLineInterface::Run(
        int argc,
        const char *const argv)

Run the Protocol Compiler with the given command-line parameters.

Returns the error code which should be returned by main().

It may not be safe to call Run() in a multi-threaded environment because it calls strerror(). I'm not sure why you'd want to do this anyway.


void CommandLineInterface::SetInputsAreProtoPathRelative(
        bool )

DEPRECATED.

Calling this method has no effect. Protocol compiler now always try to find the .proto file relative to the current directory first and if the file is not found, it will then treat the input path as a virtual path.


void CommandLineInterface::SetVersionInfo(
        const std::string & text)

Provides some text which will be printed when the –version flag is used.

The version of libprotoc will also be printed on the next line after this text.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.cpp_generator/index.html b/reference/cpp/api-docs/google.protobuf.compiler.cpp_generator/index.html new file mode 100644 index 000000000..7b74b60db --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.cpp_generator/index.html @@ -0,0 +1,8 @@ +cpp_generator.h | Protocol Buffers Documentation +

cpp_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/cpp/cpp_generator.h>
namespace google::protobuf::compiler::cpp

Generates C++ code for a given .proto file.

Classes in this file

CodeGenerator implementation which generates a C++ source file and header.

class CppGenerator: public CodeGenerator

#include <google/protobuf/compiler/cpp/cpp_generator.h>
namespace google::protobuf::compiler::cpp

CodeGenerator implementation which generates a C++ source file and header.

If you create your own protocol compiler binary and you want it to support C++ output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.

Members

enum
Runtime
CppGenerator()
~CppGenerator()
void
set_opensource_runtime(bool opensource)
void
set_runtime_include_base(const std::string & base)
If set to a non-empty string, generated code will do: more...

implements CodeGenerator

virtual bool
Generate(const FileDescriptor * file, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
Generates code for the given proto file, generating one or more files in the given output directory. more...
virtual uint64_t
GetSupportedFeatures() const
Implement this to indicate what features this code generator supports. more...

enum CppGenerator::Runtime {
  kGoogle3,
  kOpensource,
  kOpensourceGoogle3
}

kGoogle3Use the internal google3 runtime.
kOpensourceUse the open-source runtime.
kOpensourceGoogle3

Use the open-source runtime with google3 #include paths.

We make these absolute to avoid ambiguity, so the runtime will be #included like:


void CppGenerator::set_runtime_include_base(
        const std::string & base)

If set to a non-empty string, generated code will do:

/google/protobuf/message.h"

instead of:

This has no effect if opensource_runtime = false.


virtual bool CppGenerator::Generate(
        const FileDescriptor * file,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const

Generates code for the given proto file, generating one or more files in the given output directory.

A parameter to be passed to the generator can be specified on the command line. This is intended to be used to pass generator specific parameters. It is empty if no parameter was given. ParseGeneratorParameter (below), can be used to accept multiple parameters within the single parameter command line flag.

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.


virtual uint64_t CppGenerator::GetSupportedFeatures() const

Implement this to indicate what features this code generator supports.

This should be a bitwise OR of features from the Features enum in plugin.proto.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.csharp_generator/index.html b/reference/cpp/api-docs/google.protobuf.compiler.csharp_generator/index.html new file mode 100644 index 000000000..f5470545b --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.csharp_generator/index.html @@ -0,0 +1,8 @@ +csharp_generator.h | Protocol Buffers Documentation +

csharp_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/csharp/csharp_generator.h>
namespace google::protobuf::compiler::csharp

Generates C# code for a given .proto file.

Classes in this file

CodeGenerator implementation which generates a C# source file and header.

class Generator: public CodeGenerator

#include <google/protobuf/compiler/csharp/csharp_generator.h>
namespace google::protobuf::compiler::csharp

CodeGenerator implementation which generates a C# source file and header.

If you create your own protocol compiler binary and you want it to support C# output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.

Members

Generator()
~Generator()
virtual bool
Generate(const FileDescriptor * file, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
Generates code for the given proto file, generating one or more files in the given output directory. more...
virtual uint64_t
GetSupportedFeatures() const
Implement this to indicate what features this code generator supports. more...

virtual bool Generator::Generate(
        const FileDescriptor * file,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const

Generates code for the given proto file, generating one or more files in the given output directory.

A parameter to be passed to the generator can be specified on the command line. This is intended to be used to pass generator specific parameters. It is empty if no parameter was given. ParseGeneratorParameter (below), can be used to accept multiple parameters within the single parameter command line flag.

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.


virtual uint64_t Generator::GetSupportedFeatures() const

Implement this to indicate what features this code generator supports.

This should be a bitwise OR of features from the Features enum in plugin.proto.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.csharp_names/index.html b/reference/cpp/api-docs/google.protobuf.compiler.csharp_names/index.html new file mode 100644 index 000000000..bc45288ad --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.csharp_names/index.html @@ -0,0 +1,13 @@ +csharp_names.h | Protocol Buffers Documentation +

csharp_names.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/csharp/csharp_names.h>
namespace google::protobuf::compiler::csharp

Provides a mechanism for mapping a descriptor to the fully-qualified name of the corresponding C# class.

Classes in this file

File Members

These definitions are not part of any class.
std::string
GetFileNamespace(const FileDescriptor * descriptor)
Requires: more...
std::string
GetClassName(const Descriptor * descriptor)
Requires: more...
std::string
GetReflectionClassName(const FileDescriptor * descriptor)
Requires: more...
std::string
GetOutputFile(const FileDescriptor * descriptor, const std::string file_extension, const bool generate_directories, const std::string base_namespace, std::string * error)
Generates output file name for given file descriptor. more...

std::string csharp::GetFileNamespace(
        const FileDescriptor * descriptor)

Requires:

descriptor != NULL

Returns:

The namespace to use for given file descriptor.

std::string csharp::GetClassName(
        const Descriptor * descriptor)

Requires:

descriptor != NULL

Returns:

The fully-qualified C# class name.

std::string csharp::GetReflectionClassName(
        const FileDescriptor * descriptor)

Requires:

descriptor != NULL

Returns:

The fully-qualified name of the C# class that provides
+access to the file descriptor. Proto compiler generates
+such class for each .proto file processed.

std::string csharp::GetOutputFile(
        const FileDescriptor * descriptor,
        const std::string file_extension,
        const bool generate_directories,
        const std::string base_namespace,
        std::string * error)

Generates output file name for given file descriptor.

If generate_directories is true, the output file will be put under directory corresponding to file's namespace. base_namespace can be used to strip some of the top level directories. E.g. for file with namespace "Bar.Foo" and base_namespace="Bar", the resulting file will be put under directory "Foo" (and not "Bar/Foo").

Requires:

descriptor != NULL
+error != NULL

Returns:

The file name to use as output file for given file descriptor. In case
+of failure, this function will return empty string and error parameter
+will contain the error message.
\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.importer/index.html b/reference/cpp/api-docs/google.protobuf.compiler.importer/index.html new file mode 100644 index 000000000..f0ef44e8d --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.importer/index.html @@ -0,0 +1,9 @@ +importer.h | Protocol Buffers Documentation +

importer.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/importer.h>
namespace google::protobuf::compiler

This file is the public interface to the .proto file parser.

Classes in this file

An implementation of DescriptorDatabase which loads files from a SourceTree and parses them.
Simple interface for parsing .proto files.
If the importer encounters problems while trying to import the proto files, it reports them to a MultiFileErrorCollector.
Abstract interface which represents a directory tree containing proto files.
An implementation of SourceTree which loads files from locations on disk.

class SourceTreeDescriptorDatabase: public DescriptorDatabase

#include <google/protobuf/compiler/importer.h>
namespace google::protobuf::compiler

An implementation of DescriptorDatabase which loads files from a SourceTree and parses them.

Note: This class is not thread-safe since it maintains a table of source code locations for error reporting. However, when a DescriptorPool wraps a DescriptorDatabase, it uses mutex locking to make sure only one method of the database is called at a time, even if the DescriptorPool is used from multiple threads. Therefore, there is only a problem if you create multiple DescriptorPools wrapping the same SourceTreeDescriptorDatabase and use them from multiple threads.

Note: This class does not implement FindFileContainingSymbol() or FindFileContainingExtension(); these will always return false.

Members

SourceTreeDescriptorDatabase(SourceTree * source_tree)
SourceTreeDescriptorDatabase(SourceTree * source_tree, DescriptorDatabase * fallback_database)
If non-NULL, fallback_database will be checked if a file doesn't exist in the specified source_tree.
~SourceTreeDescriptorDatabase()
void
RecordErrorsTo(MultiFileErrorCollector * error_collector)
Instructs the SourceTreeDescriptorDatabase to report any parse errors to the given MultiFileErrorCollector. more...
DescriptorPool::ErrorCollector *
GetValidationErrorCollector()
Gets a DescriptorPool::ErrorCollector which records errors to the MultiFileErrorCollector specified with RecordErrorsTo(). more...

implements DescriptorDatabase

virtual bool
FindFileByName(const std::string & filename, FileDescriptorProto * output)
Find a file by file name. more...
virtual bool
FindFileContainingSymbol(const std::string & symbol_name, FileDescriptorProto * output)
Find the file that declares the given fully-qualified symbol name. more...
virtual bool
FindFileContainingExtension(const std::string & containing_type, int field_number, FileDescriptorProto * output)
Find the file which defines an extension extending the given message type with the given field number. more...

void SourceTreeDescriptorDatabase::RecordErrorsTo(
        MultiFileErrorCollector * error_collector)

Instructs the SourceTreeDescriptorDatabase to report any parse errors to the given MultiFileErrorCollector.

This should be called before parsing. error_collector must remain valid until either this method is called again or the SourceTreeDescriptorDatabase is destroyed.


DescriptorPool::ErrorCollector *
    SourceTreeDescriptorDatabase::GetValidationErrorCollector()

Gets a DescriptorPool::ErrorCollector which records errors to the MultiFileErrorCollector specified with RecordErrorsTo().

This collector has the ability to determine exact line and column numbers of errors from the information given to it by the DescriptorPool.


virtual bool SourceTreeDescriptorDatabase::FindFileByName(
        const std::string & filename,
        FileDescriptorProto * output)

Find a file by file name.

Fills in in *output and returns true if found. Otherwise, returns false, leaving the contents of *output undefined.


virtual bool SourceTreeDescriptorDatabase::FindFileContainingSymbol(
        const std::string & symbol_name,
        FileDescriptorProto * output)

Find the file that declares the given fully-qualified symbol name.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined.


virtual bool SourceTreeDescriptorDatabase::FindFileContainingExtension(
        const std::string & containing_type,
        int field_number,
        FileDescriptorProto * output)

Find the file which defines an extension extending the given message type with the given field number.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined. containing_type must be a fully-qualified type name.

class Importer

#include <google/protobuf/compiler/importer.h>
namespace google::protobuf::compiler

Simple interface for parsing .proto files.

This wraps the process of opening the file, parsing it with a Parser, recursively parsing all its imports, and then cross-linking the results to produce a FileDescriptor.

This is really just a thin wrapper around SourceTreeDescriptorDatabase. You may find that SourceTreeDescriptorDatabase is more flexible.

Members

Importer(SourceTree * source_tree, MultiFileErrorCollector * error_collector)
~Importer()
const FileDescriptor *
Import(const std::string & filename)
Import the given file and build a FileDescriptor representing it. more...
const DescriptorPool *
pool() const
The DescriptorPool in which all imported FileDescriptors and their contents are stored.
void
AddUnusedImportTrackFile(const std::string & file_name, bool is_error = false)
void
ClearUnusedImportTrackFiles()

const FileDescriptor *
    Importer::Import(
        const std::string & filename)

Import the given file and build a FileDescriptor representing it.

If the file is already in the DescriptorPool, the existing FileDescriptor will be returned. The FileDescriptor is property of the DescriptorPool, and will remain valid until it is destroyed. If any errors occur, they will be reported using the error collector and Import() will return NULL.

A particular Importer object will only report errors for a particular file once. All future attempts to import the same file will return NULL without reporting any errors. The idea is that you might want to import a lot of files without seeing the same errors over and over again. If you want to see errors for the same files repeatedly, you can use a separate Importer object to import each one (but use the same DescriptorPool so that they can be cross-linked).

class MultiFileErrorCollector

#include <google/protobuf/compiler/importer.h>
namespace google::protobuf::compiler

If the importer encounters problems while trying to import the proto files, it reports them to a MultiFileErrorCollector.

Members

MultiFileErrorCollector()
virtual
~MultiFileErrorCollector()
virtual void
AddError(const std::string & filename, int line, int column, const std::string & message) = 0
Line and column numbers are zero-based. more...
virtual void
AddWarning(const std::string & , int , int , const std::string & )

virtual void MultiFileErrorCollector::AddError(
        const std::string & filename,
        int line,
        int column,
        const std::string & message) = 0

Line and column numbers are zero-based.

A line number of -1 indicates an error with the entire file (e.g. "not found").

class SourceTree

#include <google/protobuf/compiler/importer.h>
namespace google::protobuf::compiler

Abstract interface which represents a directory tree containing proto files.

Used by the default implementation of Importer to resolve import statements Most users will probably want to use the DiskSourceTree implementation, below.

Known subclasses:

Members

SourceTree()
virtual
~SourceTree()
virtual io::ZeroCopyInputStream *
Open(const std::string & filename) = 0
Open the given file and return a stream that reads it, or NULL if not found. more...
virtual std::string
GetLastErrorMessage()
If Open() returns NULL, calling this method immediately will return an description of the error. more...

virtual io::ZeroCopyInputStream *
    SourceTree::Open(
        const std::string & filename) = 0

Open the given file and return a stream that reads it, or NULL if not found.

The caller takes ownership of the returned object. The filename must be a path relative to the root of the source tree and must not contain "." or ".." components.


virtual std::string SourceTree::GetLastErrorMessage()

If Open() returns NULL, calling this method immediately will return an description of the error.

Subclasses should implement this method and return a meaningful value for better error reporting.

class DiskSourceTree: public SourceTree

#include <google/protobuf/compiler/importer.h>
namespace google::protobuf::compiler

An implementation of SourceTree which loads files from locations on disk.

Multiple mappings can be set up to map locations in the DiskSourceTree to locations in the physical filesystem.

Members

enum
DiskFileToVirtualFileResult
DiskSourceTree()
~DiskSourceTree()
void
MapPath(const std::string & virtual_path, const std::string & disk_path)
Map a path on disk to a location in the SourceTree. more...
DiskFileToVirtualFileResult
DiskFileToVirtualFile(const std::string & disk_file, std::string * virtual_file, std::string * shadowing_disk_file)
Given a path to a file on disk, find a virtual path mapping to that file. more...
bool
VirtualFileToDiskFile(const std::string & virtual_file, std::string * disk_file)
Given a virtual path, find the path to the file on disk. more...

implements SourceTree

virtual io::ZeroCopyInputStream *
Open(const std::string & filename)
Open the given file and return a stream that reads it, or NULL if not found. more...
virtual std::string
GetLastErrorMessage()
If Open() returns NULL, calling this method immediately will return an description of the error. more...

enum DiskSourceTree::DiskFileToVirtualFileResult {
  SUCCESS,
  SHADOWED,
  CANNOT_OPEN,
  NO_MAPPING
}

Return type for DiskFileToVirtualFile().

SUCCESS
SHADOWED
CANNOT_OPEN
NO_MAPPING

void DiskSourceTree::MapPath(
        const std::string & virtual_path,
        const std::string & disk_path)

Map a path on disk to a location in the SourceTree.

The path may be either a file or a directory. If it is a directory, the entire tree under it will be mapped to the given virtual location. To map a directory to the root of the source tree, pass an empty string for virtual_path.

If multiple mapped paths apply when opening a file, they will be searched in order. For example, if you do:

MapPath("bar", "foo/bar");
+MapPath("", "baz");

and then you do:

Open("bar/qux");

the DiskSourceTree will first try to open foo/bar/qux, then baz/bar/qux, returning the first one that opens successfully.

disk_path may be an absolute path or relative to the current directory, just like a path you'd pass to open().


DiskFileToVirtualFileResult
    DiskSourceTree::DiskFileToVirtualFile(
        const std::string & disk_file,
        std::string * virtual_file,
        std::string * shadowing_disk_file)

Given a path to a file on disk, find a virtual path mapping to that file.

The first mapping created with MapPath() whose disk_path contains the filename is used. However, that virtual path may not actually be usable to open the given file. Possible return values are:

  • SUCCESS: The mapping was found. *virtual_file is filled in so that calling Open(*virtual_file) will open the file named by disk_file.
  • SHADOWED: A mapping was found, but using Open() to open this virtual path will end up returning some different file. This is because some other mapping with a higher precedence also matches this virtual path and maps it to a different file that exists on disk. *virtual_file is filled in as it would be in the SUCCESS case. *shadowing_disk_file is filled in with the disk path of the file which would be opened if you were to call Open(*virtual_file).
  • CANNOT_OPEN: The mapping was found and was not shadowed, but the file specified cannot be opened. When this value is returned, errno will indicate the reason the file cannot be opened. *virtual_file will be set to the virtual path as in the SUCCESS case, even though it is not useful.
  • NO_MAPPING: Indicates that no mapping was found which contains this file.

bool DiskSourceTree::VirtualFileToDiskFile(
        const std::string & virtual_file,
        std::string * disk_file)

Given a virtual path, find the path to the file on disk.

Return true and update disk_file with the on-disk path if the file exists. Return false and leave disk_file untouched if the file doesn't exist.


virtual io::ZeroCopyInputStream *
    DiskSourceTree::Open(
        const std::string & filename)

Open the given file and return a stream that reads it, or NULL if not found.

The caller takes ownership of the returned object. The filename must be a path relative to the root of the source tree and must not contain "." or ".." components.


virtual std::string DiskSourceTree::GetLastErrorMessage()

If Open() returns NULL, calling this method immediately will return an description of the error.

Subclasses should implement this method and return a meaningful value for better error reporting.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.java_generator/index.html b/reference/cpp/api-docs/google.protobuf.compiler.java_generator/index.html new file mode 100644 index 000000000..a6a93ce91 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.java_generator/index.html @@ -0,0 +1,8 @@ +java_generator.h | Protocol Buffers Documentation +

java_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/java/java_generator.h>
namespace google::protobuf::compiler::java

Generates Java code for a given .proto file.

Classes in this file

CodeGenerator implementation which generates Java code.

class JavaGenerator: public CodeGenerator

#include <google/protobuf/compiler/java/java_generator.h>
namespace google::protobuf::compiler::java

CodeGenerator implementation which generates Java code.

If you create your own protocol compiler binary and you want it to support Java output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.

Members

JavaGenerator()
~JavaGenerator()

implements CodeGenerator

virtual bool
Generate(const FileDescriptor * file, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
Generates code for the given proto file, generating one or more files in the given output directory. more...
virtual uint64_t
GetSupportedFeatures() const
Implement this to indicate what features this code generator supports. more...

virtual bool JavaGenerator::Generate(
        const FileDescriptor * file,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const

Generates code for the given proto file, generating one or more files in the given output directory.

A parameter to be passed to the generator can be specified on the command line. This is intended to be used to pass generator specific parameters. It is empty if no parameter was given. ParseGeneratorParameter (below), can be used to accept multiple parameters within the single parameter command line flag.

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.


virtual uint64_t JavaGenerator::GetSupportedFeatures() const

Implement this to indicate what features this code generator supports.

This should be a bitwise OR of features from the Features enum in plugin.proto.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.java_names/index.html b/reference/cpp/api-docs/google.protobuf.compiler.java_names/index.html new file mode 100644 index 000000000..d02c84c39 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.java_names/index.html @@ -0,0 +1,8 @@ +java_names.h | Protocol Buffers Documentation +

java_names.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/java/java_names.h>
namespace google::protobuf::compiler::java

Provides a mechanism for mapping a descriptor to the fully-qualified name of the corresponding Java class.

Classes in this file

File Members

These definitions are not part of any class.
std::string
ClassName(const Descriptor * descriptor)
Requires: more...
std::string
ClassName(const EnumDescriptor * descriptor)
Requires: more...
std::string
ClassName(const FileDescriptor * descriptor)
Requires: more...
std::string
ClassName(const ServiceDescriptor * descriptor)
Requires: more...
std::string
FileJavaPackage(const FileDescriptor * descriptor)
Requires: more...
std::string
CapitalizedFieldName(const FieldDescriptor * descriptor)
Requires: more...

std::string java::ClassName(
        const Descriptor * descriptor)

Requires:

descriptor != NULL

Returns:

The fully-qualified Java class name.

std::string java::ClassName(
        const EnumDescriptor * descriptor)

Requires:

descriptor != NULL

Returns:

The fully-qualified Java class name.

std::string java::ClassName(
        const FileDescriptor * descriptor)

Requires:

descriptor != NULL

Returns:

The fully-qualified Java class name.

std::string java::ClassName(
        const ServiceDescriptor * descriptor)

Requires:

descriptor != NULL

Returns:

The fully-qualified Java class name.

std::string java::FileJavaPackage(
        const FileDescriptor * descriptor)

Requires:

descriptor != NULL

Returns:

Java package name.

std::string java::CapitalizedFieldName(
        const FieldDescriptor * descriptor)

Requires:

descriptor != NULL

Returns:

Capitalized camel case name field name.
\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.javanano_generator/index.html b/reference/cpp/api-docs/google.protobuf.compiler.javanano_generator/index.html new file mode 100644 index 000000000..8c0cf5e35 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.javanano_generator/index.html @@ -0,0 +1,8 @@ +javanano_generator.h | Protocol Buffers Documentation +

javanano_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/javanano/javanano_generator.h>
namespace google::protobuf::compiler::javanano

Generates Java nano code for a given .proto file.

Classes in this file

CodeGenerator implementation which generates Java nano code.

class JavaNanoGenerator: public CodeGenerator

#include <google/protobuf/compiler/javanano/javanano_generator.h>
namespace google::protobuf::compiler::javanano

CodeGenerator implementation which generates Java nano code.

If you create your own protocol compiler binary and you want it to support Java output for the nano runtime, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.

Members

JavaNanoGenerator()
~JavaNanoGenerator()

implements CodeGenerator

virtual bool
Generate(const FileDescriptor * file, const string & parameter, GeneratorContext * generator_context, string * error) const
Generates code for the given proto file, generating one or more files in the given output directory. more...

virtual bool JavaNanoGenerator::Generate(
        const FileDescriptor * file,
        const string & parameter,
        GeneratorContext * generator_context,
        string * error) const

Generates code for the given proto file, generating one or more files in the given output directory.

A parameter to be passed to the generator can be specified on the command line. This is intended to be used to pass generator specific parameters. It is empty if no parameter was given. ParseGeneratorParameter (below), can be used to accept multiple parameters within the single parameter command line flag.

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.js_generator/index.html b/reference/cpp/api-docs/google.protobuf.compiler.js_generator/index.html new file mode 100644 index 000000000..429a74f90 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.js_generator/index.html @@ -0,0 +1,8 @@ +js_generator.h | Protocol Buffers Documentation +

js_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/js/js_generator.h>
namespace google::protobuf::compiler::js

Generates JavaScript code for a given .proto file.

Classes in this file

CodeGenerator implementation which generates a JavaScript source file and header.

struct GeneratorOptions

#include <google/protobuf/compiler/js/js_generator.h>
namespace google::protobuf::compiler::js

Members

enum
ImportStyle
What style of imports should be used. more...
enum
OutputMode
std::string
output_dir
Output path.
std::string
namespace_prefix
Namespace prefix.
bool
binary
Enable binary-format support?
enum google::protobuf::compiler::js::GeneratorOptions::ImportStyle
import_style
bool
add_require_for_enums
Add a goog.requires() call for each enum type used. more...
bool
testonly
Set this as a test-only module via goog.setTestOnly();.
std::string
library
Create a library with name <name>_lib.js rather than a separate .js file per type?
bool
error_on_name_conflict
Error if there are two types that would generate the same output file?
std::string
extension
The extension to use for output file names.
bool
one_output_file_per_input_file
Create a separate output file for each input file?
bool
annotate_code
If true, we should append annotations as comments on the last line for generated .js file. more...
GeneratorOptions()
bool
ParseFromOptions(const std::vector< std::pair< std::string, std::string > > & options, std::string * error)
std::string
GetFileNameExtension() const
Returns the file name extension to use for generated code.
OutputMode
output_mode() const
Indicates how to output the generated code based on the provided options.

enum GeneratorOptions::ImportStyle {
  kImportClosure,
  kImportCommonJs,
  kImportCommonJsStrict,
  kImportBrowser,
  kImportEs6
}

What style of imports should be used.

kImportClosuregoog.require()
kImportCommonJsrequire()
kImportCommonJsStrictrequire() with no global export
kImportBrowserno import statements
kImportEs6import { member } from ''

enum GeneratorOptions::OutputMode {
  kOneOutputFilePerInputFile,
  kOneOutputFilePerSCC,
  kEverythingInOneFile
}

kOneOutputFilePerInputFileCreate an output file for each input .proto file.
kOneOutputFilePerSCCCreate an output file for each type.
kEverythingInOneFilePut everything in a single file named by the library option.

bool GeneratorOptions::add_require_for_enums

Add a goog.requires() call for each enum type used.

If not set, a forward declaration with goog.forwardDeclare is produced instead.


bool GeneratorOptions::annotate_code

If true, we should append annotations as comments on the last line for generated .js file.

Annotations used by tools like to provide cross-references between .js and .proto files. Annotations are encoded as base64 proto of GeneratedCodeInfo message (see descriptor.proto).

class Generator: public CodeGenerator

#include <google/protobuf/compiler/js/js_generator.h>
namespace google::protobuf::compiler::js

CodeGenerator implementation which generates a JavaScript source file and header.

If you create your own protocol compiler binary and you want it to support JavaScript output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.

Members

Generator()
virtual
~Generator()
virtual bool
Generate(const FileDescriptor * file, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
Generates code for the given proto file, generating one or more files in the given output directory. more...
virtual bool
HasGenerateAll() const
This is no longer used, but this class is part of the opensource protobuf library, so it has to remain to keep vtables the same for the current version of the library. more...
virtual bool
GenerateAll(const std::vector< const FileDescriptor * > & files, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
Generates code for all given proto files. more...
virtual uint64
GetSupportedFeatures() const
Implement this to indicate what features this code generator supports. more...

virtual bool Generator::Generate(
        const FileDescriptor * file,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const

Generates code for the given proto file, generating one or more files in the given output directory.

A parameter to be passed to the generator can be specified on the command line. This is intended to be used to pass generator specific parameters. It is empty if no parameter was given. ParseGeneratorParameter (below), can be used to accept multiple parameters within the single parameter command line flag.

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.


virtual bool Generator::HasGenerateAll() const

This is no longer used, but this class is part of the opensource protobuf library, so it has to remain to keep vtables the same for the current version of the library.

When protobufs does a api breaking change, the method can be removed.


virtual bool Generator::GenerateAll(
        const std::vector< const FileDescriptor * > & files,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const

Generates code for all given proto files.

WARNING: The canonical code generator design produces one or two output files per input .proto file, and we do not wish to encourage alternate designs.

A parameter is given as passed on the command line, as in |Generate()| above.

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.


virtual uint64 Generator::GetSupportedFeatures() const

Implement this to indicate what features this code generator supports.

This should be a bitwise OR of features from the Features enum in plugin.proto.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.objectivec_generator/index.html b/reference/cpp/api-docs/google.protobuf.compiler.objectivec_generator/index.html new file mode 100644 index 000000000..b41c04311 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.objectivec_generator/index.html @@ -0,0 +1,8 @@ +objectivec_generator.h | Protocol Buffers Documentation +

objectivec_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/objectivec/objectivec_generator.h>
namespace google::protobuf::compiler::objectivec

Generates ObjectiveC code for a given .proto file.

Classes in this file

CodeGenerator implementation which generates a ObjectiveC source file and header.

class ObjectiveCGenerator: public CodeGenerator

#include <google/protobuf/compiler/objectivec/objectivec_generator.h>
namespace google::protobuf::compiler::objectivec

CodeGenerator implementation which generates a ObjectiveC source file and header.

If you create your own protocol compiler binary and you want it to support ObjectiveC output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.

Members

ObjectiveCGenerator()
~ObjectiveCGenerator()
ObjectiveCGenerator(const ObjectiveCGenerator & )
ObjectiveCGenerator &
operator=(const ObjectiveCGenerator & )

implements CodeGenerator

virtual bool
HasGenerateAll() const
This is no longer used, but this class is part of the opensource protobuf library, so it has to remain to keep vtables the same for the current version of the library. more...
virtual bool
Generate(const FileDescriptor * file, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
Generates code for the given proto file, generating one or more files in the given output directory. more...
virtual bool
GenerateAll(const std::vector< const FileDescriptor * > & files, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
Generates code for all given proto files. more...
virtual uint64_t
GetSupportedFeatures() const
Implement this to indicate what features this code generator supports. more...

virtual bool ObjectiveCGenerator::HasGenerateAll() const

This is no longer used, but this class is part of the opensource protobuf library, so it has to remain to keep vtables the same for the current version of the library.

When protobufs does a api breaking change, the method can be removed.


virtual bool ObjectiveCGenerator::Generate(
        const FileDescriptor * file,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const

Generates code for the given proto file, generating one or more files in the given output directory.

A parameter to be passed to the generator can be specified on the command line. This is intended to be used to pass generator specific parameters. It is empty if no parameter was given. ParseGeneratorParameter (below), can be used to accept multiple parameters within the single parameter command line flag.

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.


virtual bool ObjectiveCGenerator::GenerateAll(
        const std::vector< const FileDescriptor * > & files,
        const std::string & parameter,
        GeneratorContext * generator_context,
        std::string * error) const

Generates code for all given proto files.

WARNING: The canonical code generator design produces one or two output files per input .proto file, and we do not wish to encourage alternate designs.

A parameter is given as passed on the command line, as in |Generate()| above.

Returns true if successful. Otherwise, sets *error to a description of the problem (e.g. "invalid parameter") and returns false.


virtual uint64_t ObjectiveCGenerator::GetSupportedFeatures() const

Implement this to indicate what features this code generator supports.

This should be a bitwise OR of features from the Features enum in plugin.proto.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.objectivec_helpers/index.html b/reference/cpp/api-docs/google.protobuf.compiler.objectivec_helpers/index.html new file mode 100644 index 000000000..4d9ff392b --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.objectivec_helpers/index.html @@ -0,0 +1,8 @@ +objectivec_helpers.h | Protocol Buffers Documentation +

objectivec_helpers.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
namespace google::protobuf::compiler::objectivec

Helper functions for generating ObjectiveC code.

Classes in this file

Generator options (see objectivec_generator.cc for a description of each):
Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform the input into the expected output.
Helper for parsing simple files.
Helper class for parsing framework import mappings and generating import statements.

File Members

These definitions are not part of any class.
enum
ObjectiveCType
enum
FlagType
const char *const
ProtobufLibraryFrameworkName
The name the commonly used by the library when built as a framework. more...
std::string
EscapeTrigraphs(const std::string & to_escape)
Escape C++ trigraphs by escaping question marks to "\?".
void
TrimWhitespace(StringPiece * input)
Remove white space from either end of a StringPiece.
bool
IsRetainedName(const std::string & name)
Returns true if the name requires a ns_returns_not_retained attribute applied to it.
bool
IsInitName(const std::string & name)
Returns true if the name starts with "init" and will need to have special handling under ARC.
std::string
FileClassPrefix(const FileDescriptor * file)
Gets the objc_class_prefix.
std::string
FilePath(const FileDescriptor * file)
Gets the path of the file we're going to generate (sans the .pb.h extension). more...
std::string
FilePathBasename(const FileDescriptor * file)
Just like FilePath(), but without the directory part.
std::string
FileClassName(const FileDescriptor * file)
Gets the name of the root class we'll generate in the file. more...
std::string
ClassName(const Descriptor * descriptor)
These return the fully-qualified class name corresponding to the given descriptor.
std::string
ClassName(const Descriptor * descriptor, std::string * out_suffix_added)
std::string
EnumName(const EnumDescriptor * descriptor)
std::string
EnumValueName(const EnumValueDescriptor * descriptor)
Returns the fully-qualified name of the enum value corresponding to the the descriptor.
std::string
EnumValueShortName(const EnumValueDescriptor * descriptor)
Returns the name of the enum value corresponding to the descriptor.
std::string
UnCamelCaseEnumShortName(const std::string & name)
Reverse what an enum does.
std::string
ExtensionMethodName(const FieldDescriptor * descriptor)
Returns the name to use for the extension (used as the method off the file's Root class).
std::string
FieldName(const FieldDescriptor * field)
Returns the transformed field name.
std::string
FieldNameCapitalized(const FieldDescriptor * field)
std::string
OneofEnumName(const OneofDescriptor * descriptor)
Returns the transformed oneof name.
std::string
OneofName(const OneofDescriptor * descriptor)
std::string
OneofNameCapitalized(const OneofDescriptor * descriptor)
std::string
ObjCClass(const std::string & class_name)
Returns a symbol that can be used in C code to refer to an Objective C class without initializing the class.
std::string
ObjCClassDeclaration(const std::string & class_name)
Declares an Objective C class without initializing the class so that it can be refrerred to by ObjCClass.
bool
HasPreservingUnknownEnumSemantics(const FileDescriptor * file)
bool
IsMapEntryMessage(const Descriptor * descriptor)
std::string
UnCamelCaseFieldName(const std::string & name, const FieldDescriptor * field)
Reverse of the above.
template std::string
GetOptionalDeprecatedAttribute(const TDescriptor * descriptor, const FileDescriptor * file = NULL, bool preSpace = true, bool postNewline = false)
std::string
GetCapitalizedType(const FieldDescriptor * field)
ObjectiveCType
GetObjectiveCType(FieldDescriptor::Type field_type)
ObjectiveCType
GetObjectiveCType(const FieldDescriptor * field)
bool
IsPrimitiveType(const FieldDescriptor * field)
bool
IsReferenceType(const FieldDescriptor * field)
std::string
GPBGenericValueFieldName(const FieldDescriptor * field)
std::string
DefaultValue(const FieldDescriptor * field)
bool
HasNonZeroDefaultValue(const FieldDescriptor * field)
std::string
BuildFlagsString(const FlagType type, const std::vector< std::string > & strings)
std::string
BuildCommentsString(const SourceLocation & location, bool prefer_single_line)
Builds HeaderDoc/appledoc style comments out of the comments in the .proto file.
std::string
ProtobufFrameworkImportSymbol(const std::string & framework_name)
Returns the CPP symbol name to use as the gate for framework style imports for the given framework name to use.
bool
IsProtobufLibraryBundledProtoFile(const FileDescriptor * file)
Checks if the file is one of the proto's bundled with the library.
bool
ValidateObjCClassPrefixes(const std::vector< const FileDescriptor * > & files, const Options & generation_options, std::string * out_error)
Checks the prefix for the given files and outputs any warnings as needed. more...
bool
ParseSimpleFile(const std::string & path, LineConsumer * line_consumer, std::string * out_error)

enum objectivec::ObjectiveCType {
  OBJECTIVECTYPE_INT32,
  OBJECTIVECTYPE_UINT32,
  OBJECTIVECTYPE_INT64,
  OBJECTIVECTYPE_UINT64,
  OBJECTIVECTYPE_FLOAT,
  OBJECTIVECTYPE_DOUBLE,
  OBJECTIVECTYPE_BOOLEAN,
  OBJECTIVECTYPE_STRING,
  OBJECTIVECTYPE_DATA,
  OBJECTIVECTYPE_ENUM,
  OBJECTIVECTYPE_MESSAGE
}

OBJECTIVECTYPE_INT32
OBJECTIVECTYPE_UINT32
OBJECTIVECTYPE_INT64
OBJECTIVECTYPE_UINT64
OBJECTIVECTYPE_FLOAT
OBJECTIVECTYPE_DOUBLE
OBJECTIVECTYPE_BOOLEAN
OBJECTIVECTYPE_STRING
OBJECTIVECTYPE_DATA
OBJECTIVECTYPE_ENUM
OBJECTIVECTYPE_MESSAGE

enum objectivec::FlagType {
  FLAGTYPE_DESCRIPTOR_INITIALIZATION,
  FLAGTYPE_EXTENSION,
  FLAGTYPE_FIELD
}

FLAGTYPE_DESCRIPTOR_INITIALIZATION
FLAGTYPE_EXTENSION
FLAGTYPE_FIELD

const char *const objectivec::ProtobufLibraryFrameworkName

The name the commonly used by the library when built as a framework.

This lines up to the name used in the CocoaPod.


std::string objectivec::FilePath(
        const FileDescriptor * file)

Gets the path of the file we're going to generate (sans the .pb.h extension).

The path will be dependent on the objectivec package declared in the proto package.


std::string objectivec::FileClassName(
        const FileDescriptor * file)

Gets the name of the root class we'll generate in the file.

This class is not meant for external consumption, but instead contains helpers that the rest of the classes need


bool objectivec::ValidateObjCClassPrefixes(
        const std::vector< const FileDescriptor * > & files,
        const Options & generation_options,
        std::string * out_error)

Checks the prefix for the given files and outputs any warnings as needed.

If there are flat out errors, then out_error is filled in with the first error and the result is false.

struct Options

#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
namespace google::protobuf::compiler::objectivec

Generator options (see objectivec_generator.cc for a description of each):

Members

std::string
expected_prefixes_path
std::vector< std::string >
expected_prefixes_suppressions
std::string
generate_for_named_framework
std::string
named_framework_to_proto_path_mappings_path
std::string
runtime_import_prefix
Options()

class TextFormatDecodeData

#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
namespace google::protobuf::compiler::objectivec

Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform the input into the expected output.

Members

TextFormatDecodeData()
~TextFormatDecodeData()
TextFormatDecodeData(const TextFormatDecodeData & )
TextFormatDecodeData &
operator=(const TextFormatDecodeData & )
void
AddString(int32 key, const std::string & input_for_decode, const std::string & desired_output)
size_t
num_entries() const
std::string
Data() const
static std::string
DecodeDataForString(const std::string & input_for_decode, const std::string & desired_output)

class LineConsumer

#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
namespace google::protobuf::compiler::objectivec

Helper for parsing simple files.

Members

LineConsumer()
virtual
~LineConsumer()
virtual bool
ConsumeLine(const StringPiece & line, std::string * out_error) = 0

class ImportWriter

#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
namespace google::protobuf::compiler::objectivec

Helper class for parsing framework import mappings and generating import statements.

Members

ImportWriter(const std::string & generate_for_named_framework, const std::string & named_framework_to_proto_path_mappings_path, const std::string & runtime_import_prefix, bool include_wkt_imports)
~ImportWriter()
void
AddFile(const FileDescriptor * file, const std::string & header_extension)
void
Print(io::Printer * printer) const
static void
PrintRuntimeImports(io::Printer * printer, const std::vector< std::string > & header_to_import, const std::string & runtime_import_prefix, bool default_cpp_symbol = false)
\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.parser/index.html b/reference/cpp/api-docs/google.protobuf.compiler.parser/index.html new file mode 100644 index 000000000..8408f33d7 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.parser/index.html @@ -0,0 +1,9 @@ +parser.h | Protocol Buffers Documentation +

parser.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/parser.h>
namespace google::protobuf::compiler

Implements parsing of .proto files to FileDescriptorProtos.

Classes in this file

Implements parsing of protocol definitions (such as .proto files).
A table mapping (descriptor, ErrorLocation) pairs – as reported by DescriptorPool when validating descriptors – to line and column numbers within the original source code.

class Parser

#include <google/protobuf/compiler/parser.h>
namespace google::protobuf::compiler

Implements parsing of protocol definitions (such as .proto files).

Note that most users will be more interested in the Importer class. Parser is a lower-level class which simply converts a single .proto file to a FileDescriptorProto. It does not resolve import directives or perform many other kinds of validation needed to construct a complete FileDescriptor.

Members

Parser()
~Parser()
bool
Parse(io::Tokenizer * input, FileDescriptorProto * file)
Parse the entire input and construct a FileDescriptorProto representing it. more...
void
RecordSourceLocationsTo(SourceLocationTable * location_table)
DEPRECATED: New code should use the SourceCodeInfo embedded in the FileDescriptorProto. more...
void
RecordErrorsTo(io::ErrorCollector * error_collector)
Requests that errors be recorded to the given ErrorCollector while parsing. more...
const std::string &
GetSyntaxIdentifier()
Returns the identifier used in the "syntax = " declaration, if one was seen during the last call to Parse(), or the empty string otherwise.
void
SetRequireSyntaxIdentifier(bool value)
If set true, input files will be required to begin with a syntax identifier. more...
void
SetStopAfterSyntaxIdentifier(bool value)
Call SetStopAfterSyntaxIdentifier(true) to tell the parser to stop parsing as soon as it has seen the syntax identifier, or lack thereof. more...

bool Parser::Parse(
        io::Tokenizer * input,
        FileDescriptorProto * file)

Parse the entire input and construct a FileDescriptorProto representing it.

Returns true if no errors occurred, false otherwise.


void Parser::RecordSourceLocationsTo(
        SourceLocationTable * location_table)

DEPRECATED: New code should use the SourceCodeInfo embedded in the FileDescriptorProto.

Requests that locations of certain definitions be recorded to the given SourceLocationTable while parsing. This can be used to look up exact line and column numbers for errors reported by DescriptorPool during validation. Set to NULL (the default) to discard source location information.


void Parser::RecordErrorsTo(
        io::ErrorCollector * error_collector)

Requests that errors be recorded to the given ErrorCollector while parsing.

Set to NULL (the default) to discard error messages.


void Parser::SetRequireSyntaxIdentifier(
        bool value)

If set true, input files will be required to begin with a syntax identifier.

Otherwise, files may omit this. If a syntax identifier is provided, it must be 'syntax = "proto2";' and must appear at the top of this file regardless of whether or not it was required.


void Parser::SetStopAfterSyntaxIdentifier(
        bool value)

Call SetStopAfterSyntaxIdentifier(true) to tell the parser to stop parsing as soon as it has seen the syntax identifier, or lack thereof.

This is useful for quickly identifying the syntax of the file without parsing the whole thing. If this is enabled, no error will be recorded if the syntax identifier is something other than "proto2" (since presumably the caller intends to deal with that), but other kinds of errors (e.g. parse errors) will still be reported. When this is enabled, you may pass a NULL FileDescriptorProto to Parse().

class SourceLocationTable

#include <google/protobuf/compiler/parser.h>
namespace google::protobuf::compiler

A table mapping (descriptor, ErrorLocation) pairs – as reported by DescriptorPool when validating descriptors – to line and column numbers within the original source code.

This is semi-obsolete: FileDescriptorProto.source_code_info now contains far more complete information about source locations. However, as of this writing you still need to use SourceLocationTable when integrating with DescriptorPool.

Members

SourceLocationTable()
~SourceLocationTable()
bool
Find(const Message * descriptor, DescriptorPool::ErrorCollector::ErrorLocation location, int * line, int * column) const
Finds the precise location of the given error and fills in *line and *column with the line and column numbers. more...
bool
FindImport(const Message * descriptor, const std::string & name, int * line, int * column) const
void
Add(const Message * descriptor, DescriptorPool::ErrorCollector::ErrorLocation location, int line, int column)
Adds a location to the table.
void
AddImport(const Message * descriptor, const std::string & name, int line, int column)
void
Clear()
Clears the contents of the table.

bool SourceLocationTable::Find(
        const Message * descriptor,
        DescriptorPool::ErrorCollector::ErrorLocation location,
        int * line,
        int * column) const

Finds the precise location of the given error and fills in *line and *column with the line and column numbers.

If not found, sets *line to -1 and *column to 0 (since line = -1 is used to mean "error has no exact +location" in the ErrorCollector interface). Returns true if found, false otherwise.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb/index.html b/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb/index.html new file mode 100644 index 000000000..fdacff086 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb/index.html @@ -0,0 +1,192 @@ +plugin.pb.h | Protocol Buffers Documentation +

plugin.pb.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/plugin.pb.h>
namespace google::protobuf::compiler

API for protoc plugins.

This file defines a set of protocol message classes which make up the API to protoc code generator plugins. Plugins written in C++ should probably build on the API in plugin.h instead of dealing with the protobuf-level API, but plugins in other languages will need to deal with the raw messages as defined below.

The protocol compiler currently doesn't support auto-generated documentation, hence this page contains no descriptions. This file was generated by the protocol compiler from plugin.proto, whose contents are as follows:

// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// WARNING:  The plugin interface is currently EXPERIMENTAL and is subject to
+//   change.
+//
+// protoc (aka the Protocol Compiler) can be extended via plugins.  A plugin is
+// just a program that reads a CodeGeneratorRequest from stdin and writes a
+// CodeGeneratorResponse to stdout.
+//
+// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead
+// of dealing with the raw protocol defined here.
+//
+// A plugin executable needs only to be placed somewhere in the path.  The
+// plugin should be named "protoc-gen-$NAME", and will then be used when the
+// flag "--${NAME}_out" is passed to protoc.
+
+syntax = "proto2";
+
+package google.protobuf.compiler;
+option java_package = "com.google.protobuf.compiler";
+option java_outer_classname = "PluginProtos";
+
+option go_package = "google.golang.org/protobuf/types/pluginpb";
+
+import "google/protobuf/descriptor.proto";
+
+// The version number of protocol compiler.
+message Version {
+  optional int32 major = 1;
+  optional int32 minor = 2;
+  optional int32 patch = 3;
+  // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should
+  // be empty for mainline stable releases.
+  optional string suffix = 4;
+}
+
+// An encoded CodeGeneratorRequest is written to the plugin's stdin.
+message CodeGeneratorRequest {
+  // The .proto files that were explicitly listed on the command-line.  The
+  // code generator should generate code only for these files.  Each file's
+  // descriptor will be included in proto_file, below.
+  repeated string file_to_generate = 1;
+
+  // The generator parameter passed on the command-line.
+  optional string parameter = 2;
+
+  // FileDescriptorProtos for all files in files_to_generate and everything
+  // they import.  The files will appear in topological order, so each file
+  // appears before any file that imports it.
+  //
+  // protoc guarantees that all proto_files will be written after
+  // the fields above, even though this is not technically guaranteed by the
+  // protobuf wire format.  This theoretically could allow a plugin to stream
+  // in the FileDescriptorProtos and handle them one by one rather than read
+  // the entire set into memory at once.  However, as of this writing, this
+  // is not similarly optimized on protoc's end -- it will store all fields in
+  // memory at once before sending them to the plugin.
+  //
+  // Type names of fields and extensions in the FileDescriptorProto are always
+  // fully qualified.
+  repeated FileDescriptorProto proto_file = 15;
+
+  // The version number of protocol compiler.
+  optional Version compiler_version = 3;
+
+}
+
+// The plugin writes an encoded CodeGeneratorResponse to stdout.
+message CodeGeneratorResponse {
+  // Error message.  If non-empty, code generation failed.  The plugin process
+  // should exit with status code zero even if it reports an error in this way.
+  //
+  // This should be used to indicate errors in .proto files which prevent the
+  // code generator from generating correct code.  Errors which indicate a
+  // problem in protoc itself -- such as the input CodeGeneratorRequest being
+  // unparseable -- should be reported by writing a message to stderr and
+  // exiting with a non-zero status code.
+  optional string error = 1;
+
+  // A bitmask of supported features that the code generator supports.
+  // This is a bitwise "or" of values from the Feature enum.
+  optional uint64 supported_features = 2;
+
+  // Sync with code_generator.h.
+  enum Feature {
+    FEATURE_NONE = 0;
+    FEATURE_PROTO3_OPTIONAL = 1;
+  }
+
+  // Represents a single generated file.
+  message File {
+    // The file name, relative to the output directory.  The name must not
+    // contain "." or ".." components and must be relative, not be absolute (so,
+    // the file cannot lie outside the output directory).  "/" must be used as
+    // the path separator, not "\".
+    //
+    // If the name is omitted, the content will be appended to the previous
+    // file.  This allows the generator to break large files into small chunks,
+    // and allows the generated text to be streamed back to protoc so that large
+    // files need not reside completely in memory at one time.  Note that as of
+    // this writing protoc does not optimize for this -- it will read the entire
+    // CodeGeneratorResponse before writing files to disk.
+    optional string name = 1;
+
+// If non-empty, indicates that the named file should already exist, and the
+// content here is to be inserted into that file at a defined insertion
+// point.  This feature allows a code generator to extend the output
+// produced by another code generator.  The original generator may provide
+// insertion points by placing special annotations in the file that look
+// like:
+//   @@protoc_insertion_point(NAME)
+// The annotation can have arbitrary text before and after it on the line,
+// which allows it to be placed in a comment.  NAME should be replaced with
+// an identifier naming the point -- this is what other generators will use
+// as the insertion_point.  Code inserted at this point will be placed
+// immediately above the line containing the insertion point (thus multiple
+// insertions to the same point will come out in the order they were added).
+// The double-@ is intended to make it unlikely that the generated code
+// could contain things that look like insertion points by accident.
+//
+// For example, the C++ code generator places the following line in the
+// .pb.h files that it generates:
+//   // @@protoc_insertion_point(namespace_scope)
+// This line appears within the scope of the file's package namespace, but
+// outside of any particular class.  Another plugin can then specify the
+// insertion_point "namespace_scope" to generate additional classes or
+// other declarations that should be placed in this scope.
+//
+// Note that if the line containing the insertion point begins with
+// whitespace, the same whitespace will be added to every line of the
+// inserted text.  This is useful for languages like Python, where
+// indentation matters.  In these languages, the insertion point comment
+// should be indented the same amount as any inserted code will need to be
+// in order to work correctly in that context.
+//
+// The code generator that generates the initial file and the one which
+// inserts into it must both run as part of a single invocation of protoc.
+// Code generators are executed in the order in which they appear on the
+// command line.
+//
+// If |insertion_point| is present, |name| must also be present.
+optional string insertion_point = 2;
+
+// The file contents.
+optional string content = 15;
+
+// Information describing the file content being inserted. If an insertion
+// point is used, this information will be appropriately offset and inserted
+// into the code generation metadata for the generated files.
+optional GeneratedCodeInfo generated_code_info = 16;
+
+  }
+  repeated File file = 15;
+}
+

Classes in this file

File Members

These definitions are not part of any class.
const ::protobuf::internal::DescriptorTable
descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto
PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_OPEN protobuf::compiler::CodeGeneratorRequest *
Arena::CreateMaybeMessage< protobuf::compiler::CodeGeneratorRequest >(Arena * )
protobuf::compiler::CodeGeneratorResponse *
Arena::CreateMaybeMessage< protobuf::compiler::CodeGeneratorResponse >(Arena * )
protobuf::compiler::CodeGeneratorResponse_File *
Arena::CreateMaybeMessage< protobuf::compiler::CodeGeneratorResponse_File >(Arena * )
protobuf::compiler::Version *
Arena::CreateMaybeMessage< protobuf::compiler::Version >(Arena * )
const EnumDescriptor *
GetEnumDescriptor< protobuf::compiler::CodeGeneratorResponse_Feature >()
\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.plugin/index.html b/reference/cpp/api-docs/google.protobuf.compiler.plugin/index.html new file mode 100644 index 000000000..859984dc1 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.plugin/index.html @@ -0,0 +1,11 @@ +plugin.h | Protocol Buffers Documentation +

plugin.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/plugin.h>
namespace google::protobuf::compiler

Front-end for protoc code generator plugins written in C++.

To implement a protoc plugin in C++, simply write an implementation of CodeGenerator, then create a main() function like:

int main(int argc, char* argv[]) {
+  MyCodeGenerator generator;
+  return google::protobuf::compiler::PluginMain(argc, argv, &generator);
+}

You must link your plugin against libprotobuf and libprotoc.

The core part of PluginMain is to invoke the given CodeGenerator on a CodeGeneratorRequest to generate a CodeGeneratorResponse. This part is abstracted out and made into function GenerateCode so that it can be reused, for example, to implement a variant of PluginMain that does some preprocessing on the input CodeGeneratorRequest before feeding the request to the given code generator.

To get protoc to use the plugin, do one of the following:

  • Place the plugin binary somewhere in the PATH and give it the name "protoc-gen-NAME" (replacing "NAME" with the name of your plugin). If you then invoke protoc with the parameter –NAME_out=OUT_DIR (again, replace "NAME" with your plugin's name), protoc will invoke your plugin to generate the output, which will be placed in OUT_DIR.
  • Place the plugin binary anywhere, with any name, and pass the –plugin parameter to protoc to direct it to your plugin like so:

    protoc --plugin=protoc-gen-NAME=path/to/mybinary --NAME_out=OUT_DIR

    On Windows, make sure to include the .exe suffix:

    protoc --plugin=protoc-gen-NAME=path/to/mybinary.exe --NAME_out=OUT_DIR

Classes in this file

File Members

These definitions are not part of any class.
int
PluginMain(int argc, char * argv, const CodeGenerator * generator)
Implements main() for a protoc plugin exposing the given code generator.
bool
GenerateCode(const CodeGeneratorRequest & request, const CodeGenerator & generator, CodeGeneratorResponse * response, std::string * error_msg)
Generates code using the given code generator. more...

bool compiler::GenerateCode(
        const CodeGeneratorRequest & request,
        const CodeGenerator & generator,
        CodeGeneratorResponse * response,
        std::string * error_msg)

Generates code using the given code generator.

Returns true if the code generation is successful. If the code generation fails, error_msg may be populated to describe the failure cause.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.python_generator/index.html b/reference/cpp/api-docs/google.protobuf.compiler.python_generator/index.html new file mode 100644 index 000000000..bb1ad4ac3 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.python_generator/index.html @@ -0,0 +1,8 @@ +python_generator.h | Protocol Buffers Documentation +

python_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/python/python_generator.h>
namespace google::protobuf::compiler::python

Generates Python code for a given .proto file.

Classes in this file

CodeGenerator implementation for generated Python protocol buffer classes.

class Generator: public CodeGenerator

#include <google/protobuf/compiler/python/python_generator.h>
namespace google::protobuf::compiler::python

CodeGenerator implementation for generated Python protocol buffer classes.

If you create your own protocol compiler binary and you want it to support Python output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.

Members

Generator()
virtual
~Generator()
virtual bool
Generate(const FileDescriptor * file, const std::string & parameter, GeneratorContext * generator_context, std::string * error) const
CodeGenerator methods.
virtual uint64_t
GetSupportedFeatures() const
Implement this to indicate what features this code generator supports. more...

virtual uint64_t Generator::GetSupportedFeatures() const

Implement this to indicate what features this code generator supports.

This should be a bitwise OR of features from the Features enum in plugin.proto.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.compiler.ruby_generator/index.html b/reference/cpp/api-docs/google.protobuf.compiler.ruby_generator/index.html new file mode 100644 index 000000000..f7cb3ec02 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.compiler.ruby_generator/index.html @@ -0,0 +1,8 @@ +ruby_generator.h | Protocol Buffers Documentation +

ruby_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/compiler/ruby/ruby_generator.h>
namespace google::protobuf::compiler::ruby

Generates Ruby code for a given .proto file.

Classes in this file

CodeGenerator implementation for generated Ruby protocol buffer classes.

class Generator: public CodeGenerator

#include <google/protobuf/compiler/ruby/ruby_generator.h>
namespace google::protobuf::compiler::ruby

CodeGenerator implementation for generated Ruby protocol buffer classes.

If you create your own protocol compiler binary and you want it to support Ruby output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.

Members

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.descriptor.pb/index.html b/reference/cpp/api-docs/google.protobuf.descriptor.pb/index.html new file mode 100644 index 000000000..1b66409a0 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.descriptor.pb/index.html @@ -0,0 +1,910 @@ +descriptor.pb.h | Protocol Buffers Documentation +

descriptor.pb.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/descriptor.pb.h>
namespace google::protobuf

Protocol buffer representations of descriptors.

This file defines a set of protocol message classes which represent the same information represented by the classes defined in descriptor.h. You can convert a FileDescriptorProto to a FileDescriptor using the DescriptorPool class. Thus, the classes in this file allow protocol type definitions to be communicated efficiently between processes.

The protocol compiler currently doesn't support auto-generated documentation, hence this page contains no descriptions. This file was generated by the protocol compiler from descriptor.proto, whose contents are as follows:

// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// The messages in this file describe the definitions found in .proto files.
+// A valid .proto file can be translated directly to a FileDescriptorProto
+// without any other information (e.g. without reading its imports).
+
+syntax = "proto2";
+
+package google.protobuf;
+
+option go_package = "google.golang.org/protobuf/types/descriptorpb";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "DescriptorProtos";
+option csharp_namespace = "Google.Protobuf.Reflection";
+option objc_class_prefix = "GPB";
+option cc_enable_arenas = true;
+
+// descriptor.proto must be optimized for speed because reflection-based
+// algorithms don't work during bootstrapping.
+option optimize_for = SPEED;
+
+// The protocol compiler can output a FileDescriptorSet containing the .proto
+// files it parses.
+message FileDescriptorSet {
+  repeated FileDescriptorProto file = 1;
+}
+
+// Describes a complete .proto file.
+message FileDescriptorProto {
+  optional string name = 1;     // file name, relative to root of source tree
+  optional string package = 2;  // e.g. "foo", "foo.bar", etc.
+
+  // Names of files imported by this file.
+  repeated string dependency = 3;
+  // Indexes of the public imported files in the dependency list above.
+  repeated int32 public_dependency = 10;
+  // Indexes of the weak imported files in the dependency list.
+  // For Google-internal migration only. Do not use.
+  repeated int32 weak_dependency = 11;
+
+  // All top-level definitions in this file.
+  repeated DescriptorProto message_type = 4;
+  repeated EnumDescriptorProto enum_type = 5;
+  repeated ServiceDescriptorProto service = 6;
+  repeated FieldDescriptorProto extension = 7;
+
+  optional FileOptions options = 8;
+
+  // This field contains optional information about the original source code.
+  // You may safely remove this entire field without harming runtime
+  // functionality of the descriptors -- the information is needed only by
+  // development tools.
+  optional SourceCodeInfo source_code_info = 9;
+
+  // The syntax of the proto file.
+  // The supported values are "proto2" and "proto3".
+  optional string syntax = 12;
+}
+
+// Describes a message type.
+message DescriptorProto {
+  optional string name = 1;
+
+  repeated FieldDescriptorProto field = 2;
+  repeated FieldDescriptorProto extension = 6;
+
+  repeated DescriptorProto nested_type = 3;
+  repeated EnumDescriptorProto enum_type = 4;
+
+  message ExtensionRange {
+    optional int32 start = 1;  // Inclusive.
+    optional int32 end = 2;    // Exclusive.
+
+optional ExtensionRangeOptions options = 3;
+
+  }
+  repeated ExtensionRange extension_range = 5;
+
+  repeated OneofDescriptorProto oneof_decl = 8;
+
+  optional MessageOptions options = 7;
+
+  // Range of reserved tag numbers. Reserved tag numbers may not be used by
+  // fields or extension ranges in the same message. Reserved ranges may
+  // not overlap.
+  message ReservedRange {
+    optional int32 start = 1;  // Inclusive.
+    optional int32 end = 2;    // Exclusive.
+  }
+  repeated ReservedRange reserved_range = 9;
+  // Reserved field names, which may not be used by fields in the same message.
+  // A given name may only be reserved once.
+  repeated string reserved_name = 10;
+}
+
+message ExtensionRangeOptions {
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+// Describes a field within a message.
+message FieldDescriptorProto {
+  enum Type {
+    // 0 is reserved for errors.
+    // Order is weird for historical reasons.
+    TYPE_DOUBLE = 1;
+    TYPE_FLOAT = 2;
+    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT64 if
+    // negative values are likely.
+    TYPE_INT64 = 3;
+    TYPE_UINT64 = 4;
+    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT32 if
+    // negative values are likely.
+    TYPE_INT32 = 5;
+    TYPE_FIXED64 = 6;
+    TYPE_FIXED32 = 7;
+    TYPE_BOOL = 8;
+    TYPE_STRING = 9;
+    // Tag-delimited aggregate.
+    // Group type is deprecated and not supported in proto3. However, Proto3
+    // implementations should still be able to parse the group wire format and
+    // treat group fields as unknown fields.
+    TYPE_GROUP = 10;
+    TYPE_MESSAGE = 11;  // Length-delimited aggregate.
+
+// New in version 2.
+TYPE_BYTES = 12;
+TYPE_UINT32 = 13;
+TYPE_ENUM = 14;
+TYPE_SFIXED32 = 15;
+TYPE_SFIXED64 = 16;
+TYPE_SINT32 = 17;  // Uses ZigZag encoding.
+TYPE_SINT64 = 18;  // Uses ZigZag encoding.
+
+  }
+
+  enum Label {
+    // 0 is reserved for errors
+    LABEL_OPTIONAL = 1;
+    LABEL_REQUIRED = 2;
+    LABEL_REPEATED = 3;
+  }
+
+  optional string name = 1;
+  optional int32 number = 3;
+  optional Label label = 4;
+
+  // If type_name is set, this need not be set.  If both this and type_name
+  // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
+  optional Type type = 5;
+
+  // For message and enum types, this is the name of the type.  If the name
+  // starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping
+  // rules are used to find the type (i.e. first the nested types within this
+  // message are searched, then within the parent, on up to the root
+  // namespace).
+  optional string type_name = 6;
+
+  // For extensions, this is the name of the type being extended.  It is
+  // resolved in the same manner as type_name.
+  optional string extendee = 2;
+
+  // For numeric types, contains the original text representation of the value.
+  // For booleans, "true" or "false".
+  // For strings, contains the default text contents (not escaped in any way).
+  // For bytes, contains the C escaped value.  All bytes >= 128 are escaped.
+  optional string default_value = 7;
+
+  // If set, gives the index of a oneof in the containing type's oneof_decl
+  // list.  This field is a member of that oneof.
+  optional int32 oneof_index = 9;
+
+  // JSON name of this field. The value is set by protocol compiler. If the
+  // user has set a "json_name" option on this field, that option's value
+  // will be used. Otherwise, it's deduced from the field's name by converting
+  // it to camelCase.
+  optional string json_name = 10;
+
+  optional FieldOptions options = 8;
+
+  // If true, this is a proto3 "optional". When a proto3 field is optional, it
+  // tracks presence regardless of field type.
+  //
+  // When proto3_optional is true, this field must be belong to a oneof to
+  // signal to old proto3 clients that presence is tracked for this field. This
+  // oneof is known as a "synthetic" oneof, and this field must be its sole
+  // member (each proto3 optional field gets its own synthetic oneof). Synthetic
+  // oneofs exist in the descriptor only, and do not generate any API. Synthetic
+  // oneofs must be ordered after all "real" oneofs.
+  //
+  // For message fields, proto3_optional doesn't create any semantic change,
+  // since non-repeated message fields always track presence. However it still
+  // indicates the semantic detail of whether the user wrote "optional" or not.
+  // This can be useful for round-tripping the .proto file. For consistency we
+  // give message fields a synthetic oneof also, even though it is not required
+  // to track presence. This is especially important because the parser can't
+  // tell if a field is a message or an enum, so it must always create a
+  // synthetic oneof.
+  //
+  // Proto2 optional fields do not set this flag, because they already indicate
+  // optional with `LABEL_OPTIONAL`.
+  optional bool proto3_optional = 17;
+}
+
+// Describes a oneof.
+message OneofDescriptorProto {
+  optional string name = 1;
+  optional OneofOptions options = 2;
+}
+
+// Describes an enum type.
+message EnumDescriptorProto {
+  optional string name = 1;
+
+  repeated EnumValueDescriptorProto value = 2;
+
+  optional EnumOptions options = 3;
+
+  // Range of reserved numeric values. Reserved values may not be used by
+  // entries in the same enum. Reserved ranges may not overlap.
+  //
+  // Note that this is distinct from DescriptorProto.ReservedRange in that it
+  // is inclusive such that it can appropriately represent the entire int32
+  // domain.
+  message EnumReservedRange {
+    optional int32 start = 1;  // Inclusive.
+    optional int32 end = 2;    // Inclusive.
+  }
+
+  // Range of reserved numeric values. Reserved numeric values may not be used
+  // by enum values in the same enum declaration. Reserved ranges may not
+  // overlap.
+  repeated EnumReservedRange reserved_range = 4;
+
+  // Reserved enum value names, which may not be reused. A given name may only
+  // be reserved once.
+  repeated string reserved_name = 5;
+}
+
+// Describes a value within an enum.
+message EnumValueDescriptorProto {
+  optional string name = 1;
+  optional int32 number = 2;
+
+  optional EnumValueOptions options = 3;
+}
+
+// Describes a service.
+message ServiceDescriptorProto {
+  optional string name = 1;
+  repeated MethodDescriptorProto method = 2;
+
+  optional ServiceOptions options = 3;
+}
+
+// Describes a method of a service.
+message MethodDescriptorProto {
+  optional string name = 1;
+
+  // Input and output type names.  These are resolved in the same way as
+  // FieldDescriptorProto.type_name, but must refer to a message type.
+  optional string input_type = 2;
+  optional string output_type = 3;
+
+  optional MethodOptions options = 4;
+
+  // Identifies if client streams multiple client messages
+  optional bool client_streaming = 5 [default = false];
+  // Identifies if server streams multiple server messages
+  optional bool server_streaming = 6 [default = false];
+}
+
+// ===================================================================
+// Options
+
+// Each of the definitions above may have "options" attached.  These are
+// just annotations which may cause code to be generated slightly differently
+// or may contain hints for code that manipulates protocol messages.
+//
+// Clients may define custom options as extensions of the *Options messages.
+// These extensions may not yet be known at parsing time, so the parser cannot
+// store the values in them.  Instead it stores them in a field in the *Options
+// message called uninterpreted_option. This field must have the same name
+// across all *Options messages. We then use this field to populate the
+// extensions when we build a descriptor, at which point all protos have been
+// parsed and so all extensions are known.
+//
+// Extension numbers for custom options may be chosen as follows:
+// * For options which will only be used within a single application or
+//   organization, or for experimental options, use field numbers 50000
+//   through 99999.  It is up to you to ensure that you do not use the
+//   same number for multiple options.
+// * For options which will be published and used publicly by multiple
+//   independent entities, e-mail protobuf-global-extension-registry@google.com
+//   to reserve extension numbers. Simply provide your project name (e.g.
+//   Objective-C plugin) and your project website (if available) -- there's no
+//   need to explain how you intend to use them. Usually you only need one
+//   extension number. You can declare multiple options with only one extension
+//   number by putting them in a sub-message. See the Custom Options section of
+//   the docs for examples:
+//   /programming-guides/proto#options
+//   If this turns out to be popular, a web service will be set up
+//   to automatically assign option numbers.
+
+message FileOptions {
+
+  // Sets the Java package where classes generated from this .proto will be
+  // placed.  By default, the proto package is used, but this is often
+  // inappropriate because proto packages do not normally start with backwards
+  // domain names.
+  optional string java_package = 1;
+
+  // Controls the name of the wrapper Java class generated for the .proto file.
+  // That class will always contain the .proto file's getDescriptor() method as
+  // well as any top-level extensions defined in the .proto file.
+  // If java_multiple_files is disabled, then all the other classes from the
+  // .proto file will be nested inside the single wrapper outer class.
+  optional string java_outer_classname = 8;
+
+  // If enabled, then the Java code generator will generate a separate .java
+  // file for each top-level message, enum, and service defined in the .proto
+  // file.  Thus, these types will *not* be nested inside the wrapper class
+  // named by java_outer_classname.  However, the wrapper class will still be
+  // generated to contain the file's getDescriptor() method as well as any
+  // top-level extensions defined in the file.
+  optional bool java_multiple_files = 10 [default = false];
+
+  // This option does nothing.
+  optional bool java_generate_equals_and_hash = 20 [deprecated=true];
+
+  // If set true, then the Java2 code generator will generate code that
+  // throws an exception whenever an attempt is made to assign a non-UTF-8
+  // byte sequence to a string field.
+  // Message reflection will do the same.
+  // However, an extension field still accepts non-UTF-8 byte sequences.
+  // This option has no effect on when used with the lite runtime.
+  optional bool java_string_check_utf8 = 27 [default = false];
+
+  // Generated classes can be optimized for speed or code size.
+  enum OptimizeMode {
+    SPEED = 1;         // Generate complete code for parsing, serialization,
+                       // etc.
+    CODE_SIZE = 2;     // Use ReflectionOps to implement these methods.
+    LITE_RUNTIME = 3;  // Generate code using MessageLite and the lite runtime.
+  }
+  optional OptimizeMode optimize_for = 9 [default = SPEED];
+
+  // Sets the Go package where structs generated from this .proto will be
+  // placed. If omitted, the Go package will be derived from the following:
+  //   - The basename of the package import path, if provided.
+  //   - Otherwise, the package statement in the .proto file, if present.
+  //   - Otherwise, the basename of the .proto file, without extension.
+  optional string go_package = 11;
+
+  // Should generic services be generated in each language?  "Generic" services
+  // are not specific to any particular RPC system.  They are generated by the
+  // main code generators in each language (without additional plugins).
+  // Generic services were the only kind of service generation supported by
+  // early versions of google.protobuf.
+  //
+  // Generic services are now considered deprecated in favor of using plugins
+  // that generate code specific to your particular RPC system.  Therefore,
+  // these default to false.  Old code which depends on generic services should
+  // explicitly set them to true.
+  optional bool cc_generic_services = 16 [default = false];
+  optional bool java_generic_services = 17 [default = false];
+  optional bool py_generic_services = 18 [default = false];
+  optional bool php_generic_services = 42 [default = false];
+
+  // Is this file deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for everything in the file, or it will be completely ignored; in the very
+  // least, this is a formalization for deprecating files.
+  optional bool deprecated = 23 [default = false];
+
+  // Enables the use of arenas for the proto messages in this file. This applies
+  // only to generated classes for C++.
+  optional bool cc_enable_arenas = 31 [default = true];
+
+  // Sets the objective c class prefix which is prepended to all objective c
+  // generated classes from this .proto. There is no default.
+  optional string objc_class_prefix = 36;
+
+  // Namespace for generated classes; defaults to the package.
+  optional string csharp_namespace = 37;
+
+  // By default Swift generators will take the proto package and CamelCase it
+  // replacing '.' with underscore and use that to prefix the types/symbols
+  // defined. When this options is provided, they will use this value instead
+  // to prefix the types/symbols defined.
+  optional string swift_prefix = 39;
+
+  // Sets the php class prefix which is prepended to all php generated classes
+  // from this .proto. Default is empty.
+  optional string php_class_prefix = 40;
+
+  // Use this option to change the namespace of php generated classes. Default
+  // is empty. When this option is empty, the package name will be used for
+  // determining the namespace.
+  optional string php_namespace = 41;
+
+  // Use this option to change the namespace of php generated metadata classes.
+  // Default is empty. When this option is empty, the proto file name will be
+  // used for determining the namespace.
+  optional string php_metadata_namespace = 44;
+
+  // Use this option to change the package of ruby generated classes. Default
+  // is empty. When this option is not set, the package name will be used for
+  // determining the ruby package.
+  optional string ruby_package = 45;
+
+  // The parser stores options it doesn't recognize here.
+  // See the documentation for the "Options" section above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message.
+  // See the documentation for the "Options" section above.
+  extensions 1000 to max;
+
+  reserved 38;
+}
+
+message MessageOptions {
+  // Set true to use the old proto1 MessageSet wire format for extensions.
+  // This is provided for backwards-compatibility with the MessageSet wire
+  // format.  You should not use this for any other reason:  It's less
+  // efficient, has fewer features, and is more complicated.
+  //
+  // The message must be defined exactly as follows:
+  //   message Foo {
+  //     option message_set_wire_format = true;
+  //     extensions 4 to max;
+  //   }
+  // Note that the message cannot have any defined fields; MessageSets only
+  // have extensions.
+  //
+  // All extensions of your type must be singular messages; e.g. they cannot
+  // be int32s, enums, or repeated messages.
+  //
+  // Because this is an option, the above two restrictions are not enforced by
+  // the protocol compiler.
+  optional bool message_set_wire_format = 1 [default = false];
+
+  // Disables the generation of the standard "descriptor()" accessor, which can
+  // conflict with a field of the same name.  This is meant to make migration
+  // from proto1 easier; new code should avoid fields named "descriptor".
+  optional bool no_standard_descriptor_accessor = 2 [default = false];
+
+  // Is this message deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the message, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating messages.
+  optional bool deprecated = 3 [default = false];
+
+  reserved 4, 5, 6;
+
+  // Whether the message is an automatically generated map entry type for the
+  // maps field.
+  //
+  // For maps fields:
+  //     map<KeyType, ValueType> map_field = 1;
+  // The parsed descriptor looks like:
+  //     message MapFieldEntry {
+  //         option map_entry = true;
+  //         optional KeyType key = 1;
+  //         optional ValueType value = 2;
+  //     }
+  //     repeated MapFieldEntry map_field = 1;
+  //
+  // Implementations may choose not to generate the map_entry=true message, but
+  // use a native map in the target language to hold the keys and values.
+  // The reflection APIs in such implementations still need to work as
+  // if the field is a repeated message field.
+  //
+  // NOTE: Do not set the option in .proto files. Always use the maps syntax
+  // instead. The option should only be implicitly set by the proto compiler
+  // parser.
+  optional bool map_entry = 7;
+
+  reserved 8;  // javalite_serializable
+  reserved 9;  // javanano_as_lite
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message FieldOptions {
+  // The ctype option instructs the C++ code generator to use a different
+  // representation of the field than it normally would.  See the specific
+  // options below.  This option is not yet implemented in the open source
+  // release -- sorry, we'll try to include it in a future version!
+  optional CType ctype = 1 [default = STRING];
+  enum CType {
+    // Default mode.
+    STRING = 0;
+
+CORD = 1;
+
+STRING_PIECE = 2;
+
+  }
+  // The packed option can be enabled for repeated primitive fields to enable
+  // a more efficient representation on the wire. Rather than repeatedly
+  // writing the tag and type for each element, the entire array is encoded as
+  // a single length-delimited blob. In proto3, only explicit setting it to
+  // false will avoid using packed encoding.
+  optional bool packed = 2;
+
+  // The jstype option determines the JavaScript type used for values of the
+  // field.  The option is permitted only for 64 bit integral and fixed types
+  // (int64, uint64, sint64, fixed64, sfixed64).  A field with jstype JS_STRING
+  // is represented as JavaScript string, which avoids loss of precision that
+  // can happen when a large value is converted to a floating point JavaScript.
+  // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
+  // use the JavaScript "number" type.  The behavior of the default option
+  // JS_NORMAL is implementation dependent.
+  //
+  // This option is an enum to permit additional types to be added, e.g.
+  // goog.math.Integer.
+  optional JSType jstype = 6 [default = JS_NORMAL];
+  enum JSType {
+    // Use the default type.
+    JS_NORMAL = 0;
+
+// Use JavaScript strings.
+JS_STRING = 1;
+
+// Use JavaScript numbers.
+JS_NUMBER = 2;
+
+  }
+
+  // Should this field be parsed lazily?  Lazy applies only to message-type
+  // fields.  It means that when the outer message is initially parsed, the
+  // inner message's contents will not be parsed but instead stored in encoded
+  // form.  The inner message will actually be parsed when it is first accessed.
+  //
+  // This is only a hint.  Implementations are free to choose whether to use
+  // eager or lazy parsing regardless of the value of this option.  However,
+  // setting this option true suggests that the protocol author believes that
+  // using lazy parsing on this field is worth the additional bookkeeping
+  // overhead typically needed to implement it.
+  //
+  // This option does not affect the public interface of any generated code;
+  // all method signatures remain the same.  Furthermore, thread-safety of the
+  // interface is not affected by this option; const methods remain safe to
+  // call from multiple threads concurrently, while non-const methods continue
+  // to require exclusive access.
+  //
+  //
+  // Note that implementations may choose not to check required fields within
+  // a lazy sub-message.  That is, calling IsInitialized() on the outer message
+  // may return true even if the inner message has missing required fields.
+  // This is necessary because otherwise the inner message would have to be
+  // parsed in order to perform the check, defeating the purpose of lazy
+  // parsing.  An implementation which chooses not to check required fields
+  // must be consistent about it.  That is, for any particular sub-message, the
+  // implementation must either *always* check its required fields, or *never*
+  // check its required fields, regardless of whether or not the message has
+  // been parsed.
+  optional bool lazy = 5 [default = false];
+
+  // Is this field deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for accessors, or it will be completely ignored; in the very least, this
+  // is a formalization for deprecating fields.
+  optional bool deprecated = 3 [default = false];
+
+  // For Google-internal migration only. Do not use.
+  optional bool weak = 10 [default = false];
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+
+  reserved 4;  // removed jtype
+}
+
+message OneofOptions {
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message EnumOptions {
+
+  // Set this option to true to allow mapping different tag names to the same
+  // value.
+  optional bool allow_alias = 2;
+
+  // Is this enum deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the enum, or it will be completely ignored; in the very least, this
+  // is a formalization for deprecating enums.
+  optional bool deprecated = 3 [default = false];
+
+  reserved 5;  // javanano_as_lite
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message EnumValueOptions {
+  // Is this enum value deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the enum value, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating enum values.
+  optional bool deprecated = 1 [default = false];
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message ServiceOptions {
+
+  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC
+  //   framework.  We apologize for hoarding these numbers to ourselves, but
+  //   we were already using them long before we decided to release Protocol
+  //   Buffers.
+
+  // Is this service deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the service, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating services.
+  optional bool deprecated = 33 [default = false];
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message MethodOptions {
+
+  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC
+  //   framework.  We apologize for hoarding these numbers to ourselves, but
+  //   we were already using them long before we decided to release Protocol
+  //   Buffers.
+
+  // Is this method deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the method, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating methods.
+  optional bool deprecated = 33 [default = false];
+
+  // Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
+  // or neither? HTTP based RPC implementation may choose GET verb for safe
+  // methods, and PUT verb for idempotent methods instead of the default POST.
+  enum IdempotencyLevel {
+    IDEMPOTENCY_UNKNOWN = 0;
+    NO_SIDE_EFFECTS = 1;  // implies idempotent
+    IDEMPOTENT = 2;       // idempotent, but may have side effects
+  }
+  optional IdempotencyLevel idempotency_level = 34
+      [default = IDEMPOTENCY_UNKNOWN];
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+// A message representing a option the parser does not recognize. This only
+// appears in options protos created by the compiler::Parser class.
+// DescriptorPool resolves these when building Descriptor objects. Therefore,
+// options protos in descriptor objects (e.g. returned by Descriptor::options(),
+// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
+// in them.
+message UninterpretedOption {
+  // The name of the uninterpreted option.  Each string represents a segment in
+  // a dot-separated name.  is_extension is true iff a segment represents an
+  // extension (denoted with parentheses in options specs in .proto files).
+  // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
+  // "foo.(bar.baz).qux".
+  message NamePart {
+    required string name_part = 1;
+    required bool is_extension = 2;
+  }
+  repeated NamePart name = 2;
+
+  // The value of the uninterpreted option, in whatever type the tokenizer
+  // identified it as during parsing. Exactly one of these should be set.
+  optional string identifier_value = 3;
+  optional uint64 positive_int_value = 4;
+  optional int64 negative_int_value = 5;
+  optional double double_value = 6;
+  optional bytes string_value = 7;
+  optional string aggregate_value = 8;
+}
+
+// ===================================================================
+// Optional source code info
+
+// Encapsulates information about the original source file from which a
+// FileDescriptorProto was generated.
+message SourceCodeInfo {
+  // A Location identifies a piece of source code in a .proto file which
+  // corresponds to a particular definition.  This information is intended
+  // to be useful to IDEs, code indexers, documentation generators, and similar
+  // tools.
+  //
+  // For example, say we have a file like:
+  //   message Foo {
+  //     optional string foo = 1;
+  //   }
+  // Let's look at just the field definition:
+  //   optional string foo = 1;
+  //   ^       ^^     ^^  ^  ^^^
+  //   a       bc     de  f  ghi
+  // We have the following locations:
+  //   span   path               represents
+  //   [a,i)  [ 4, 0, 2, 0 ]     The whole field definition.
+  //   [a,b)  [ 4, 0, 2, 0, 4 ]  The label (optional).
+  //   [c,d)  [ 4, 0, 2, 0, 5 ]  The type (string).
+  //   [e,f)  [ 4, 0, 2, 0, 1 ]  The name (foo).
+  //   [g,h)  [ 4, 0, 2, 0, 3 ]  The number (1).
+  //
+  // Notes:
+  // - A location may refer to a repeated field itself (i.e. not to any
+  //   particular index within it).  This is used whenever a set of elements are
+  //   logically enclosed in a single code segment.  For example, an entire
+  //   extend block (possibly containing multiple extension definitions) will
+  //   have an outer location whose path refers to the "extensions" repeated
+  //   field without an index.
+  // - Multiple locations may have the same path.  This happens when a single
+  //   logical declaration is spread out across multiple places.  The most
+  //   obvious example is the "extend" block again -- there may be multiple
+  //   extend blocks in the same scope, each of which will have the same path.
+  // - A location's span is not always a subset of its parent's span.  For
+  //   example, the "extendee" of an extension declaration appears at the
+  //   beginning of the "extend" block and is shared by all extensions within
+  //   the block.
+  // - Just because a location's span is a subset of some other location's span
+  //   does not mean that it is a descendant.  For example, a "group" defines
+  //   both a type and a field in a single declaration.  Thus, the locations
+  //   corresponding to the type and field and their components will overlap.
+  // - Code which tries to interpret locations should probably be designed to
+  //   ignore those that it doesn't understand, as more types of locations could
+  //   be recorded in the future.
+  repeated Location location = 1;
+  message Location {
+    // Identifies which part of the FileDescriptorProto was defined at this
+    // location.
+    //
+    // Each element is a field number or an index.  They form a path from
+    // the root FileDescriptorProto to the place where the definition.  For
+    // example, this path:
+    //   [ 4, 3, 2, 7, 1 ]
+    // refers to:
+    //   file.message_type(3)  // 4, 3
+    //       .field(7)         // 2, 7
+    //       .name()           // 1
+    // This is because FileDescriptorProto.message_type has field number 4:
+    //   repeated DescriptorProto message_type = 4;
+    // and DescriptorProto.field has field number 2:
+    //   repeated FieldDescriptorProto field = 2;
+    // and FieldDescriptorProto.name has field number 1:
+    //   optional string name = 1;
+    //
+    // Thus, the above path gives the location of a field name.  If we removed
+    // the last element:
+    //   [ 4, 3, 2, 7 ]
+    // this path refers to the whole field declaration (from the beginning
+    // of the label to the terminating semicolon).
+    repeated int32 path = 1 [packed = true];
+
+// Always has exactly three or four elements: start line, start column,
+// end line (optional, otherwise assumed same as start line), end column.
+// These are packed into a single field for efficiency.  Note that line
+// and column numbers are zero-based -- typically you will want to add
+// 1 to each before displaying to a user.
+repeated int32 span = 2 [packed = true];
+
+// If this SourceCodeInfo represents a complete declaration, these are any
+// comments appearing before and after the declaration which appear to be
+// attached to the declaration.
+//
+// A series of line comments appearing on consecutive lines, with no other
+// tokens appearing on those lines, will be treated as a single comment.
+//
+// leading_detached_comments will keep paragraphs of comments that appear
+// before (but not connected to) the current element. Each paragraph,
+// separated by empty lines, will be one comment element in the repeated
+// field.
+//
+// Only the comment content is provided; comment markers (e.g. //) are
+// stripped out.  For block comments, leading whitespace and an asterisk
+// will be stripped from the beginning of each line other than the first.
+// Newlines are included in the output.
+//
+// Examples:
+//
+//   optional int32 foo = 1;  // Comment attached to foo.
+//   // Comment attached to bar.
+//   optional int32 bar = 2;
+//
+//   optional string baz = 3;
+//   // Comment attached to baz.
+//   // Another line attached to baz.
+//
+//   // Comment attached to qux.
+//   //
+//   // Another line attached to qux.
+//   optional double qux = 4;
+//
+//   // Detached comment for corge. This is not leading or trailing comments
+//   // to qux or corge because there are blank lines separating it from
+//   // both.
+//
+//   // Detached comment for corge paragraph 2.
+//
+//   optional string corge = 5;
+//   /* Block comment attached
+//    * to corge.  Leading asterisks
+//    * will be removed. */ // /* Block comment attached to
+//    * grault. */
+//   optional int32 grault = 6;
+//
+//   // ignored detached comments.
+optional string leading_comments = 3;
+optional string trailing_comments = 4;
+repeated string leading_detached_comments = 6;
+
+  }
+}
+
+// Describes the relationship between generated code and its original source
+// file. A GeneratedCodeInfo message is associated with only one generated
+// source file, but may contain references to different source .proto files.
+message GeneratedCodeInfo {
+  // An Annotation connects some span of text in generated code to an element
+  // of its generating .proto file.
+  repeated Annotation annotation = 1;
+  message Annotation {
+    // Identifies the element in the original source .proto file. This field
+    // is formatted the same as SourceCodeInfo.Location.path.
+    repeated int32 path = 1 [packed = true];
+
+// Identifies the filesystem path to the original source .proto.
+optional string source_file = 2;
+
+// Identifies the starting offset in bytes in the generated code
+// that relates to the identified object.
+optional int32 begin = 3;
+
+// Identifies the ending offset in bytes in the generated code that
+// relates to the identified offset. The end offset should be one past
+// the last relevant byte (so the length of the text = end - begin).
+optional int32 end = 4;
+
+  }
+}
+

Classes in this file

File Members

These definitions are not part of any class.
enum
FieldDescriptorProto_Type
enum
FieldDescriptorProto_Label
enum
FileOptions_OptimizeMode
enum
FieldOptions_CType
enum
FieldOptions_JSType
enum
MethodOptions_IdempotencyLevel
const ::protobuf::internal::DescriptorTable
descriptor_table_google_2fprotobuf_2fdescriptor_2eproto
DescriptorProtoDefaultTypeInternal
_DescriptorProto_default_instance_
DescriptorProto_ExtensionRangeDefaultTypeInternal
_DescriptorProto_ExtensionRange_default_instance_
DescriptorProto_ReservedRangeDefaultTypeInternal
_DescriptorProto_ReservedRange_default_instance_
EnumDescriptorProtoDefaultTypeInternal
_EnumDescriptorProto_default_instance_
EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal
_EnumDescriptorProto_EnumReservedRange_default_instance_
EnumOptionsDefaultTypeInternal
_EnumOptions_default_instance_
EnumValueDescriptorProtoDefaultTypeInternal
_EnumValueDescriptorProto_default_instance_
EnumValueOptionsDefaultTypeInternal
_EnumValueOptions_default_instance_
ExtensionRangeOptionsDefaultTypeInternal
_ExtensionRangeOptions_default_instance_
FieldDescriptorProtoDefaultTypeInternal
_FieldDescriptorProto_default_instance_
FieldOptionsDefaultTypeInternal
_FieldOptions_default_instance_
FileDescriptorProtoDefaultTypeInternal
_FileDescriptorProto_default_instance_
FileDescriptorSetDefaultTypeInternal
_FileDescriptorSet_default_instance_
FileOptionsDefaultTypeInternal
_FileOptions_default_instance_
GeneratedCodeInfoDefaultTypeInternal
_GeneratedCodeInfo_default_instance_
GeneratedCodeInfo_AnnotationDefaultTypeInternal
_GeneratedCodeInfo_Annotation_default_instance_
MessageOptionsDefaultTypeInternal
_MessageOptions_default_instance_
MethodDescriptorProtoDefaultTypeInternal
_MethodDescriptorProto_default_instance_
MethodOptionsDefaultTypeInternal
_MethodOptions_default_instance_
OneofDescriptorProtoDefaultTypeInternal
_OneofDescriptorProto_default_instance_
OneofOptionsDefaultTypeInternal
_OneofOptions_default_instance_
ServiceDescriptorProtoDefaultTypeInternal
_ServiceDescriptorProto_default_instance_
ServiceOptionsDefaultTypeInternal
_ServiceOptions_default_instance_
SourceCodeInfoDefaultTypeInternal
_SourceCodeInfo_default_instance_
SourceCodeInfo_LocationDefaultTypeInternal
_SourceCodeInfo_Location_default_instance_
UninterpretedOptionDefaultTypeInternal
_UninterpretedOption_default_instance_
UninterpretedOption_NamePartDefaultTypeInternal
_UninterpretedOption_NamePart_default_instance_
constexpr FieldDescriptorProto_Type
FieldDescriptorProto_Type_Type_MIN = = FieldDescriptorProto_Type_TYPE_DOUBLE
constexpr FieldDescriptorProto_Type
FieldDescriptorProto_Type_Type_MAX = = FieldDescriptorProto_Type_TYPE_SINT64
constexpr int
FieldDescriptorProto_Type_Type_ARRAYSIZE = = FieldDescriptorProto_Type_Type_MAX + 1
constexpr FieldDescriptorProto_Label
FieldDescriptorProto_Label_Label_MIN = = FieldDescriptorProto_Label_LABEL_OPTIONAL
constexpr FieldDescriptorProto_Label
FieldDescriptorProto_Label_Label_MAX = = FieldDescriptorProto_Label_LABEL_REPEATED
constexpr int
FieldDescriptorProto_Label_Label_ARRAYSIZE = = FieldDescriptorProto_Label_Label_MAX + 1
constexpr FileOptions_OptimizeMode
FileOptions_OptimizeMode_OptimizeMode_MIN = = FileOptions_OptimizeMode_SPEED
constexpr FileOptions_OptimizeMode
FileOptions_OptimizeMode_OptimizeMode_MAX = = FileOptions_OptimizeMode_LITE_RUNTIME
constexpr int
FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE = = FileOptions_OptimizeMode_OptimizeMode_MAX + 1
constexpr FieldOptions_CType
FieldOptions_CType_CType_MIN = = FieldOptions_CType_STRING
constexpr FieldOptions_CType
FieldOptions_CType_CType_MAX = = FieldOptions_CType_STRING_PIECE
constexpr int
FieldOptions_CType_CType_ARRAYSIZE = = FieldOptions_CType_CType_MAX + 1
constexpr FieldOptions_JSType
FieldOptions_JSType_JSType_MIN = = FieldOptions_JSType_JS_NORMAL
constexpr FieldOptions_JSType
FieldOptions_JSType_JSType_MAX = = FieldOptions_JSType_JS_NUMBER
constexpr int
FieldOptions_JSType_JSType_ARRAYSIZE = = FieldOptions_JSType_JSType_MAX + 1
constexpr MethodOptions_IdempotencyLevel
MethodOptions_IdempotencyLevel_IdempotencyLevel_MIN = = MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN
constexpr MethodOptions_IdempotencyLevel
MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX = = MethodOptions_IdempotencyLevel_IDEMPOTENT
constexpr int
MethodOptions_IdempotencyLevel_IdempotencyLevel_ARRAYSIZE = = MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX + 1
PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_OPEN protobuf::DescriptorProto *
Arena::CreateMaybeMessage< protobuf::DescriptorProto >(Arena * )
protobuf::DescriptorProto_ExtensionRange *
Arena::CreateMaybeMessage< protobuf::DescriptorProto_ExtensionRange >(Arena * )
protobuf::DescriptorProto_ReservedRange *
Arena::CreateMaybeMessage< protobuf::DescriptorProto_ReservedRange >(Arena * )
protobuf::EnumDescriptorProto *
Arena::CreateMaybeMessage< protobuf::EnumDescriptorProto >(Arena * )
protobuf::EnumDescriptorProto_EnumReservedRange *
Arena::CreateMaybeMessage< protobuf::EnumDescriptorProto_EnumReservedRange >(Arena * )
protobuf::EnumOptions *
Arena::CreateMaybeMessage< protobuf::EnumOptions >(Arena * )
protobuf::EnumValueDescriptorProto *
Arena::CreateMaybeMessage< protobuf::EnumValueDescriptorProto >(Arena * )
protobuf::EnumValueOptions *
Arena::CreateMaybeMessage< protobuf::EnumValueOptions >(Arena * )
protobuf::ExtensionRangeOptions *
Arena::CreateMaybeMessage< protobuf::ExtensionRangeOptions >(Arena * )
protobuf::FieldDescriptorProto *
Arena::CreateMaybeMessage< protobuf::FieldDescriptorProto >(Arena * )
protobuf::FieldOptions *
Arena::CreateMaybeMessage< protobuf::FieldOptions >(Arena * )
protobuf::FileDescriptorProto *
Arena::CreateMaybeMessage< protobuf::FileDescriptorProto >(Arena * )
protobuf::FileDescriptorSet *
Arena::CreateMaybeMessage< protobuf::FileDescriptorSet >(Arena * )
protobuf::FileOptions *
Arena::CreateMaybeMessage< protobuf::FileOptions >(Arena * )
protobuf::GeneratedCodeInfo *
Arena::CreateMaybeMessage< protobuf::GeneratedCodeInfo >(Arena * )
protobuf::GeneratedCodeInfo_Annotation *
Arena::CreateMaybeMessage< protobuf::GeneratedCodeInfo_Annotation >(Arena * )
protobuf::MessageOptions *
Arena::CreateMaybeMessage< protobuf::MessageOptions >(Arena * )
protobuf::MethodDescriptorProto *
Arena::CreateMaybeMessage< protobuf::MethodDescriptorProto >(Arena * )
protobuf::MethodOptions *
Arena::CreateMaybeMessage< protobuf::MethodOptions >(Arena * )
protobuf::OneofDescriptorProto *
Arena::CreateMaybeMessage< protobuf::OneofDescriptorProto >(Arena * )
protobuf::OneofOptions *
Arena::CreateMaybeMessage< protobuf::OneofOptions >(Arena * )
protobuf::ServiceDescriptorProto *
Arena::CreateMaybeMessage< protobuf::ServiceDescriptorProto >(Arena * )
protobuf::ServiceOptions *
Arena::CreateMaybeMessage< protobuf::ServiceOptions >(Arena * )
protobuf::SourceCodeInfo *
Arena::CreateMaybeMessage< protobuf::SourceCodeInfo >(Arena * )
protobuf::SourceCodeInfo_Location *
Arena::CreateMaybeMessage< protobuf::SourceCodeInfo_Location >(Arena * )
protobuf::UninterpretedOption *
Arena::CreateMaybeMessage< protobuf::UninterpretedOption >(Arena * )
protobuf::UninterpretedOption_NamePart *
Arena::CreateMaybeMessage< protobuf::UninterpretedOption_NamePart >(Arena * )
bool
FieldDescriptorProto_Type_IsValid(int value)
const ::protobuf::EnumDescriptor *
FieldDescriptorProto_Type_descriptor()
template const std::string &
FieldDescriptorProto_Type_Name(T enum_t_value)
bool
FieldDescriptorProto_Type_Parse(::protobuf::ConstStringParam name, FieldDescriptorProto_Type * value)
bool
FieldDescriptorProto_Label_IsValid(int value)
const ::protobuf::EnumDescriptor *
FieldDescriptorProto_Label_descriptor()
template const std::string &
FieldDescriptorProto_Label_Name(T enum_t_value)
bool
FieldDescriptorProto_Label_Parse(::protobuf::ConstStringParam name, FieldDescriptorProto_Label * value)
bool
FileOptions_OptimizeMode_IsValid(int value)
const ::protobuf::EnumDescriptor *
FileOptions_OptimizeMode_descriptor()
template const std::string &
FileOptions_OptimizeMode_Name(T enum_t_value)
bool
FileOptions_OptimizeMode_Parse(::protobuf::ConstStringParam name, FileOptions_OptimizeMode * value)
bool
FieldOptions_CType_IsValid(int value)
const ::protobuf::EnumDescriptor *
FieldOptions_CType_descriptor()
template const std::string &
FieldOptions_CType_Name(T enum_t_value)
bool
FieldOptions_CType_Parse(::protobuf::ConstStringParam name, FieldOptions_CType * value)
bool
FieldOptions_JSType_IsValid(int value)
const ::protobuf::EnumDescriptor *
FieldOptions_JSType_descriptor()
template const std::string &
FieldOptions_JSType_Name(T enum_t_value)
bool
FieldOptions_JSType_Parse(::protobuf::ConstStringParam name, FieldOptions_JSType * value)
bool
MethodOptions_IdempotencyLevel_IsValid(int value)
const ::protobuf::EnumDescriptor *
MethodOptions_IdempotencyLevel_descriptor()
template const std::string &
MethodOptions_IdempotencyLevel_Name(T enum_t_value)
bool
MethodOptions_IdempotencyLevel_Parse(::protobuf::ConstStringParam name, MethodOptions_IdempotencyLevel * value)
const EnumDescriptor *
GetEnumDescriptor< protobuf::FieldDescriptorProto_Type >()
const EnumDescriptor *
GetEnumDescriptor< protobuf::FieldDescriptorProto_Label >()
const EnumDescriptor *
GetEnumDescriptor< protobuf::FileOptions_OptimizeMode >()
const EnumDescriptor *
GetEnumDescriptor< protobuf::FieldOptions_CType >()
const EnumDescriptor *
GetEnumDescriptor< protobuf::FieldOptions_JSType >()
const EnumDescriptor *
GetEnumDescriptor< protobuf::MethodOptions_IdempotencyLevel >()

enum protobuf::FieldDescriptorProto_Type {
  FieldDescriptorProto_Type_TYPE_DOUBLE = = 1,
  FieldDescriptorProto_Type_TYPE_FLOAT = = 2,
  FieldDescriptorProto_Type_TYPE_INT64 = = 3,
  FieldDescriptorProto_Type_TYPE_UINT64 = = 4,
  FieldDescriptorProto_Type_TYPE_INT32 = = 5,
  FieldDescriptorProto_Type_TYPE_FIXED64 = = 6,
  FieldDescriptorProto_Type_TYPE_FIXED32 = = 7,
  FieldDescriptorProto_Type_TYPE_BOOL = = 8,
  FieldDescriptorProto_Type_TYPE_STRING = = 9,
  FieldDescriptorProto_Type_TYPE_GROUP = = 10,
  FieldDescriptorProto_Type_TYPE_MESSAGE = = 11,
  FieldDescriptorProto_Type_TYPE_BYTES = = 12,
  FieldDescriptorProto_Type_TYPE_UINT32 = = 13,
  FieldDescriptorProto_Type_TYPE_ENUM = = 14,
  FieldDescriptorProto_Type_TYPE_SFIXED32 = = 15,
  FieldDescriptorProto_Type_TYPE_SFIXED64 = = 16,
  FieldDescriptorProto_Type_TYPE_SINT32 = = 17,
  FieldDescriptorProto_Type_TYPE_SINT64 = = 18
}

FieldDescriptorProto_Type_TYPE_DOUBLE
FieldDescriptorProto_Type_TYPE_FLOAT
FieldDescriptorProto_Type_TYPE_INT64
FieldDescriptorProto_Type_TYPE_UINT64
FieldDescriptorProto_Type_TYPE_INT32
FieldDescriptorProto_Type_TYPE_FIXED64
FieldDescriptorProto_Type_TYPE_FIXED32
FieldDescriptorProto_Type_TYPE_BOOL
FieldDescriptorProto_Type_TYPE_STRING
FieldDescriptorProto_Type_TYPE_GROUP
FieldDescriptorProto_Type_TYPE_MESSAGE
FieldDescriptorProto_Type_TYPE_BYTES
FieldDescriptorProto_Type_TYPE_UINT32
FieldDescriptorProto_Type_TYPE_ENUM
FieldDescriptorProto_Type_TYPE_SFIXED32
FieldDescriptorProto_Type_TYPE_SFIXED64
FieldDescriptorProto_Type_TYPE_SINT32
FieldDescriptorProto_Type_TYPE_SINT64

enum protobuf::FieldDescriptorProto_Label {
  FieldDescriptorProto_Label_LABEL_OPTIONAL = = 1,
  FieldDescriptorProto_Label_LABEL_REQUIRED = = 2,
  FieldDescriptorProto_Label_LABEL_REPEATED = = 3
}

FieldDescriptorProto_Label_LABEL_OPTIONAL
FieldDescriptorProto_Label_LABEL_REQUIRED
FieldDescriptorProto_Label_LABEL_REPEATED

enum protobuf::FileOptions_OptimizeMode {
  FileOptions_OptimizeMode_SPEED = = 1,
  FileOptions_OptimizeMode_CODE_SIZE = = 2,
  FileOptions_OptimizeMode_LITE_RUNTIME = = 3
}

FileOptions_OptimizeMode_SPEED
FileOptions_OptimizeMode_CODE_SIZE
FileOptions_OptimizeMode_LITE_RUNTIME

enum protobuf::FieldOptions_CType {
  FieldOptions_CType_STRING = = 0,
  FieldOptions_CType_CORD = = 1,
  FieldOptions_CType_STRING_PIECE = = 2
}

FieldOptions_CType_STRING
FieldOptions_CType_CORD
FieldOptions_CType_STRING_PIECE

enum protobuf::FieldOptions_JSType {
  FieldOptions_JSType_JS_NORMAL = = 0,
  FieldOptions_JSType_JS_STRING = = 1,
  FieldOptions_JSType_JS_NUMBER = = 2
}

FieldOptions_JSType_JS_NORMAL
FieldOptions_JSType_JS_STRING
FieldOptions_JSType_JS_NUMBER

enum protobuf::MethodOptions_IdempotencyLevel {
  MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN = = 0,
  MethodOptions_IdempotencyLevel_NO_SIDE_EFFECTS = = 1,
  MethodOptions_IdempotencyLevel_IDEMPOTENT = = 2
}

MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN
MethodOptions_IdempotencyLevel_NO_SIDE_EFFECTS
MethodOptions_IdempotencyLevel_IDEMPOTENT
\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.descriptor/index.html b/reference/cpp/api-docs/google.protobuf.descriptor/index.html new file mode 100644 index 000000000..c188e1675 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.descriptor/index.html @@ -0,0 +1,21 @@ +descriptor.h | Protocol Buffers Documentation +

descriptor.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/descriptor.h>
namespace google::protobuf

This file contains classes which describe a type of protocol message.

You can use a message's descriptor to learn at runtime what fields it contains and what the types of those fields are. The Message interface also allows you to dynamically access and modify individual fields by passing the FieldDescriptor of the field you are interested in.

Most users will not care about descriptors, because they will write code specific to certain protocol types and will simply use the classes generated by the protocol compiler directly. Advanced users who want to operate on arbitrary types (not known at compile time) may want to read descriptors in order to learn about the contents of a message. A very small number of users will want to construct their own Descriptors, either because they are implementing Message manually or because they are writing something like the protocol compiler.

For an example of how you might use descriptors, see the code example at the top of message.h.

Classes in this file

NB, all indices are zero-based.
Options when generating machine-parsable output from a descriptor with DebugString().
Describes a type of protocol message, or a particular group within a message.
A range of field numbers which are designated for third-party extensions.
A range of reserved field numbers.
Describes a single field of a message.
Describes a oneof defined in a message type.
Describes an enum type defined in a .proto file.
A range of reserved field numbers.
Describes an individual enum constant of a particular type.
Describes an RPC service.
Describes an individual service method.
Describes a whole .proto file.
Used to construct descriptors.
When converting a FileDescriptorProto to a FileDescriptor, various errors might be detected in the input.

struct SourceLocation

#include <google/protobuf/descriptor.h>
namespace google::protobuf

NB, all indices are zero-based.

Members

int
start_line
int
end_line
int
start_column
int
end_column
std::string
leading_comments
Doc comments found at the source location. more...
std::string
trailing_comments
std::vector< std::string >
leading_detached_comments

std::string SourceLocation::leading_comments

Doc comments found at the source location.

See the comments in SourceCodeInfo.Location (descriptor.proto) for details.

struct DebugStringOptions

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Options when generating machine-parsable output from a descriptor with DebugString().

Members

bool
include_comments
include original user comments as recorded in SourceLocation entries. more...
bool
elide_group_body
If true, elide the braced body in the debug string.
bool
elide_oneof_body
DebugStringOptions()

bool DebugStringOptions::include_comments

include original user comments as recorded in SourceLocation entries.

N.B. that this must be |false| by default: several other pieces of code (for example, the C++ code generation for fields in the proto compiler) rely on DebugString() output being unobstructed by user comments.

class Descriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Describes a type of protocol message, or a particular group within a message.

To obtain the Descriptor for a given message object, call Message::GetDescriptor(). Generated message classes also have a static method called descriptor() which returns the type's descriptor. Use DescriptorPool to construct your own descriptors.

Members

enum
WellKnownType
typedef
DescriptorProto Proto
const std::string &
name() const
The name of the message type, not including its scope.
const std::string &
full_name() const
The fully-qualified name of the message type, scope delimited by periods. more...
int
index() const
Index of this descriptor within the file or containing type's message type array.
const FileDescriptor *
file() const
The .proto file in which this message type was defined. Never nullptr.
const Descriptor *
containing_type() const
If this Descriptor describes a nested type, this returns the type in which it is nested. more...
const MessageOptions &
options() const
Get options for this message type. more...
void
CopyTo(DescriptorProto * proto) const
Write the contents of this Descriptor into the given DescriptorProto. more...
std::string
DebugString() const
Write the contents of this descriptor in a human-readable form. more...
std::string
DebugStringWithOptions(const DebugStringOptions & options) const
Similar to DebugString(), but additionally takes options (e.g., include original user comments in output).
bool
is_placeholder() const
Returns true if this is a placeholder for an unknown type. more...
WellKnownType
well_known_type() const

Field stuff

int
field_count() const
The number of fields in this message type.
const FieldDescriptor *
field(int index) const
Gets a field by index, where 0 <= index < field_count(). more...
const FieldDescriptor *
FindFieldByNumber(int number) const
Looks up a field by declared tag number. more...
const FieldDescriptor *
FindFieldByName(ConstStringParam name) const
Looks up a field by name. Returns nullptr if no such field exists.
const FieldDescriptor *
FindFieldByLowercaseName(ConstStringParam lowercase_name) const
Looks up a field by lowercased name (as returned by lowercase_name()). more...
const FieldDescriptor *
FindFieldByCamelcaseName(ConstStringParam camelcase_name) const
Looks up a field by camel-case name (as returned by camelcase_name()). more...
int
oneof_decl_count() const
The number of oneofs in this message type.
int
real_oneof_decl_count() const
The number of oneofs in this message type, excluding synthetic oneofs. more...
const OneofDescriptor *
oneof_decl(int index) const
Get a oneof by index, where 0 <= index < oneof_decl_count(). more...
const OneofDescriptor *
FindOneofByName(ConstStringParam name) const
Looks up a oneof by name. Returns nullptr if no such oneof exists.

Nested type stuff

int
nested_type_count() const
The number of nested types in this message type.
const Descriptor *
nested_type(int index) const
Gets a nested type by index, where 0 <= index < nested_type_count(). more...
const Descriptor *
FindNestedTypeByName(ConstStringParam name) const
Looks up a nested type by name. more...

Enum stuff

int
enum_type_count() const
The number of enum types in this message type.
const EnumDescriptor *
enum_type(int index) const
Gets an enum type by index, where 0 <= index < enum_type_count(). more...
const EnumDescriptor *
FindEnumTypeByName(ConstStringParam name) const
Looks up an enum type by name. more...
const EnumValueDescriptor *
FindEnumValueByName(ConstStringParam name) const
Looks up an enum value by name, among all enum types in this message. more...

Extensions

int
extension_range_count() const
The number of extension ranges in this message type.
const ExtensionRange *
extension_range(int index) const
Gets an extension range by index, where 0 <= index < extension_range_count(). more...
bool
IsExtensionNumber(int number) const
Returns true if the number is in one of the extension ranges.
const ExtensionRange *
FindExtensionRangeContainingNumber(int number) const
Returns nullptr if no extension range contains the given number.
int
extension_count() const
The number of extensions defined nested within this message type's scope. more...
const FieldDescriptor *
extension(int index) const
Get an extension by index, where 0 <= index < extension_count(). more...
const FieldDescriptor *
FindExtensionByName(ConstStringParam name) const
Looks up a named extension (which extends some other message type) defined within this message type's scope.
const FieldDescriptor *
FindExtensionByLowercaseName(ConstStringParam name) const
Similar to FindFieldByLowercaseName(), but finds extensions defined within this message type's scope.
const FieldDescriptor *
FindExtensionByCamelcaseName(ConstStringParam name) const
Similar to FindFieldByCamelcaseName(), but finds extensions defined within this message type's scope.

Reserved fields

int
reserved_range_count() const
The number of reserved ranges in this message type.
const ReservedRange *
reserved_range(int index) const
Gets an reserved range by index, where 0 <= index < reserved_range_count(). more...
bool
IsReservedNumber(int number) const
Returns true if the number is in one of the reserved ranges.
const ReservedRange *
FindReservedRangeContainingNumber(int number) const
Returns nullptr if no reserved range contains the given number.
int
reserved_name_count() const
The number of reserved field names in this message type.
const std::string &
reserved_name(int index) const
Gets a reserved name by index, where 0 <= index < reserved_name_count(). more...
bool
IsReservedName(ConstStringParam name) const
Returns true if the field name is reserved.

Source Location

bool
GetSourceLocation(SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of this message declaration. more...

Maps

const FieldDescriptor *
map_key() const
Returns the FieldDescriptor for the "key" field. more...
const FieldDescriptor *
map_value() const
Returns the FieldDescriptor for the "value" field. more...

enum Descriptor::WellKnownType {
  WELLKNOWNTYPE_UNSPECIFIED,
  WELLKNOWNTYPE_DOUBLEVALUE,
  WELLKNOWNTYPE_FLOATVALUE,
  WELLKNOWNTYPE_INT64VALUE,
  WELLKNOWNTYPE_UINT64VALUE,
  WELLKNOWNTYPE_INT32VALUE,
  WELLKNOWNTYPE_UINT32VALUE,
  WELLKNOWNTYPE_STRINGVALUE,
  WELLKNOWNTYPE_BYTESVALUE,
  WELLKNOWNTYPE_BOOLVALUE,
  WELLKNOWNTYPE_ANY,
  WELLKNOWNTYPE_FIELDMASK,
  WELLKNOWNTYPE_DURATION,
  WELLKNOWNTYPE_TIMESTAMP,
  WELLKNOWNTYPE_VALUE,
  WELLKNOWNTYPE_LISTVALUE,
  WELLKNOWNTYPE_STRUCT,
  **WELLKNOWNTYPE**DO_NOT_USE__ADD_DEFAULT_INSTEAD__
}

WELLKNOWNTYPE_UNSPECIFIEDNot a well-known type.
WELLKNOWNTYPE_DOUBLEVALUE

Wrapper types.

google.protobuf.DoubleValue

WELLKNOWNTYPE_FLOATVALUEgoogle.protobuf.FloatValue
WELLKNOWNTYPE_INT64VALUEgoogle.protobuf.Int64Value
WELLKNOWNTYPE_UINT64VALUEgoogle.protobuf.UInt64Value
WELLKNOWNTYPE_INT32VALUEgoogle.protobuf.Int32Value
WELLKNOWNTYPE_UINT32VALUEgoogle.protobuf.UInt32Value
WELLKNOWNTYPE_STRINGVALUEgoogle.protobuf.StringValue
WELLKNOWNTYPE_BYTESVALUEgoogle.protobuf.BytesValue
WELLKNOWNTYPE_BOOLVALUEgoogle.protobuf.BoolValue
WELLKNOWNTYPE_ANY

Other well known types.

google.protobuf.Any

WELLKNOWNTYPE_FIELDMASKgoogle.protobuf.FieldMask
WELLKNOWNTYPE_DURATIONgoogle.protobuf.Duration
WELLKNOWNTYPE_TIMESTAMPgoogle.protobuf.Timestamp
WELLKNOWNTYPE_VALUEgoogle.protobuf.Value
WELLKNOWNTYPE_LISTVALUEgoogle.protobuf.ListValue
WELLKNOWNTYPE_STRUCTgoogle.protobuf.Struct
**WELLKNOWNTYPE**DO_NOT_USE__ADD_DEFAULT_INSTEAD__

New well-known types may be added in the future.

Please make sure any switch() statements have a 'default' case.


const std::string &
    Descriptor::full_name() const

The fully-qualified name of the message type, scope delimited by periods.

For example, message type "Foo" which is declared in package "bar" has full name "bar.Foo". If a type "Baz" is nested within Foo, Baz's full_name is "bar.Foo.Baz". To get only the part that comes after the last '.', use name().


const Descriptor *
    Descriptor::containing_type() const

If this Descriptor describes a nested type, this returns the type in which it is nested.

Otherwise, returns nullptr.


const MessageOptions &
    Descriptor::options() const

Get options for this message type.

These are specified in the .proto file by placing lines like "option foo = 1234;" in the message definition. Allowed options are defined by MessageOptions in descriptor.proto, and any available extensions of that message.


void Descriptor::CopyTo(
        DescriptorProto * proto) const

Write the contents of this Descriptor into the given DescriptorProto.

The target DescriptorProto must be clear before calling this; if it isn't, the result may be garbage.


std::string Descriptor::DebugString() const

Write the contents of this descriptor in a human-readable form.

Output will be suitable for re-parsing.


bool Descriptor::is_placeholder() const

Returns true if this is a placeholder for an unknown type.

This will only be the case if this descriptor comes from a DescriptorPool with AllowUnknownDependencies() set.


const FieldDescriptor *
    Descriptor::field(
        int index) const

Gets a field by index, where 0 <= index < field_count().

These are returned in the order they were defined in the .proto file.


const FieldDescriptor *
    Descriptor::FindFieldByNumber(
        int number) const

Looks up a field by declared tag number.

Returns nullptr if no such field exists.


const FieldDescriptor *
    Descriptor::FindFieldByLowercaseName(
        ConstStringParam lowercase_name) const

Looks up a field by lowercased name (as returned by lowercase_name()).

This lookup may be ambiguous if multiple field names differ only by case, in which case the field returned is chosen arbitrarily from the matches.


const FieldDescriptor *
    Descriptor::FindFieldByCamelcaseName(
        ConstStringParam camelcase_name) const

Looks up a field by camel-case name (as returned by camelcase_name()).

This lookup may be ambiguous if multiple field names differ in a way that leads them to have identical camel-case names, in which case the field returned is chosen arbitrarily from the matches.


int Descriptor::real_oneof_decl_count() const

The number of oneofs in this message type, excluding synthetic oneofs.

Real oneofs always come first, so iterating up to real_oneof_decl_cout() will yield all real oneofs.


const OneofDescriptor *
    Descriptor::oneof_decl(
        int index) const

Get a oneof by index, where 0 <= index < oneof_decl_count().

These are returned in the order they were defined in the .proto file.


const Descriptor *
    Descriptor::nested_type(
        int index) const

Gets a nested type by index, where 0 <= index < nested_type_count().

These are returned in the order they were defined in the .proto file.


const Descriptor *
    Descriptor::FindNestedTypeByName(
        ConstStringParam name) const

Looks up a nested type by name.

Returns nullptr if no such nested type exists.


const EnumDescriptor *
    Descriptor::enum_type(
        int index) const

Gets an enum type by index, where 0 <= index < enum_type_count().

These are returned in the order they were defined in the .proto file.


const EnumDescriptor *
    Descriptor::FindEnumTypeByName(
        ConstStringParam name) const

Looks up an enum type by name.

Returns nullptr if no such enum type exists.


const EnumValueDescriptor *
    Descriptor::FindEnumValueByName(
        ConstStringParam name) const

Looks up an enum value by name, among all enum types in this message.

Returns nullptr if no such value exists.


const ExtensionRange *
    Descriptor::extension_range(
        int index) const

Gets an extension range by index, where 0 <= index < extension_range_count().

These are returned in the order they were defined in the .proto file.


int Descriptor::extension_count() const


const FieldDescriptor *
    Descriptor::extension(
        int index) const

Get an extension by index, where 0 <= index < extension_count().

These are returned in the order they were defined in the .proto file.


const ReservedRange *
    Descriptor::reserved_range(
        int index) const

Gets an reserved range by index, where 0 <= index < reserved_range_count().

These are returned in the order they were defined in the .proto file.


const std::string &
    Descriptor::reserved_name(
        int index) const

Gets a reserved name by index, where 0 <= index < reserved_name_count().

Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because reserved_names_ is actually an array of pointers rather than the usual array of objects.


bool Descriptor::GetSourceLocation(
        SourceLocation * out_location) const

Updates |*out_location| to the source location of the complete extent of this message declaration.

Returns false and leaves |*out_location| unchanged iff location information was not available.


const FieldDescriptor *
    Descriptor::map_key() const

Returns the FieldDescriptor for the "key" field.

If this isn't a map entry field, returns nullptr.


const FieldDescriptor *
    Descriptor::map_value() const

Returns the FieldDescriptor for the "value" field.

If this isn't a map entry field, returns nullptr.

struct Descriptor::ExtensionRange

#include <google/protobuf/descriptor.h>
namespace google::protobuf

A range of field numbers which are designated for third-party extensions.

Members

typedef
DescriptorProto_ExtensionRange Proto
typedef
ExtensionRangeOptions OptionsType
int
start
inclusive
int
end
exclusive
const ExtensionRangeOptions *
options_
void
CopyTo(DescriptorProto_ExtensionRange * proto) const

struct Descriptor::ReservedRange

#include <google/protobuf/descriptor.h>
namespace google::protobuf

A range of reserved field numbers.

Members

int
start
inclusive
int
end
exclusive

class FieldDescriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Describes a single field of a message.

To get the descriptor for a given field, first get the Descriptor for the message in which it is defined, then call Descriptor::FindFieldByName(). To get a FieldDescriptor for an extension, do one of the following:

Members

enum
Type
Identifies a field type. more...
enum
CppType
Specifies the C++ data type used to represent the field. more...
enum
Label
Identifies whether the field is optional, required, or repeated. more...
typedef
FieldDescriptorProto Proto
const int
kMaxNumber = = (1 << 29) - 1
Valid field numbers are positive integers up to kMaxNumber.
const int
kFirstReservedNumber = = 19000
First field number reserved for the protocol buffer library implementation. more...
const int
kLastReservedNumber = = 19999
Last field number reserved for the protocol buffer library implementation. more...
int32
default_value_int32_
int64
default_value_int64_
uint32
default_value_uint32_
uint64
default_value_uint64_
float
default_value_float_
double
default_value_double_
bool
default_value_bool_
const EnumValueDescriptor *
default_value_enum_
const std::string *
default_value_string_
std::atomic< const Message * >
default_generated_instance_
const std::string &
name() const
Name of this field within the message.
const std::string &
full_name() const
Fully-qualified name of the field.
const std::string &
json_name() const
JSON name of this field.
const FileDescriptor *
file() const
File in which this field was defined.
bool
is_extension() const
Is this an extension field?
int
number() const
Declared tag number.
const std::string &
lowercase_name() const
Same as name() except converted to lower-case. more...
const std::string &
camelcase_name() const
Same as name() except converted to camel-case. more...
Type
type() const
Declared type of this field.
const char *
type_name() const
Name of the declared type.
CppType
cpp_type() const
C++ type of this field.
const char *
cpp_type_name() const
Name of the C++ type.
Label
label() const
optional/required/repeated
bool
is_required() const
shorthand for label() == LABEL_REQUIRED
bool
is_optional() const
shorthand for label() == LABEL_OPTIONAL
bool
is_repeated() const
shorthand for label() == LABEL_REPEATED
bool
is_packable() const
shorthand for is_repeated() && IsTypePackable(type())
bool
is_packed() const
shorthand for is_packable() && options().packed()
bool
is_map() const
shorthand for type() == TYPE_MESSAGE && message_type()->options().map_entry()
bool
has_optional_keyword() const
Returns true if this field was syntactically written with "optional" in the .proto file. more...
bool
has_presence() const
Returns true if this field tracks presence, ie. more...
int
index() const
Index of this field within the message's field array, or the file or extension scope's extensions array.
bool
has_default_value() const
Does this field have an explicitly-declared default value?
bool
has_json_name() const
Whether the user has specified the json_name field option in the .proto file.
int32
default_value_int32() const
Get the field default value if cpp_type() == CPPTYPE_INT32. more...
int64
default_value_int64() const
Get the field default value if cpp_type() == CPPTYPE_INT64. more...
uint32
default_value_uint32() const
Get the field default value if cpp_type() == CPPTYPE_UINT32. more...
uint64
default_value_uint64() const
Get the field default value if cpp_type() == CPPTYPE_UINT64. more...
float
default_value_float() const
Get the field default value if cpp_type() == CPPTYPE_FLOAT. more...
double
default_value_double() const
Get the field default value if cpp_type() == CPPTYPE_DOUBLE. more...
bool
default_value_bool() const
Get the field default value if cpp_type() == CPPTYPE_BOOL. more...
const EnumValueDescriptor *
default_value_enum() const
Get the field default value if cpp_type() == CPPTYPE_ENUM. more...
const std::string &
default_value_string() const
Get the field default value if cpp_type() == CPPTYPE_STRING. more...
const Descriptor *
containing_type() const
The Descriptor for the message of which this is a field. more...
const OneofDescriptor *
containing_oneof() const
If the field is a member of a oneof, this is the one, otherwise this is nullptr.
const OneofDescriptor *
real_containing_oneof() const
If the field is a member of a non-synthetic oneof, returns the descriptor for the oneof, otherwise returns nullptr.
int
index_in_oneof() const
If the field is a member of a oneof, returns the index in that oneof.
const Descriptor *
extension_scope() const
An extension may be declared within the scope of another message. more...
const Descriptor *
message_type() const
If type is TYPE_MESSAGE or TYPE_GROUP, returns a descriptor for the message or the group type. more...
const EnumDescriptor *
enum_type() const
If type is TYPE_ENUM, returns a descriptor for the enum. more...
const FieldOptions &
options() const
Get the FieldOptions for this field. more...
void
CopyTo(FieldDescriptorProto * proto) const
std::string
DebugString() const
std::string
DebugStringWithOptions(const DebugStringOptions & options) const
const std::string &
PrintableNameForExtension() const
Returns full_name() except if the field is a MessageSet extension, in which case it returns the full_name() of the containing message type for backwards compatibility with proto1. more...
static CppType
TypeToCppType(Type type)
Helper method to get the CppType for a particular Type.
static const char *
TypeName(Type type)
Helper method to get the name of a Type.
static const char *
CppTypeName(CppType cpp_type)
Helper method to get the name of a CppType.
static bool
IsTypePackable(Type field_type)
Return true iff [[]packed = true] is valid for fields of this type.

Source Location

bool
GetSourceLocation(SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of this field declaration. more...

enum FieldDescriptor::Type {
  TYPE_DOUBLE = = 1,
  TYPE_FLOAT = = 2,
  TYPE_INT64 = = 3,
  TYPE_UINT64 = = 4,
  TYPE_INT32 = = 5,
  TYPE_FIXED64 = = 6,
  TYPE_FIXED32 = = 7,
  TYPE_BOOL = = 8,
  TYPE_STRING = = 9,
  TYPE_GROUP = = 10,
  TYPE_MESSAGE = = 11,
  TYPE_BYTES = = 12,
  TYPE_UINT32 = = 13,
  TYPE_ENUM = = 14,
  TYPE_SFIXED32 = = 15,
  TYPE_SFIXED64 = = 16,
  TYPE_SINT32 = = 17,
  TYPE_SINT64 = = 18,
  MAX_TYPE = = 18
}

Identifies a field type.

0 is reserved for errors. The order is weird for historical reasons. Types 12 and up are new in proto2.

TYPE_DOUBLEdouble, exactly eight bytes on the wire.
TYPE_FLOATfloat, exactly four bytes on the wire.
TYPE_INT64

int64, varint on the wire.

Negative numbers take 10 bytes. Use TYPE_SINT64 if negative values are likely.

TYPE_UINT64uint64, varint on the wire.
TYPE_INT32

int32, varint on the wire.

Negative numbers take 10 bytes. Use TYPE_SINT32 if negative values are likely.

TYPE_FIXED64uint64, exactly eight bytes on the wire.
TYPE_FIXED32uint32, exactly four bytes on the wire.
TYPE_BOOLbool, varint on the wire.
TYPE_STRINGUTF-8 text.
TYPE_GROUPTag-delimited message. Deprecated.
TYPE_MESSAGELength-delimited message.
TYPE_BYTESArbitrary byte array.
TYPE_UINT32uint32, varint on the wire
TYPE_ENUMEnum, varint on the wire.
TYPE_SFIXED32int32, exactly four bytes on the wire
TYPE_SFIXED64int64, exactly eight bytes on the wire
TYPE_SINT32int32, ZigZag-encoded varint on the wire
TYPE_SINT64int64, ZigZag-encoded varint on the wire
MAX_TYPEConstant useful for defining lookup tables indexed by Type.

enum FieldDescriptor::CppType {
  CPPTYPE_INT32 = = 1,
  CPPTYPE_INT64 = = 2,
  CPPTYPE_UINT32 = = 3,
  CPPTYPE_UINT64 = = 4,
  CPPTYPE_DOUBLE = = 5,
  CPPTYPE_FLOAT = = 6,
  CPPTYPE_BOOL = = 7,
  CPPTYPE_ENUM = = 8,
  CPPTYPE_STRING = = 9,
  CPPTYPE_MESSAGE = = 10,
  MAX_CPPTYPE = = 10
}

Specifies the C++ data type used to represent the field.

There is a fixed mapping from Type to CppType where each Type maps to exactly one CppType. 0 is reserved for errors.

CPPTYPE_INT32TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32.
CPPTYPE_INT64TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64.
CPPTYPE_UINT32TYPE_UINT32, TYPE_FIXED32.
CPPTYPE_UINT64TYPE_UINT64, TYPE_FIXED64.
CPPTYPE_DOUBLETYPE_DOUBLE.
CPPTYPE_FLOATTYPE_FLOAT.
CPPTYPE_BOOLTYPE_BOOL.
CPPTYPE_ENUMTYPE_ENUM.
CPPTYPE_STRINGTYPE_STRING, TYPE_BYTES.
CPPTYPE_MESSAGETYPE_MESSAGE, TYPE_GROUP.
MAX_CPPTYPEConstant useful for defining lookup tables indexed by CppType.

enum FieldDescriptor::Label {
  LABEL_OPTIONAL = = 1,
  LABEL_REQUIRED = = 2,
  LABEL_REPEATED = = 3,
  MAX_LABEL = = 3
}

Identifies whether the field is optional, required, or repeated.

0 is reserved for errors.

LABEL_OPTIONALoptional
LABEL_REQUIREDrequired
LABEL_REPEATEDrepeated
MAX_LABELConstant useful for defining lookup tables indexed by Label.

const int FieldDescriptor::kFirstReservedNumber = = 19000

First field number reserved for the protocol buffer library implementation.

Users may not declare fields that use reserved numbers.


const int FieldDescriptor::kLastReservedNumber = = 19999

Last field number reserved for the protocol buffer library implementation.

Users may not declare fields that use reserved numbers.


const std::string &
    FieldDescriptor::lowercase_name() const

Same as name() except converted to lower-case.

This (and especially the FindFieldByLowercaseName() method) can be useful when parsing formats which prefer to use lowercase naming style. (Although, technically field names should be lowercased anyway according to the protobuf style guide, so this only makes a difference when dealing with old .proto files which do not follow the guide.)


const std::string &
    FieldDescriptor::camelcase_name() const

Same as name() except converted to camel-case.

In this conversion, any time an underscore appears in the name, it is removed and the next letter is capitalized. Furthermore, the first letter of the name is lower-cased. Examples:

FooBar -> fooBar
+foo_bar -> fooBar
+fooBar -> fooBar

This (and especially the FindFieldByCamelcaseName() method) can be useful when parsing formats which prefer to use camel-case naming style.


bool FieldDescriptor::has_optional_keyword() const

Returns true if this field was syntactically written with "optional" in the .proto file.

Excludes singular proto3 fields that do not have a label.


bool FieldDescriptor::has_presence() const

Returns true if this field tracks presence, ie.

does the field distinguish between "unset" and "present with default value." This includes required, optional, and oneof fields. It excludes maps, repeated fields, and singular proto3 fields without "optional".

For fields where has_presence() == true, the return value of Reflection::HasField() is semantically meaningful.


int32 FieldDescriptor::default_value_int32() const

Get the field default value if cpp_type() == CPPTYPE_INT32.

If no explicit default was defined, the default is 0.


int64 FieldDescriptor::default_value_int64() const

Get the field default value if cpp_type() == CPPTYPE_INT64.

If no explicit default was defined, the default is 0.


uint32 FieldDescriptor::default_value_uint32() const

Get the field default value if cpp_type() == CPPTYPE_UINT32.

If no explicit default was defined, the default is 0.


uint64 FieldDescriptor::default_value_uint64() const

Get the field default value if cpp_type() == CPPTYPE_UINT64.

If no explicit default was defined, the default is 0.


float FieldDescriptor::default_value_float() const

Get the field default value if cpp_type() == CPPTYPE_FLOAT.

If no explicit default was defined, the default is 0.0.


double FieldDescriptor::default_value_double() const

Get the field default value if cpp_type() == CPPTYPE_DOUBLE.

If no explicit default was defined, the default is 0.0.


bool FieldDescriptor::default_value_bool() const

Get the field default value if cpp_type() == CPPTYPE_BOOL.

If no explicit default was defined, the default is false.


const EnumValueDescriptor *
    FieldDescriptor::default_value_enum() const

Get the field default value if cpp_type() == CPPTYPE_ENUM.

If no explicit default was defined, the default is the first value defined in the enum type (all enum types are required to have at least one value). This never returns nullptr.


const std::string &
    FieldDescriptor::default_value_string() const

Get the field default value if cpp_type() == CPPTYPE_STRING.

If no explicit default was defined, the default is the empty string.


const Descriptor *
    FieldDescriptor::containing_type() const

The Descriptor for the message of which this is a field.

For extensions, this is the extended type. Never nullptr.


const Descriptor *
    FieldDescriptor::extension_scope() const

An extension may be declared within the scope of another message.

If this field is an extension (is_extension() is true), then extension_scope() returns that message, or nullptr if the extension was declared at global scope. If this is not an extension, extension_scope() is undefined (may assert-fail).


const Descriptor *
    FieldDescriptor::message_type() const

If type is TYPE_MESSAGE or TYPE_GROUP, returns a descriptor for the message or the group type.

Otherwise, returns null.


const EnumDescriptor *
    FieldDescriptor::enum_type() const

If type is TYPE_ENUM, returns a descriptor for the enum.

Otherwise, returns null.


const FieldOptions &
    FieldDescriptor::options() const

Get the FieldOptions for this field.

This includes things listed in square brackets after the field definition. E.g., the field:

optional string text = 1 [[]ctype=CORD];

has the "ctype" option set. Allowed options are defined by FieldOptions in descriptor.proto, and any available extensions of that message.


const std::string &
    FieldDescriptor::PrintableNameForExtension() const

Returns full_name() except if the field is a MessageSet extension, in which case it returns the full_name() of the containing message type for backwards compatibility with proto1.

A MessageSet extension is defined as an optional message extension whose containing type has the message_set_wire_format option set. This should be true of extensions of google.protobuf.bridge.MessageSet; by convention, such extensions are named "message_set_extension".

The opposite operation (looking up an extension's FieldDescriptor given its printable name) can be accomplished with

message->file()->pool()->FindExtensionByPrintableName(message, name)

where the extension extends "message".


bool FieldDescriptor::GetSourceLocation(
        SourceLocation * out_location) const

Updates |*out_location| to the source location of the complete extent of this field declaration.

Returns false and leaves |*out_location| unchanged iff location information was not available.

class OneofDescriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Describes a oneof defined in a message type.

Members

typedef
OneofDescriptorProto Proto
const std::string &
name() const
Name of this oneof.
const std::string &
full_name() const
Fully-qualified name of the oneof.
int
index() const
Index of this oneof within the message's oneof array.
bool
is_synthetic() const
Returns whether this oneof was inserted by the compiler to wrap a proto3 optional field. more...
const FileDescriptor *
file() const
The .proto file in which this oneof was defined. Never nullptr.
const Descriptor *
containing_type() const
The Descriptor for the message containing this oneof.
int
field_count() const
The number of (non-extension) fields which are members of this oneof.
const FieldDescriptor *
field(int index) const
Get a member of this oneof, in the order in which they were declared in the .proto file. more...
const OneofOptions &
options() const
void
CopyTo(OneofDescriptorProto * proto) const
std::string
DebugString() const
std::string
DebugStringWithOptions(const DebugStringOptions & options) const

Source Location

bool
GetSourceLocation(SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of this oneof declaration. more...

bool OneofDescriptor::is_synthetic() const

Returns whether this oneof was inserted by the compiler to wrap a proto3 optional field.

If this returns true, code generators should not emit it.


const FieldDescriptor *
    OneofDescriptor::field(
        int index) const

Get a member of this oneof, in the order in which they were declared in the .proto file.

Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because fields_ is actually an array of pointers rather than the usual array of objects.

Does not include extensions.


bool OneofDescriptor::GetSourceLocation(
        SourceLocation * out_location) const

Updates |*out_location| to the source location of the complete extent of this oneof declaration.

Returns false and leaves |*out_location| unchanged iff location information was not available.

class EnumDescriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Describes an enum type defined in a .proto file.

To get the EnumDescriptor for a generated enum type, call TypeName_descriptor(). Use DescriptorPool to construct your own descriptors.

Members

typedef
EnumDescriptorProto Proto
const std::string &
name() const
The name of this enum type in the containing scope.
const std::string &
full_name() const
The fully-qualified name of the enum type, scope delimited by periods.
int
index() const
Index of this enum within the file or containing message's enum array.
const FileDescriptor *
file() const
The .proto file in which this enum type was defined. Never nullptr.
int
value_count() const
The number of values for this EnumDescriptor. more...
const EnumValueDescriptor *
value(int index) const
Gets a value by index, where 0 <= index < value_count(). more...
const EnumValueDescriptor *
FindValueByName(ConstStringParam name) const
Looks up a value by name. Returns nullptr if no such value exists.
const EnumValueDescriptor *
FindValueByNumber(int number) const
Looks up a value by number. more...
const Descriptor *
containing_type() const
If this enum type is nested in a message type, this is that message type. more...
const EnumOptions &
options() const
Get options for this enum type. more...
void
CopyTo(EnumDescriptorProto * proto) const
std::string
DebugString() const
std::string
DebugStringWithOptions(const DebugStringOptions & options) const
bool
is_placeholder() const
Returns true if this is a placeholder for an unknown enum. more...

Reserved fields

int
reserved_range_count() const
The number of reserved ranges in this message type.
const EnumDescriptor::ReservedRange *
reserved_range(int index) const
Gets an reserved range by index, where 0 <= index < reserved_range_count(). more...
bool
IsReservedNumber(int number) const
Returns true if the number is in one of the reserved ranges.
const EnumDescriptor::ReservedRange *
FindReservedRangeContainingNumber(int number) const
Returns nullptr if no reserved range contains the given number.
int
reserved_name_count() const
The number of reserved field names in this message type.
const std::string &
reserved_name(int index) const
Gets a reserved name by index, where 0 <= index < reserved_name_count(). more...
bool
IsReservedName(ConstStringParam name) const
Returns true if the field name is reserved.

Source Location

bool
GetSourceLocation(SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of this enum declaration. more...

int EnumDescriptor::value_count() const

The number of values for this EnumDescriptor.

Guaranteed to be greater than zero.


const EnumValueDescriptor *
    EnumDescriptor::value(
        int index) const

Gets a value by index, where 0 <= index < value_count().

These are returned in the order they were defined in the .proto file.


const EnumValueDescriptor *
    EnumDescriptor::FindValueByNumber(
        int number) const

Looks up a value by number.

Returns nullptr if no such value exists. If multiple values have this number, the first one defined is returned.


const Descriptor *
    EnumDescriptor::containing_type() const

If this enum type is nested in a message type, this is that message type.

Otherwise, nullptr.


const EnumOptions &
    EnumDescriptor::options() const

Get options for this enum type.

These are specified in the .proto file by placing lines like "option foo = 1234;" in the enum definition. Allowed options are defined by EnumOptions in descriptor.proto, and any available extensions of that message.


bool EnumDescriptor::is_placeholder() const

Returns true if this is a placeholder for an unknown enum.

This will only be the case if this descriptor comes from a DescriptorPool with AllowUnknownDependencies() set.


const EnumDescriptor::ReservedRange *
    EnumDescriptor::reserved_range(
        int index) const

Gets an reserved range by index, where 0 <= index < reserved_range_count().

These are returned in the order they were defined in the .proto file.


const std::string &
    EnumDescriptor::reserved_name(
        int index) const

Gets a reserved name by index, where 0 <= index < reserved_name_count().

Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because reserved_names_ is actually an array of pointers rather than the usual array of objects.


bool EnumDescriptor::GetSourceLocation(
        SourceLocation * out_location) const

Updates |*out_location| to the source location of the complete extent of this enum declaration.

Returns false and leaves |*out_location| unchanged iff location information was not available.

struct EnumDescriptor::ReservedRange

#include <google/protobuf/descriptor.h>
namespace google::protobuf

A range of reserved field numbers.

Members

int
start
inclusive
int
end
inclusive

class EnumValueDescriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Describes an individual enum constant of a particular type.

To get the EnumValueDescriptor for a given enum value, first get the EnumDescriptor for its type, then use EnumDescriptor::FindValueByName() or EnumDescriptor::FindValueByNumber(). Use DescriptorPool to construct your own descriptors.

Members

typedef
EnumValueDescriptorProto Proto
const std::string &
name() const
Name of this enum constant.
int
index() const
Index within the enums's Descriptor.
int
number() const
Numeric value of this enum constant.
const std::string &
full_name() const
The full_name of an enum value is a sibling symbol of the enum type. more...
const FileDescriptor *
file() const
The .proto file in which this value was defined. Never nullptr.
const EnumDescriptor *
type() const
The type of this value. Never nullptr.
const EnumValueOptions &
options() const
Get options for this enum value. more...
void
CopyTo(EnumValueDescriptorProto * proto) const
std::string
DebugString() const
std::string
DebugStringWithOptions(const DebugStringOptions & options) const

Source Location

bool
GetSourceLocation(SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of this enum value declaration. more...

const std::string &
    EnumValueDescriptor::full_name() const

The full_name of an enum value is a sibling symbol of the enum type.

e.g. the full name of FieldDescriptorProto::TYPE_INT32 is actually "google.protobuf.FieldDescriptorProto.TYPE_INT32", NOT "google.protobuf.FieldDescriptorProto.Type.TYPE_INT32". This is to conform with C++ scoping rules for enums.


const EnumValueOptions &
    EnumValueDescriptor::options() const

Get options for this enum value.

These are specified in the .proto file by adding text like "[[]foo = 1234]" after an enum value definition. Allowed options are defined by EnumValueOptions in descriptor.proto, and any available extensions of that message.


bool EnumValueDescriptor::GetSourceLocation(
        SourceLocation * out_location) const

Updates |*out_location| to the source location of the complete extent of this enum value declaration.

Returns false and leaves |*out_location| unchanged iff location information was not available.

class ServiceDescriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Describes an RPC service.

Use DescriptorPool to construct your own descriptors.

Members

typedef
ServiceDescriptorProto Proto
const std::string &
name() const
The name of the service, not including its containing scope.
const std::string &
full_name() const
The fully-qualified name of the service, scope delimited by periods.
int
index() const
Index of this service within the file's services array.
const FileDescriptor *
file() const
The .proto file in which this service was defined. Never nullptr.
const ServiceOptions &
options() const
Get options for this service type. more...
int
method_count() const
The number of methods this service defines.
const MethodDescriptor *
method(int index) const
Gets a MethodDescriptor by index, where 0 <= index < method_count(). more...
const MethodDescriptor *
FindMethodByName(ConstStringParam name) const
Look up a MethodDescriptor by name.
void
CopyTo(ServiceDescriptorProto * proto) const
std::string
DebugString() const
std::string
DebugStringWithOptions(const DebugStringOptions & options) const

Source Location

bool
GetSourceLocation(SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of this service declaration. more...

const ServiceOptions &
    ServiceDescriptor::options() const

Get options for this service type.

These are specified in the .proto file by placing lines like "option foo = 1234;" in the service definition. Allowed options are defined by ServiceOptions in descriptor.proto, and any available extensions of that message.


const MethodDescriptor *
    ServiceDescriptor::method(
        int index) const

Gets a MethodDescriptor by index, where 0 <= index < method_count().

These are returned in the order they were defined in the .proto file.


bool ServiceDescriptor::GetSourceLocation(
        SourceLocation * out_location) const

Updates |*out_location| to the source location of the complete extent of this service declaration.

Returns false and leaves |*out_location| unchanged iff location information was not available.

class MethodDescriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Describes an individual service method.

To obtain a MethodDescriptor given a service, first get its ServiceDescriptor, then call ServiceDescriptor::FindMethodByName(). Use DescriptorPool to construct your own descriptors.

Members

typedef
MethodDescriptorProto Proto
const std::string &
name() const
Name of this method, not including containing scope.
const std::string &
full_name() const
The fully-qualified name of the method, scope delimited by periods.
int
index() const
Index within the service's Descriptor.
const FileDescriptor *
file() const
The .proto file in which this method was defined. Never nullptr.
const ServiceDescriptor *
service() const
Gets the service to which this method belongs. Never nullptr.
const Descriptor *
input_type() const
Gets the type of protocol message which this method accepts as input.
const Descriptor *
output_type() const
Gets the type of protocol message which this message produces as output.
bool
client_streaming() const
Gets whether the client streams multiple requests.
bool
server_streaming() const
Gets whether the server streams multiple responses.
const MethodOptions &
options() const
Get options for this method. more...
void
CopyTo(MethodDescriptorProto * proto) const
std::string
DebugString() const
std::string
DebugStringWithOptions(const DebugStringOptions & options) const

Source Location

bool
GetSourceLocation(SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of this method declaration. more...

const MethodOptions &
    MethodDescriptor::options() const

Get options for this method.

These are specified in the .proto file by placing lines like "option foo = 1234;" in curly-braces after a method declaration. Allowed options are defined by MethodOptions in descriptor.proto, and any available extensions of that message.


bool MethodDescriptor::GetSourceLocation(
        SourceLocation * out_location) const

Updates |*out_location| to the source location of the complete extent of this method declaration.

Returns false and leaves |*out_location| unchanged iff location information was not available.

class FileDescriptor

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Describes a whole .proto file.

To get the FileDescriptor for a compiled-in file, get the descriptor for something defined in that file and call descriptor->file(). Use DescriptorPool to construct your own descriptors.

Members

enum
Syntax
Syntax of this file. more...
typedef
FileDescriptorProto Proto
const std::string &
name() const
The filename, relative to the source tree. more...
const std::string &
package() const
The package, e.g. "google.protobuf.compiler".
const DescriptorPool *
pool() const
The DescriptorPool in which this FileDescriptor and all its contents were allocated. more...
int
dependency_count() const
The number of files imported by this one.
const FileDescriptor *
dependency(int index) const
Gets an imported file by index, where 0 <= index < dependency_count(). more...
int
public_dependency_count() const
The number of files public imported by this one. more...
const FileDescriptor *
public_dependency(int index) const
Gets a public imported file by index, where 0 <= index < public_dependency_count(). more...
int
weak_dependency_count() const
The number of files that are imported for weak fields. more...
const FileDescriptor *
weak_dependency(int index) const
Gets a weak imported file by index, where 0 <= index < weak_dependency_count(). more...
int
message_type_count() const
Number of top-level message types defined in this file. more...
const Descriptor *
message_type(int index) const
Gets a top-level message type, where 0 <= index < message_type_count(). more...
int
enum_type_count() const
Number of top-level enum types defined in this file. more...
const EnumDescriptor *
enum_type(int index) const
Gets a top-level enum type, where 0 <= index < enum_type_count(). more...
int
service_count() const
Number of services defined in this file.
const ServiceDescriptor *
service(int index) const
Gets a service, where 0 <= index < service_count(). more...
int
extension_count() const
Number of extensions defined at file scope. more...
const FieldDescriptor *
extension(int index) const
Gets an extension's descriptor, where 0 <= index < extension_count(). more...
const FileOptions &
options() const
Get options for this file. more...
Syntax
syntax() const
const Descriptor *
FindMessageTypeByName(ConstStringParam name) const
Find a top-level message type by name (not full_name). more...
const EnumDescriptor *
FindEnumTypeByName(ConstStringParam name) const
Find a top-level enum type by name. Returns nullptr if not found.
const EnumValueDescriptor *
FindEnumValueByName(ConstStringParam name) const
Find an enum value defined in any top-level enum by name. more...
const ServiceDescriptor *
FindServiceByName(ConstStringParam name) const
Find a service definition by name. Returns nullptr if not found.
const FieldDescriptor *
FindExtensionByName(ConstStringParam name) const
Find a top-level extension definition by name. more...
const FieldDescriptor *
FindExtensionByLowercaseName(ConstStringParam name) const
Similar to FindExtensionByName(), but searches by lowercased-name. more...
const FieldDescriptor *
FindExtensionByCamelcaseName(ConstStringParam name) const
Similar to FindExtensionByName(), but searches by camelcased-name. more...
void
CopyTo(FileDescriptorProto * proto) const
void
CopySourceCodeInfoTo(FileDescriptorProto * proto) const
Write the source code information of this FileDescriptor into the given FileDescriptorProto. more...
void
CopyJsonNameTo(FileDescriptorProto * proto) const
Fill the json_name field of FieldDescriptorProto for all fields. more...
std::string
DebugString() const
std::string
DebugStringWithOptions(const DebugStringOptions & options) const
bool
is_placeholder() const
Returns true if this is a placeholder for an unknown file. more...
bool
GetSourceLocation(SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of this file declaration (namely, the empty path).
bool
GetSourceLocation(const std::vector< int > & path, SourceLocation * out_location) const
Updates |*out_location| to the source location of the complete extent of the declaration or declaration-part denoted by |path|. more...
static const char *
SyntaxName(Syntax syntax)

enum FileDescriptor::Syntax {
  SYNTAX_UNKNOWN = = 0,
  SYNTAX_PROTO2 = = 2,
  SYNTAX_PROTO3 = = 3
}

Syntax of this file.

SYNTAX_UNKNOWN
SYNTAX_PROTO2
SYNTAX_PROTO3

const std::string &
    FileDescriptor::name() const

The filename, relative to the source tree.

e.g. "foo/bar/baz.proto"


const DescriptorPool *
    FileDescriptor::pool() const

The DescriptorPool in which this FileDescriptor and all its contents were allocated.

Never nullptr.


const FileDescriptor *
    FileDescriptor::dependency(
        int index) const

Gets an imported file by index, where 0 <= index < dependency_count().

These are returned in the order they were defined in the .proto file.


int FileDescriptor::public_dependency_count() const

The number of files public imported by this one.

The public dependency list is a subset of the dependency list.


const FileDescriptor *
    FileDescriptor::public_dependency(
        int index) const

Gets a public imported file by index, where 0 <= index < public_dependency_count().

These are returned in the order they were defined in the .proto file.


int FileDescriptor::weak_dependency_count() const

The number of files that are imported for weak fields.

The weak dependency list is a subset of the dependency list.


const FileDescriptor *
    FileDescriptor::weak_dependency(
        int index) const

Gets a weak imported file by index, where 0 <= index < weak_dependency_count().

These are returned in the order they were defined in the .proto file.


int FileDescriptor::message_type_count() const

Number of top-level message types defined in this file.

(This does not include nested types.)


const Descriptor *
    FileDescriptor::message_type(
        int index) const

Gets a top-level message type, where 0 <= index < message_type_count().

These are returned in the order they were defined in the .proto file.


int FileDescriptor::enum_type_count() const

Number of top-level enum types defined in this file.

(This does not include nested types.)


const EnumDescriptor *
    FileDescriptor::enum_type(
        int index) const

Gets a top-level enum type, where 0 <= index < enum_type_count().

These are returned in the order they were defined in the .proto file.


const ServiceDescriptor *
    FileDescriptor::service(
        int index) const

Gets a service, where 0 <= index < service_count().

These are returned in the order they were defined in the .proto file.


int FileDescriptor::extension_count() const

Number of extensions defined at file scope.

(This does not include extensions nested within message types.)


const FieldDescriptor *
    FileDescriptor::extension(
        int index) const

Gets an extension's descriptor, where 0 <= index < extension_count().

These are returned in the order they were defined in the .proto file.


const FileOptions &
    FileDescriptor::options() const

Get options for this file.

These are specified in the .proto file by placing lines like "option foo = 1234;" at the top level, outside of any other definitions. Allowed options are defined by FileOptions in descriptor.proto, and any available extensions of that message.


const Descriptor *
    FileDescriptor::FindMessageTypeByName(
        ConstStringParam name) const

Find a top-level message type by name (not full_name).

Returns nullptr if not found.


const EnumValueDescriptor *
    FileDescriptor::FindEnumValueByName(
        ConstStringParam name) const

Find an enum value defined in any top-level enum by name.

Returns nullptr if not found.


const FieldDescriptor *
    FileDescriptor::FindExtensionByName(
        ConstStringParam name) const

Find a top-level extension definition by name.

Returns nullptr if not found.


const FieldDescriptor *
    FileDescriptor::FindExtensionByLowercaseName(
        ConstStringParam name) const

Similar to FindExtensionByName(), but searches by lowercased-name.

See Descriptor::FindFieldByLowercaseName().


const FieldDescriptor *
    FileDescriptor::FindExtensionByCamelcaseName(
        ConstStringParam name) const

Similar to FindExtensionByName(), but searches by camelcased-name.

See Descriptor::FindFieldByCamelcaseName().


void FileDescriptor::CopyTo(
        FileDescriptorProto * proto) const

See Descriptor::CopyTo().

Notes:

  • This method does NOT copy source code information since it is relatively large and rarely needed. See CopySourceCodeInfoTo() below.

void FileDescriptor::CopySourceCodeInfoTo(
        FileDescriptorProto * proto) const

Write the source code information of this FileDescriptor into the given FileDescriptorProto.

See CopyTo() above.


void FileDescriptor::CopyJsonNameTo(
        FileDescriptorProto * proto) const

Fill the json_name field of FieldDescriptorProto for all fields.

Can only be called after CopyTo().


bool FileDescriptor::is_placeholder() const

Returns true if this is a placeholder for an unknown file.

This will only be the case if this descriptor comes from a DescriptorPool with AllowUnknownDependencies() set.


bool FileDescriptor::GetSourceLocation(
        const std::vector< int > & path,
        SourceLocation * out_location) const

Updates |*out_location| to the source location of the complete extent of the declaration or declaration-part denoted by |path|.

Returns false and leaves |*out_location| unchanged iff location information was not available. (See SourceCodeInfo for description of path encoding.)

class DescriptorPool

#include <google/protobuf/descriptor.h>
namespace google::protobuf

Used to construct descriptors.

Normally you won't want to build your own descriptors. Message classes constructed by the protocol compiler will provide them for you. However, if you are implementing Message on your own, or if you are writing a program which can operate on totally arbitrary types and needs to load them from some sort of database, you might need to.

Since Descriptors are composed of a whole lot of cross-linked bits of data that would be a pain to put together manually, the DescriptorPool class is provided to make the process easier. It can take a FileDescriptorProto (defined in descriptor.proto), validate it, and convert it to a set of nicely cross-linked Descriptors.

DescriptorPool also helps with memory management. Descriptors are composed of many objects containing static data and pointers to each other. In all likelihood, when it comes time to delete this data, you'll want to delete it all at once. In fact, it is not uncommon to have a whole pool of descriptors all cross-linked with each other which you wish to delete all at once. This class represents such a pool, and handles the memory management for you.

You can also search for descriptors within a DescriptorPool by name, and extensions by number.

Members

DescriptorPool()
Create a normal, empty DescriptorPool.
explicit
DescriptorPool(DescriptorDatabase * fallback_database, ErrorCollector * error_collector = nullptr)
~DescriptorPool()
const FileDescriptor *
FindFileByName(ConstStringParam name) const
Find a FileDescriptor in the pool by file name. more...
const FileDescriptor *
FindFileContainingSymbol(ConstStringParam symbol_name) const
Find the FileDescriptor in the pool which defines the given symbol. more...
static const DescriptorPool *
generated_pool()
Get a pointer to the generated pool. more...

Looking up descriptors

These find descriptors by fully-qualified name. These will find both top-level descriptors and nested descriptors. They return nullptr if not found.
const Descriptor *
FindMessageTypeByName(ConstStringParam name) const
const FieldDescriptor *
FindFieldByName(ConstStringParam name) const
const FieldDescriptor *
FindExtensionByName(ConstStringParam name) const
const OneofDescriptor *
FindOneofByName(ConstStringParam name) const
const EnumDescriptor *
FindEnumTypeByName(ConstStringParam name) const
const EnumValueDescriptor *
FindEnumValueByName(ConstStringParam name) const
const ServiceDescriptor *
FindServiceByName(ConstStringParam name) const
const MethodDescriptor *
FindMethodByName(ConstStringParam name) const
const FieldDescriptor *
FindExtensionByNumber(const Descriptor * extendee, int number) const
Finds an extension of the given type by number. more...
const FieldDescriptor *
FindExtensionByPrintableName(const Descriptor * extendee, ConstStringParam printable_name) const
Finds an extension of the given type by its printable name. more...
void
FindAllExtensions(const Descriptor * extendee, std::vector< const FieldDescriptor * > * out) const
Finds extensions of extendee. more...

Building descriptors

const FileDescriptor *
BuildFile(const FileDescriptorProto & proto)
Convert the FileDescriptorProto to real descriptors and place them in this DescriptorPool. more...
const FileDescriptor *
BuildFileCollectingErrors(const FileDescriptorProto & proto, ErrorCollector * error_collector)
Same as BuildFile() except errors are sent to the given ErrorCollector.
void
AllowUnknownDependencies()
By default, it is an error if a FileDescriptorProto contains references to types or other files that are not found in the DescriptorPool (or its backing DescriptorDatabase, if any). more...
void
EnforceWeakDependencies(bool enforce)
By default, weak imports are allowed to be missing, in which case we will use a placeholder for the dependency and convert the field to be an Empty message field. more...

Internal stuff

These methods MUST NOT be called from outside the proto2 library.

These methods may contain hidden pitfalls and may be removed in a future library version.

explicit
DescriptorPool(const DescriptorPool * underlay)
Create a DescriptorPool which is overlaid on top of some other pool. more...
void
DisallowEnforceUtf8()
Disallow [[]enforce_utf8 = false] in .proto files.
void
InternalDontEnforceDependencies()
For internal use only: Changes the behavior of BuildFile() such that it allows the file to make reference to message types declared in other files which it did not officially declare as dependencies.
void
InternalSetLazilyBuildDependencies()
For internal use only: Enables lazy building of dependencies of a file. more...
void
internal_set_underlay(const DescriptorPool * underlay)
For internal use only.
bool
InternalIsFileLoaded(ConstStringParam filename) const
For internal (unit test) use only: Returns true if a FileDescriptor has been constructed for the given file, false otherwise. more...
void
AddUnusedImportTrackFile(ConstStringParam file_name, bool is_error = false)
Add a file to unused_import_track_files_. more...
void
ClearUnusedImportTrackFiles()
static void
InternalAddGeneratedFile(const void * encoded_file_descriptor, int size)
Called by generated classes at init time to add their descriptors to generated_pool. more...
static DescriptorPool *
internal_generated_pool()
For internal use only: Gets a non-const pointer to the generated pool. more...
static DescriptorDatabase *
internal_generated_database()
For internal use only: Gets a non-const pointer to the generated descriptor database. more...

const FileDescriptor *
    DescriptorPool::FindFileByName(
        ConstStringParam name) const

Find a FileDescriptor in the pool by file name.

Returns nullptr if not found.


const FileDescriptor *
    DescriptorPool::FindFileContainingSymbol(
        ConstStringParam symbol_name) const

Find the FileDescriptor in the pool which defines the given symbol.

If any of the Find*ByName() methods below would succeed, then this is equivalent to calling that method and calling the result's file() method. Otherwise this returns nullptr.


static const DescriptorPool *
    DescriptorPool::generated_pool()

Get a pointer to the generated pool.

Generated protocol message classes which are compiled into the binary will allocate their descriptors in this pool. Do not add your own descriptors to this pool.


const FieldDescriptor *
    DescriptorPool::FindExtensionByNumber(
        const Descriptor * extendee,
        int number) const

Finds an extension of the given type by number.

The extendee must be a member of this DescriptorPool or one of its underlays.


const FieldDescriptor *
    DescriptorPool::FindExtensionByPrintableName(
        const Descriptor * extendee,
        ConstStringParam printable_name) const

Finds an extension of the given type by its printable name.

See comments above PrintableNameForExtension() for the definition of "printable name". The extendee must be a member of this DescriptorPool or one of its underlays. Returns nullptr if there is no known message extension with the given printable name.


void DescriptorPool::FindAllExtensions(
        const Descriptor * extendee,
        std::vector< const FieldDescriptor * > * out) const

Finds extensions of extendee.

The extensions will be appended to out in an undefined order. Only extensions defined directly in this DescriptorPool or one of its underlays are guaranteed to be found: extensions defined in the fallback database might not be found depending on the database implementation.


const FileDescriptor *
    DescriptorPool::BuildFile(
        const FileDescriptorProto & proto)

Convert the FileDescriptorProto to real descriptors and place them in this DescriptorPool.

All dependencies of the file must already be in the pool. Returns the resulting FileDescriptor, or nullptr if there were problems with the input (e.g. the message was invalid, or dependencies were missing). Details about the errors are written to GOOGLE_LOG(ERROR).


void DescriptorPool::AllowUnknownDependencies()

By default, it is an error if a FileDescriptorProto contains references to types or other files that are not found in the DescriptorPool (or its backing DescriptorDatabase, if any).

If you call AllowUnknownDependencies(), however, then unknown types and files will be replaced by placeholder descriptors (which can be identified by the is_placeholder() method). This can allow you to perform some useful operations with a .proto file even if you do not have access to other .proto files on which it depends. However, some heuristics must be used to fill in the gaps in information, and these can lead to descriptors which are inaccurate. For example, the DescriptorPool may be forced to guess whether an unknown type is a message or an enum, as well as what package it resides in. Furthermore, placeholder types will not be discoverable via FindMessageTypeByName() and similar methods, which could confuse some descriptor-based algorithms. Generally, the results of this option should be handled with extreme care.


void DescriptorPool::EnforceWeakDependencies(
        bool enforce)

By default, weak imports are allowed to be missing, in which case we will use a placeholder for the dependency and convert the field to be an Empty message field.

If you call EnforceWeakDependencies(true), however, the DescriptorPool will report a import not found error.


explicit DescriptorPool::DescriptorPool(
        const DescriptorPool * underlay)

Create a DescriptorPool which is overlaid on top of some other pool.

If you search for a descriptor in the overlay and it is not found, the underlay will be searched as a backup. If the underlay has its own underlay, that will be searched next, and so on. This also means that files built in the overlay will be cross-linked with the underlay's descriptors if necessary. The underlay remains property of the caller; it must remain valid for the lifetime of the newly-constructed pool.

Example: Say you want to parse a .proto file at runtime in order to use its type with a DynamicMessage. Say this .proto file has dependencies, but you know that all the dependencies will be things that are already compiled into the binary. For ease of use, you'd like to load the types right out of generated_pool() rather than have to parse redundant copies of all these .protos and runtime. But, you don't want to add the parsed types directly into generated_pool(): this is not allowed, and would be bad design anyway. So, instead, you could use generated_pool() as an underlay for a new DescriptorPool in which you add only the new file.

WARNING: Use of underlays can lead to many subtle gotchas. Instead, try to formulate what you want to do in terms of DescriptorDatabases.


void DescriptorPool::InternalSetLazilyBuildDependencies()

For internal use only: Enables lazy building of dependencies of a file.

Delay the building of dependencies of a file descriptor until absolutely necessary, like when message_type() is called on a field that is defined in that dependency's file. This will cause functional issues if a proto or one of its dependencies has errors. Should only be enabled for the generated_pool_ (because no descriptor build errors are guaranteed by the compilation generation process), testing, or if a lack of descriptor build errors can be guaranteed for a pool.


bool DescriptorPool::InternalIsFileLoaded(
        ConstStringParam filename) const

For internal (unit test) use only: Returns true if a FileDescriptor has been constructed for the given file, false otherwise.

Useful for testing lazy descriptor initialization behavior.


void DescriptorPool::AddUnusedImportTrackFile(
        ConstStringParam file_name,
        bool is_error = false)

Add a file to unused_import_track_files_.

DescriptorBuilder will log warnings or errors for those files if there is any unused import.


static void DescriptorPool::InternalAddGeneratedFile(
        const void * encoded_file_descriptor,
        int size)

Called by generated classes at init time to add their descriptors to generated_pool.

Do NOT call this in your own code! filename must be a permanent string (e.g. a string literal).


static DescriptorPool * DescriptorPool::internal_generated_pool()

For internal use only: Gets a non-const pointer to the generated pool.

This is called at static-initialization time only, so thread-safety is not a concern. If both an underlay and a fallback database are present, the underlay takes precedence.


static DescriptorDatabase *
    DescriptorPool::internal_generated_database()

For internal use only: Gets a non-const pointer to the generated descriptor database.

Only used for testing.

class DescriptorPool::ErrorCollector

#include <google/protobuf/descriptor.h>
namespace google::protobuf

When converting a FileDescriptorProto to a FileDescriptor, various errors might be detected in the input.

The caller may handle these programmatically by implementing an ErrorCollector.

Members

enum
ErrorLocation
These constants specify what exact part of the construct is broken. more...
ErrorCollector()
virtual
~ErrorCollector()
virtual void
AddError(const std::string & filename, const std::string & element_name, const Message * descriptor, ErrorLocation location, const std::string & message) = 0
Reports an error in the FileDescriptorProto. more...
virtual void
AddWarning(const std::string & , const std::string & , const Message * , ErrorLocation , const std::string & )
Reports a warning in the FileDescriptorProto. more...

enum ErrorCollector::ErrorLocation {
  NAME,
  NUMBER,
  TYPE,
  EXTENDEE,
  DEFAULT_VALUE,
  INPUT_TYPE,
  OUTPUT_TYPE,
  OPTION_NAME,
  OPTION_VALUE,
  IMPORT,
  OTHER
}

These constants specify what exact part of the construct is broken.

This is useful e.g. for mapping the error back to an exact location in a .proto file.

NAMEthe symbol name, or the package name for files
NUMBERfield or extension range number
TYPEfield type
EXTENDEEfield extendee
DEFAULT_VALUEfield default value
INPUT_TYPEmethod input type
OUTPUT_TYPEmethod output type
OPTION_NAMEname in assignment
OPTION_VALUEvalue in option assignment
IMPORTimport error
OTHERsome other problem

virtual void ErrorCollector::AddError(
        const std::string & filename,
        const std::string & element_name,
        const Message * descriptor,
        ErrorLocation location,
        const std::string & message) = 0

Reports an error in the FileDescriptorProto.

Use this function if the problem occurred should interrupt building the FileDescriptorProto.


virtual void ErrorCollector::AddWarning(
        const std::string & ,
        const std::string & ,
        const Message * ,
        ErrorLocation ,
        const std::string & )

Reports a warning in the FileDescriptorProto.

Use this function if the problem occurred should NOT interrupt building the FileDescriptorProto.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.descriptor_database/index.html b/reference/cpp/api-docs/google.protobuf.descriptor_database/index.html new file mode 100644 index 000000000..776b93ad1 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.descriptor_database/index.html @@ -0,0 +1,8 @@ +descriptor_database.h | Protocol Buffers Documentation +

descriptor_database.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/descriptor_database.h>
namespace google::protobuf

Interface for manipulating databases of descriptors.

Classes in this file

Abstract interface for a database of descriptors.
A DescriptorDatabase into which you can insert files manually.
Very similar to SimpleDescriptorDatabase, but stores all the descriptors as raw bytes and generally tries to use as little memory as possible.
A DescriptorDatabase that fetches files from a given pool.
A DescriptorDatabase that wraps two or more others.

class DescriptorDatabase

#include <google/protobuf/descriptor_database.h>
namespace google::protobuf

Abstract interface for a database of descriptors.

This is useful if you want to create a DescriptorPool which loads descriptors on-demand from some sort of large database. If the database is large, it may be inefficient to enumerate every .proto file inside it calling DescriptorPool::BuildFile() for each one. Instead, a DescriptorPool can be created which wraps a DescriptorDatabase and only builds particular descriptors when they are needed.

Known subclasses:

Members

DescriptorDatabase()
virtual
~DescriptorDatabase()
virtual bool
FindFileByName(const std::string & filename, FileDescriptorProto * output) = 0
Find a file by file name. more...
virtual bool
FindFileContainingSymbol(const std::string & symbol_name, FileDescriptorProto * output) = 0
Find the file that declares the given fully-qualified symbol name. more...
virtual bool
FindFileContainingExtension(const std::string & containing_type, int field_number, FileDescriptorProto * output) = 0
Find the file which defines an extension extending the given message type with the given field number. more...
virtual bool
FindAllExtensionNumbers(const std::string & , std::vector< int > * )
Finds the tag numbers used by all known extensions of extendee_type, and appends them to output in an undefined order. more...
virtual bool
FindAllFileNames(std::vector< std::string > * )
Finds the file names and appends them to the output in an undefined order. more...
bool
FindAllPackageNames(std::vector< std::string > * output)
Finds the package names and appends them to the output in an undefined order. more...
bool
FindAllMessageNames(std::vector< std::string > * output)
Finds the message names and appends them to the output in an undefined order. more...

virtual bool DescriptorDatabase::FindFileByName(
        const std::string & filename,
        FileDescriptorProto * output) = 0

Find a file by file name.

Fills in in *output and returns true if found. Otherwise, returns false, leaving the contents of *output undefined.


virtual bool DescriptorDatabase::FindFileContainingSymbol(
        const std::string & symbol_name,
        FileDescriptorProto * output) = 0

Find the file that declares the given fully-qualified symbol name.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined.


virtual bool DescriptorDatabase::FindFileContainingExtension(
        const std::string & containing_type,
        int field_number,
        FileDescriptorProto * output) = 0

Find the file which defines an extension extending the given message type with the given field number.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined. containing_type must be a fully-qualified type name.


virtual bool DescriptorDatabase::FindAllExtensionNumbers(
        const std::string & ,
        std::vector< int > * )

Finds the tag numbers used by all known extensions of extendee_type, and appends them to output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all extensions, and it's not guaranteed that FindFileContainingExtension will return true on all of the found numbers. Returns true if the search was successful, otherwise returns false and leaves output unchanged.

This method has a default implementation that always returns false.


virtual bool DescriptorDatabase::FindAllFileNames(
        std::vector< std::string > * )

Finds the file names and appends them to the output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all files. Returns true if the database supports searching all file names, otherwise returns false and leaves output unchanged.

This method has a default implementation that always returns false.


bool DescriptorDatabase::FindAllPackageNames(
        std::vector< std::string > * output)

Finds the package names and appends them to the output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all packages. Returns true if the database supports searching all package names, otherwise returns false and leaves output unchanged.


bool DescriptorDatabase::FindAllMessageNames(
        std::vector< std::string > * output)

Finds the message names and appends them to the output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all messages. Returns true if the database supports searching all message names, otherwise returns false and leaves output unchanged.

class SimpleDescriptorDatabase: public DescriptorDatabase

#include <google/protobuf/descriptor_database.h>
namespace google::protobuf

A DescriptorDatabase into which you can insert files manually.

FindFileContainingSymbol() is fully-implemented. When you add a file, its symbols will be indexed for this purpose. Note that the implementation may return false positives, but only if it isn't possible for the symbol to be defined in any other file. In particular, if a file defines a symbol "Foo", then searching for "Foo.[anything]" will match that file. This way, the database does not need to aggressively index all children of a symbol.

FindFileContainingExtension() is mostly-implemented. It works if and only if the original FieldDescriptorProto defining the extension has a fully-qualified type name in its "extendee" field (i.e. starts with a '.'). If the extendee is a relative name, SimpleDescriptorDatabase will not attempt to resolve the type, so it will not know what type the extension is extending. Therefore, calling FindFileContainingExtension() with the extension's containing type will never actually find that extension. Note that this is an unlikely problem, as all FileDescriptorProtos created by the protocol compiler (as well as ones created by calling FileDescriptor::CopyTo()) will always use fully-qualified names for all types. You only need to worry if you are constructing FileDescriptorProtos yourself, or are calling compiler::Parser directly.

Members

SimpleDescriptorDatabase()
~SimpleDescriptorDatabase()
bool
Add(const FileDescriptorProto & file)
Adds the FileDescriptorProto to the database, making a copy. more...
bool
AddAndOwn(const FileDescriptorProto * file)
Adds the FileDescriptorProto to the database and takes ownership of it.

implements DescriptorDatabase

virtual bool
FindFileByName(const std::string & filename, FileDescriptorProto * output)
Find a file by file name. more...
virtual bool
FindFileContainingSymbol(const std::string & symbol_name, FileDescriptorProto * output)
Find the file that declares the given fully-qualified symbol name. more...
virtual bool
FindFileContainingExtension(const std::string & containing_type, int field_number, FileDescriptorProto * output)
Find the file which defines an extension extending the given message type with the given field number. more...
virtual bool
FindAllExtensionNumbers(const std::string & , std::vector< int > * )
Finds the tag numbers used by all known extensions of extendee_type, and appends them to output in an undefined order. more...
virtual bool
FindAllFileNames(std::vector< std::string > * )
Finds the file names and appends them to the output in an undefined order. more...

bool SimpleDescriptorDatabase::Add(
        const FileDescriptorProto & file)

Adds the FileDescriptorProto to the database, making a copy.

The object can be deleted after Add() returns. Returns false if the file conflicted with a file already in the database, in which case an error will have been written to GOOGLE_LOG(ERROR).


virtual bool SimpleDescriptorDatabase::FindFileByName(
        const std::string & filename,
        FileDescriptorProto * output)

Find a file by file name.

Fills in in *output and returns true if found. Otherwise, returns false, leaving the contents of *output undefined.


virtual bool SimpleDescriptorDatabase::FindFileContainingSymbol(
        const std::string & symbol_name,
        FileDescriptorProto * output)

Find the file that declares the given fully-qualified symbol name.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined.


virtual bool SimpleDescriptorDatabase::FindFileContainingExtension(
        const std::string & containing_type,
        int field_number,
        FileDescriptorProto * output)

Find the file which defines an extension extending the given message type with the given field number.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined. containing_type must be a fully-qualified type name.


virtual bool SimpleDescriptorDatabase::FindAllExtensionNumbers(
        const std::string & ,
        std::vector< int > * )

Finds the tag numbers used by all known extensions of extendee_type, and appends them to output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all extensions, and it's not guaranteed that FindFileContainingExtension will return true on all of the found numbers. Returns true if the search was successful, otherwise returns false and leaves output unchanged.

This method has a default implementation that always returns false.


virtual bool SimpleDescriptorDatabase::FindAllFileNames(
        std::vector< std::string > * )

Finds the file names and appends them to the output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all files. Returns true if the database supports searching all file names, otherwise returns false and leaves output unchanged.

This method has a default implementation that always returns false.

class EncodedDescriptorDatabase: public DescriptorDatabase

#include <google/protobuf/descriptor_database.h>
namespace google::protobuf

Very similar to SimpleDescriptorDatabase, but stores all the descriptors as raw bytes and generally tries to use as little memory as possible.

The same caveats regarding FindFileContainingExtension() apply as with SimpleDescriptorDatabase.

Members

EncodedDescriptorDatabase()
~EncodedDescriptorDatabase()
bool
Add(const void * encoded_file_descriptor, int size)
Adds the FileDescriptorProto to the database. more...
bool
AddCopy(const void * encoded_file_descriptor, int size)
Like Add(), but makes a copy of the data, so that the caller does not need to keep it around.
bool
FindNameOfFileContainingSymbol(const std::string & symbol_name, std::string * output)
Like FindFileContainingSymbol but returns only the name of the file.

implements DescriptorDatabase

virtual bool
FindFileByName(const std::string & filename, FileDescriptorProto * output)
Find a file by file name. more...
virtual bool
FindFileContainingSymbol(const std::string & symbol_name, FileDescriptorProto * output)
Find the file that declares the given fully-qualified symbol name. more...
virtual bool
FindFileContainingExtension(const std::string & containing_type, int field_number, FileDescriptorProto * output)
Find the file which defines an extension extending the given message type with the given field number. more...
virtual bool
FindAllExtensionNumbers(const std::string & , std::vector< int > * )
Finds the tag numbers used by all known extensions of extendee_type, and appends them to output in an undefined order. more...
virtual bool
FindAllFileNames(std::vector< std::string > * )
Finds the file names and appends them to the output in an undefined order. more...

bool EncodedDescriptorDatabase::Add(
        const void * encoded_file_descriptor,
        int size)

Adds the FileDescriptorProto to the database.

The descriptor is provided in encoded form. The database does not make a copy of the bytes, nor does it take ownership; it's up to the caller to make sure the bytes remain valid for the life of the database. Returns false and logs an error if the bytes are not a valid FileDescriptorProto or if the file conflicted with a file already in the database.


virtual bool EncodedDescriptorDatabase::FindFileByName(
        const std::string & filename,
        FileDescriptorProto * output)

Find a file by file name.

Fills in in *output and returns true if found. Otherwise, returns false, leaving the contents of *output undefined.


virtual bool EncodedDescriptorDatabase::FindFileContainingSymbol(
        const std::string & symbol_name,
        FileDescriptorProto * output)

Find the file that declares the given fully-qualified symbol name.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined.


virtual bool EncodedDescriptorDatabase::FindFileContainingExtension(
        const std::string & containing_type,
        int field_number,
        FileDescriptorProto * output)

Find the file which defines an extension extending the given message type with the given field number.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined. containing_type must be a fully-qualified type name.


virtual bool EncodedDescriptorDatabase::FindAllExtensionNumbers(
        const std::string & ,
        std::vector< int > * )

Finds the tag numbers used by all known extensions of extendee_type, and appends them to output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all extensions, and it's not guaranteed that FindFileContainingExtension will return true on all of the found numbers. Returns true if the search was successful, otherwise returns false and leaves output unchanged.

This method has a default implementation that always returns false.


virtual bool EncodedDescriptorDatabase::FindAllFileNames(
        std::vector< std::string > * )

Finds the file names and appends them to the output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all files. Returns true if the database supports searching all file names, otherwise returns false and leaves output unchanged.

This method has a default implementation that always returns false.

class DescriptorPoolDatabase: public DescriptorDatabase

#include <google/protobuf/descriptor_database.h>
namespace google::protobuf

A DescriptorDatabase that fetches files from a given pool.

Members

explicit
DescriptorPoolDatabase(const DescriptorPool & pool)
~DescriptorPoolDatabase()

implements DescriptorDatabase

virtual bool
FindFileByName(const std::string & filename, FileDescriptorProto * output)
Find a file by file name. more...
virtual bool
FindFileContainingSymbol(const std::string & symbol_name, FileDescriptorProto * output)
Find the file that declares the given fully-qualified symbol name. more...
virtual bool
FindFileContainingExtension(const std::string & containing_type, int field_number, FileDescriptorProto * output)
Find the file which defines an extension extending the given message type with the given field number. more...
virtual bool
FindAllExtensionNumbers(const std::string & , std::vector< int > * )
Finds the tag numbers used by all known extensions of extendee_type, and appends them to output in an undefined order. more...

virtual bool DescriptorPoolDatabase::FindFileByName(
        const std::string & filename,
        FileDescriptorProto * output)

Find a file by file name.

Fills in in *output and returns true if found. Otherwise, returns false, leaving the contents of *output undefined.


virtual bool DescriptorPoolDatabase::FindFileContainingSymbol(
        const std::string & symbol_name,
        FileDescriptorProto * output)

Find the file that declares the given fully-qualified symbol name.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined.


virtual bool DescriptorPoolDatabase::FindFileContainingExtension(
        const std::string & containing_type,
        int field_number,
        FileDescriptorProto * output)

Find the file which defines an extension extending the given message type with the given field number.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined. containing_type must be a fully-qualified type name.


virtual bool DescriptorPoolDatabase::FindAllExtensionNumbers(
        const std::string & ,
        std::vector< int > * )

Finds the tag numbers used by all known extensions of extendee_type, and appends them to output in an undefined order.

This method is best-effort: it's not guaranteed that the database will find all extensions, and it's not guaranteed that FindFileContainingExtension will return true on all of the found numbers. Returns true if the search was successful, otherwise returns false and leaves output unchanged.

This method has a default implementation that always returns false.

class MergedDescriptorDatabase: public DescriptorDatabase

#include <google/protobuf/descriptor_database.h>
namespace google::protobuf

A DescriptorDatabase that wraps two or more others.

It first searches the first database and, if that fails, tries the second, and so on.

Members

MergedDescriptorDatabase(DescriptorDatabase * source1, DescriptorDatabase * source2)
Merge just two databases. The sources remain property of the caller.
explicit
MergedDescriptorDatabase(const std::vector< DescriptorDatabase * > & sources)
Merge more than two databases. more...
~MergedDescriptorDatabase()

implements DescriptorDatabase

virtual bool
FindFileByName(const std::string & filename, FileDescriptorProto * output)
Find a file by file name. more...
virtual bool
FindFileContainingSymbol(const std::string & symbol_name, FileDescriptorProto * output)
Find the file that declares the given fully-qualified symbol name. more...
virtual bool
FindFileContainingExtension(const std::string & containing_type, int field_number, FileDescriptorProto * output)
Find the file which defines an extension extending the given message type with the given field number. more...
virtual bool
FindAllExtensionNumbers(const std::string & extendee_type, std::vector< int > * output)
Merges the results of calling all databases. more...

explicit MergedDescriptorDatabase::MergedDescriptorDatabase(
        const std::vector< DescriptorDatabase * > & sources)

Merge more than two databases.

The sources remain property of the caller. The vector may be deleted after the constructor returns but the DescriptorDatabases need to stick around.


virtual bool MergedDescriptorDatabase::FindFileByName(
        const std::string & filename,
        FileDescriptorProto * output)

Find a file by file name.

Fills in in *output and returns true if found. Otherwise, returns false, leaving the contents of *output undefined.


virtual bool MergedDescriptorDatabase::FindFileContainingSymbol(
        const std::string & symbol_name,
        FileDescriptorProto * output)

Find the file that declares the given fully-qualified symbol name.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined.


virtual bool MergedDescriptorDatabase::FindFileContainingExtension(
        const std::string & containing_type,
        int field_number,
        FileDescriptorProto * output)

Find the file which defines an extension extending the given message type with the given field number.

If found, fills in *output and returns true, otherwise returns false and leaves *output undefined. containing_type must be a fully-qualified type name.


virtual bool MergedDescriptorDatabase::FindAllExtensionNumbers(
        const std::string & extendee_type,
        std::vector< int > * output)

Merges the results of calling all databases.

Returns true iff any of the databases returned true.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.dynamic_message/index.html b/reference/cpp/api-docs/google.protobuf.dynamic_message/index.html new file mode 100644 index 000000000..5ff57cc41 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.dynamic_message/index.html @@ -0,0 +1,8 @@ +dynamic_message.h | Protocol Buffers Documentation +

dynamic_message.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/dynamic_message.h>
namespace google::protobuf

Defines an implementation of Message which can emulate types which are not known at compile-time.

Classes in this file

Constructs implementations of Message which can emulate types which are not known at compile-time.
Helper for computing a sorted list of map entries via reflection.

class DynamicMessageFactory: public MessageFactory

#include <google/protobuf/dynamic_message.h>
namespace google::protobuf

Constructs implementations of Message which can emulate types which are not known at compile-time.

Sometimes you want to be able to manipulate protocol types that you don't know about at compile time. It would be nice to be able to construct a Message object which implements the message type given by any arbitrary Descriptor. DynamicMessage provides this.

As it turns out, a DynamicMessage needs to construct extra information about its type in order to operate. Most of this information can be shared between all DynamicMessages of the same type. But, caching this information in some sort of global map would be a bad idea, since the cached information for a particular descriptor could outlive the descriptor itself. To avoid this problem, DynamicMessageFactory encapsulates this "cache". All DynamicMessages of the same type created from the same factory will share the same support data. Any Descriptors used with a particular factory must outlive the factory.

Members

DynamicMessageFactory()
Construct a DynamicMessageFactory that will search for extensions in the DescriptorPool in which the extendee is defined.
DynamicMessageFactory(const DescriptorPool * pool)
Construct a DynamicMessageFactory that will search for extensions in the given DescriptorPool. more...
~DynamicMessageFactory()
void
SetDelegateToGeneratedFactory(bool enable)
Call this to tell the DynamicMessageFactory that if it is given a Descriptor d for which: more...

implements MessageFactory

virtual const Message *
GetPrototype(const Descriptor * type)
Given a Descriptor, constructs the default (prototype) Message of that type. more...

DynamicMessageFactory::DynamicMessageFactory(
        const DescriptorPool * pool)

Construct a DynamicMessageFactory that will search for extensions in the given DescriptorPool.

DEPRECATED: Use CodedInputStream::SetExtensionRegistry() to tell the parser to look for extensions in an alternate pool. However, note that this is almost never what you want to do. Almost all users should use the zero-arg constructor.


void DynamicMessageFactory::SetDelegateToGeneratedFactory(
        bool enable)

Call this to tell the DynamicMessageFactory that if it is given a Descriptor d for which:

d->file()->pool() == DescriptorPool::generated_pool(),

then it should delegate to MessageFactory::generated_factory() instead of constructing a dynamic implementation of the message. In theory there is no down side to doing this, so it may become the default in the future.


virtual const Message * DynamicMessageFactory::GetPrototype(
        const Descriptor * type)

Given a Descriptor, constructs the default (prototype) Message of that type.

You can then call that message's New() method to construct a mutable message of that type.

Calling this method twice with the same Descriptor returns the same object. The returned object remains property of the factory and will be destroyed when the factory is destroyed. Also, any objects created by calling the prototype's New() method share some data with the prototype, so these must be destroyed before the DynamicMessageFactory is destroyed.

The given descriptor must outlive the returned message, and hence must outlive the DynamicMessageFactory.

The method is thread-safe.

class DynamicMapSorter

#include <google/protobuf/dynamic_message.h>
namespace google::protobuf

Helper for computing a sorted list of map entries via reflection.

Members

static std::vector< const Message * >
Sort(const Message & message, int map_size, const Reflection * reflection, const FieldDescriptor * field)
\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.io.coded_stream/index.html b/reference/cpp/api-docs/google.protobuf.io.coded_stream/index.html new file mode 100644 index 000000000..4db2dcef2 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.io.coded_stream/index.html @@ -0,0 +1,79 @@ +coded_stream.h | Protocol Buffers Documentation +

coded_stream.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/io/coded_stream.h>
namespace google::protobuf::io

This file contains the CodedInputStream and CodedOutputStream classes, which wrap a ZeroCopyInputStream or ZeroCopyOutputStream, respectively, and allow you to read or write individual pieces of data in various formats.

In particular, these implement the varint encoding for integers, a simple variable-length encoding in which smaller numbers take fewer bytes.

Typically these classes will only be used internally by the protocol buffer library in order to encode and decode protocol buffers. Clients of the library only need to know about this class if they wish to write custom message parsing or serialization procedures.

CodedOutputStream example:

// Write some data to "myfile".  First we write a 4-byte "magic number"
+// to identify the file type, then write a length-delimited string.  The
+// string is composed of a varint giving the length followed by the raw
+// bytes.
+int fd = open("myfile", O_CREAT | O_WRONLY);
+ZeroCopyOutputStream* raw_output = new FileOutputStream(fd);
+CodedOutputStream* coded_output = new CodedOutputStream(raw_output);
+
+int magic_number = 1234;
+char text[] = "Hello world!";
+coded_output->WriteLittleEndian32(magic_number);
+coded_output->WriteVarint32(strlen(text));
+coded_output->WriteRaw(text, strlen(text));
+
+delete coded_output;
+delete raw_output;
+close(fd);

CodedInputStream example:

// Read a file created by the above code.
+int fd = open("myfile", O_RDONLY);
+ZeroCopyInputStream* raw_input = new FileInputStream(fd);
+CodedInputStream* coded_input = new CodedInputStream(raw_input);
+
+coded_input->ReadLittleEndian32(&magic_number);
+if (magic_number != 1234) {
+  cerr << "File not in expected format." << endl;
+  return;
+}
+
+uint32 size;
+coded_input->ReadVarint32(&size);
+
+char* text = new char[size + 1];
+coded_input->ReadRaw(buffer, size);
+text[size] = '\0';
+
+delete coded_input;
+delete raw_input;
+close(fd);
+
+cout << "Text is: " << text << endl;
+delete [] text;

For those who are interested, varint encoding is defined as follows:

The encoding operates on unsigned integers of up to 64 bits in length. Each byte of the encoded value has the format:

  • bits 0-6: Seven bits of the number being encoded.
  • bit 7: Zero if this is the last byte in the encoding (in which case all remaining bits of the number are zero) or 1 if more bytes follow. The first byte contains the least-significant 7 bits of the number, the second byte (if present) contains the next-least-significant 7 bits, and so on. So, the binary number 1011000101011 would be encoded in two bytes as "10101011 00101100".

In theory, varint could be used to encode integers of any length. However, for practicality we set a limit at 64 bits. The maximum encoded length of a number is thus 10 bytes.

Classes in this file

Class which reads and decodes binary data which is composed of varint- encoded integers and fixed-width pieces.
EpsCopyOutputStream wraps a ZeroCopyOutputStream and exposes a new stream, which has the property you can write kSlopBytes (16 bytes) from the current position without bounds checks.
Class which encodes and writes binary data which is composed of varint- encoded integers and fixed-width pieces.
Compile-time equivalent of VarintSize32().

class CodedInputStream

#include <google/protobuf/io/coded_stream.h>
namespace google::protobuf::io

Class which reads and decodes binary data which is composed of varint- encoded integers and fixed-width pieces.

Wraps a ZeroCopyInputStream. Most users will not need to deal with CodedInputStream.

Most methods of CodedInputStream that return a bool return false if an underlying I/O error occurs or if the data is malformed. Once such a failure occurs, the CodedInputStream is broken and is no longer useful. After a failure, callers also should assume writes to "out" args may have occurred, though nothing useful can be determined from those writes.

Members

explicit
CodedInputStream(ZeroCopyInputStream * input)
Create a CodedInputStream that reads from the given ZeroCopyInputStream.
explicit
CodedInputStream(const uint8 * buffer, int size)
Create a CodedInputStream that reads from the given flat array. more...
~CodedInputStream()
Destroy the CodedInputStream and position the underlying ZeroCopyInputStream at the first unread byte. more...
bool
IsFlat() const
Return true if this CodedInputStream reads from a flat array instead of a ZeroCopyInputStream.
bool
Skip(int count)
Skips a number of bytes. more...
bool
GetDirectBufferPointer(const void ** data, int * size)
Sets *data to point directly at the unread part of the CodedInputStream's underlying buffer, and *size to the size of that buffer, but does not advance the stream's current position. more...
void
GetDirectBufferPointerInline(const void ** data, int * size)
Like GetDirectBufferPointer, but this method is inlined, and does not attempt to Refresh() if the buffer is currently empty.
bool
ReadRaw(void * buffer, int size)
Read raw bytes, copying them into the given buffer.
bool
ReadString(std::string * buffer, int size)
Like ReadRaw, but reads into a string.
bool
ReadLittleEndian32(uint32 * value)
Read a 32-bit little-endian integer.
bool
ReadLittleEndian64(uint64 * value)
Read a 64-bit little-endian integer.
bool
ReadVarint32(uint32 * value)
Read an unsigned integer with Varint encoding, truncating to 32 bits. more...
bool
ReadVarint64(uint64 * value)
Read an unsigned integer with Varint encoding.
bool
ReadVarintSizeAsInt(int * value)
Reads a varint off the wire into an "int". more...
uint32
ReadTag()
Read a tag. more...
uint32
ReadTagNoLastTag()
std::pair< uint32, bool >
ReadTagWithCutoff(uint32 cutoff)
This usually a faster alternative to ReadTag() when cutoff is a manifest constant. more...
std::pair< uint32, bool >
ReadTagWithCutoffNoLastTag(uint32 cutoff)
bool
ExpectTag(uint32 expected)
Usually returns true if calling ReadVarint32() now would produce the given value. more...
bool
ExpectAtEnd()
Usually returns true if no more bytes can be read. more...
bool
LastTagWas(uint32 expected)
If the last call to ReadTag() or ReadTagWithCutoff() returned the given value, returns true. more...
void
SetLastTag(uint32 tag)
bool
ConsumedEntireMessage()
When parsing message (but NOT a group), this method must be called immediately after MergeFromCodedStream() returns (if it returns true) to further verify that the message ended in a legitimate way. more...
void
SetConsumed()
static const uint8 *
ReadLittleEndian32FromArray(const uint8 * buffer, uint32 * value)
These methods read from an externally provided buffer. more...
static const uint8 *
ReadLittleEndian64FromArray(const uint8 * buffer, uint64 * value)
Read a 64-bit little-endian integer. more...
static const uint8 *
ExpectTagFromArray(const uint8 * buffer, uint32 expected)
Like above, except this reads from the specified buffer. more...

Limits

Limits are used when parsing length-delimited embedded messages. After the message's length is read, PushLimit() is used to prevent the CodedInputStream from reading beyond that length. Once the embedded message has been parsed, PopLimit() is called to undo the limit.
typedef
int Limit
Opaque type used with PushLimit() and PopLimit(). more...
Limit
PushLimit(int byte_limit)
Places a limit on the number of bytes that the stream may read, starting from the current position. more...
void
PopLimit(Limit limit)
Pops the last limit pushed by PushLimit(). more...
int
BytesUntilLimit() const
Returns the number of bytes left until the nearest limit on the stack is hit, or -1 if no limits are in place.
int
CurrentPosition() const
Returns current position relative to the beginning of the input stream.

Total Bytes Limit

To prevent malicious users from sending excessively large messages and causing memory exhaustion, CodedInputStream imposes a hard limit on the total number of bytes it will read.
int = { +SetTotalBytesLimit(total_bytes_limit)
void
SetTotalBytesLimit(int total_bytes_limit)
Sets the maximum number of bytes that this CodedInputStream will read before refusing to continue. more...
PROTOBUF_DEPRECATED_MSG("Please use the single parameter version of SetTotalBytesLimit(). The " "second parameter is ignored." )
int
BytesUntilTotalBytesLimit() const
The Total Bytes Limit minus the Current Position, or -1 if the total bytes limit is INT_MAX.

Recursion Limit

To prevent corrupt or malicious messages from causing stack overflows, we must keep track of the depth of recursion when parsing embedded messages and groups.

CodedInputStream keeps track of this because it is the only object that is passed down the stack during parsing.

void
SetRecursionLimit(int limit)
Sets the maximum recursion depth. The default is 100.
int
RecursionBudget()
bool
IncrementRecursionDepth()
Increments the current recursion depth. more...
void
DecrementRecursionDepth()
Decrements the recursion depth if possible.
void
UnsafeDecrementRecursionDepth()
Decrements the recursion depth blindly. more...
std::pair< CodedInputStream::Limit, int >
IncrementRecursionDepthAndPushLimit(int byte_limit)
Shorthand for make_pair(PushLimit(byte_limit), –recursion_budget_). more...
Limit
ReadLengthAndPushLimit()
Shorthand for PushLimit(ReadVarint32(&length) ? length : 0).
bool
DecrementRecursionDepthAndPopLimit(Limit limit)
Helper that is equivalent to: { bool result = ConsumedEntireMessage(); PopLimit(limit); UnsafeDecrementRecursionDepth(); return result; } Using this can reduce code size and complexity in some cases. more...
bool
CheckEntireMessageConsumedAndPopLimit(Limit limit)
Helper that is equivalent to: { bool result = ConsumedEntireMessage(); PopLimit(limit); return result; } Using this can reduce code size and complexity in some cases.
static int
GetDefaultRecursionLimit()

Extension Registry

ADVANCED USAGE: 99.9% of people can ignore this section.

By default, when parsing extensions, the parser looks for extension definitions in the pool which owns the outer message's Descriptor. However, you may call SetExtensionRegistry() to provide an alternative pool instead. This makes it possible, for example, to parse a message using a generated class, but represent some extensions using DynamicMessage.

void
SetExtensionRegistry(const DescriptorPool * pool, MessageFactory * factory)
Set the pool used to look up extensions. more...
const DescriptorPool *
GetExtensionPool()
Get the DescriptorPool set via SetExtensionRegistry(), or NULL if no pool has been provided.
MessageFactory *
GetExtensionFactory()
Get the MessageFactory set via SetExtensionRegistry(), or NULL if no factory has been provided.

explicit CodedInputStream::CodedInputStream(
        const uint8 * buffer,
        int size)

Create a CodedInputStream that reads from the given flat array.

This is faster than using an ArrayInputStream. PushLimit(size) is implied by this constructor.


CodedInputStream::~CodedInputStream()

Destroy the CodedInputStream and position the underlying ZeroCopyInputStream at the first unread byte.

If an error occurred while reading (causing a method to return false), then the exact position of the input stream may be anywhere between the last value that was read successfully and the stream's byte limit.


bool CodedInputStream::Skip(
        int count)

Skips a number of bytes.

Returns false if an underlying read error occurs.


bool CodedInputStream::GetDirectBufferPointer(
        const void ** data,
        int * size)

Sets *data to point directly at the unread part of the CodedInputStream's underlying buffer, and *size to the size of that buffer, but does not advance the stream's current position.

This will always either produce a non-empty buffer or return false. If the caller consumes any of this data, it should then call Skip() to skip over the consumed bytes. This may be useful for implementing external fast parsing routines for types of data not covered by the CodedInputStream interface.


bool CodedInputStream::ReadVarint32(
        uint32 * value)

Read an unsigned integer with Varint encoding, truncating to 32 bits.

Reading a 32-bit value is equivalent to reading a 64-bit one and casting it to uint32, but may be more efficient.


bool CodedInputStream::ReadVarintSizeAsInt(
        int * value)

Reads a varint off the wire into an "int".

This should be used for reading sizes off the wire (sizes of strings, submessages, bytes fields, etc).

The value from the wire is interpreted as unsigned. If its value exceeds the representable value of an integer on this platform, instead of truncating we return false. Truncating (as performed by ReadVarint32() above) is an acceptable approach for fields representing an integer, but when we are parsing a size from the wire, truncating the value would result in us misparsing the payload.


uint32 CodedInputStream::ReadTag()

Read a tag.

This calls ReadVarint32() and returns the result, or returns zero (which is not a valid tag) if ReadVarint32() fails. Also, ReadTag (but not ReadTagNoLastTag) updates the last tag value, which can be checked with LastTagWas().

Always inline because this is only called in one place per parse loop but it is called for every iteration of said loop, so it should be fast. GCC doesn't want to inline this by default.


std::pair< uint32, bool >
    CodedInputStream::ReadTagWithCutoff(
        uint32 cutoff)

This usually a faster alternative to ReadTag() when cutoff is a manifest constant.

It does particularly well for cutoff >= 127. The first part of the return value is the tag that was read, though it can also be 0 in the cases where ReadTag() would return 0. If the second part is true then the tag is known to be in [0, cutoff]. If not, the tag either is above cutoff or is 0. (There's intentional wiggle room when tag is 0, because that can arise in several ways, and for best performance we want to avoid an extra "is tag == 0?" check here.)


bool CodedInputStream::ExpectTag(
        uint32 expected)

Usually returns true if calling ReadVarint32() now would produce the given value.

Will always return false if ReadVarint32() would not return the given value. If ExpectTag() returns true, it also advances past the varint. For best performance, use a compile-time constant as the parameter. Always inline because this collapses to a small number of instructions when given a constant parameter, but GCC doesn't want to inline by default.


bool CodedInputStream::ExpectAtEnd()

Usually returns true if no more bytes can be read.

Always returns false if more bytes can be read. If ExpectAtEnd() returns true, a subsequent call to LastTagWas() will act as if ReadTag() had been called and returned zero, and ConsumedEntireMessage() will return true.


bool CodedInputStream::LastTagWas(
        uint32 expected)

If the last call to ReadTag() or ReadTagWithCutoff() returned the given value, returns true.

Otherwise, returns false. ReadTagNoLastTag/ReadTagWithCutoffNoLastTag do not preserve the last returned value.

This is needed because parsers for some types of embedded messages (with field type TYPE_GROUP) don't actually know that they've reached the end of a message until they see an ENDGROUP tag, which was actually part of the enclosing message. The enclosing message would like to check that tag to make sure it had the right number, so it calls LastTagWas() on return from the embedded parser to check.


bool CodedInputStream::ConsumedEntireMessage()

When parsing message (but NOT a group), this method must be called immediately after MergeFromCodedStream() returns (if it returns true) to further verify that the message ended in a legitimate way.

For example, this verifies that parsing did not end on an end-group tag. It also checks for some cases where, due to optimizations, MergeFromCodedStream() can incorrectly return true.


static const uint8 * CodedInputStream::ReadLittleEndian32FromArray(
        const uint8 * buffer,
        uint32 * value)

These methods read from an externally provided buffer.

static

The caller is responsible for ensuring that the buffer has sufficient space. Read a 32-bit little-endian integer.


static const uint8 * CodedInputStream::ReadLittleEndian64FromArray(
        const uint8 * buffer,
        uint64 * value)

Read a 64-bit little-endian integer.

static


static const uint8 * CodedInputStream::ExpectTagFromArray(
        const uint8 * buffer,
        uint32 expected)

Like above, except this reads from the specified buffer.

The caller is responsible for ensuring that the buffer is large enough to read a varint of the expected size. For best performance, use a compile-time constant as the expected tag parameter.

Returns a pointer beyond the expected tag if it was found, or NULL if it was not.


typedef CodedInputStream::Limit

Opaque type used with PushLimit() and PopLimit().

Do not modify values of this type yourself. The only reason that this isn't a struct with private internals is for efficiency.


Limit CodedInputStream::PushLimit(
        int byte_limit)

Places a limit on the number of bytes that the stream may read, starting from the current position.

Once the stream hits this limit, it will act like the end of the input has been reached until PopLimit() is called.

As the names imply, the stream conceptually has a stack of limits. The shortest limit on the stack is always enforced, even if it is not the top limit.

The value returned by PushLimit() is opaque to the caller, and must be passed unchanged to the corresponding call to PopLimit().


void CodedInputStream::PopLimit(
        Limit limit)

Pops the last limit pushed by PushLimit().

The input must be the value returned by that call to PushLimit().


void CodedInputStream::SetTotalBytesLimit(
        int total_bytes_limit)

Sets the maximum number of bytes that this CodedInputStream will read before refusing to continue.

To prevent servers from allocating enormous amounts of memory to hold parsed messages, the maximum message length should be limited to the shortest length that will not harm usability. The default limit is INT_MAX (~2GB) and apps should set shorter limits if possible. An error will always be printed to stderr if the limit is reached.

Note: setting a limit less than the current read position is interpreted as a limit on the current position.

This is unrelated to PushLimit()/PopLimit().


bool CodedInputStream::IncrementRecursionDepth()

Increments the current recursion depth.

Returns true if the depth is under the limit, false if it has gone over.


void CodedInputStream::UnsafeDecrementRecursionDepth()

Decrements the recursion depth blindly.

This is faster than DecrementRecursionDepth(). It should be used only if all previous increments to recursion depth were successful.


std::pair< CodedInputStream::Limit, int >
    CodedInputStream::IncrementRecursionDepthAndPushLimit(
        int byte_limit)

Shorthand for make_pair(PushLimit(byte_limit), –recursion_budget_).

Using this can reduce code size and complexity in some cases. The caller is expected to check that the second part of the result is non-negative (to bail out if the depth of recursion is too high) and, if all is well, to later pass the first part of the result to PopLimit() or similar.


bool CodedInputStream::DecrementRecursionDepthAndPopLimit(
        Limit limit)

Helper that is equivalent to: { bool result = ConsumedEntireMessage(); PopLimit(limit); UnsafeDecrementRecursionDepth(); return result; } Using this can reduce code size and complexity in some cases.

Do not use unless the current recursion depth is greater than zero.


void CodedInputStream::SetExtensionRegistry(
        const DescriptorPool * pool,
        MessageFactory * factory)

Set the pool used to look up extensions.

Most users do not need to call this as the correct pool will be chosen automatically.

WARNING: It is very easy to misuse this. Carefully read the requirements below. Do not use this unless you are sure you need it. Almost no one does.

Let's say you are parsing a message into message object m, and you want to take advantage of SetExtensionRegistry(). You must follow these requirements:

The given DescriptorPool must contain m->GetDescriptor(). It is not sufficient for it to simply contain a descriptor that has the same name and content – it must be the exact object. In other words:

assert(pool->FindMessageTypeByName(m->GetDescriptor()->full_name()) ==
+       m->GetDescriptor());

There are two ways to satisfy this requirement: 1) Use m->GetDescriptor()->pool() as the pool. This is generally useless

because this is the pool that would be used anyway if you didn't call
+SetExtensionRegistry() at all.

2) Use a DescriptorPool which has m->GetDescriptor()->pool() as an

"underlay".  Read the documentation for DescriptorPool for more
+information about underlays.

You must also provide a MessageFactory. This factory will be used to construct Message objects representing extensions. The factory's GetPrototype() MUST return non-NULL for any Descriptor which can be found through the provided pool.

If the provided factory might return instances of protocol-compiler- generated (i.e. compiled-in) types, or if the outer message object m is a generated type, then the given factory MUST have this property: If GetPrototype() is given a Descriptor which resides in DescriptorPool::generated_pool(), the factory MUST return the same prototype which MessageFactory::generated_factory() would return. That is, given a descriptor for a generated type, the factory must return an instance of the generated class (NOT DynamicMessage). However, when given a descriptor for a type that is NOT in generated_pool, the factory is free to return any implementation.

The reason for this requirement is that generated sub-objects may be accessed via the standard (non-reflection) extension accessor methods, and these methods will down-cast the object to the generated class type. If the object is not actually of that type, the results would be undefined. On the other hand, if an extension is not compiled in, then there is no way the code could end up accessing it via the standard accessors – the only way to access the extension is via reflection. When using reflection, DynamicMessage and generated messages are indistinguishable, so it's fine if these objects are represented using DynamicMessage.

Using DynamicMessageFactory on which you have called SetDelegateToGeneratedFactory(true) should be sufficient to satisfy the above requirement.

If either pool or factory is NULL, both must be NULL.

Note that this feature is ignored when parsing "lite" messages as they do not have descriptors.

class EpsCopyOutputStream

#include <google/protobuf/io/coded_stream.h>
namespace google::protobuf::io

EpsCopyOutputStream wraps a ZeroCopyOutputStream and exposes a new stream, which has the property you can write kSlopBytes (16 bytes) from the current position without bounds checks.

The cursor into the stream is managed by the user of the class and is an explicit parameter in the methods. Careful use of this class, ie. keep ptr a local variable, eliminates the need to for the compiler to sync the ptr value between register and memory.

Members

enum
@33
EpsCopyOutputStream(ZeroCopyOutputStream * stream, bool deterministic, uint8 ** pp)
Initialize from a stream.
EpsCopyOutputStream(void * data, int size, bool deterministic)
Only for array serialization. more...
EpsCopyOutputStream(void * data, int size, ZeroCopyOutputStream * stream, bool deterministic, uint8 ** pp)
Initialize from stream but with the first buffer already given (eager).
uint8 *
Trim(uint8 * ptr)
Flush everything that's written into the underlying ZeroCopyOutputStream and trims the underlying stream to the location of ptr.
PROTOBUF_MUST_USE_RESULT uint8 *
EnsureSpace(uint8 * ptr)
After this it's guaranteed you can safely write kSlopBytes to ptr. more...
uint8 *
WriteRaw(const void * data, int size, uint8 * ptr)
uint8 *
WriteRawMaybeAliased(const void * data, int size, uint8 * ptr)
Writes the buffer specified by data, size to the stream. more...
uint8 *
WriteStringMaybeAliased(uint32 num, const std::string & s, uint8 * ptr)
uint8 *
WriteBytesMaybeAliased(uint32 num, const std::string & s, uint8 * ptr)
template uint8 *
WriteString(uint32 num, const T & s, uint8 * ptr)
template uint8 *
WriteBytes(uint32 num, const T & s, uint8 * ptr)
template uint8 *
WriteInt32Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteUInt32Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteSInt32Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteInt64Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteUInt64Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteSInt64Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteEnumPacked(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteFixedPacked(int num, const T & r, uint8 * ptr)
bool
HadError() const
Returns true if there was an underlying I/O error since this object was created.
void
EnableAliasing(bool enabled)
Instructs the EpsCopyOutputStream to allow the underlying ZeroCopyOutputStream to hold pointers to the original structure instead of copying, if it supports it (i.e. more...
void
SetSerializationDeterministic(bool value)
bool
IsSerializationDeterministic() const
int64
ByteCount(uint8 * ptr) const
The number of bytes written to the stream at position ptr, relative to the stream's overall position.
uint8 *
SetInitialBuffer(void * data, int size)
These methods are for CodedOutputStream. more...

enum EpsCopyOutputStream::@33 {
  kSlopBytes = = 16
}

kSlopBytes

EpsCopyOutputStream::EpsCopyOutputStream(
        void * data,
        int size,
        bool deterministic)

Only for array serialization.

No overflow protection, end_ will be the pointed to the end of the array. When using this the total size is already known, so no need to maintain the slop region.


PROTOBUF_MUST_USE_RESULT uint8 *
    EpsCopyOutputStream::EnsureSpace(
        uint8 * ptr)

After this it's guaranteed you can safely write kSlopBytes to ptr.

This will never fail! The underlying stream can produce an error. Use HadError to check for errors.


uint8 * EpsCopyOutputStream::WriteRawMaybeAliased(
        const void * data,
        int size,
        uint8 * ptr)

Writes the buffer specified by data, size to the stream.

Possibly by aliasing the buffer (ie. not copying the data). The caller is responsible to make sure the buffer is alive for the duration of the ZeroCopyOutputStream.


void EpsCopyOutputStream::EnableAliasing(
        bool enabled)

Instructs the EpsCopyOutputStream to allow the underlying ZeroCopyOutputStream to hold pointers to the original structure instead of copying, if it supports it (i.e.

output->AllowsAliasing() is true). If the underlying stream does not support aliasing, then enabling it has no affect. For now, this only affects the behavior of WriteRawMaybeAliased().

NOTE: It is caller's responsibility to ensure that the chunk of memory remains live until all of the data has been consumed from the stream.


uint8 * EpsCopyOutputStream::SetInitialBuffer(
        void * data,
        int size)

These methods are for CodedOutputStream.

Ideally they should be private but to match current behavior of CodedOutputStream as close as possible we allow it some functionality.

class CodedOutputStream

#include <google/protobuf/io/coded_stream.h>
namespace google::protobuf::io

Class which encodes and writes binary data which is composed of varint- encoded integers and fixed-width pieces.

Wraps a ZeroCopyOutputStream. Most users will not need to deal with CodedOutputStream.

Most methods of CodedOutputStream which return a bool return false if an underlying I/O error occurs. Once such a failure occurs, the CodedOutputStream is broken and is no longer useful. The Write* methods do not return the stream status, but will invalidate the stream if an error occurs. The client can probe HadError() to determine the status.

Note that every method of CodedOutputStream which writes some data has a corresponding static "ToArray" version. These versions write directly to the provided buffer, returning a pointer past the last written byte. They require that the buffer has sufficient capacity for the encoded data. This allows an optimization where we check if an output stream has enough space for an entire message before we start writing and, if there is, we call only the ToArray methods to avoid doing bound checks for each individual value. i.e., in the example above:

CodedOutputStream* coded_output = new CodedOutputStream(raw_output);
+int magic_number = 1234;
+char text[] = "Hello world!";
+

int coded_size = sizeof(magic_number) + +CodedOutputStream::VarintSize32(strlen(text)) + +strlen(text);

+

uint8* buffer = +coded_output->GetDirectBufferForNBytesAndAdvance(coded_size); +if (buffer != nullptr) { +// The output stream has enough space in the buffer: write directly to +// the array. +buffer = CodedOutputStream::WriteLittleEndian32ToArray(magic_number, +buffer); +buffer = CodedOutputStream::WriteVarint32ToArray(strlen(text), buffer); +buffer = CodedOutputStream::WriteRawToArray(text, strlen(text), buffer); +} else { +// Make bound-checked writes, which will ask the underlying stream for +// more space as needed. +coded_output->WriteLittleEndian32(magic_number); +coded_output->WriteVarint32(strlen(text)); +coded_output->WriteRaw(text, strlen(text)); +}

+

delete coded_output;

Members

explicit
CodedOutputStream(ZeroCopyOutputStream * stream)
Create an CodedOutputStream that writes to the given ZeroCopyOutputStream.
CodedOutputStream(ZeroCopyOutputStream * stream, bool do_eager_refresh)
~CodedOutputStream()
Destroy the CodedOutputStream and position the underlying ZeroCopyOutputStream immediately after the last byte written.
bool
HadError()
Returns true if there was an underlying I/O error since this object was created. more...
void
Trim()
Trims any unused space in the underlying buffer so that its size matches the number of bytes written by this stream. more...
bool
Skip(int count)
Skips a number of bytes, leaving the bytes unmodified in the underlying buffer. more...
bool
GetDirectBufferPointer(void ** data, int * size)
Sets *data to point directly at the unwritten part of the CodedOutputStream's underlying buffer, and *size to the size of that buffer, but does not advance the stream's current position. more...
uint8 *
GetDirectBufferForNBytesAndAdvance(int size)
If there are at least "size" bytes available in the current buffer, returns a pointer directly into the buffer and advances over these bytes. more...
void
WriteRaw(const void * buffer, int size)
Write raw bytes, copying them from the given buffer.
void
WriteRawMaybeAliased(const void * data, int size)
Like WriteRaw() but will try to write aliased data if aliasing is turned on.
void
WriteString(const std::string & str)
Equivalent to WriteRaw(str.data(), str.size()).
void
WriteLittleEndian32(uint32 value)
Write a 32-bit little-endian integer.
void
WriteLittleEndian64(uint64 value)
Write a 64-bit little-endian integer.
void
WriteVarint32(uint32 value)
Write an unsigned integer with Varint encoding. more...
void
WriteVarint64(uint64 value)
Write an unsigned integer with Varint encoding.
void
WriteVarint32SignExtended(int32 value)
Equivalent to WriteVarint32() except when the value is negative, in which case it must be sign-extended to a full 10 bytes.
void
WriteTag(uint32 value)
This is identical to WriteVarint32(), but optimized for writing tags. more...
int
ByteCount() const
Returns the total number of bytes written since this object was created.
void
EnableAliasing(bool enabled)
Instructs the CodedOutputStream to allow the underlying ZeroCopyOutputStream to hold pointers to the original structure instead of copying, if it supports it (i.e. more...
void
SetSerializationDeterministic(bool value)
Indicate to the serializer whether the user wants derministic serialization. more...
bool
IsSerializationDeterministic() const
Return whether the user wants deterministic serialization. See above.
template void
Serialize(const Func & func)
uint8 *
Cur() const
void
SetCur(uint8 * ptr)
EpsCopyOutputStream *
EpsCopy()
static uint8 *
WriteRawToArray(const void * buffer, int size, uint8 * target)
Like WriteRaw() but writing directly to the target array. more...
static uint8 *
WriteStringToArray(const std::string & str, uint8 * target)
Like WriteString() but writing directly to the target array.
static uint8 *
WriteStringWithSizeToArray(const std::string & str, uint8 * target)
Write the varint-encoded size of str followed by str.
static uint8 *
WriteLittleEndian32ToArray(uint32 value, uint8 * target)
Like WriteLittleEndian32() but writing directly to the target array.
static uint8 *
WriteLittleEndian64ToArray(uint64 value, uint8 * target)
Like WriteLittleEndian64() but writing directly to the target array.
static uint8 *
WriteVarint32ToArray(uint32 value, uint8 * target)
Like WriteVarint32() but writing directly to the target array.
static uint8 *
WriteVarint32ToArrayOutOfLine(uint32 value, uint8 * target)
Like WriteVarint32() but writing directly to the target array, and with the less common-case paths being out of line rather than inlined.
static uint8 *
WriteVarint64ToArray(uint64 value, uint8 * target)
Like WriteVarint64() but writing directly to the target array.
static uint8 *
WriteVarint32SignExtendedToArray(int32 value, uint8 * target)
Like WriteVarint32SignExtended() but writing directly to the target array.
static uint8 *
WriteTagToArray(uint32 value, uint8 * target)
Like WriteTag() but writing directly to the target array.
static size_t
VarintSize32(uint32 value)
Returns the number of bytes needed to encode the given value as a varint.
static size_t
VarintSize64(uint64 value)
Returns the number of bytes needed to encode the given value as a varint.
static size_t
VarintSize32SignExtended(int32 value)
If negative, 10 bytes. Otherwise, same as VarintSize32().
static bool
IsDefaultSerializationDeterministic()

bool CodedOutputStream::HadError()

Returns true if there was an underlying I/O error since this object was created.

On should call Trim before this function in order to catch all errors.


void CodedOutputStream::Trim()

Trims any unused space in the underlying buffer so that its size matches the number of bytes written by this stream.

The underlying buffer will automatically be trimmed when this stream is destroyed; this call is only necessary if the underlying buffer is accessed before the stream is destroyed.


bool CodedOutputStream::Skip(
        int count)

Skips a number of bytes, leaving the bytes unmodified in the underlying buffer.

Returns false if an underlying write error occurs. This is mainly useful with GetDirectBufferPointer(). Note of caution, the skipped bytes may contain uninitialized data. The caller must make sure that the skipped bytes are properly initialized, otherwise you might leak bytes from your heap.


bool CodedOutputStream::GetDirectBufferPointer(
        void ** data,
        int * size)

Sets *data to point directly at the unwritten part of the CodedOutputStream's underlying buffer, and *size to the size of that buffer, but does not advance the stream's current position.

This will always either produce a non-empty buffer or return false. If the caller writes any data to this buffer, it should then call Skip() to skip over the consumed bytes. This may be useful for implementing external fast serialization routines for types of data not covered by the CodedOutputStream interface.


uint8 * CodedOutputStream::GetDirectBufferForNBytesAndAdvance(
        int size)

If there are at least "size" bytes available in the current buffer, returns a pointer directly into the buffer and advances over these bytes.

The caller may then write directly into this buffer (e.g. using the *ToArray static methods) rather than go through CodedOutputStream. If there are not enough bytes available, returns NULL. The return pointer is invalidated as soon as any other non-const method of CodedOutputStream is called.


void CodedOutputStream::WriteVarint32(
        uint32 value)

Write an unsigned integer with Varint encoding.

Writing a 32-bit value is equivalent to casting it to uint64 and writing it as a 64-bit value, but may be more efficient.


void CodedOutputStream::WriteTag(
        uint32 value)

This is identical to WriteVarint32(), but optimized for writing tags.

In particular, if the input is a compile-time constant, this method compiles down to a couple instructions. Always inline because otherwise the aforementioned optimization can't work, but GCC by default doesn't want to inline this.


void CodedOutputStream::EnableAliasing(
        bool enabled)

Instructs the CodedOutputStream to allow the underlying ZeroCopyOutputStream to hold pointers to the original structure instead of copying, if it supports it (i.e.

output->AllowsAliasing() is true). If the underlying stream does not support aliasing, then enabling it has no affect. For now, this only affects the behavior of WriteRawMaybeAliased().

NOTE: It is caller's responsibility to ensure that the chunk of memory remains live until all of the data has been consumed from the stream.


void CodedOutputStream::SetSerializationDeterministic(
        bool value)

Indicate to the serializer whether the user wants derministic serialization.

The default when this is not called comes from the global default, controlled by SetDefaultSerializationDeterministic.

What deterministic serialization means is entirely up to the driver of the serialization process (i.e. the caller of methods like WriteVarint32). In the case of serializing a proto buffer message using one of the methods of MessageLite, this means that for a given binary equal messages will always be serialized to the same bytes. This implies:

Repeated serialization of a message will return the same bytes.
+

Different processes running the same binary (including on different +machines) will serialize equal messages to the same bytes.

Note that this is not canonical across languages. It is also unstable across different builds with intervening message definition changes, due to unknown fields. Users who need canonical serialization (e.g. persistent storage in a canonical form, fingerprinting) should define their own canonicalization specification and implement the serializer using reflection APIs rather than relying on this API.


static uint8 * CodedOutputStream::WriteRawToArray(
        const void * buffer,
        int size,
        uint8 * target)

Like WriteRaw() but writing directly to the target array.

This is not inlined, as the compiler often optimizes memcpy into inline copy loops. Since this gets called by every field with string or bytes type, inlining may lead to a significant amount of code bloat, with only a minor performance gain.

template struct CodedOutputStream::StaticVarintSize32

#include <google/protobuf/io/coded_stream.h>
namespace google::protobuf::io

template <typename Value>

Compile-time equivalent of VarintSize32().

Members

const size_t
value = = (Value < (1 << 7)) ? 1 +: (Value < (1 << 14)) ? 2 +: (Value < (1 << 21)) ? 3 +: (Value < (1 << 28)) ? 4 +: 5
\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.io.gzip_stream/index.html b/reference/cpp/api-docs/google.protobuf.io.gzip_stream/index.html new file mode 100644 index 000000000..3e71dc111 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.io.gzip_stream/index.html @@ -0,0 +1,8 @@ +gzip_stream.h | Protocol Buffers Documentation +

gzip_stream.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/io/gzip_stream.h>
namespace google::protobuf::io

This file contains the definition for classes GzipInputStream and GzipOutputStream.

GzipInputStream decompresses data from an underlying ZeroCopyInputStream and provides the decompressed data as a ZeroCopyInputStream.

GzipOutputStream is an ZeroCopyOutputStream that compresses data to an underlying ZeroCopyOutputStream.

Classes in this file

A ZeroCopyInputStream that reads compressed data through zlib.

class GzipInputStream: public ZeroCopyInputStream

#include <google/protobuf/io/gzip_stream.h>
namespace google::protobuf::io

A ZeroCopyInputStream that reads compressed data through zlib.

Members

enum
Format
Format key for constructor. more...
explicit
GzipInputStream(ZeroCopyInputStream * sub_stream, Format format = AUTO, int buffer_size = -1)
buffer_size and format may be -1 for default of 64kB and GZIP format
virtual
~GzipInputStream()
const char *
ZlibErrorMessage() const
Return last error message or NULL if no error.
int
ZlibErrorCode() const

implements ZeroCopyInputStream

virtual bool
Next(const void ** data, int * size)
Obtains a chunk of data from the stream. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next(). more...
virtual bool
Skip(int count)
Skips a number of bytes. more...
virtual int64
ByteCount() const
Returns the total number of bytes read since this object was created.

enum GzipInputStream::Format {
  AUTO = = 0,
  GZIP = = 1,
  ZLIB = = 2
}

Format key for constructor.

AUTOzlib will autodetect gzip header or deflate stream
GZIPGZIP streams have some extra header data for file attributes.
ZLIBSimpler zlib stream format.

virtual bool GzipInputStream::Next(
        const void ** data,
        int * size)

Obtains a chunk of data from the stream.

Preconditions:

  • "size" and "data" are not NULL.

Postconditions:

  • If the returned value is false, there is no more data to return or an error occurred. All errors are permanent.
  • Otherwise, "size" points to the actual number of bytes read and "data" points to a pointer to a buffer containing these bytes.
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.

virtual void GzipInputStream::BackUp(
        int count)

Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next().

This is useful when writing procedures that are only supposed to read up to a certain point in the input, then return. If Next() returns a buffer that goes beyond what you wanted to read, you can use BackUp() to return to the point where you intended to finish.

Preconditions:

  • The last method called must have been Next().
  • count must be less than or equal to the size of the last buffer returned by Next().

Postconditions:

  • The last "count" bytes of the last buffer returned by Next() will be pushed back into the stream. Subsequent calls to Next() will return the same data again before producing new data.

virtual bool GzipInputStream::Skip(
        int count)

Skips a number of bytes.

Returns false if the end of the stream is reached or some input error occurred. In the end-of-stream case, the stream is advanced to the end of the stream (so ByteCount() will return the total size of the stream).

class GzipOutputStream: public ZeroCopyOutputStream

#include <google/protobuf/io/gzip_stream.h>
namespace google::protobuf::io

Members

enum
Format
Format key for constructor. more...
explicit
GzipOutputStream(ZeroCopyOutputStream * sub_stream)
Create a GzipOutputStream with default options.
GzipOutputStream(ZeroCopyOutputStream * sub_stream, const Options & options)
Create a GzipOutputStream with the given options.
virtual
~GzipOutputStream()
const char *
ZlibErrorMessage() const
Return last error message or NULL if no error.
int
ZlibErrorCode() const
bool
Flush()
Flushes data written so far to zipped data in the underlying stream. more...
bool
Close()
Writes out all data and closes the gzip stream. more...

implements ZeroCopyOutputStream

virtual bool
Next(void ** data, int * size)
Obtains a buffer into which data can be written. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written. more...
virtual int64
ByteCount() const
Returns the total number of bytes written since this object was created.

enum GzipOutputStream::Format {
  GZIP = = 1,
  ZLIB = = 2
}

Format key for constructor.

GZIPGZIP streams have some extra header data for file attributes.
ZLIBSimpler zlib stream format.

bool GzipOutputStream::Flush()

Flushes data written so far to zipped data in the underlying stream.

It is the caller's responsibility to flush the underlying stream if necessary. Compression may be less efficient stopping and starting around flushes. Returns true if no error.

Please ensure that block size is > 6. Here is an excerpt from the zlib doc that explains why:

In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out is greater than six to avoid repeated flush markers due to avail_out == 0 on return.


bool GzipOutputStream::Close()

Writes out all data and closes the gzip stream.

It is the caller's responsibility to close the underlying stream if necessary. Returns true if no error.


virtual bool GzipOutputStream::Next(
        void ** data,
        int * size)

Obtains a buffer into which data can be written.

Any data written into this buffer will eventually (maybe instantly, maybe later on) be written to the output.

Preconditions:

  • "size" and "data" are not NULL.

Postconditions:

  • If the returned value is false, an error occurred. All errors are permanent.
  • Otherwise, "size" points to the actual number of bytes in the buffer and "data" points to the buffer.
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • Any data which the caller stores in this buffer will eventually be written to the output (unless BackUp() is called).
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.

virtual void GzipOutputStream::BackUp(
        int count)

Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written.

This is needed when you finish writing all the data you want to write, but the last buffer was bigger than you needed. You don't want to write a bunch of garbage after the end of your data, so you use BackUp() to back up.

Preconditions:

  • The last method called must have been Next().
  • count must be less than or equal to the size of the last buffer returned by Next().
  • The caller must not have written anything to the last "count" bytes of that buffer.

Postconditions:

  • The last "count" bytes of the last buffer returned by Next() will be ignored.

struct GzipOutputStream::Options

#include <google/protobuf/io/gzip_stream.h>
namespace google::protobuf::io

Members

Format
format
Defaults to GZIP.
int
buffer_size
What size buffer to use internally. Defaults to 64kB.
int
compression_level
A number between 0 and 9, where 0 is no compression and 9 is best compression. more...
int
compression_strategy
Defaults to Z_DEFAULT_STRATEGY. more...
Options()
Initializes with default values.

intOptions::compression_level

A number between 0 and 9, where 0 is no compression and 9 is best compression.

Defaults to Z_DEFAULT_COMPRESSION (see zlib.h).


intOptions::compression_strategy

Defaults to Z_DEFAULT_STRATEGY.

Can also be set to Z_FILTERED, Z_HUFFMAN_ONLY, or Z_RLE. See the documentation for deflateInit2 in zlib.h for definitions of these constants.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.io.printer/index.html b/reference/cpp/api-docs/google.protobuf.io.printer/index.html new file mode 100644 index 000000000..378df9b6b --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.io.printer/index.html @@ -0,0 +1,9 @@ +printer.h | Protocol Buffers Documentation +

printer.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/io/printer.h>
namespace google::protobuf::io

Utility class for writing text to a ZeroCopyOutputStream.

Classes in this file

Records annotations about a Printer's output.
Records annotations about a Printer's output to the given protocol buffer, assuming that the buffer has an ::Annotation message exposing path, source_file, begin and end fields.

class AnnotationCollector

#include <google/protobuf/io/printer.h>
namespace google::protobuf::io

Records annotations about a Printer's output.

Known subclasses:

Members

typedef
std::pair< std::pair< size_t, size_t >, std::string > Annotation
Annotation is a offset range and a payload pair.
virtual void
AddAnnotation(size_t begin_offset, size_t end_offset, const std::string & file_path, const std::vector< int > & path) = 0
Records that the bytes in file_path beginning with begin_offset and ending before end_offset are associated with the SourceCodeInfo-style path.
virtual void
AddAnnotationNew(Annotation & )
virtual
~AnnotationCollector()

virtual void AnnotationCollector::AddAnnotationNew(
        Annotation & )

Just a vector of range, payload pairs stored in a context should suffice.

template class AnnotationProtoCollector: public AnnotationCollector

#include <google/protobuf/io/printer.h>
namespace google::protobuf::io

template <typename >

Records annotations about a Printer's output to the given protocol buffer, assuming that the buffer has an ::Annotation message exposing path, source_file, begin and end fields.

Members

explicit
AnnotationProtoCollector(AnnotationProto * annotation_proto)
annotation_proto is the protocol buffer to which new Annotations should be added. more...
virtual void
AddAnnotation(size_t begin_offset, size_t end_offset, const std::string & file_path, const std::vector< int > & path)
virtual void
AddAnnotationNew(Annotation & a)

explicit AnnotationProtoCollector::AnnotationProtoCollector(
        AnnotationProto * annotation_proto)

annotation_proto is the protocol buffer to which new Annotations should be added.

It is not owned by the AnnotationProtoCollector.

class Printer

#include <google/protobuf/io/printer.h>
namespace google::protobuf::io

Members

Printer(ZeroCopyOutputStream * output, char variable_delimiter)
Create a printer that writes text to the given output stream. more...
Printer(ZeroCopyOutputStream * output, char variable_delimiter, AnnotationCollector * annotation_collector)
Create a printer that writes text to the given output stream. more...
~Printer()
template void
Annotate(const char * varname, const SomeDescriptor * descriptor)
Link a substitution variable emitted by the last call to Print to the object described by descriptor.
template void
Annotate(const char * begin_varname, const char * end_varname, const SomeDescriptor * descriptor)
Link the output range defined by the substitution variables as emitted by the last call to Print to the object described by descriptor. more...
void
Annotate(const char * varname, const std::string & file_name)
Link a substitution variable emitted by the last call to Print to the file with path file_name.
void
Annotate(const char * begin_varname, const char * end_varname, const std::string & file_name)
Link the output range defined by the substitution variables as emitted by the last call to Print to the file with path file_name. more...
void
Print(const std::map< std::string, std::string > & variables, const char * text)
Print some text after applying variable substitutions. more...
template void
Print(const char * text, const Args &... args)
Like the first Print(), except the substitutions are given as parameters.
void
Indent()
Indent text by two spaces. more...
void
Outdent()
Reduces the current indent level by two spaces, or crashes if the indent level is zero.
void
PrintRaw(const std::string & data)
Write a string to the output buffer. more...
void
PrintRaw(const char * data)
Write a zero-delimited string to output buffer. more...
void
WriteRaw(const char * data, int size)
Write some bytes to the output buffer. more...
void
FormatInternal(const std::vector< std::string > & args, const std::map< std::string, std::string > & vars, const char * format)
FormatInternal is a helper function not meant to use directly, use compiler::cpp::Formatter instead. more...
bool
failed() const
True if any write to the underlying stream failed. more...

Printer::Printer(
        ZeroCopyOutputStream * output,
        char variable_delimiter)

Create a printer that writes text to the given output stream.

Use the given character as the delimiter for variables.


Printer::Printer(
        ZeroCopyOutputStream * output,
        char variable_delimiter,
        AnnotationCollector * annotation_collector)

Create a printer that writes text to the given output stream.

Use the given character as the delimiter for variables. If annotation_collector is not null, Printer will provide it with annotations about code written to the stream. annotation_collector is not owned by Printer.


template void Printer::Annotate(
        const char * begin_varname,
        const char * end_varname,
        const SomeDescriptor * descriptor)

Link the output range defined by the substitution variables as emitted by the last call to Print to the object described by descriptor.

The range begins at begin_varname's value and ends after the last character of the value substituted for end_varname.


void Printer::Annotate(
        const char * begin_varname,
        const char * end_varname,
        const std::string & file_name)

Link the output range defined by the substitution variables as emitted by the last call to Print to the file with path file_name.

The range begins at begin_varname's value and ends after the last character of the value substituted for end_varname.


void Printer::Print(
        const std::map< std::string, std::string > & variables,
        const char * text)

Print some text after applying variable substitutions.

If a particular variable in the text is not defined, this will crash. Variables to be substituted are identified by their names surrounded by delimiter characters (as given to the constructor). The variable bindings are defined by the given map.


void Printer::Indent()

Indent text by two spaces.

After calling Indent(), two spaces will be inserted at the beginning of each line of text. Indent() may be called multiple times to produce deeper indents.


void Printer::PrintRaw(
        const std::string & data)

Write a string to the output buffer.

This method does not look for newlines to add indentation.


void Printer::PrintRaw(
        const char * data)

Write a zero-delimited string to output buffer.

This method does not look for newlines to add indentation.


void Printer::WriteRaw(
        const char * data,
        int size)

Write some bytes to the output buffer.

This method does not look for newlines to add indentation.


void Printer::FormatInternal(
        const std::vector< std::string > & args,
        const std::map< std::string, std::string > & vars,
        const char * format)

FormatInternal is a helper function not meant to use directly, use compiler::cpp::Formatter instead.

This function is meant to support formatting text using named variables (eq. "$foo$) from a lookup map (vars) +and variables directly supplied by arguments (eq "$1$" meaning first argument which is the zero index element of args).


bool Printer::failed() const

True if any write to the underlying stream failed.

(We don't just crash in this case because this is an I/O failure, not a programming error.)

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.io.tokenizer/index.html b/reference/cpp/api-docs/google.protobuf.io.tokenizer/index.html new file mode 100644 index 000000000..e47f4fdca --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.io.tokenizer/index.html @@ -0,0 +1,29 @@ +tokenizer.h | Protocol Buffers Documentation +

tokenizer.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/io/tokenizer.h>
namespace google::protobuf::io

Class for parsing tokenized text from a ZeroCopyInputStream.

Classes in this file

Abstract interface for an object which collects the errors that occur during parsing.
This class converts a stream of raw text into a stream of tokens for the protocol definition parser to parse.
Structure representing a token read from the token stream.

File Members

These definitions are not part of any class.
typedef
int ColumnNumber
By "column number", the proto compiler refers to a count of the number of bytes before a given byte, except that a tab character advances to the next multiple of 8 bytes. more...

typedef io::ColumnNumber

By "column number", the proto compiler refers to a count of the number of bytes before a given byte, except that a tab character advances to the next multiple of 8 bytes.

Note in particular that column numbers are zero-based, while many user interfaces use one-based column numbers.

class ErrorCollector

#include <google/protobuf/io/tokenizer.h>
namespace google::protobuf::io

Abstract interface for an object which collects the errors that occur during parsing.

A typical implementation might simply print the errors to stdout.

Members

ErrorCollector()
virtual
~ErrorCollector()
virtual void
AddError(int line, ColumnNumber column, const std::string & message) = 0
Indicates that there was an error in the input at the given line and column numbers. more...
virtual void
AddWarning(int , ColumnNumber , const std::string & )
Indicates that there was a warning in the input at the given line and column numbers. more...

virtual void ErrorCollector::AddError(
        int line,
        ColumnNumber column,
        const std::string & message) = 0

Indicates that there was an error in the input at the given line and column numbers.

The numbers are zero-based, so you may want to add 1 to each before printing them.


virtual void ErrorCollector::AddWarning(
        int ,
        ColumnNumber ,
        const std::string & )

Indicates that there was a warning in the input at the given line and column numbers.

The numbers are zero-based, so you may want to add 1 to each before printing them.

class Tokenizer

#include <google/protobuf/io/tokenizer.h>
namespace google::protobuf::io

This class converts a stream of raw text into a stream of tokens for the protocol definition parser to parse.

The tokens recognized are similar to those that make up the C language; see the TokenType enum for precise descriptions. Whitespace and comments are skipped. By default, C- and C++-style comments are recognized, but other styles can be used by calling set_comment_style().

Members

enum
TokenType
Tokenizer(ZeroCopyInputStream * input, ErrorCollector * error_collector)
Construct a Tokenizer that reads and tokenizes text from the given input stream and writes errors to the given error_collector. more...
~Tokenizer()
const Token &
current()
Get the current token. more...
const Token &
previous()
Return the previous token – i.e. more...
bool
Next()
Advance to the next token. more...
bool
NextWithComments(std::string * prev_trailing_comments, std::vector< std::string > * detached_comments, std::string * next_leading_comments)
Like Next(), but also collects comments which appear between the previous and next tokens. more...

Options

enum
CommentStyle
Valid values for set_comment_style(). more...
void
set_allow_f_after_float(bool value)
Set true to allow floats to be suffixed with the letter 'f'. more...
void
set_comment_style(CommentStyle style)
Sets the comment style.
void
set_require_space_after_number(bool require)
Whether to require whitespace between a number and a field name. more...
void
set_allow_multiline_strings(bool allow)
Whether to allow string literals to span multiple lines. more...
static bool
IsIdentifier(const std::string & text)
External helper: validate an identifier.

Parse helpers

static double
ParseFloat(const std::string & text)
Parses a TYPE_FLOAT token. more...
static void
ParseString(const std::string & text, std::string * output)
Parses a TYPE_STRING token. more...
static void
ParseStringAppend(const std::string & text, std::string * output)
Identical to ParseString, but appends to output.
static bool
ParseInteger(const std::string & text, uint64 max_value, uint64 * output)
Parses a TYPE_INTEGER token. more...

enum Tokenizer::TokenType {
  TYPE_START,
  TYPE_END,
  TYPE_IDENTIFIER,
  TYPE_INTEGER,
  TYPE_FLOAT,
  TYPE_STRING,
  TYPE_SYMBOL
}

TYPE_STARTNext() has not yet been called.
TYPE_ENDEnd of input reached. "text" is empty.
TYPE_IDENTIFIER

A sequence of letters, digits, and underscores, not starting with a digit.

It is an error for a number to be followed by an identifier with no space in between.

TYPE_INTEGER

A sequence of digits representing an integer.

Normally the digits are decimal, but a prefix of "0x" indicates a hex number and a leading zero indicates octal, just like with C numeric literals. A leading negative sign is NOT included in the token; it's up to the parser to interpret the unary minus operator on its own.

TYPE_FLOAT

A floating point literal, with a fractional part and/or an exponent.

Always in decimal. Again, never negative.

TYPE_STRING

A quoted sequence of escaped characters.

Either single or double quotes can be used, but they must match. A string literal cannot cross a line break.

TYPE_SYMBOL

Any other printable character, like '!' or '+'.

Symbols are always a single character, so "!+$%" is four tokens.


Tokenizer::Tokenizer(
        ZeroCopyInputStream * input,
        ErrorCollector * error_collector)

Construct a Tokenizer that reads and tokenizes text from the given input stream and writes errors to the given error_collector.

The caller keeps ownership of input and error_collector.


const Token & Tokenizer::current()

Get the current token.

This is updated when Next() is called. Before the first call to Next(), current() has type TYPE_START and no contents.


const Token & Tokenizer::previous()

Return the previous token – i.e.

what current() returned before the previous call to Next().


bool Tokenizer::Next()

Advance to the next token.

Returns false if the end of the input is reached.


bool Tokenizer::NextWithComments(
        std::string * prev_trailing_comments,
        std::vector< std::string > * detached_comments,
        std::string * next_leading_comments)

Like Next(), but also collects comments which appear between the previous and next tokens.

Comments which appear to be attached to the previous token are stored in *prev_tailing_comments. Comments which appear to be attached to the next token are stored in *next_leading_comments. Comments appearing in between which do not appear to be attached to either will be added to detached_comments. Any of these parameters can be NULL to simply discard the comments.

A series of line comments appearing on consecutive lines, with no other tokens appearing on those lines, will be treated as a single comment.

Only the comment content is returned; comment markers (e.g. //) are stripped out. For block comments, leading whitespace and an asterisk will be stripped from the beginning of each line other than the first. Newlines are included in the output.

Examples:

optional int32 foo = 1;  // Comment attached to foo.
+// Comment attached to bar.
+optional int32 bar = 2;
+

optional string baz = 3; +// Comment attached to baz. +// Another line attached to baz.

+

// Comment attached to qux. +// +// Another line attached to qux. +optional double qux = 4;

+

// Detached comment. This is not attached to qux or corge +// because there are blank lines separating it from both.

+

optional string corge = 5; +/* Block comment attached

+
    +
  • to corge. Leading asterisks
  • +
  • will be removed. * / +/* Block comment attached to
  • +
  • grault. * / +optional int32 grault = 6; +
      +

enum Tokenizer::CommentStyle {
  CPP_COMMENT_STYLE,
  SH_COMMENT_STYLE
}

Valid values for set_comment_style().

CPP_COMMENT_STYLELine comments begin with "//", block comments are delimited by "/*" and "* /".
SH_COMMENT_STYLELine comments begin with "#". No way to write block comments.

void Tokenizer::set_allow_f_after_float(
        bool value)

Set true to allow floats to be suffixed with the letter 'f'.

Tokens which would otherwise be integers but which have the 'f' suffix will be forced to be interpreted as floats. For all other purposes, the 'f' is ignored.


void Tokenizer::set_require_space_after_number(
        bool require)

Whether to require whitespace between a number and a field name.

Default is true. Do not use this; for Google-internal cleanup only.


void Tokenizer::set_allow_multiline_strings(
        bool allow)

Whether to allow string literals to span multiple lines.

Default is false. Do not use this; for Google-internal cleanup only.


static double Tokenizer::ParseFloat(
        const std::string & text)

Parses a TYPE_FLOAT token.

This never fails, so long as the text actually comes from a TYPE_FLOAT token parsed by Tokenizer. If it doesn't, the result is undefined (possibly an assert failure).


static void Tokenizer::ParseString(
        const std::string & text,
        std::string * output)

Parses a TYPE_STRING token.

This never fails, so long as the text actually comes from a TYPE_STRING token parsed by Tokenizer. If it doesn't, the result is undefined (possibly an assert failure).


static bool Tokenizer::ParseInteger(
        const std::string & text,
        uint64 max_value,
        uint64 * output)

Parses a TYPE_INTEGER token.

Returns false if the result would be greater than max_value. Otherwise, returns true and sets *output to the result. If the text is not from a Token of type TYPE_INTEGER originally parsed by a Tokenizer, the result is undefined (possibly an assert failure).

struct Tokenizer::Token

#include <google/protobuf/io/tokenizer.h>
namespace google::protobuf::io

Structure representing a token read from the token stream.

Members

TokenType
type
std::string
text
The exact text of the token as it appeared in the input. more...
int
line
"line" and "column" specify the position of the first character of the token within the input stream. more...
ColumnNumber
column
ColumnNumber
end_column

std::string Token::text

The exact text of the token as it appeared in the input.

e.g. tokens of TYPE_STRING will still be escaped and in quotes.


int Token::line

"line" and "column" specify the position of the first character of the token within the input stream.

They are zero-based.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream/index.html b/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream/index.html new file mode 100644 index 000000000..4bc807235 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream/index.html @@ -0,0 +1,43 @@ +zero_copy_stream.h | Protocol Buffers Documentation +

zero_copy_stream.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/io/zero_copy_stream.h>
namespace google::protobuf::io

This file contains the ZeroCopyInputStream and ZeroCopyOutputStream interfaces, which represent abstract I/O streams to and from which protocol buffers can be read and written.

For a few simple implementations of these interfaces, see zero_copy_stream_impl.h.

These interfaces are different from classic I/O streams in that they try to minimize the amount of data copying that needs to be done. To accomplish this, responsibility for allocating buffers is moved to the stream object, rather than being the responsibility of the caller. So, the stream can return a buffer which actually points directly into the final data structure where the bytes are to be stored, and the caller can interact directly with that buffer, eliminating an intermediate copy operation.

As an example, consider the common case in which you are reading bytes from an array that is already in memory (or perhaps an mmap()ed file). With classic I/O streams, you would do something like:

char buffer[BUFFER_SIZE];
+input->Read(buffer, BUFFER_SIZE);
+DoSomething(buffer, BUFFER_SIZE);

Then, the stream basically just calls memcpy() to copy the data from the array into your buffer. With a ZeroCopyInputStream, you would do this instead:

const void* buffer;
+int size;
+input->Next(&buffer, &size);
+DoSomething(buffer, size);

Here, no copy is performed. The input stream returns a pointer directly into the backing array, and the caller ends up reading directly from it.

If you want to be able to read the old-fashion way, you can create a CodedInputStream or CodedOutputStream wrapping these objects and use their ReadRaw()/WriteRaw() methods. These will, of course, add a copy step, but Coded*Stream will handle buffering so at least it will be reasonably efficient.

ZeroCopyInputStream example:

// Read in a file and print its contents to stdout.
+int fd = open("myfile", O_RDONLY);
+ZeroCopyInputStream* input = new FileInputStream(fd);
+
+const void* buffer;
+int size;
+while (input->Next(&buffer, &size)) {
+  cout.write(buffer, size);
+}
+
+delete input;
+close(fd);

ZeroCopyOutputStream example:

// Copy the contents of "infile" to "outfile", using plain read() for
+// "infile" but a ZeroCopyOutputStream for "outfile".
+int infd = open("infile", O_RDONLY);
+int outfd = open("outfile", O_WRONLY);
+ZeroCopyOutputStream* output = new FileOutputStream(outfd);
+
+void* buffer;
+int size;
+while (output->Next(&buffer, &size)) {
+  int bytes = read(infd, buffer, size);
+  if (bytes < size) {
+    // Reached EOF.
+    output->BackUp(size - bytes);
+    break;
+  }
+}
+
+delete output;
+close(infd);
+close(outfd);

Classes in this file

Abstract interface similar to an input stream but designed to minimize copying.
Abstract interface similar to an output stream but designed to minimize copying.

class ZeroCopyInputStream

#include <google/protobuf/io/zero_copy_stream.h>
namespace google::protobuf::io

Abstract interface similar to an input stream but designed to minimize copying.

Known subclasses:

Members

ZeroCopyInputStream()
virtual
~ZeroCopyInputStream()
virtual bool
Next(const void ** data, int * size) = 0
Obtains a chunk of data from the stream. more...
virtual void
BackUp(int count) = 0
Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next(). more...
virtual bool
Skip(int count) = 0
Skips a number of bytes. more...
virtual int64_t
ByteCount() const = 0
Returns the total number of bytes read since this object was created.

virtual bool ZeroCopyInputStream::Next(
        const void ** data,
        int * size) = 0

Obtains a chunk of data from the stream.

Preconditions:

  • "size" and "data" are not NULL.

Postconditions:

  • If the returned value is false, there is no more data to return or an error occurred. All errors are permanent.
  • Otherwise, "size" points to the actual number of bytes read and "data" points to a pointer to a buffer containing these bytes.
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.

virtual void ZeroCopyInputStream::BackUp(
        int count) = 0

Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next().

This is useful when writing procedures that are only supposed to read up to a certain point in the input, then return. If Next() returns a buffer that goes beyond what you wanted to read, you can use BackUp() to return to the point where you intended to finish.

Preconditions:

  • The last method called must have been Next().
  • count must be less than or equal to the size of the last buffer returned by Next().

Postconditions:

  • The last "count" bytes of the last buffer returned by Next() will be pushed back into the stream. Subsequent calls to Next() will return the same data again before producing new data.

virtual bool ZeroCopyInputStream::Skip(
        int count) = 0

Skips a number of bytes.

Returns false if the end of the stream is reached or some input error occurred. In the end-of-stream case, the stream is advanced to the end of the stream (so ByteCount() will return the total size of the stream).

class ZeroCopyOutputStream

#include <google/protobuf/io/zero_copy_stream.h>
namespace google::protobuf::io

Abstract interface similar to an output stream but designed to minimize copying.

Known subclasses:

Members

ZeroCopyOutputStream()
virtual
~ZeroCopyOutputStream()
virtual bool
Next(void ** data, int * size) = 0
Obtains a buffer into which data can be written. more...
virtual void
BackUp(int count) = 0
Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written. more...
virtual int64_t
ByteCount() const = 0
Returns the total number of bytes written since this object was created.
virtual bool
WriteAliasedRaw(const void * data, int size)
Write a given chunk of data to the output. more...
virtual bool
AllowsAliasing() const

virtual bool ZeroCopyOutputStream::Next(
        void ** data,
        int * size) = 0

Obtains a buffer into which data can be written.

Any data written into this buffer will eventually (maybe instantly, maybe later on) be written to the output.

Preconditions:

  • "size" and "data" are not NULL.

Postconditions:

  • If the returned value is false, an error occurred. All errors are permanent.
  • Otherwise, "size" points to the actual number of bytes in the buffer and "data" points to the buffer.
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • Any data which the caller stores in this buffer will eventually be written to the output (unless BackUp() is called).
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.

virtual void ZeroCopyOutputStream::BackUp(
        int count) = 0

Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written.

This is needed when you finish writing all the data you want to write, but the last buffer was bigger than you needed. You don't want to write a bunch of garbage after the end of your data, so you use BackUp() to back up.

Preconditions:

  • The last method called must have been Next().
  • count must be less than or equal to the size of the last buffer returned by Next().
  • The caller must not have written anything to the last "count" bytes of that buffer.

Postconditions:

  • The last "count" bytes of the last buffer returned by Next() will be ignored.

virtual bool ZeroCopyOutputStream::WriteAliasedRaw(
        const void * data,
        int size)

Write a given chunk of data to the output.

Some output streams may implement this in a way that avoids copying. Check AllowsAliasing() before calling WriteAliasedRaw(). It will GOOGLE_CHECK fail if WriteAliasedRaw() is called on a stream that does not allow aliasing.

NOTE: It is caller's responsibility to ensure that the chunk of memory remains live until all of the data has been consumed from the stream.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl/index.html b/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl/index.html new file mode 100644 index 000000000..633ec10f6 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl/index.html @@ -0,0 +1,8 @@ +zero_copy_stream_impl.h | Protocol Buffers Documentation +

zero_copy_stream_impl.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/io/zero_copy_stream_impl.h>
namespace google::protobuf::io

This file contains common implementations of the interfaces defined in zero_copy_stream.h which are only included in the full (non-lite) protobuf library.

These implementations include Unix file descriptors and C++ iostreams. See also: zero_copy_stream_impl_lite.h

Classes in this file

A ZeroCopyInputStream which reads from a file descriptor.
A ZeroCopyOutputStream which writes to a file descriptor.
A ZeroCopyInputStream which reads from a C++ istream.
A ZeroCopyOutputStream which writes to a C++ ostream.
A ZeroCopyInputStream which reads from several other streams in sequence.

class FileInputStream: public ZeroCopyInputStream

#include <google/protobuf/io/zero_copy_stream_impl.h>
namespace google::protobuf::io

A ZeroCopyInputStream which reads from a file descriptor.

FileInputStream is preferred over using an ifstream with IstreamInputStream. The latter will introduce an extra layer of buffering, harming performance. Also, it's conceivable that FileInputStream could someday be enhanced to use zero-copy file descriptors on OSs which support them.

Members

explicit
FileInputStream(int file_descriptor, int block_size = -1)
Creates a stream that reads from the given Unix file descriptor. more...
bool
Close()
Flushes any buffers and closes the underlying file. more...
void
SetCloseOnDelete(bool value)
By default, the file descriptor is not closed when the stream is destroyed. more...
int
GetErrno() const
If an I/O error has occurred on this file descriptor, this is the errno from that error. more...

implements ZeroCopyInputStream

virtual bool
Next(const void ** data, int * size)
Obtains a chunk of data from the stream. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next(). more...
virtual bool
Skip(int count)
Skips a number of bytes. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes read since this object was created.

explicit FileInputStream::FileInputStream(
        int file_descriptor,
        int block_size = -1)

Creates a stream that reads from the given Unix file descriptor.

If a block_size is given, it specifies the number of bytes that should be read and returned with each call to Next(). Otherwise, a reasonable default is used.


bool FileInputStream::Close()

Flushes any buffers and closes the underlying file.

Returns false if an error occurs during the process; use GetErrno() to examine the error. Even if an error occurs, the file descriptor is closed when this returns.


void FileInputStream::SetCloseOnDelete(
        bool value)

By default, the file descriptor is not closed when the stream is destroyed.

Call SetCloseOnDelete(true) to change that. WARNING: This leaves no way for the caller to detect if close() fails. If detecting close() errors is important to you, you should arrange to close the descriptor yourself.


int FileInputStream::GetErrno() const

If an I/O error has occurred on this file descriptor, this is the errno from that error.

Otherwise, this is zero. Once an error occurs, the stream is broken and all subsequent operations will fail.


virtual bool FileInputStream::Next(
        const void ** data,
        int * size)

Obtains a chunk of data from the stream.

Preconditions:

  • "size" and "data" are not NULL.

Postconditions:

  • If the returned value is false, there is no more data to return or an error occurred. All errors are permanent.
  • Otherwise, "size" points to the actual number of bytes read and "data" points to a pointer to a buffer containing these bytes.
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.

virtual void FileInputStream::BackUp(
        int count)

Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next().

This is useful when writing procedures that are only supposed to read up to a certain point in the input, then return. If Next() returns a buffer that goes beyond what you wanted to read, you can use BackUp() to return to the point where you intended to finish.

Preconditions:

  • The last method called must have been Next().
  • count must be less than or equal to the size of the last buffer returned by Next().

Postconditions:

  • The last "count" bytes of the last buffer returned by Next() will be pushed back into the stream. Subsequent calls to Next() will return the same data again before producing new data.

virtual bool FileInputStream::Skip(
        int count)

Skips a number of bytes.

Returns false if the end of the stream is reached or some input error occurred. In the end-of-stream case, the stream is advanced to the end of the stream (so ByteCount() will return the total size of the stream).

class FileOutputStream: public CopyingOutputStreamAdaptor

#include <google/protobuf/io/zero_copy_stream_impl.h>
namespace google::protobuf::io

A ZeroCopyOutputStream which writes to a file descriptor.

FileOutputStream is preferred over using an ofstream with OstreamOutputStream. The latter will introduce an extra layer of buffering, harming performance. Also, it's conceivable that FileOutputStream could someday be enhanced to use zero-copy file descriptors on OSs which support them.

Members

explicit
FileOutputStream(int file_descriptor, int block_size = -1)
Creates a stream that writes to the given Unix file descriptor. more...
~FileOutputStream()
bool
Close()
Flushes any buffers and closes the underlying file. more...
void
SetCloseOnDelete(bool value)
By default, the file descriptor is not closed when the stream is destroyed. more...
int
GetErrno() const
If an I/O error has occurred on this file descriptor, this is the errno from that error. more...

explicit FileOutputStream::FileOutputStream(
        int file_descriptor,
        int block_size = -1)

Creates a stream that writes to the given Unix file descriptor.

If a block_size is given, it specifies the size of the buffers that should be returned by Next(). Otherwise, a reasonable default is used.


bool FileOutputStream::Close()

Flushes any buffers and closes the underlying file.

Returns false if an error occurs during the process; use GetErrno() to examine the error. Even if an error occurs, the file descriptor is closed when this returns.


void FileOutputStream::SetCloseOnDelete(
        bool value)

By default, the file descriptor is not closed when the stream is destroyed.

Call SetCloseOnDelete(true) to change that. WARNING: This leaves no way for the caller to detect if close() fails. If detecting close() errors is important to you, you should arrange to close the descriptor yourself.


int FileOutputStream::GetErrno() const

If an I/O error has occurred on this file descriptor, this is the errno from that error.

Otherwise, this is zero. Once an error occurs, the stream is broken and all subsequent operations will fail.

class IstreamInputStream: public ZeroCopyInputStream

#include <google/protobuf/io/zero_copy_stream_impl.h>
namespace google::protobuf::io

A ZeroCopyInputStream which reads from a C++ istream.

Note that for reading files (or anything represented by a file descriptor), FileInputStream is more efficient.

Members

explicit
IstreamInputStream(std::istream * stream, int block_size = -1)
Creates a stream that reads from the given C++ istream. more...

implements ZeroCopyInputStream

virtual bool
Next(const void ** data, int * size)
Obtains a chunk of data from the stream. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next(). more...
virtual bool
Skip(int count)
Skips a number of bytes. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes read since this object was created.

explicit IstreamInputStream::IstreamInputStream(
        std::istream * stream,
        int block_size = -1)

Creates a stream that reads from the given C++ istream.

If a block_size is given, it specifies the number of bytes that should be read and returned with each call to Next(). Otherwise, a reasonable default is used.


virtual bool IstreamInputStream::Next(
        const void ** data,
        int * size)

Obtains a chunk of data from the stream.

Preconditions:

  • "size" and "data" are not NULL.

Postconditions:

  • If the returned value is false, there is no more data to return or an error occurred. All errors are permanent.
  • Otherwise, "size" points to the actual number of bytes read and "data" points to a pointer to a buffer containing these bytes.
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.

virtual void IstreamInputStream::BackUp(
        int count)

Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next().

This is useful when writing procedures that are only supposed to read up to a certain point in the input, then return. If Next() returns a buffer that goes beyond what you wanted to read, you can use BackUp() to return to the point where you intended to finish.

Preconditions:

  • The last method called must have been Next().
  • count must be less than or equal to the size of the last buffer returned by Next().

Postconditions:

  • The last "count" bytes of the last buffer returned by Next() will be pushed back into the stream. Subsequent calls to Next() will return the same data again before producing new data.

virtual bool IstreamInputStream::Skip(
        int count)

Skips a number of bytes.

Returns false if the end of the stream is reached or some input error occurred. In the end-of-stream case, the stream is advanced to the end of the stream (so ByteCount() will return the total size of the stream).

class OstreamOutputStream: public ZeroCopyOutputStream

#include <google/protobuf/io/zero_copy_stream_impl.h>
namespace google::protobuf::io

A ZeroCopyOutputStream which writes to a C++ ostream.

Note that for writing files (or anything represented by a file descriptor), FileOutputStream is more efficient.

Members

explicit
OstreamOutputStream(std::ostream * stream, int block_size = -1)
Creates a stream that writes to the given C++ ostream. more...
~OstreamOutputStream()

implements ZeroCopyOutputStream

virtual bool
Next(void ** data, int * size)
Obtains a buffer into which data can be written. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes written since this object was created.

explicit OstreamOutputStream::OstreamOutputStream(
        std::ostream * stream,
        int block_size = -1)

Creates a stream that writes to the given C++ ostream.

If a block_size is given, it specifies the size of the buffers that should be returned by Next(). Otherwise, a reasonable default is used.


virtual bool OstreamOutputStream::Next(
        void ** data,
        int * size)

Obtains a buffer into which data can be written.

Any data written into this buffer will eventually (maybe instantly, maybe later on) be written to the output.

Preconditions:

  • "size" and "data" are not NULL.

Postconditions:

  • If the returned value is false, an error occurred. All errors are permanent.
  • Otherwise, "size" points to the actual number of bytes in the buffer and "data" points to the buffer.
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • Any data which the caller stores in this buffer will eventually be written to the output (unless BackUp() is called).
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.

virtual void OstreamOutputStream::BackUp(
        int count)

Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written.

This is needed when you finish writing all the data you want to write, but the last buffer was bigger than you needed. You don't want to write a bunch of garbage after the end of your data, so you use BackUp() to back up.

Preconditions:

  • The last method called must have been Next().
  • count must be less than or equal to the size of the last buffer returned by Next().
  • The caller must not have written anything to the last "count" bytes of that buffer.

Postconditions:

  • The last "count" bytes of the last buffer returned by Next() will be ignored.

class ConcatenatingInputStream: public ZeroCopyInputStream

#include <google/protobuf/io/zero_copy_stream_impl.h>
namespace google::protobuf::io

A ZeroCopyInputStream which reads from several other streams in sequence.

ConcatenatingInputStream is unable to distinguish between end-of-stream and read errors in the underlying streams, so it assumes any errors mean end-of-stream. So, if the underlying streams fail for any other reason, ConcatenatingInputStream may do odd things. It is suggested that you do not use ConcatenatingInputStream on streams that might produce read errors other than end-of-stream.

Members

ConcatenatingInputStream(ZeroCopyInputStream *const streams, int count)
All streams passed in as well as the array itself must remain valid until the ConcatenatingInputStream is destroyed.
~ConcatenatingInputStream()

implements ZeroCopyInputStream

virtual bool
Next(const void ** data, int * size)
Obtains a chunk of data from the stream. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next(). more...
virtual bool
Skip(int count)
Skips a number of bytes. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes read since this object was created.

virtual bool ConcatenatingInputStream::Next(
        const void ** data,
        int * size)

Obtains a chunk of data from the stream.

Preconditions:

  • "size" and "data" are not NULL.

Postconditions:

  • If the returned value is false, there is no more data to return or an error occurred. All errors are permanent.
  • Otherwise, "size" points to the actual number of bytes read and "data" points to a pointer to a buffer containing these bytes.
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.

virtual void ConcatenatingInputStream::BackUp(
        int count)

Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next().

This is useful when writing procedures that are only supposed to read up to a certain point in the input, then return. If Next() returns a buffer that goes beyond what you wanted to read, you can use BackUp() to return to the point where you intended to finish.

Preconditions:

  • The last method called must have been Next().
  • count must be less than or equal to the size of the last buffer returned by Next().

Postconditions:

  • The last "count" bytes of the last buffer returned by Next() will be pushed back into the stream. Subsequent calls to Next() will return the same data again before producing new data.

virtual bool ConcatenatingInputStream::Skip(
        int count)

Skips a number of bytes.

Returns false if the end of the stream is reached or some input error occurred. In the end-of-stream case, the stream is advanced to the end of the stream (so ByteCount() will return the total size of the stream).

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl_lite/index.html b/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl_lite/index.html new file mode 100644 index 000000000..65c1c88fd --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl_lite/index.html @@ -0,0 +1,8 @@ +zero_copy_stream_iml_lite.h | Protocol Buffers Documentation +

zero_copy_stream_iml_lite.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

This file contains common implementations of the interfaces defined in zero_copy_stream.h which are included in the "lite" protobuf library.

These implementations cover I/O on raw arrays and strings, as well as adaptors which make it easy to implement streams based on traditional streams. Of course, many users will probably want to write their own implementations of these interfaces specific to the particular I/O abstractions they prefer to use, but these should cover the most common cases.

Classes in this file

A ZeroCopyInputStream backed by an in-memory array of bytes.
A ZeroCopyOutputStream backed by an in-memory array of bytes.
A ZeroCopyOutputStream which appends bytes to a string.
A generic traditional input stream interface.
A generic traditional output stream interface.
A ZeroCopyInputStream which wraps some other stream and limits it to a particular byte count.

File Members

These definitions are not part of any class.
char *
mutable_string_data(std::string * s)
Return a pointer to mutable characters underlying the given string. more...
std::pair< char *, bool >
as_string_data(std::string * s)
as_string_data(s) is equivalent to ({ char* p = mutable_string_data(s); make_pair(p, p != NULL); }) Sometimes it's faster: in some scenarios p cannot be NULL, and then the code can avoid that check.

char * io::mutable_string_data(
        std::string * s)

Return a pointer to mutable characters underlying the given string.

The return value is valid until the next time the string is resized. We trust the caller to treat the return value as an array of length s->size().

class ArrayInputStream: public ZeroCopyInputStream

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

A ZeroCopyInputStream backed by an in-memory array of bytes.

Members

ArrayInputStream(const void * data, int size, int block_size = -1)
Create an InputStream that returns the bytes pointed to by "data". more...
~ArrayInputStream()

implements ZeroCopyInputStream

virtual bool
Next(const void ** data, int * size)
Obtains a chunk of data from the stream. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next(). more...
virtual bool
Skip(int count)
Skips a number of bytes. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes read since this object was created.

ArrayInputStream::ArrayInputStream(
        const void * data,
        int size,
        int block_size = -1)

Create an InputStream that returns the bytes pointed to by "data".

"data" remains the property of the caller but must remain valid until the stream is destroyed. If a block_size is given, calls to Next() will return data blocks no larger than the given size. Otherwise, the first call to Next() returns the entire array. block_size is mainly useful for testing; in production you would probably never want to set it.


virtual bool ArrayInputStream::Next(
        const void ** data,
        int * size)

Obtains a chunk of data from the stream.

Preconditions:

  • "size" and "data" are not NULL.

Postconditions:

  • If the returned value is false, there is no more data to return or an error occurred. All errors are permanent.
  • Otherwise, "size" points to the actual number of bytes read and "data" points to a pointer to a buffer containing these bytes.
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.

virtual void ArrayInputStream::BackUp(
        int count)

Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next().

This is useful when writing procedures that are only supposed to read up to a certain point in the input, then return. If Next() returns a buffer that goes beyond what you wanted to read, you can use BackUp() to return to the point where you intended to finish.

Preconditions:

  • The last method called must have been Next().
  • count must be less than or equal to the size of the last buffer returned by Next().

Postconditions:

  • The last "count" bytes of the last buffer returned by Next() will be pushed back into the stream. Subsequent calls to Next() will return the same data again before producing new data.

virtual bool ArrayInputStream::Skip(
        int count)

Skips a number of bytes.

Returns false if the end of the stream is reached or some input error occurred. In the end-of-stream case, the stream is advanced to the end of the stream (so ByteCount() will return the total size of the stream).

class ArrayOutputStream: public ZeroCopyOutputStream

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

A ZeroCopyOutputStream backed by an in-memory array of bytes.

Members

ArrayOutputStream(void * data, int size, int block_size = -1)
Create an OutputStream that writes to the bytes pointed to by "data". more...
~ArrayOutputStream()

implements ZeroCopyOutputStream

virtual bool
Next(void ** data, int * size)
Obtains a buffer into which data can be written. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes written since this object was created.

ArrayOutputStream::ArrayOutputStream(
        void * data,
        int size,
        int block_size = -1)

Create an OutputStream that writes to the bytes pointed to by "data".

"data" remains the property of the caller but must remain valid until the stream is destroyed. If a block_size is given, calls to Next() will return data blocks no larger than the given size. Otherwise, the first call to Next() returns the entire array. block_size is mainly useful for testing; in production you would probably never want to set it.


virtual bool ArrayOutputStream::Next(
        void ** data,
        int * size)

Obtains a buffer into which data can be written.

Any data written into this buffer will eventually (maybe instantly, maybe later on) be written to the output.

Preconditions:

  • "size" and "data" are not NULL.

Postconditions:

  • If the returned value is false, an error occurred. All errors are permanent.
  • Otherwise, "size" points to the actual number of bytes in the buffer and "data" points to the buffer.
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • Any data which the caller stores in this buffer will eventually be written to the output (unless BackUp() is called).
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.

virtual void ArrayOutputStream::BackUp(
        int count)

Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written.

This is needed when you finish writing all the data you want to write, but the last buffer was bigger than you needed. You don't want to write a bunch of garbage after the end of your data, so you use BackUp() to back up.

Preconditions:

  • The last method called must have been Next().
  • count must be less than or equal to the size of the last buffer returned by Next().
  • The caller must not have written anything to the last "count" bytes of that buffer.

Postconditions:

  • The last "count" bytes of the last buffer returned by Next() will be ignored.

class StringOutputStream: public ZeroCopyOutputStream

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

A ZeroCopyOutputStream which appends bytes to a string.

Members

explicit
StringOutputStream(std::string * target)
Create a StringOutputStream which appends bytes to the given string. more...
~StringOutputStream()

implements ZeroCopyOutputStream

virtual bool
Next(void ** data, int * size)
Obtains a buffer into which data can be written. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes written since this object was created.

explicit StringOutputStream::StringOutputStream(
        std::string * target)

Create a StringOutputStream which appends bytes to the given string.

The string remains property of the caller, but it is mutated in arbitrary ways and MUST NOT be accessed in any way until you're done with the stream. Either be sure there's no further usage, or (safest) destroy the stream before using the contents.

Hint: If you call target->reserve(n) before creating the stream, the first call to Next() will return at least n bytes of buffer space.


virtual bool StringOutputStream::Next(
        void ** data,
        int * size)

Obtains a buffer into which data can be written.

Any data written into this buffer will eventually (maybe instantly, maybe later on) be written to the output.

Preconditions:

  • "size" and "data" are not NULL.

Postconditions:

  • If the returned value is false, an error occurred. All errors are permanent.
  • Otherwise, "size" points to the actual number of bytes in the buffer and "data" points to the buffer.
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • Any data which the caller stores in this buffer will eventually be written to the output (unless BackUp() is called).
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.

virtual void StringOutputStream::BackUp(
        int count)

Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written.

This is needed when you finish writing all the data you want to write, but the last buffer was bigger than you needed. You don't want to write a bunch of garbage after the end of your data, so you use BackUp() to back up.

Preconditions:

  • The last method called must have been Next().
  • count must be less than or equal to the size of the last buffer returned by Next().
  • The caller must not have written anything to the last "count" bytes of that buffer.

Postconditions:

  • The last "count" bytes of the last buffer returned by Next() will be ignored.

class CopyingInputStream

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

A generic traditional input stream interface.

Lots of traditional input streams (e.g. file descriptors, C stdio streams, and C++ iostreams) expose an interface where every read involves copying bytes into a buffer. If you want to take such an interface and make a ZeroCopyInputStream based on it, simply implement CopyingInputStream and then use CopyingInputStreamAdaptor.

CopyingInputStream implementations should avoid buffering if possible. CopyingInputStreamAdaptor does its own buffering and will read data in large blocks.

Members

virtual
~CopyingInputStream()
virtual int
Read(void * buffer, int size) = 0
Reads up to "size" bytes into the given buffer. more...
virtual int
Skip(int count)
Skips the next "count" bytes of input. more...

virtual int CopyingInputStream::Read(
        void * buffer,
        int size) = 0

Reads up to "size" bytes into the given buffer.

Returns the number of bytes read. Read() waits until at least one byte is available, or returns zero if no bytes will ever become available (EOF), or -1 if a permanent read error occurred.


virtual int CopyingInputStream::Skip(
        int count)

Skips the next "count" bytes of input.

Returns the number of bytes actually skipped. This will always be exactly equal to "count" unless EOF was reached or a permanent read error occurred.

The default implementation just repeatedly calls Read() into a scratch buffer.

class CopyingInputStreamAdaptor: public ZeroCopyInputStream

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

A ZeroCopyInputStream which reads from a CopyingInputStream.

This is useful for implementing ZeroCopyInputStreams that read from traditional streams. Note that this class is not really zero-copy.

If you want to read from file descriptors or C++ istreams, this is already implemented for you: use FileInputStream or IstreamInputStream respectively.

Members

explicit
CopyingInputStreamAdaptor(CopyingInputStream * copying_stream, int block_size = -1)
Creates a stream that reads from the given CopyingInputStream. more...
~CopyingInputStreamAdaptor()
void
SetOwnsCopyingStream(bool value)
Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to delete the underlying CopyingInputStream when it is destroyed.

implements ZeroCopyInputStream

virtual bool
Next(const void ** data, int * size)
Obtains a chunk of data from the stream. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next(). more...
virtual bool
Skip(int count)
Skips a number of bytes. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes read since this object was created.

explicit CopyingInputStreamAdaptor::CopyingInputStreamAdaptor(
        CopyingInputStream * copying_stream,
        int block_size = -1)

Creates a stream that reads from the given CopyingInputStream.

If a block_size is given, it specifies the number of bytes that should be read and returned with each call to Next(). Otherwise, a reasonable default is used. The caller retains ownership of copying_stream unless SetOwnsCopyingStream(true) is called.


virtual bool CopyingInputStreamAdaptor::Next(
        const void ** data,
        int * size)

Obtains a chunk of data from the stream.

Preconditions:

  • "size" and "data" are not NULL.

Postconditions:

  • If the returned value is false, there is no more data to return or an error occurred. All errors are permanent.
  • Otherwise, "size" points to the actual number of bytes read and "data" points to a pointer to a buffer containing these bytes.
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.

virtual void CopyingInputStreamAdaptor::BackUp(
        int count)

Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next().

This is useful when writing procedures that are only supposed to read up to a certain point in the input, then return. If Next() returns a buffer that goes beyond what you wanted to read, you can use BackUp() to return to the point where you intended to finish.

Preconditions:

  • The last method called must have been Next().
  • count must be less than or equal to the size of the last buffer returned by Next().

Postconditions:

  • The last "count" bytes of the last buffer returned by Next() will be pushed back into the stream. Subsequent calls to Next() will return the same data again before producing new data.

virtual bool CopyingInputStreamAdaptor::Skip(
        int count)

Skips a number of bytes.

Returns false if the end of the stream is reached or some input error occurred. In the end-of-stream case, the stream is advanced to the end of the stream (so ByteCount() will return the total size of the stream).

class CopyingOutputStream

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

A generic traditional output stream interface.

Lots of traditional output streams (e.g. file descriptors, C stdio streams, and C++ iostreams) expose an interface where every write involves copying bytes from a buffer. If you want to take such an interface and make a ZeroCopyOutputStream based on it, simply implement CopyingOutputStream and then use CopyingOutputStreamAdaptor.

CopyingOutputStream implementations should avoid buffering if possible. CopyingOutputStreamAdaptor does its own buffering and will write data in large blocks.

Members

virtual
~CopyingOutputStream()
virtual bool
Write(const void * buffer, int size) = 0
Writes "size" bytes from the given buffer to the output. more...

virtual bool CopyingOutputStream::Write(
        const void * buffer,
        int size) = 0

Writes "size" bytes from the given buffer to the output.

Returns true if successful, false on a write error.

class CopyingOutputStreamAdaptor: public ZeroCopyOutputStream

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

A ZeroCopyOutputStream which writes to a CopyingOutputStream.

This is useful for implementing ZeroCopyOutputStreams that write to traditional streams. Note that this class is not really zero-copy.

If you want to write to file descriptors or C++ ostreams, this is already implemented for you: use FileOutputStream or OstreamOutputStream respectively.

Known subclasses:

Members

explicit
CopyingOutputStreamAdaptor(CopyingOutputStream * copying_stream, int block_size = -1)
Creates a stream that writes to the given Unix file descriptor. more...
~CopyingOutputStreamAdaptor()
bool
Flush()
Writes all pending data to the underlying stream. more...
void
SetOwnsCopyingStream(bool value)
Call SetOwnsCopyingStream(true) to tell the CopyingOutputStreamAdaptor to delete the underlying CopyingOutputStream when it is destroyed.

implements ZeroCopyOutputStream

virtual bool
Next(void ** data, int * size)
Obtains a buffer into which data can be written. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes written since this object was created.
virtual bool
WriteAliasedRaw(const void * data, int size)
Write a given chunk of data to the output. more...
virtual bool
AllowsAliasing() const

explicit CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor(
        CopyingOutputStream * copying_stream,
        int block_size = -1)

Creates a stream that writes to the given Unix file descriptor.

If a block_size is given, it specifies the size of the buffers that should be returned by Next(). Otherwise, a reasonable default is used.


bool CopyingOutputStreamAdaptor::Flush()

Writes all pending data to the underlying stream.

Returns false if a write error occurred on the underlying stream. (The underlying stream itself is not necessarily flushed.)


virtual bool CopyingOutputStreamAdaptor::Next(
        void ** data,
        int * size)

Obtains a buffer into which data can be written.

Any data written into this buffer will eventually (maybe instantly, maybe later on) be written to the output.

Preconditions:

  • "size" and "data" are not NULL.

Postconditions:

  • If the returned value is false, an error occurred. All errors are permanent.
  • Otherwise, "size" points to the actual number of bytes in the buffer and "data" points to the buffer.
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • Any data which the caller stores in this buffer will eventually be written to the output (unless BackUp() is called).
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.

virtual void CopyingOutputStreamAdaptor::BackUp(
        int count)

Backs up a number of bytes, so that the end of the last buffer returned by Next() is not actually written.

This is needed when you finish writing all the data you want to write, but the last buffer was bigger than you needed. You don't want to write a bunch of garbage after the end of your data, so you use BackUp() to back up.

Preconditions:

  • The last method called must have been Next().
  • count must be less than or equal to the size of the last buffer returned by Next().
  • The caller must not have written anything to the last "count" bytes of that buffer.

Postconditions:

  • The last "count" bytes of the last buffer returned by Next() will be ignored.

virtual bool CopyingOutputStreamAdaptor::WriteAliasedRaw(
        const void * data,
        int size)

Write a given chunk of data to the output.

Some output streams may implement this in a way that avoids copying. Check AllowsAliasing() before calling WriteAliasedRaw(). It will GOOGLE_CHECK fail if WriteAliasedRaw() is called on a stream that does not allow aliasing.

NOTE: It is caller's responsibility to ensure that the chunk of memory remains live until all of the data has been consumed from the stream.

class LimitingInputStream: public ZeroCopyInputStream

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

A ZeroCopyInputStream which wraps some other stream and limits it to a particular byte count.

Members

LimitingInputStream(ZeroCopyInputStream * input, int64 limit)
~LimitingInputStream()

implements ZeroCopyInputStream

virtual bool
Next(const void ** data, int * size)
Obtains a chunk of data from the stream. more...
virtual void
BackUp(int count)
Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next(). more...
virtual bool
Skip(int count)
Skips a number of bytes. more...
virtual int64_t
ByteCount() const
Returns the total number of bytes read since this object was created.

virtual bool LimitingInputStream::Next(
        const void ** data,
        int * size)

Obtains a chunk of data from the stream.

Preconditions:

  • "size" and "data" are not NULL.

Postconditions:

  • If the returned value is false, there is no more data to return or an error occurred. All errors are permanent.
  • Otherwise, "size" points to the actual number of bytes read and "data" points to a pointer to a buffer containing these bytes.
  • Ownership of this buffer remains with the stream, and the buffer remains valid only until some other method of the stream is called or the stream is destroyed.
  • It is legal for the returned buffer to have zero size, as long as repeatedly calling Next() eventually yields a buffer with non-zero size.

virtual void LimitingInputStream::BackUp(
        int count)

Backs up a number of bytes, so that the next call to Next() returns data again that was already returned by the last call to Next().

This is useful when writing procedures that are only supposed to read up to a certain point in the input, then return. If Next() returns a buffer that goes beyond what you wanted to read, you can use BackUp() to return to the point where you intended to finish.

Preconditions:

  • The last method called must have been Next().
  • count must be less than or equal to the size of the last buffer returned by Next().

Postconditions:

  • The last "count" bytes of the last buffer returned by Next() will be pushed back into the stream. Subsequent calls to Next() will return the same data again before producing new data.

virtual bool LimitingInputStream::Skip(
        int count)

Skips a number of bytes.

Returns false if the end of the stream is reached or some input error occurred. In the end-of-stream case, the stream is advanced to the end of the stream (so ByteCount() will return the total size of the stream).

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.map/index.html b/reference/cpp/api-docs/google.protobuf.map/index.html new file mode 100644 index 000000000..a117bd733 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.map/index.html @@ -0,0 +1,8 @@ +map.h | Protocol Buffers Documentation +

map.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/map.h>
namespace google::protobuf

This file defines the map container and its helpers to support protobuf maps.

The Map and MapIterator types are provided by this header file. Please avoid using other types defined here, unless they are public types within Map or MapIterator, such as Map::value_type.

Classes in this file

This is the class for Map's internal value_type.
Map is an associative container type used to store protobuf map fields.
Iterators.

template alias MapPair

#include <google/protobuf/map.h>
namespace google::protobuf

template <typename , typename >

This is the class for Map's internal value_type, which is just an alias to std::pair.

template class Map

#include <google/protobuf/map.h>
namespace google::protobuf

template <typename , typename >

Map is an associative container type used to store protobuf map fields.

Each Map instance may or may not use a different hash function, a different iteration order, and so on. E.g., please don't examine implementation details to decide if the following would work: Map<int, int> m0, m1; m0[0] = m1[0] = m0[1] = m1[1] = 0; assert(m0.begin()->first == m1.begin()->first); // Bug!

Map's interface is similar to std::unordered_map, except that Map is not designed to play well with exceptions.

Members

typedef
Key key_type
typedef
T mapped_type
typedef
MapPair< Key, T > value_type
typedef
value_type * pointer
typedef
const value_type * const_pointer
typedef
value_type & reference
typedef
const value_type & const_reference
typedef
size_t size_type
typedef
typename internal::TransparentSupport< Key >::hash hasher
constexpr
Map()
explicit
Map(Arena * arena)
Map(const Map & other)
Map(Map && other)
Map &
operator=(Map && other)
template
Map(const InputIt & first, const InputIt & last)
~Map()
iterator
begin()
iterator
end()
const_iterator
begin() const
const_iterator
end() const
const_iterator
cbegin() const
const_iterator
cend() const
size_type
size() const
Capacity.
bool
empty() const
template T &
operator[](const key_arg< K > & key)
Element access.
template T &
operator[](key_arg< K > && key)
template const T &
at(const key_arg< K > & key) const
template T &
at(const key_arg< K > & key)
template size_type
count(const key_arg< K > & key) const
Lookup.
template const_iterator
find(const key_arg< K > & key) const
template iterator
find(const key_arg< K > & key)
template bool
contains(const key_arg< K > & key) const
template std::pair< const_iterator, const_iterator >
equal_range(const key_arg< K > & key) const
template std::pair< iterator, iterator >
equal_range(const key_arg< K > & key)
std::pair< iterator, bool >
insert(const value_type & value)
insert
template void
insert(InputIt first, InputIt last)
void
insert(std::initializer_list< value_type > values)
template size_type
erase(const key_arg< K > & key)
Erase and clear.
iterator
erase(iterator pos)
void
erase(iterator first, iterator last)
void
clear()
Map &
operator=(const Map & other)
Assign.
void
swap(Map & other)
void
InternalSwap(Map & other)
hasher
hash_function() const
Access to hasher. more...
size_t
SpaceUsedExcludingSelfLong() const

hasher Map::hash_function() const

Access to hasher.

Currently this returns a copy, but it may be modified to return a const reference in the future.

class Map::const_iterator

#include <google/protobuf/map.h>
namespace google::protobuf

Iterators.

Members

typedef
std::forward_iterator_tag iterator_category
typedef
typename Map::value_type value_type
typedef
ptrdiff_t difference_type
typedef
const value_type * pointer
typedef
const value_type & reference
const_iterator()
explicit
const_iterator(const InnerIt & it)
const_reference
operator*() const
const_pointer
operator->() const
const_iterator &
operator++()
const_iterator
operator++(int )

class Map::iterator

#include <google/protobuf/map.h>
namespace google::protobuf

Members

typedef
std::forward_iterator_tag iterator_category
typedef
typename Map::value_type value_type
typedef
ptrdiff_t difference_type
typedef
value_type * pointer
typedef
value_type & reference
iterator()
explicit
iterator(const InnerIt & it)
reference
operator*() const
pointer
operator->() const
iterator &
operator++()
iterator
operator++(int )
operator const_iterator() const
Allow implicit conversion to const_iterator.
\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.message/index.html b/reference/cpp/api-docs/google.protobuf.message/index.html new file mode 100644 index 000000000..d0850dcaa --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.message/index.html @@ -0,0 +1,96 @@ +message.h | Protocol Buffers Documentation +

message.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/message.h>
namespace google::protobuf

Defines Message, the abstract interface implemented by non-lite protocol message objects.

Although it's possible to implement this interface manually, most users will use the protocol compiler to generate implementations.

Example usage:

Say you have a message defined as:

message Foo {
+  optional string text = 1;
+  repeated int32 numbers = 2;
+}

Then, if you used the protocol compiler to generate a class from the above definition, you could use it like so:

std::string data;  // Will store a serialized version of the message.
+
+{
+  // Create a message and serialize it.
+  Foo foo;
+  foo.set_text("Hello World!");
+  foo.add_numbers(1);
+  foo.add_numbers(5);
+  foo.add_numbers(42);
+
+  foo.SerializeToString(&data);
+}
+
+{
+  // Parse the serialized message and check that it contains the
+  // correct data.
+  Foo foo;
+  foo.ParseFromString(data);
+
+  assert(foo.text() == "Hello World!");
+  assert(foo.numbers_size() == 3);
+  assert(foo.numbers(0) == 1);
+  assert(foo.numbers(1) == 5);
+  assert(foo.numbers(2) == 42);
+}
+
+{
+  // Same as the last block, but do it dynamically via the Message
+  // reflection interface.
+  Message* foo = new Foo;
+  const Descriptor* descriptor = foo->GetDescriptor();
+
+  // Get the descriptors for the fields we're interested in and verify
+  // their types.
+  const FieldDescriptor* text_field = descriptor->FindFieldByName("text");
+  assert(text_field != nullptr);
+  assert(text_field->type() == FieldDescriptor::TYPE_STRING);
+  assert(text_field->label() == FieldDescriptor::LABEL_OPTIONAL);
+  const FieldDescriptor* numbers_field = descriptor->
+                                         FindFieldByName("numbers");
+  assert(numbers_field != nullptr);
+  assert(numbers_field->type() == FieldDescriptor::TYPE_INT32);
+  assert(numbers_field->label() == FieldDescriptor::LABEL_REPEATED);
+
+  // Parse the message.
+  foo->ParseFromString(data);
+
+  // Use the reflection interface to examine the contents.
+  const Reflection* reflection = foo->GetReflection();
+  assert(reflection->GetString(*foo, text_field) == "Hello World!");
+  assert(reflection->FieldSize(*foo, numbers_field) == 3);
+  assert(reflection->GetRepeatedInt32(*foo, numbers_field, 0) == 1);
+  assert(reflection->GetRepeatedInt32(*foo, numbers_field, 1) == 5);
+  assert(reflection->GetRepeatedInt32(*foo, numbers_field, 2) == 42);
+
+  delete foo;
+}

Classes in this file

A container to hold message metadata.
Abstract interface for protocol messages.
This interface contains methods that can be used to dynamically access and modify the fields of a protocol message.
Abstract interface for a factory for message objects.

File Members

These definitions are not part of any class.
template const T *
DynamicCastToGenerated(const Message * from)
Tries to downcast this message to a generated message type. more...
template T *
DynamicCastToGenerated(Message * from)
template void
LinkMessageReflection()
Call this function to ensure that this message's reflection is linked into the binary: more...
const RepeatedPtrField< std::string > &
Reflection::GetRepeatedPtrFieldInternal< std::string >(const Message & message, const FieldDescriptor * field) const
RepeatedPtrField< std::string > *
Reflection::MutableRepeatedPtrFieldInternal< std::string >(Message * message, const FieldDescriptor * field) const

template const T * protobuf::DynamicCastToGenerated(
        const Message * from)

Tries to downcast this message to a generated message type.

Returns nullptr if this class is not an instance of T. This works even if RTTI is disabled.

This also has the effect of creating a strong reference to T that will prevent the linker from stripping it out at link time. This can be important if you are using a DynamicMessageFactory that delegates to the generated factory.


template void protobuf::LinkMessageReflection()

Call this function to ensure that this message's reflection is linked into the binary:

google::protobuf::LinkMessageReflection<FooMessage>();

This will ensure that the following lookup will succeed:

DescriptorPool::generated_pool()->FindMessageTypeByName("FooMessage");

As a side-effect, it will also guarantee that anything else from the same .proto file will also be available for lookup in the generated pool.

This function does not actually register the message, so it does not need to be called before the lookup. However it does need to occur in a function that cannot be stripped from the binary (ie. it must be reachable from main).

Best practice is to call this function as close as possible to where the reflection is actually needed. This function is very cheap to call, so you should not need to worry about its runtime overhead except in the tightest of loops (on x86-64 it compiles into two "mov" instructions).

struct Metadata

#include <google/protobuf/message.h>
namespace google::protobuf

A container to hold message metadata.

Members

const Descriptor *
descriptor
const Reflection *
reflection

class Message: public MessageLite

#include <google/protobuf/message.h>
namespace google::protobuf

Abstract interface for protocol messages.

See also MessageLite, which contains most every-day operations. Message adds descriptors and reflection on top of that.

The methods of this class that are virtual but not pure-virtual have default implementations based on reflection. Message classes which are optimized for speed will want to override these with faster implementations, but classes optimized for code size may be happy with keeping them. See the optimize_for option in descriptor.proto.

Users must not derive from this class. Only the protocol compiler and the internal library are allowed to create subclasses.

Members

constexpr
Message()
protected virtual Metadata
GetMetadata() const = 0
Get a struct containing the metadata for the Message, which is used in turn to implement GetDescriptor() and GetReflection() above.
protected explicit
Message(Arena * arena)
protected static uint64
GetInvariantPerBuild(uint64 salt)

Basic Operations

virtual Message *
New() const = 0
Construct a new instance of the same type. more...
virtual Message *
New(Arena * arena) const
Construct a new instance on the arena. more...
virtual void
CopyFrom(const Message & from)
Make this message into a copy of the given message. more...
virtual void
MergeFrom(const Message & from)
Merge the fields from the given message into this message. more...
void
CheckInitialized() const
Verifies that IsInitialized() returns true. more...
void
FindInitializationErrors(std::vector< std::string > * errors) const
Slowly build a list of all required fields that are not set. more...
virtual std::string
InitializationErrorString() const
Like FindInitializationErrors, but joins all the strings, delimited by commas, and returns them.
virtual void
DiscardUnknownFields()
Clears all unknown fields from this message and all embedded messages. more...
virtual size_t
SpaceUsedLong() const
Computes (an estimate of) the total number of bytes currently used for storing the message in memory. more...
int
SpaceUsed() const

Debugging & Testing

std::string
DebugString() const
Generates a human readable form of this message, useful for debugging and other purposes.
std::string
ShortDebugString() const
Like DebugString(), but with less whitespace.
std::string
Utf8DebugString() const
Like DebugString(), but do not escape UTF-8 byte sequences.
void
PrintDebugString() const
Convenience function useful in GDB. Prints DebugString() to stdout.

Reflection-based methods

These methods are pure-virtual in MessageLite, but Message provides reflection-based default implementations.
virtual std::string
GetTypeName() const
Get the name of this message type, e.g. "foo.bar.BazProto".
virtual void
Clear()
Clear all fields of the message and set them to their default values. more...
virtual bool
IsInitialized() const
Returns whether all required fields have been set. more...
virtual void
CheckTypeAndMergeFrom(const MessageLite & other)
If |other| is the exact same class as this, calls MergeFrom(). more...
virtual const char *
_InternalParse(const char * ptr, internal::ParseContext * ctx)
Reflective parser.
virtual size_t
ByteSizeLong() const
Computes the serialized size of the message. more...
virtual uint8 *
_InternalSerialize(uint8 * ptr, io::EpsCopyOutputStream * stream) const
Fast path when conditions match (ie. more...

Introspection

const Descriptor *
GetDescriptor() const
Get a non-owning pointer to a Descriptor for this message's type. more...
const Reflection *
GetReflection() const
Get a non-owning pointer to the Reflection interface for this Message, which can be used to read and modify the fields of the Message dynamically (in other words, without knowing the message type at compile time). more...

virtual Message * Message::New() const = 0

Construct a new instance of the same type.

Ownership is passed to the caller. (This is also defined in MessageLite, but is defined again here for return-type covariance.)


virtual Message * Message::New(
        Arena * arena) const

Construct a new instance on the arena.

Ownership is passed to the caller if arena is a nullptr. Default implementation allows for API compatibility during the Arena transition.


virtual void Message::CopyFrom(
        const Message & from)

Make this message into a copy of the given message.

The given message must have the same descriptor, but need not necessarily be the same class. By default this is just implemented as "Clear(); MergeFrom(from);".


virtual void Message::MergeFrom(
        const Message & from)

Merge the fields from the given message into this message.

Singular fields will be overwritten, if specified in from, except for embedded messages which will be merged. Repeated fields will be concatenated. The given message must be of the same type as this message (i.e. the exact same class).


void Message::CheckInitialized() const

Verifies that IsInitialized() returns true.

GOOGLE_CHECK-fails otherwise, with a nice error message.


void Message::FindInitializationErrors(
        std::vector< std::string > * errors) const

Slowly build a list of all required fields that are not set.

This is much, much slower than IsInitialized() as it is implemented purely via reflection. Generally, you should not call this unless you have already determined that an error exists by calling IsInitialized().


virtual void Message::DiscardUnknownFields()

Clears all unknown fields from this message and all embedded messages.

Normally, if unknown tag numbers are encountered when parsing a message, the tag and value are stored in the message's UnknownFieldSet and then written back out when the message is serialized. This allows servers which simply route messages to other servers to pass through messages that have new field definitions which they don't yet know about. However, this behavior can have security implications. To avoid it, call this method after parsing.

See Reflection::GetUnknownFields() for more on unknown fields.


virtual size_t Message::SpaceUsedLong() const

Computes (an estimate of) the total number of bytes currently used for storing the message in memory.

The default implementation calls the Reflection object's SpaceUsed() method.

SpaceUsed() is noticeably slower than ByteSize(), as it is implemented using reflection (rather than the generated code implementation for ByteSize()). Like ByteSize(), its CPU time is linear in the number of fields defined for the proto.


virtual void Message::Clear()

Clear all fields of the message and set them to their default values.

Clear() avoids freeing memory, assuming that any memory allocated to hold parts of the message will be needed again to hold the next message. If you actually want to free the memory used by a Message, you must delete it.


virtual bool Message::IsInitialized() const

Returns whether all required fields have been set.

Note that required fields no longer exist starting in proto3.


virtual void Message::CheckTypeAndMergeFrom(
        const MessageLite & other)

If |other| is the exact same class as this, calls MergeFrom().

Otherwise, results are undefined (probably crash).


virtual size_t Message::ByteSizeLong() const

Computes the serialized size of the message.

This recursively calls ByteSizeLong() on all embedded messages.

ByteSizeLong() is generally linear in the number of fields defined for the proto.


virtual uint8 * Message::_InternalSerialize(
        uint8 * ptr,
        io::EpsCopyOutputStream * stream) const

Fast path when conditions match (ie.

non-deterministic) uint8* _InternalSerialize(uint8* ptr) const;


const Descriptor *
    Message::GetDescriptor() const

Get a non-owning pointer to a Descriptor for this message's type.

This describes what fields the message contains, the types of those fields, etc. This object remains property of the Message.


const Reflection *
    Message::GetReflection() const

Get a non-owning pointer to the Reflection interface for this Message, which can be used to read and modify the fields of the Message dynamically (in other words, without knowing the message type at compile time).

This object remains property of the Message.

class Reflection

#include <google/protobuf/message.h>
namespace google::protobuf

This interface contains methods that can be used to dynamically access and modify the fields of a protocol message.

Their semantics are similar to the accessors the protocol compiler generates.

To get the Reflection for a given Message, call Message::GetReflection().

This interface is separate from Message only for efficiency reasons; the vast majority of implementations of Message will share the same implementation of Reflection (GeneratedMessageReflection, defined in generated_message.h), and all Messages of a particular class should share the same Reflection object (though you should not rely on the latter fact).

There are several ways that these methods can be used incorrectly. For example, any of the following conditions will lead to undefined results (probably assertion failures):

  • The FieldDescriptor is not a field of this message type.
  • The method called is not appropriate for the field's type. For each field type in FieldDescriptor::TYPE_*, there is only one Get*() method, one Set*() method, and one Add*() method that is valid for that type. It should be obvious which (except maybe for TYPE_BYTES, which are represented using strings in C++).
  • A Get*() or Set*() method for singular fields is called on a repeated field.
  • GetRepeated*(), SetRepeated*(), or Add*() is called on a non-repeated field.
  • The Message object passed to any method is not of the right type for this Reflection object (i.e. message.GetReflection() != reflection).

You might wonder why there is not any abstract representation for a field of arbitrary type. E.g., why isn't there just a "GetField()" method that returns "const Field&", where "Field" is some class with accessors like "GetInt32Value()". The problem is that someone would have to deal with allocating these Field objects. For generated message classes, having to allocate space for an additional object to wrap every field would at least double the message's memory footprint, probably worse. Allocating the objects on-demand, on the other hand, would be expensive and prone to memory leaks. So, instead we ended up with this flat interface.

Members

const UnknownFieldSet &
GetUnknownFields(const Message & message) const
Get the UnknownFieldSet for the message. more...
UnknownFieldSet *
MutableUnknownFields(Message * message) const
Get a mutable pointer to the UnknownFieldSet for the message. more...
size_t
SpaceUsedLong(const Message & message) const
Estimate the amount of memory used by the message object.
int
SpaceUsed(const Message & message) const
bool
HasField(const Message & message, const FieldDescriptor * field) const
Check if the given non-repeated field is set.
int
FieldSize(const Message & message, const FieldDescriptor * field) const
Get the number of elements of a repeated field.
void
ClearField(Message * message, const FieldDescriptor * field) const
Clear the value of a field, so that HasField() returns false or FieldSize() returns zero.
bool
HasOneof(const Message & message, const OneofDescriptor * oneof_descriptor) const
Check if the oneof is set. more...
void
ClearOneof(Message * message, const OneofDescriptor * oneof_descriptor) const
const FieldDescriptor *
GetOneofFieldDescriptor(const Message & message, const OneofDescriptor * oneof_descriptor) const
Returns the field descriptor if the oneof is set. nullptr otherwise.
void
RemoveLast(Message * message, const FieldDescriptor * field) const
Removes the last element of a repeated field. more...
PROTOBUF_FUTURE_MUST_USE_RESULT Message *
ReleaseLast(Message * message, const FieldDescriptor * field) const
Removes the last element of a repeated message field, and returns the pointer to the caller. more...
void
Swap(Message * message1, Message * message2) const
Swap the complete contents of two messages.
void
SwapFields(Message * message1, Message * message2, const std::vector< const FieldDescriptor * > & fields) const
Swap fields listed in fields vector of two messages.
void
SwapElements(Message * message, const FieldDescriptor * field, int index1, int index2) const
Swap two elements of a repeated field.
void
ListFields(const Message & message, std::vector< const FieldDescriptor * > * output) const
List all fields of the message which are currently set, except for unknown fields, but including extension known to the parser (i.e. more...
const RepeatedPtrField< Message > &
GetRepeatedPtrFieldInternal(const Message & message, const FieldDescriptor * field) const
RepeatedPtrField< Message > *
MutableRepeatedPtrFieldInternal(Message * message, const FieldDescriptor * field) const

Singular field getters

These get the value of a non-repeated field. They return the default value for fields that aren't set.
int32
GetInt32(const Message & message, const FieldDescriptor * field) const
int64
GetInt64(const Message & message, const FieldDescriptor * field) const
uint32
GetUInt32(const Message & message, const FieldDescriptor * field) const
uint64
GetUInt64(const Message & message, const FieldDescriptor * field) const
float
GetFloat(const Message & message, const FieldDescriptor * field) const
double
GetDouble(const Message & message, const FieldDescriptor * field) const
bool
GetBool(const Message & message, const FieldDescriptor * field) const
std::string
GetString(const Message & message, const FieldDescriptor * field) const
const EnumValueDescriptor *
GetEnum(const Message & message, const FieldDescriptor * field) const
int
GetEnumValue(const Message & message, const FieldDescriptor * field) const
GetEnumValue() returns an enum field's value as an integer rather than an EnumValueDescriptor*. more...
const Message &
GetMessage(const Message & message, const FieldDescriptor * field, MessageFactory * factory = nullptr) const
See MutableMessage() for the meaning of the "factory" parameter.
const std::string &
GetStringReference(const Message & message, const FieldDescriptor * field, std::string * scratch) const
Get a string value without copying, if possible. more...

Singular field mutators

These mutate the value of a non-repeated field.
void
SetInt32(Message * message, const FieldDescriptor * field, int32 value) const
void
SetInt64(Message * message, const FieldDescriptor * field, int64 value) const
void
SetUInt32(Message * message, const FieldDescriptor * field, uint32 value) const
void
SetUInt64(Message * message, const FieldDescriptor * field, uint64 value) const
void
SetFloat(Message * message, const FieldDescriptor * field, float value) const
void
SetDouble(Message * message, const FieldDescriptor * field, double value) const
void
SetBool(Message * message, const FieldDescriptor * field, bool value) const
void
SetString(Message * message, const FieldDescriptor * field, std::string value) const
void
SetEnum(Message * message, const FieldDescriptor * field, const EnumValueDescriptor * value) const
void
SetEnumValue(Message * message, const FieldDescriptor * field, int value) const
Set an enum field's value with an integer rather than EnumValueDescriptor. more...
Message *
MutableMessage(Message * message, const FieldDescriptor * field, MessageFactory * factory = nullptr) const
Get a mutable pointer to a field with a message type. more...
void
SetAllocatedMessage(Message * message, Message * sub_message, const FieldDescriptor * field) const
Replaces the message specified by 'field' with the already-allocated object sub_message, passing ownership to the message. more...
void
UnsafeArenaSetAllocatedMessage(Message * message, Message * sub_message, const FieldDescriptor * field) const
Similar to SetAllocatedMessage, but omits all internal safety and ownership checks. more...
PROTOBUF_FUTURE_MUST_USE_RESULT Message *
ReleaseMessage(Message * message, const FieldDescriptor * field, MessageFactory * factory = nullptr) const
Releases the message specified by 'field' and returns the pointer, ReleaseMessage() will return the message the message object if it exists. more...
Message *
UnsafeArenaReleaseMessage(Message * message, const FieldDescriptor * field, MessageFactory * factory = nullptr) const
Similar to ReleaseMessage, but omits all internal safety and ownership checks. more...

Repeated field getters

These get the value of one element of a repeated field.
int32
GetRepeatedInt32(const Message & message, const FieldDescriptor * field, int index) const
int64
GetRepeatedInt64(const Message & message, const FieldDescriptor * field, int index) const
uint32
GetRepeatedUInt32(const Message & message, const FieldDescriptor * field, int index) const
uint64
GetRepeatedUInt64(const Message & message, const FieldDescriptor * field, int index) const
float
GetRepeatedFloat(const Message & message, const FieldDescriptor * field, int index) const
double
GetRepeatedDouble(const Message & message, const FieldDescriptor * field, int index) const
bool
GetRepeatedBool(const Message & message, const FieldDescriptor * field, int index) const
std::string
GetRepeatedString(const Message & message, const FieldDescriptor * field, int index) const
const EnumValueDescriptor *
GetRepeatedEnum(const Message & message, const FieldDescriptor * field, int index) const
int
GetRepeatedEnumValue(const Message & message, const FieldDescriptor * field, int index) const
GetRepeatedEnumValue() returns an enum field's value as an integer rather than an EnumValueDescriptor*. more...
const Message &
GetRepeatedMessage(const Message & message, const FieldDescriptor * field, int index) const
const std::string &
GetRepeatedStringReference(const Message & message, const FieldDescriptor * field, int index, std::string * scratch) const

Repeated field mutators

These mutate the value of one element of a repeated field.
void
SetRepeatedInt32(Message * message, const FieldDescriptor * field, int index, int32 value) const
void
SetRepeatedInt64(Message * message, const FieldDescriptor * field, int index, int64 value) const
void
SetRepeatedUInt32(Message * message, const FieldDescriptor * field, int index, uint32 value) const
void
SetRepeatedUInt64(Message * message, const FieldDescriptor * field, int index, uint64 value) const
void
SetRepeatedFloat(Message * message, const FieldDescriptor * field, int index, float value) const
void
SetRepeatedDouble(Message * message, const FieldDescriptor * field, int index, double value) const
void
SetRepeatedBool(Message * message, const FieldDescriptor * field, int index, bool value) const
void
SetRepeatedString(Message * message, const FieldDescriptor * field, int index, std::string value) const
void
SetRepeatedEnum(Message * message, const FieldDescriptor * field, int index, const EnumValueDescriptor * value) const
void
SetRepeatedEnumValue(Message * message, const FieldDescriptor * field, int index, int value) const
Set an enum field's value with an integer rather than EnumValueDescriptor. more...
Message *
MutableRepeatedMessage(Message * message, const FieldDescriptor * field, int index) const
Get a mutable pointer to an element of a repeated field with a message type.

Repeated field adders

These add an element to a repeated field.
void
AddInt32(Message * message, const FieldDescriptor * field, int32 value) const
void
AddInt64(Message * message, const FieldDescriptor * field, int64 value) const
void
AddUInt32(Message * message, const FieldDescriptor * field, uint32 value) const
void
AddUInt64(Message * message, const FieldDescriptor * field, uint64 value) const
void
AddFloat(Message * message, const FieldDescriptor * field, float value) const
void
AddDouble(Message * message, const FieldDescriptor * field, double value) const
void
AddBool(Message * message, const FieldDescriptor * field, bool value) const
void
AddString(Message * message, const FieldDescriptor * field, std::string value) const
void
AddEnum(Message * message, const FieldDescriptor * field, const EnumValueDescriptor * value) const
void
AddEnumValue(Message * message, const FieldDescriptor * field, int value) const
Add an integer value to a repeated enum field rather than EnumValueDescriptor. more...
Message *
AddMessage(Message * message, const FieldDescriptor * field, MessageFactory * factory = nullptr) const
See MutableMessage() for comments on the "factory" parameter.
void
AddAllocatedMessage(Message * message, const FieldDescriptor * field, Message * new_entry) const
Appends an already-allocated object 'new_entry' to the repeated field specified by 'field' passing ownership to the message.
template RepeatedFieldRef< T >
GetRepeatedFieldRef(const Message & message, const FieldDescriptor * field) const
Get a RepeatedFieldRef object that can be used to read the underlying repeated field. more...
template MutableRepeatedFieldRef< T >
GetMutableRepeatedFieldRef(Message * message, const FieldDescriptor * field) const
Like GetRepeatedFieldRef() but return an object that can also be used manipulate the underlying repeated field.
template const RepeatedField< T > &
GetRepeatedField(const Message & msg, const FieldDescriptor * d) const
DEPRECATED. more...
template RepeatedField< T > *
MutableRepeatedField(Message * msg, const FieldDescriptor * d) const
DEPRECATED. more...
template const RepeatedPtrField< T > &
GetRepeatedPtrField(const Message & msg, const FieldDescriptor * d) const
DEPRECATED. more...
template RepeatedPtrField< T > *
MutableRepeatedPtrField(Message * msg, const FieldDescriptor * d) const
DEPRECATED. more...

Extensions

const FieldDescriptor *
FindKnownExtensionByName(const std::string & name) const
Try to find an extension of this message type by fully-qualified field name. more...
const FieldDescriptor *
FindKnownExtensionByNumber(int number) const
Try to find an extension of this message type by field number. more...

Feature Flags

bool
SupportsUnknownEnumValues() const
Does this message support storing arbitrary integer values in enum fields? If |true|, GetEnumValue/SetEnumValue and associated repeated-field versions take arbitrary integer values, and the legacy GetEnum() getter will dynamically create an EnumValueDescriptor for any integer value without one. more...
MessageFactory *
GetMessageFactory() const
Returns the MessageFactory associated with this message. more...

const UnknownFieldSet &
    Reflection::GetUnknownFields(
        const Message & message) const

Get the UnknownFieldSet for the message.

This contains fields which were seen when the Message was parsed but were not recognized according to the Message's definition.


UnknownFieldSet *
    Reflection::MutableUnknownFields(
        Message * message) const

Get a mutable pointer to the UnknownFieldSet for the message.

This contains fields which were seen when the Message was parsed but were not recognized according to the Message's definition.


bool Reflection::HasOneof(
        const Message & message,
        const OneofDescriptor * oneof_descriptor) const

Check if the oneof is set.

Returns true if any field in oneof is set, false otherwise.


void Reflection::RemoveLast(
        Message * message,
        const FieldDescriptor * field) const

Removes the last element of a repeated field.

We don't provide a way to remove any element other than the last because it invites inefficient use, such as O(n^2) filtering loops that should have been O(n). If you want to remove an element other than the last, the best way to do it is to re-arrange the elements (using Swap()) so that the one you want removed is at the end, then call RemoveLast().


PROTOBUF_FUTURE_MUST_USE_RESULT Message *
    Reflection::ReleaseLast(
        Message * message,
        const FieldDescriptor * field) const

Removes the last element of a repeated message field, and returns the pointer to the caller.

Caller takes ownership of the returned pointer.


void Reflection::ListFields(
        const Message & message,
        std::vector< const FieldDescriptor * > * output) const

List all fields of the message which are currently set, except for unknown fields, but including extension known to the parser (i.e.

compiled in). Singular fields will only be listed if HasField(field) would return true and repeated fields will only be listed if FieldSize(field) would return non-zero. Fields (both normal fields and extension fields) will be listed ordered by field number. Use Reflection::GetUnknownFields() or message.unknown_fields() to also get access to fields/extensions unknown to the parser.


int Reflection::GetEnumValue(
        const Message & message,
        const FieldDescriptor * field) const

GetEnumValue() returns an enum field's value as an integer rather than an EnumValueDescriptor*.

If the integer value does not correspond to a known value descriptor, a new value descriptor is created. (Such a value will only be present when the new unknown-enum-value semantics are enabled for a message.)


const std::string &
    Reflection::GetStringReference(
        const Message & message,
        const FieldDescriptor * field,
        std::string * scratch) const

Get a string value without copying, if possible.

GetString() necessarily returns a copy of the string. This can be inefficient when the std::string is already stored in a std::string object in the underlying message. GetStringReference() will return a reference to the underlying std::string in this case. Otherwise, it will copy the string into *scratch and return that.

Note: It is perfectly reasonable and useful to write code like:

str = reflection->GetStringReference(message, field, &str);

This line would ensure that only one copy of the string is made regardless of the field's underlying representation. When initializing a newly-constructed string, though, it's just as fast and more readable to use code like:

std::string str = reflection->GetString(message, field);

void Reflection::SetEnumValue(
        Message * message,
        const FieldDescriptor * field,
        int value) const

Set an enum field's value with an integer rather than EnumValueDescriptor.

For proto3 this is just setting the enum field to the value specified, for proto2 it's more complicated. If value is a known enum value the field is set as usual. If the value is unknown then it is added to the unknown field set. Note this matches the behavior of parsing unknown enum values. If multiple calls with unknown values happen than they are all added to the unknown field set in order of the calls.


Message * Reflection::MutableMessage(
        Message * message,
        const FieldDescriptor * field,
        MessageFactory * factory = nullptr) const

Get a mutable pointer to a field with a message type.

If a MessageFactory is provided, it will be used to construct instances of the sub-message; otherwise, the default factory is used. If the field is an extension that does not live in the same pool as the containing message's descriptor (e.g. it lives in an overlay pool), then a MessageFactory must be provided. If you have no idea what that meant, then you probably don't need to worry about it (don't provide a MessageFactory). WARNING: If the FieldDescriptor is for a compiled-in extension, then factory->GetPrototype(field->message_type()) MUST return an instance of the compiled-in class for this type, NOT DynamicMessage.


void Reflection::SetAllocatedMessage(
        Message * message,
        Message * sub_message,
        const FieldDescriptor * field) const

Replaces the message specified by 'field' with the already-allocated object sub_message, passing ownership to the message.

If the field contained a message, that message is deleted. If sub_message is nullptr, the field is cleared.


void Reflection::UnsafeArenaSetAllocatedMessage(
        Message * message,
        Message * sub_message,
        const FieldDescriptor * field) const

Similar to SetAllocatedMessage, but omits all internal safety and ownership checks.

This method should only be used when the objects are on the same arena or paired with a call to UnsafeArenaReleaseMessage.


PROTOBUF_FUTURE_MUST_USE_RESULT Message *
    Reflection::ReleaseMessage(
        Message * message,
        const FieldDescriptor * field,
        MessageFactory * factory = nullptr) const

Releases the message specified by 'field' and returns the pointer, ReleaseMessage() will return the message the message object if it exists.

Otherwise, it may or may not return nullptr. In any case, if the return value is non-null, the caller takes ownership of the pointer. If the field existed (HasField() is true), then the returned pointer will be the same as the pointer returned by MutableMessage(). This function has the same effect as ClearField().


Message * Reflection::UnsafeArenaReleaseMessage(
        Message * message,
        const FieldDescriptor * field,
        MessageFactory * factory = nullptr) const

Similar to ReleaseMessage, but omits all internal safety and ownership checks.

This method should only be used when the objects are on the same arena or paired with a call to UnsafeArenaSetAllocatedMessage.


int Reflection::GetRepeatedEnumValue(
        const Message & message,
        const FieldDescriptor * field,
        int index) const

GetRepeatedEnumValue() returns an enum field's value as an integer rather than an EnumValueDescriptor*.

If the integer value does not correspond to a known value descriptor, a new value descriptor is created. (Such a value will only be present when the new unknown-enum-value semantics are enabled for a message.)


void Reflection::SetRepeatedEnumValue(
        Message * message,
        const FieldDescriptor * field,
        int index,
        int value) const

Set an enum field's value with an integer rather than EnumValueDescriptor.

For proto3 this is just setting the enum field to the value specified, for proto2 it's more complicated. If value is a known enum value the field is set as usual. If the value is unknown then it is added to the unknown field set. Note this matches the behavior of parsing unknown enum values. If multiple calls with unknown values happen than they are all added to the unknown field set in order of the calls.


void Reflection::AddEnumValue(
        Message * message,
        const FieldDescriptor * field,
        int value) const

Add an integer value to a repeated enum field rather than EnumValueDescriptor.

For proto3 this is just setting the enum field to the value specified, for proto2 it's more complicated. If value is a known enum value the field is set as usual. If the value is unknown then it is added to the unknown field set. Note this matches the behavior of parsing unknown enum values. If multiple calls with unknown values happen than they are all added to the unknown field set in order of the calls.


template RepeatedFieldRef< T >
    Reflection::GetRepeatedFieldRef(
        const Message & message,
        const FieldDescriptor * field) const

Get a RepeatedFieldRef object that can be used to read the underlying repeated field.

The type parameter T must be set according to the field's cpp type. The following table shows the mapping from cpp type to acceptable T.

field->cpp_type()      T
+CPPTYPE_INT32        int32
+CPPTYPE_UINT32       uint32
+CPPTYPE_INT64        int64
+CPPTYPE_UINT64       uint64
+CPPTYPE_DOUBLE       double
+CPPTYPE_FLOAT        float
+CPPTYPE_BOOL         bool
+CPPTYPE_ENUM         generated enum type or int32
+CPPTYPE_STRING       std::string
+CPPTYPE_MESSAGE      generated message type or google::protobuf::Message

A RepeatedFieldRef object can be copied and the resulted object will point to the same repeated field in the same message. The object can be used as long as the message is not destroyed.

Note that to use this method users need to include the header file "reflection.h" (which defines the RepeatedFieldRef class templates).


template const RepeatedField< T > &
    Reflection::GetRepeatedField(
        const Message & msg,
        const FieldDescriptor * d) const

DEPRECATED.

Please use GetRepeatedFieldRef().

for T = Cord and all protobuf scalar types except enums.


template RepeatedField< T > *
    Reflection::MutableRepeatedField(
        Message * msg,
        const FieldDescriptor * d) const

DEPRECATED.

Please use GetMutableRepeatedFieldRef().

for T = Cord and all protobuf scalar types except enums.


template const RepeatedPtrField< T > &
    Reflection::GetRepeatedPtrField(
        const Message & msg,
        const FieldDescriptor * d) const

DEPRECATED.

Please use GetRepeatedFieldRef().

for T = std::string, google::protobuf::internal::StringPieceField

google::protobuf::Message & descendants.

template RepeatedPtrField< T > *
    Reflection::MutableRepeatedPtrField(
        Message * msg,
        const FieldDescriptor * d) const

DEPRECATED.

Please use GetMutableRepeatedFieldRef().

for T = std::string, google::protobuf::internal::StringPieceField

google::protobuf::Message & descendants.

const FieldDescriptor *
    Reflection::FindKnownExtensionByName(
        const std::string & name) const

Try to find an extension of this message type by fully-qualified field name.

Returns nullptr if no extension is known for this name or number.


const FieldDescriptor *
    Reflection::FindKnownExtensionByNumber(
        int number) const

Try to find an extension of this message type by field number.

Returns nullptr if no extension is known for this name or number.


bool Reflection::SupportsUnknownEnumValues() const

Does this message support storing arbitrary integer values in enum fields? If |true|, GetEnumValue/SetEnumValue and associated repeated-field versions take arbitrary integer values, and the legacy GetEnum() getter will dynamically create an EnumValueDescriptor for any integer value without one.

If |false|, setting an unknown enum value via the integer-based setters results in undefined behavior (in practice, GOOGLE_DCHECK-fails).

Generic code that uses reflection to handle messages with enum fields should check this flag before using the integer-based setter, and either downgrade to a compatible value or use the UnknownFieldSet if not. For example:

int new_value = GetValueFromApplicationLogic();
+if (reflection->SupportsUnknownEnumValues()) {
+  reflection->SetEnumValue(message, field, new_value);
+} else {
+  if (field_descriptor->enum_type()->
+          FindValueByNumber(new_value) != nullptr) {
+    reflection->SetEnumValue(message, field, new_value);
+  } else if (emit_unknown_enum_values) {
+    reflection->MutableUnknownFields(message)->AddVarint(
+        field->number(), new_value);
+  } else {
+    // convert value to a compatible/default value.
+    new_value = CompatibleDowngrade(new_value);
+    reflection->SetEnumValue(message, field, new_value);
+  }
+}

MessageFactory * Reflection::GetMessageFactory() const

Returns the MessageFactory associated with this message.

This can be useful for determining if a message is a generated message or not, for example:

if (message->GetReflection()->GetMessageFactory() ==
+    google::protobuf::MessageFactory::generated_factory()) {
+  // This is a generated message.
+}

It can also be used to create more messages of this type, though Message::New() is an easier way to accomplish this.

class MessageFactory

#include <google/protobuf/message.h>
namespace google::protobuf

Abstract interface for a factory for message objects.

Known subclasses:

Members

MessageFactory()
virtual
~MessageFactory()
virtual const Message *
GetPrototype(const Descriptor * type) = 0
Given a Descriptor, gets or constructs the default (prototype) Message of that type. more...
static MessageFactory *
generated_factory()
Gets a MessageFactory which supports all generated, compiled-in messages. more...
static void
InternalRegisterGeneratedFile(const google::protobuf::internal::DescriptorTable * table)
For internal use only: Registers a .proto file at static initialization time, to be placed in generated_factory. more...
static void
InternalRegisterGeneratedMessage(const Descriptor * descriptor, const Message * prototype)
For internal use only: Registers a message type. more...

virtual const Message * MessageFactory::GetPrototype(
        const Descriptor * type) = 0

Given a Descriptor, gets or constructs the default (prototype) Message of that type.

You can then call that message's New() method to construct a mutable message of that type.

Calling this method twice with the same Descriptor returns the same object. The returned object remains property of the factory. Also, any objects created by calling the prototype's New() method share some data with the prototype, so these must be destroyed before the MessageFactory is destroyed.

The given descriptor must outlive the returned message, and hence must outlive the MessageFactory.

Some implementations do not support all types. GetPrototype() will return nullptr if the descriptor passed in is not supported.

This method may or may not be thread-safe depending on the implementation. Each implementation should document its own degree thread-safety.


static MessageFactory * MessageFactory::generated_factory()

Gets a MessageFactory which supports all generated, compiled-in messages.

In other words, for any compiled-in type FooMessage, the following is true:

MessageFactory::generated_factory()->GetPrototype(
+  FooMessage::descriptor()) == FooMessage::default_instance()

This factory supports all types which are found in DescriptorPool::generated_pool(). If given a descriptor from any other pool, GetPrototype() will return nullptr. (You can also check if a descriptor is for a generated message by checking if descriptor->file()->pool() == DescriptorPool::generated_pool().)

This factory is 100% thread-safe; calling GetPrototype() does not modify any shared data.

This factory is a singleton. The caller must not delete the object.


static void MessageFactory::InternalRegisterGeneratedFile(
        const google::protobuf::internal::DescriptorTable * table)

For internal use only: Registers a .proto file at static initialization time, to be placed in generated_factory.

The first time GetPrototype() is called with a descriptor from this file, |register_messages| will be called, with the file name as the parameter. It must call InternalRegisterGeneratedMessage() (below) to register each message type in the file. This strange mechanism is necessary because descriptors are built lazily, so we can't register types by their descriptor until we know that the descriptor exists. |filename| must be a permanent string.


static void MessageFactory::InternalRegisterGeneratedMessage(
        const Descriptor * descriptor,
        const Message * prototype)

For internal use only: Registers a message type.

Called only by the functions which are registered with InternalRegisterGeneratedFile(), above.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.message_lite/index.html b/reference/cpp/api-docs/google.protobuf.message_lite/index.html new file mode 100644 index 000000000..037dbee72 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.message_lite/index.html @@ -0,0 +1,10 @@ +message_lite.h | Protocol Buffers Documentation +

message_lite.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/message_lite.h>
namespace google::protobuf

Defines MessageLite, the abstract interface implemented by all (lite and non-lite) protocol message objects.

Classes in this file

Interface to light weight protocol messages.

File Members

These definitions are not part of any class.
void
ShutdownProtobufLibrary()
Shut down the entire protocol buffers library, deleting all static-duration objects allocated by the library or by generated .pb.cc files. more...

void protobuf::ShutdownProtobufLibrary()

Shut down the entire protocol buffers library, deleting all static-duration objects allocated by the library or by generated .pb.cc files.

There are two reasons you might want to call this:

  • You use a draconian definition of "memory leak" in which you expect every single malloc() to have a corresponding free(), even for objects which live until program exit.
  • You are writing a dynamically-loaded library which needs to clean up after itself when the library is unloaded.

It is safe to call this multiple times. However, it is not safe to use any other part of the protocol buffers library after ShutdownProtobufLibrary() has been called. Furthermore this call is not thread safe, user needs to synchronize multiple calls.

class MessageLite

#include <google/protobuf/message_lite.h>
namespace google::protobuf

Interface to light weight protocol messages.

This interface is implemented by all protocol message objects. Non-lite messages additionally implement the Message interface, which is a subclass of MessageLite. Use MessageLite instead when you only need the subset of features which it supports – namely, nothing that uses descriptors or reflection. You can instruct the protocol compiler to generate classes which implement only MessageLite, not the full Message interface, by adding the following line to the .proto file:

option optimize_for = LITE_RUNTIME;

This is particularly useful on resource-constrained systems where the full protocol buffers runtime library is too big.

Note that on non-constrained systems (e.g. servers) when you need to link in lots of protocol definitions, a better way to reduce total code footprint is to use optimize_for = CODE_SIZE. This will make the generated code smaller while still supporting all the same features (at the expense of speed). optimize_for = LITE_RUNTIME is best when you only have a small number of message types linked into your binary, in which case the size of the protocol buffers runtime itself is the biggest problem.

Users must not derive from this class. Only the protocol compiler and the internal library are allowed to create subclasses.

Known subclasses:

Members

enum
ParseFlags
protected internal::InternalMetadata
_internal_metadata_
constexpr
MessageLite()
virtual
~MessageLite()
template bool
ParseFrom(const T & input)
virtual uint8 *
_InternalSerialize(uint8 * ptr, io::EpsCopyOutputStream * stream) const = 0
Fast path when conditions match (ie. more...
bool
IsInitializedWithErrors() const
Identical to IsInitialized() except that it logs an error message.
protected template static T *
CreateMaybeMessage(Arena * arena)
protected explicit
MessageLite(Arena * arena)
protected Arena *
GetOwningArena() const
Returns the arena, if any, that directly owns this message and its internal memory (Arena::Own is different in that the arena doesn't directly own the internal memory). more...
protected Arena *
GetArenaForAllocation() const
Returns the arena, used for allocating internal objects(e.g., child messages, etc), or owning incoming objects (e.g., set allocated).

Basic Operations

virtual std::string
GetTypeName() const = 0
Get the name of this message type, e.g. "foo.bar.BazProto".
virtual MessageLite *
New() const = 0
Construct a new instance of the same type. more...
virtual MessageLite *
New(Arena * arena) const
Construct a new instance on the arena. more...
Arena *
GetArena() const
Same as GetOwningArena.
void *
GetMaybeArenaPointer() const
Get a pointer that may be equal to this message's arena, or may not be. more...
virtual void
Clear() = 0
Clear all fields of the message and set them to their default values. more...
virtual bool
IsInitialized() const = 0
Quickly check if all required fields have values set.
virtual std::string
InitializationErrorString() const
This is not implemented for Lite messages – it just returns "(cannot +determine missing fields for lite message)". more...
virtual void
CheckTypeAndMergeFrom(const MessageLite & other) = 0
If |other| is the exact same class as this, calls MergeFrom(). more...
std::string
DebugString() const
These methods return a human-readable summary of the message. more...
std::string
ShortDebugString() const
std::string
Utf8DebugString() const
MessageLite::DebugString is already Utf8 Safe. more...

Parsing

Methods for parsing in protocol buffer format.

Most of these are just simple wrappers around MergeFromCodedStream(). Clear() will be called before merging the input.

PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParseFromCodedStream(io::CodedInputStream * input)
Fill the message with a protocol buffer parsed from the given input stream. more...
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParsePartialFromCodedStream(io::CodedInputStream * input)
Like ParseFromCodedStream(), but accepts messages that are missing required fields.
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParseFromZeroCopyStream(io::ZeroCopyInputStream * input)
Read a protocol buffer from the given zero-copy input stream. more...
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream * input)
Like ParseFromZeroCopyStream(), but accepts messages that are missing required fields.
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParseFromFileDescriptor(int file_descriptor)
Parse a protocol buffer from a file descriptor. more...
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParsePartialFromFileDescriptor(int file_descriptor)
Like ParseFromFileDescriptor(), but accepts messages that are missing required fields.
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParseFromIstream(std::istream * input)
Parse a protocol buffer from a C++ istream. more...
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParsePartialFromIstream(std::istream * input)
Like ParseFromIstream(), but accepts messages that are missing required fields.
bool
MergePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream * input, int size)
Read a protocol buffer from the given zero-copy input stream, expecting the message to be exactly "size" bytes long. more...
bool
MergeFromBoundedZeroCopyStream(io::ZeroCopyInputStream * input, int size)
Like ParseFromBoundedZeroCopyStream(), but accepts messages that are missing required fields.
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream * input, int size)
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream * input, int size)
Like ParseFromBoundedZeroCopyStream(), but accepts messages that are missing required fields.
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParseFromString(ConstStringParam data)
Parses a protocol buffer contained in a string. more...
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParsePartialFromString(ConstStringParam data)
Like ParseFromString(), but accepts messages that are missing required fields.
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParseFromArray(const void * data, int size)
Parse a protocol buffer contained in an array of bytes.
PROTOBUF_ATTRIBUTE_REINITIALIZES bool
ParsePartialFromArray(const void * data, int size)
Like ParseFromArray(), but accepts messages that are missing required fields.
bool
MergeFromCodedStream(io::CodedInputStream * input)
Reads a protocol buffer from the stream and merges it into this Message. more...
bool
MergePartialFromCodedStream(io::CodedInputStream * input)
Like MergeFromCodedStream(), but succeeds even if required fields are missing in the input. more...
bool
MergeFromString(ConstStringParam data)
Merge a protocol buffer contained in a string.

Serialization

Methods for serializing in protocol buffer format.

Most of these are just simple wrappers around ByteSize() and SerializeWithCachedSizes().

bool
SerializeToCodedStream(io::CodedOutputStream * output) const
Write a protocol buffer of this message to the given output. more...
bool
SerializePartialToCodedStream(io::CodedOutputStream * output) const
Like SerializeToCodedStream(), but allows missing required fields.
bool
SerializeToZeroCopyStream(io::ZeroCopyOutputStream * output) const
Write the message to the given zero-copy output stream. more...
bool
SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream * output) const
Like SerializeToZeroCopyStream(), but allows missing required fields.
bool
SerializeToString(std::string * output) const
Serialize the message and store it in the given string. more...
bool
SerializePartialToString(std::string * output) const
Like SerializeToString(), but allows missing required fields.
bool
SerializeToArray(void * data, int size) const
Serialize the message and store it in the given byte array. more...
bool
SerializePartialToArray(void * data, int size) const
Like SerializeToArray(), but allows missing required fields.
std::string
SerializeAsString() const
Make a string encoding the message. more...
std::string
SerializePartialAsString() const
Like SerializeAsString(), but allows missing required fields.
bool
SerializeToFileDescriptor(int file_descriptor) const
Serialize the message and write it to the given file descriptor. more...
bool
SerializePartialToFileDescriptor(int file_descriptor) const
Like SerializeToFileDescriptor(), but allows missing required fields.
bool
SerializeToOstream(std::ostream * output) const
Serialize the message and write it to the given C++ ostream. more...
bool
SerializePartialToOstream(std::ostream * output) const
Like SerializeToOstream(), but allows missing required fields.
bool
AppendToString(std::string * output) const
Like SerializeToString(), but appends to the data to the string's existing contents. more...
bool
AppendPartialToString(std::string * output) const
Like AppendToString(), but allows missing required fields.
virtual size_t
ByteSizeLong() const = 0
Computes the serialized size of the message. more...
int
ByteSize() const
Legacy ByteSize() API.
void
SerializeWithCachedSizes(io::CodedOutputStream * output) const
Serializes the message without recomputing the size. more...
uint8 *
SerializeWithCachedSizesToArray(uint8 * target) const
Like SerializeWithCachedSizes, but writes directly to *target, returning a pointer to the byte immediately after the last byte written. more...
virtual int
GetCachedSize() const = 0
Returns the result of the last call to ByteSize(). more...
virtual const char *
_InternalParse(const char * , internal::ParseContext * )

enum MessageLite::ParseFlags {
  kMerge = = 0,
  kParse = = 1,
  kMergePartial = = 2,
  kParsePartial = = 3,
  kMergeWithAliasing = = 4,
  kParseWithAliasing = = 5,
  kMergePartialWithAliasing = = 6,
  kParsePartialWithAliasing = = 7
}

kMerge
kParse
kMergePartial
kParsePartial
kMergeWithAliasing
kParseWithAliasing
kMergePartialWithAliasing
kParsePartialWithAliasing

virtual uint8 * MessageLite::_InternalSerialize(
        uint8 * ptr,
        io::EpsCopyOutputStream * stream) const = 0

Fast path when conditions match (ie.

non-deterministic) uint8* _InternalSerialize(uint8* ptr) const;


protected Arena * MessageLite::GetOwningArena() const

Returns the arena, if any, that directly owns this message and its internal memory (Arena::Own is different in that the arena doesn't directly own the internal memory).

This method is used in proto's implementation for swapping, moving and setting allocated, for deciding whether the ownership of this message or its internal memory could be changed.


virtual MessageLite * MessageLite::New() const = 0

Construct a new instance of the same type.

Ownership is passed to the caller.


virtual MessageLite * MessageLite::New(
        Arena * arena) const

Construct a new instance on the arena.

Ownership is passed to the caller if arena is a NULL. Default implementation for backwards compatibility.


void * MessageLite::GetMaybeArenaPointer() const

Get a pointer that may be equal to this message's arena, or may not be.

If the value returned by this method is equal to some arena pointer, then this message is on that arena; however, if this message is on some arena, this method may or may not return that arena's pointer. As a tradeoff, this method may be more efficient than GetArena(). The intent is to allow underlying representations that use e.g. tagged pointers to sometimes store the arena pointer directly, and sometimes in a more indirect way, and allow a fastpath comparison against the arena pointer when it's easy to obtain.


virtual void MessageLite::Clear() = 0

Clear all fields of the message and set them to their default values.

Clear() avoids freeing memory, assuming that any memory allocated to hold parts of the message will be needed again to hold the next message. If you actually want to free the memory used by a Message, you must delete it.


virtual std::string MessageLite::InitializationErrorString() const

This is not implemented for Lite messages – it just returns "(cannot +determine missing fields for lite message)".

However, it is implemented for full messages. See message.h.


virtual void MessageLite::CheckTypeAndMergeFrom(
        const MessageLite & other) = 0

If |other| is the exact same class as this, calls MergeFrom().

Otherwise, results are undefined (probably crash).


std::string MessageLite::DebugString() const

These methods return a human-readable summary of the message.

Note that since the MessageLite interface does not support reflection, there is very little information that these methods can provide. They are shadowed by methods of the same name on the Message interface which provide much more information. The methods here are intended primarily to facilitate code reuse for logic that needs to interoperate with both full and lite protos.

The format of the returned string is subject to change, so please do not assume it will remain stable over time.


std::string MessageLite::Utf8DebugString() const

MessageLite::DebugString is already Utf8 Safe.

This is to add compatibility with Message.


PROTOBUF_ATTRIBUTE_REINITIALIZES bool
    MessageLite::ParseFromCodedStream(
        io::CodedInputStream * input)

Fill the message with a protocol buffer parsed from the given input stream.

Returns false on a read error or if the input is in the wrong format. A successful return does not indicate the entire input is consumed, ensure you call ConsumedEntireMessage() to check that if applicable.


PROTOBUF_ATTRIBUTE_REINITIALIZES bool
    MessageLite::ParseFromZeroCopyStream(
        io::ZeroCopyInputStream * input)

Read a protocol buffer from the given zero-copy input stream.

If successful, the entire input will be consumed.


PROTOBUF_ATTRIBUTE_REINITIALIZES bool
    MessageLite::ParseFromFileDescriptor(
        int file_descriptor)

Parse a protocol buffer from a file descriptor.

If successful, the entire input will be consumed.


PROTOBUF_ATTRIBUTE_REINITIALIZES bool
    MessageLite::ParseFromIstream(
        std::istream * input)

Parse a protocol buffer from a C++ istream.

If successful, the entire input will be consumed.


bool MessageLite::MergePartialFromBoundedZeroCopyStream(
        io::ZeroCopyInputStream * input,
        int size)

Read a protocol buffer from the given zero-copy input stream, expecting the message to be exactly "size" bytes long.

If successful, exactly this many bytes will have been consumed from the input.


PROTOBUF_ATTRIBUTE_REINITIALIZES bool
    MessageLite::ParseFromString(
        ConstStringParam data)

Parses a protocol buffer contained in a string.

Returns true on success. This function takes a string in the (non-human-readable) binary wire format, matching the encoding output by MessageLite::SerializeToString(). If you'd like to convert a human-readable string into a protocol buffer object, see google::protobuf::TextFormat::ParseFromString().


bool MessageLite::MergeFromCodedStream(
        io::CodedInputStream * input)

Reads a protocol buffer from the stream and merges it into this Message.

Singular fields read from the what is already in the Message and repeated fields are appended to those already present.

It is the responsibility of the caller to call input->LastTagWas() (for groups) or input->ConsumedEntireMessage() (for non-groups) after this returns to verify that the message's end was delimited correctly.

ParseFromCodedStream() is implemented as Clear() followed by MergeFromCodedStream().


bool MessageLite::MergePartialFromCodedStream(
        io::CodedInputStream * input)

Like MergeFromCodedStream(), but succeeds even if required fields are missing in the input.

MergeFromCodedStream() is just implemented as MergePartialFromCodedStream() followed by IsInitialized().


bool MessageLite::SerializeToCodedStream(
        io::CodedOutputStream * output) const

Write a protocol buffer of this message to the given output.

Returns false on a write error. If the message is missing required fields, this may GOOGLE_CHECK-fail.


bool MessageLite::SerializeToZeroCopyStream(
        io::ZeroCopyOutputStream * output) const

Write the message to the given zero-copy output stream.

All required fields must be set.


bool MessageLite::SerializeToString(
        std::string * output) const

Serialize the message and store it in the given string.

All required fields must be set.


bool MessageLite::SerializeToArray(
        void * data,
        int size) const

Serialize the message and store it in the given byte array.

All required fields must be set.


std::string MessageLite::SerializeAsString() const

Make a string encoding the message.

Is equivalent to calling SerializeToString() on a string and using that. Returns the empty string if SerializeToString() would have returned an error. Note: If you intend to generate many such strings, you may reduce heap fragmentation by instead re-using the same string object with calls to SerializeToString().


bool MessageLite::SerializeToFileDescriptor(
        int file_descriptor) const

Serialize the message and write it to the given file descriptor.

All required fields must be set.


bool MessageLite::SerializeToOstream(
        std::ostream * output) const

Serialize the message and write it to the given C++ ostream.

All required fields must be set.


bool MessageLite::AppendToString(
        std::string * output) const

Like SerializeToString(), but appends to the data to the string's existing contents.

All required fields must be set.


virtual size_t MessageLite::ByteSizeLong() const = 0

Computes the serialized size of the message.

This recursively calls ByteSizeLong() on all embedded messages.

ByteSizeLong() is generally linear in the number of fields defined for the proto.


void MessageLite::SerializeWithCachedSizes(
        io::CodedOutputStream * output) const

Serializes the message without recomputing the size.

The message must not have changed since the last call to ByteSize(), and the value returned by ByteSize must be non-negative. Otherwise the results are undefined.


uint8 * MessageLite::SerializeWithCachedSizesToArray(
        uint8 * target) const

Like SerializeWithCachedSizes, but writes directly to *target, returning a pointer to the byte immediately after the last byte written.

"target" must point at a byte array of at least ByteSize() bytes. Whether to use deterministic serialization, e.g., maps in sorted order, is determined by CodedOutputStream::IsDefaultSerializationDeterministic().


virtual int MessageLite::GetCachedSize() const = 0

Returns the result of the last call to ByteSize().

An embedded message's size is needed both to serialize it (because embedded messages are length-delimited) and to compute the outer message's size. Caching the size avoids computing it multiple times.

ByteSize() does not automatically use the cached size when available because this would require invalidating it every time the message was modified, which would be too hard and expensive. (E.g. if a deeply-nested sub-message is changed, all of its parents' cached sizes would need to be invalidated, which is too much work for an otherwise inlined setter method.)

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.repeated_field/index.html b/reference/cpp/api-docs/google.protobuf.repeated_field/index.html new file mode 100644 index 000000000..dd14a8f5a --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.repeated_field/index.html @@ -0,0 +1,19 @@ +repeated_field.h | Protocol Buffers Documentation +

repeated_field.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/repeated_field.h>
namespace google::protobuf

RepeatedField and RepeatedPtrField are used by generated protocol message classes to manipulate repeated fields.

These classes are very similar to STL's vector, but include a number of optimizations found to be useful specifically in the case of Protocol Buffers. RepeatedPtrField is particularly different from STL vector as it manages ownership of the pointers that it contains.

Typically, clients should not need to access RepeatedField objects directly, but should instead use the accessor functions generated automatically by the protocol compiler.

Classes in this file

RepeatedField is used to represent repeated fields of a primitive type (in other words, everything except strings and nested Messages).
RepeatedPtrField is like RepeatedField, but used for repeated strings or Messages.

File Members

These definitions are not part of any class.
template internal::RepeatedFieldBackInsertIterator< T >
RepeatedFieldBackInserter(RepeatedField< T > *const mutable_field)
Provides a back insert iterator for RepeatedField instances, similar to std::back_inserter().
template internal::RepeatedPtrFieldBackInsertIterator< T >
RepeatedPtrFieldBackInserter(RepeatedPtrField< T > *const mutable_field)
Provides a back insert iterator for RepeatedPtrField instances, similar to std::back_inserter().
template internal::RepeatedPtrFieldBackInsertIterator< T >
RepeatedFieldBackInserter(RepeatedPtrField< T > *const mutable_field)
Special back insert iterator for RepeatedPtrField instances, just in case someone wants to write generic template code that can access both RepeatedFields and RepeatedPtrFields using a common name.
template internal::AllocatedRepeatedPtrFieldBackInsertIterator< T >
AllocatedRepeatedPtrFieldBackInserter(RepeatedPtrField< T > *const mutable_field)
Provides a back insert iterator for RepeatedPtrField instances similar to std::back_inserter() which transfers the ownership while copying elements.
template internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator< T >
UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(RepeatedPtrField< T > *const mutable_field)
Similar to AllocatedRepeatedPtrFieldBackInserter, using UnsafeArenaAddAllocated instead of AddAllocated. more...

template internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator< T >
    protobuf::UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
        RepeatedPtrField< T > *const mutable_field)

Similar to AllocatedRepeatedPtrFieldBackInserter, using UnsafeArenaAddAllocated instead of AddAllocated.

This is slightly faster if that matters. It is also useful in legacy code that uses temporary ownership to avoid copies. Example:

RepeatedPtrField<T> temp_field;
+temp_field.AddAllocated(new T);
+... // Do something with temp_field
+temp_field.ExtractSubrange(0, temp_field.size(), nullptr);

If you put temp_field on the arena this fails, because the ownership transfers to the arena at the "AddAllocated" call and is not released anymore causing a double delete. Using UnsafeArenaAddAllocated prevents this.

template class RepeatedField

#include <google/protobuf/repeated_field.h>
namespace google::protobuf

template <typename >

RepeatedField is used to represent repeated fields of a primitive type (in other words, everything except strings and nested Messages).

Most users will not ever use a RepeatedField directly; they will use the get-by-index, set-by-index, and add accessors that are generated for all repeated fields.

Members

typedef
Element * iterator
STL-like iterator support.
typedef
const Element * const_iterator
typedef
Element value_type
typedef
value_type & reference
typedef
const value_type & const_reference
typedef
value_type * pointer
typedef
const value_type * const_pointer
typedef
int size_type
typedef
ptrdiff_t difference_type
typedef
std::reverse_iterator< const_iterator > const_reverse_iterator
Reverse iterator support.
typedef
std::reverse_iterator< iterator > reverse_iterator
constexpr
RepeatedField()
explicit
RepeatedField(Arena * arena)
RepeatedField(const RepeatedField & other)
template
RepeatedField(Iter begin, Iter end)
~RepeatedField()
RepeatedField &
operator=(const RepeatedField & other)
RepeatedField(RepeatedField && other)
RepeatedField &
operator=(RepeatedField && other)
bool
empty() const
int
size() const
const Element &
Get(int index) const
Element *
Mutable(int index)
const Element &
operator[](int index) const
Element &
operator[](int index)
const Element &
at(int index) const
Element &
at(int index)
void
Set(int index, const Element & value)
void
Add(const Element & value)
Element *
Add()
Appends a new element and return a pointer to it. more...
template void
Add(Iter begin, Iter end)
Append elements in the range [begin, end) after reserving the appropriate number of elements.
void
RemoveLast()
Remove the last element in the array.
void
ExtractSubrange(int start, int num, Element * elements)
Extract elements with indices in "[start .. start+num-1]". more...
void
Clear()
void
MergeFrom(const RepeatedField & other)
void
CopyFrom(const RepeatedField & other)
template void
Assign(Iter begin, Iter end)
Replaces the contents with RepeatedField(begin, end).
void
Reserve(int new_size)
Reserve space to expand the field to at least the given size. more...
void
Truncate(int new_size)
Resize the RepeatedField to a new, smaller size. This is O(1).
void
AddAlreadyReserved(const Element & value)
Element *
AddAlreadyReserved()
Appends a new element and return a pointer to it. more...
Element *
AddNAlreadyReserved(int elements)
int
Capacity() const
void
Resize(int new_size, const Element & value)
Like STL resize. more...
Element *
mutable_data()
Gets the underlying array. more...
const Element *
data() const
void
Swap(RepeatedField * other)
Swap entire contents with "other". more...
void
UnsafeArenaSwap(RepeatedField * other)
Swap entire contents with "other". more...
void
SwapElements(int index1, int index2)
Swap two elements.
iterator
begin()
const_iterator
begin() const
const_iterator
cbegin() const
iterator
end()
const_iterator
end() const
const_iterator
cend() const
reverse_iterator
rbegin()
const_reverse_iterator
rbegin() const
reverse_iterator
rend()
const_reverse_iterator
rend() const
size_t
SpaceUsedExcludingSelfLong() const
Returns the number of bytes used by the repeated field, excluding sizeof(*this)
int
SpaceUsedExcludingSelf() const
iterator
erase(const_iterator position)
Removes the element referenced by position. more...
iterator
erase(const_iterator first, const_iterator last)
Removes the elements in the range [first, last). more...
Arena *
GetArena() const
Get the Arena on which this RepeatedField stores its elements.
void
InternalSwap(RepeatedField * other)
For internal use only. more...
template
RepeatedField(Iter begin, Iter end)

Element * RepeatedField::Add()

Appends a new element and return a pointer to it.

The new element is uninitialized if |Element| is a POD type.


void RepeatedField::ExtractSubrange(
        int start,
        int num,
        Element * elements)

Extract elements with indices in "[start .. start+num-1]".

Copy them into "elements[0 .. num-1]" if "elements" is not NULL. Caution: implementation also moves elements with indices [start+num ..]. Calling this routine inside a loop can cause quadratic behavior.


void RepeatedField::Reserve(
        int new_size)

Reserve space to expand the field to at least the given size.

Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant amount of code bloat.

If the array is grown, it will always be at least doubled in size.


Element * RepeatedField::AddAlreadyReserved()

Appends a new element and return a pointer to it.

The new element is uninitialized if |Element| is a POD type. Should be called only if Capacity() > Size().


void RepeatedField::Resize(
        int new_size,
        const Element & value)

Like STL resize.

Uses value to fill appended elements. Like Truncate() if new_size <= size(), otherwise this is O(new_size - size()).


Element * RepeatedField::mutable_data()

Gets the underlying array.

This pointer is possibly invalidated by any add or remove operation.


void RepeatedField::Swap(
        RepeatedField * other)

Swap entire contents with "other".

If they are separate arenas then, copies data between each other.


void RepeatedField::UnsafeArenaSwap(
        RepeatedField * other)

Swap entire contents with "other".

Should be called only if the caller can guarantee that both repeated fields are on the same arena or are on the heap. Swapping between different arenas is disallowed and caught by a GOOGLE_DCHECK (see API docs for details).


iterator RepeatedField::erase(
        const_iterator position)

Removes the element referenced by position.

Returns an iterator to the element immediately following the removed element.

Invalidates all iterators at or after the removed element, including end().


iterator RepeatedField::erase(
        const_iterator first,
        const_iterator last)

Removes the elements in the range [first, last).

Returns an iterator to the element immediately following the removed range.

Invalidates all iterators at or after the removed range, including end().


void RepeatedField::InternalSwap(
        RepeatedField * other)

For internal use only.

This is public due to it being called by generated code.

template class RepeatedPtrField

#include <google/protobuf/repeated_field.h>
namespace google::protobuf

template <typename >

RepeatedPtrField is like RepeatedField, but used for repeated strings or Messages.

Members

typedef
internal::RepeatedPtrIterator< Element > iterator
STL-like iterator support.
typedef
internal::RepeatedPtrIterator< const Element > const_iterator
typedef
Element value_type
typedef
value_type & reference
typedef
const value_type & const_reference
typedef
value_type * pointer
typedef
const value_type * const_pointer
typedef
int size_type
typedef
ptrdiff_t difference_type
typedef
std::reverse_iterator< const_iterator > const_reverse_iterator
Reverse iterator support.
typedef
std::reverse_iterator< iterator > reverse_iterator
typedef
internal::RepeatedPtrOverPtrsIterator< Element *, void * > pointer_iterator
Custom STL-like iterator that iterates over and returns the underlying pointers to Element rather than Element itself.
typedef
internal::RepeatedPtrOverPtrsIterator< const Element *const, const void *const > const_pointer_iterator
constexpr
RepeatedPtrField()
explicit
RepeatedPtrField(Arena * arena)
RepeatedPtrField(const RepeatedPtrField & other)
template
RepeatedPtrField(Iter begin, Iter end)
~RepeatedPtrField()
RepeatedPtrField &
operator=(const RepeatedPtrField & other)
RepeatedPtrField(RepeatedPtrField && other)
RepeatedPtrField &
operator=(RepeatedPtrField && other)
bool
empty() const
int
size() const
const Element &
Get(int index) const
Element *
Mutable(int index)
Element *
Add()
void
Add(Element && value)
template void
Add(Iter begin, Iter end)
Append elements in the range [begin, end) after reserving the appropriate number of elements.
const Element &
operator[](int index) const
Element &
operator[](int index)
const Element &
at(int index) const
Element &
at(int index)
void
RemoveLast()
Remove the last element in the array. more...
void
DeleteSubrange(int start, int num)
Delete elements with indices in the range [start . more...
void
Clear()
void
MergeFrom(const RepeatedPtrField & other)
void
CopyFrom(const RepeatedPtrField & other)
template void
Assign(Iter begin, Iter end)
Replaces the contents with RepeatedPtrField(begin, end).
void
Reserve(int new_size)
Reserve space to expand the field to at least the given size. more...
int
Capacity() const
Element **
mutable_data()
Gets the underlying array. more...
const Element *const *
data() const
void
Swap(RepeatedPtrField * other)
Swap entire contents with "other". more...
void
UnsafeArenaSwap(RepeatedPtrField * other)
Swap entire contents with "other". more...
void
SwapElements(int index1, int index2)
Swap two elements.
iterator
begin()
const_iterator
begin() const
const_iterator
cbegin() const
iterator
end()
const_iterator
end() const
const_iterator
cend() const
reverse_iterator
rbegin()
const_reverse_iterator
rbegin() const
reverse_iterator
rend()
const_reverse_iterator
rend() const
pointer_iterator
pointer_begin()
const_pointer_iterator
pointer_begin() const
pointer_iterator
pointer_end()
const_pointer_iterator
pointer_end() const
size_t
SpaceUsedExcludingSelfLong() const
Returns (an estimate of) the number of bytes used by the repeated field, excluding sizeof(*this).
int
SpaceUsedExcludingSelf() const
template
RepeatedPtrField(Iter begin, Iter end)

Advanced memory management

When hardcore memory management becomes necessary – as it sometimes does here at Google – the following methods may be useful.
void
AddAllocated(Element * value)
Add an already-allocated object, passing ownership to the RepeatedPtrField. more...
PROTOBUF_FUTURE_MUST_USE_RESULT Element *
ReleaseLast()
Remove the last element and return it, passing ownership to the caller. more...
void
UnsafeArenaAddAllocated(Element * value)
Add an already-allocated object, skipping arena-ownership checks. more...
Element *
UnsafeArenaReleaseLast()
Remove the last element and return it. more...
void
ExtractSubrange(int start, int num, Element ** elements)
Extract elements with indices in the range "[start .. start+num-1]". more...
void
UnsafeArenaExtractSubrange(int start, int num, Element ** elements)
Identical to ExtractSubrange() described above, except that when this repeated field is on an arena, no object copies are performed. more...
int
ClearedCount() const
Get the number of cleared objects that are currently being kept around for reuse.
void
AddCleared(Element * value)
Add an element to the pool of cleared objects, passing ownership to the RepeatedPtrField. more...
PROTOBUF_FUTURE_MUST_USE_RESULT Element *
ReleaseCleared()
Remove a single element from the cleared pool and return it, passing ownership to the caller. more...
iterator
erase(const_iterator position)
Removes the element referenced by position. more...
iterator
erase(const_iterator first, const_iterator last)
Removes the elements in the range [first, last). more...
Arena *
GetArena() const
Gets the arena on which this RepeatedPtrField stores its elements.
void
InternalSwap(RepeatedPtrField * other)
For internal use only. more...

void RepeatedPtrField::RemoveLast()

Remove the last element in the array.

Ownership of the element is retained by the array.


void RepeatedPtrField::DeleteSubrange(
        int start,
        int num)

Delete elements with indices in the range [start .

. start+num-1]. Caution: implementation moves all elements with indices [start+num .. ]. Calling this routine inside a loop can cause quadratic behavior.


void RepeatedPtrField::Reserve(
        int new_size)

Reserve space to expand the field to at least the given size.

This only resizes the pointer array; it doesn't allocate any objects. If the array is grown, it will always be at least doubled in size.


Element ** RepeatedPtrField::mutable_data()

Gets the underlying array.

This pointer is possibly invalidated by any add or remove operation.


void RepeatedPtrField::Swap(
        RepeatedPtrField * other)

Swap entire contents with "other".

If they are on separate arenas, then copies data.


void RepeatedPtrField::UnsafeArenaSwap(
        RepeatedPtrField * other)

Swap entire contents with "other".

Caller should guarantee that either both fields are on the same arena or both are on the heap. Swapping between different arenas with this function is disallowed and is caught via GOOGLE_DCHECK.


void RepeatedPtrField::AddAllocated(
        Element * value)

Add an already-allocated object, passing ownership to the RepeatedPtrField.

Note that some special behavior occurs with respect to arenas:

(i) if this field holds submessages, the new submessage will be copied if
+the original is in an arena and this RepeatedPtrField is either in a
+different arena, or on the heap.
+(ii) if this field holds strings, the passed-in string *must* be
+heap-allocated, not arena-allocated. There is no way to dynamically check
+this at runtime, so User Beware.

PROTOBUF_FUTURE_MUST_USE_RESULT Element *
    RepeatedPtrField::ReleaseLast()

Remove the last element and return it, passing ownership to the caller.

Requires: size() > 0

If this RepeatedPtrField is on an arena, an object copy is required to pass ownership back to the user (for compatible semantics). Use UnsafeArenaReleaseLast() if this behavior is undesired.


void RepeatedPtrField::UnsafeArenaAddAllocated(
        Element * value)

Add an already-allocated object, skipping arena-ownership checks.

The user must guarantee that the given object is in the same arena as this RepeatedPtrField. It is also useful in legacy code that uses temporary ownership to avoid copies. Example:

RepeatedPtrField<T> temp_field;
+temp_field.AddAllocated(new T);
+... // Do something with temp_field
+temp_field.ExtractSubrange(0, temp_field.size(), nullptr);

If you put temp_field on the arena this fails, because the ownership transfers to the arena at the "AddAllocated" call and is not released anymore causing a double delete. UnsafeArenaAddAllocated prevents this.


Element * RepeatedPtrField::UnsafeArenaReleaseLast()

Remove the last element and return it.

Works only when operating on an arena. The returned pointer is to the original object in the arena, hence has the arena's lifetime. Requires: current_size_ > 0


void RepeatedPtrField::ExtractSubrange(
        int start,
        int num,
        Element ** elements)

Extract elements with indices in the range "[start .. start+num-1]".

The caller assumes ownership of the extracted elements and is responsible for deleting them when they are no longer needed. If "elements" is non-NULL, then pointers to the extracted elements are stored in "elements[0 .. num-1]" for the convenience of the caller. If "elements" is NULL, then the caller must use some other mechanism to perform any further operations (like deletion) on these elements. Caution: implementation also moves elements with indices [start+num ..]. Calling this routine inside a loop can cause quadratic behavior.

Memory copying behavior is identical to ReleaseLast(), described above: if this RepeatedPtrField is on an arena, an object copy is performed for each returned element, so that all returned element pointers are to heap-allocated copies. If this copy is not desired, the user should call UnsafeArenaExtractSubrange().


void RepeatedPtrField::UnsafeArenaExtractSubrange(
        int start,
        int num,
        Element ** elements)

Identical to ExtractSubrange() described above, except that when this repeated field is on an arena, no object copies are performed.

Instead, the raw object pointers are returned. Thus, if on an arena, the returned objects must not be freed, because they will not be heap-allocated objects.


void RepeatedPtrField::AddCleared(
        Element * value)

Add an element to the pool of cleared objects, passing ownership to the RepeatedPtrField.

The element must be cleared prior to calling this method.

This method cannot be called when the repeated field is on an arena or when |value| is; both cases will trigger a GOOGLE_DCHECK-failure.


PROTOBUF_FUTURE_MUST_USE_RESULT Element *
    RepeatedPtrField::ReleaseCleared()

Remove a single element from the cleared pool and return it, passing ownership to the caller.

The element is guaranteed to be cleared. Requires: ClearedCount() > 0

This method cannot be called when the repeated field is on an arena; doing so will trigger a GOOGLE_DCHECK-failure.


iterator RepeatedPtrField::erase(
        const_iterator position)

Removes the element referenced by position.

Returns an iterator to the element immediately following the removed element.

Invalidates all iterators at or after the removed element, including end().


iterator RepeatedPtrField::erase(
        const_iterator first,
        const_iterator last)

Removes the elements in the range [first, last).

Returns an iterator to the element immediately following the removed range.

Invalidates all iterators at or after the removed range, including end().


void RepeatedPtrField::InternalSwap(
        RepeatedPtrField * other)

For internal use only.

This is public due to it being called by generated code.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.service/index.html b/reference/cpp/api-docs/google.protobuf.service/index.html new file mode 100644 index 000000000..8ded00365 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.service/index.html @@ -0,0 +1,39 @@ +service.h | Protocol Buffers Documentation +

service.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/service.h>
namespace google::protobuf

DEPRECATED: This module declares the abstract interfaces underlying proto2 RPC services.

These are intended to be independent of any particular RPC implementation, so that proto2 services can be used on top of a variety of implementations. Starting with version 2.3.0, RPC implementations should not try to build on these, but should instead provide code generator plugins which generate code specific to the particular RPC implementation. This way the generated code can be more appropriate for the implementation in use and can avoid unnecessary layers of indirection.

When you use the protocol compiler to compile a service definition, it generates two classes: An abstract interface for the service (with methods matching the service definition) and a "stub" implementation. A stub is just a type-safe wrapper around an RpcChannel which emulates a local implementation of the service.

For example, the service definition:

service MyService {
+  rpc Foo(MyRequest) returns(MyResponse);
+}

will generate abstract interface "MyService" and class "MyService::Stub". You could implement a MyService as follows:

class MyServiceImpl : public MyService {
+ public:
+  MyServiceImpl() {}
+  ~MyServiceImpl() {}
+
+  // implements MyService ---------------------------------------
+
+  void Foo(google::protobuf::RpcController* controller,
+           const MyRequest* request,
+           MyResponse* response,
+           Closure* done) {
+    // ... read request and fill in response ...
+    done->Run();
+  }
+};

You would then register an instance of MyServiceImpl with your RPC server implementation. (How to do that depends on the implementation.)

To call a remote MyServiceImpl, first you need an RpcChannel connected to it. How to construct a channel depends, again, on your RPC implementation. Here we use a hypothetical "MyRpcChannel" as an example:

MyRpcChannel channel("rpc:hostname:1234/myservice");
+MyRpcController controller;
+MyServiceImpl::Stub stub(&channel);
+FooRequest request;
+FooResponse response;
+
+// ... fill in request ...
+
+stub.Foo(&controller, request, &response, NewCallback(HandleResponse));

On Thread-Safety:

Different RPC implementations may make different guarantees about what threads they may run callbacks on, and what threads the application is allowed to use to call the RPC system. Portable software should be ready for callbacks to be called on any thread, but should not try to call the RPC system from any thread except for the ones on which it received the callbacks. Realistically, though, simple software will probably want to use a single-threaded RPC system while high-end software will want to use multiple threads. RPC implementations should provide multiple choices.

Classes in this file

Abstract base interface for protocol-buffer-based RPC services.
An RpcController mediates a single method call.
Abstract interface for an RPC channel.

class Service

#include <google/protobuf/service.h>
namespace google::protobuf

Abstract base interface for protocol-buffer-based RPC services.

Services themselves are abstract interfaces (implemented either by servers or as stubs), but they subclass this base interface. The methods of this interface can be used to call the methods of the Service without knowing its exact type at compile time (analogous to Reflection).

Members

enum
ChannelOwnership
When constructing a stub, you may pass STUB_OWNS_CHANNEL as the second parameter to the constructor to tell it to delete its RpcChannel when destroyed. more...
Service()
virtual
~Service()
virtual const ServiceDescriptor *
GetDescriptor() = 0
Get the ServiceDescriptor describing this service and its methods.
virtual void
CallMethod(const MethodDescriptor * method, RpcController * controller, const Message * request, Message * response, Closure * done) = 0
Call a method of the service specified by MethodDescriptor. more...
virtual const Message &
GetRequestPrototype(const MethodDescriptor * method) const = 0
CallMethod() requires that the request and response passed in are of a particular subclass of Message. more...
virtual const Message &
GetResponsePrototype(const MethodDescriptor * method) const = 0

enum Service::ChannelOwnership {
  STUB_OWNS_CHANNEL,
  STUB_DOESNT_OWN_CHANNEL
}

When constructing a stub, you may pass STUB_OWNS_CHANNEL as the second parameter to the constructor to tell it to delete its RpcChannel when destroyed.

STUB_OWNS_CHANNEL
STUB_DOESNT_OWN_CHANNEL

virtual void Service::CallMethod(
        const MethodDescriptor * method,
        RpcController * controller,
        const Message * request,
        Message * response,
        Closure * done) = 0

Call a method of the service specified by MethodDescriptor.

This is normally implemented as a simple switch() that calls the standard definitions of the service's methods.

Preconditions:

  • method->service() == GetDescriptor()
  • request and response are of the exact same classes as the objects returned by GetRequestPrototype(method) and GetResponsePrototype(method).
  • After the call has started, the request must not be modified and the response must not be accessed at all until "done" is called.
  • "controller" is of the correct type for the RPC implementation being used by this Service. For stubs, the "correct type" depends on the RpcChannel which the stub is using. Server-side Service implementations are expected to accept whatever type of RpcController the server-side RPC implementation uses.

Postconditions:

  • "done" will be called when the method is complete. This may be before CallMethod() returns or it may be at some point in the future.
  • If the RPC succeeded, "response" contains the response returned by the server.
  • If the RPC failed, "response"'s contents are undefined. The RpcController can be queried to determine if an error occurred and possibly to get more information about the error.

virtual const Message & Service::GetRequestPrototype(
        const MethodDescriptor * method) const = 0

CallMethod() requires that the request and response passed in are of a particular subclass of Message.

GetRequestPrototype() and GetResponsePrototype() get the default instances of these required types. You can then call Message::New() on these instances to construct mutable objects which you can then pass to CallMethod().

Example:

const MethodDescriptor* method =
+  service->GetDescriptor()->FindMethodByName("Foo");
+Message* request  = stub->GetRequestPrototype (method)->New();
+Message* response = stub->GetResponsePrototype(method)->New();
+request->ParseFromString(input);
+service->CallMethod(method, *request, response, callback);

class RpcController

#include <google/protobuf/service.h>
namespace google::protobuf

An RpcController mediates a single method call.

The primary purpose of the controller is to provide a way to manipulate settings specific to the RPC implementation and to find out about RPC-level errors.

The methods provided by the RpcController interface are intended to be a "least common denominator" set of features which we expect all implementations to support. Specific implementations may provide more advanced features (e.g. deadline propagation).

Members

RpcController()
virtual
~RpcController()

Client-side methods

These calls may be made from the client side only. Their results are undefined on the server side (may crash).
virtual void
Reset() = 0
Resets the RpcController to its initial state so that it may be reused in a new call. more...
virtual bool
Failed() const = 0
After a call has finished, returns true if the call failed. more...
virtual std::string
ErrorText() const = 0
If Failed() is true, returns a human-readable description of the error.
virtual void
StartCancel() = 0
Advises the RPC system that the caller desires that the RPC call be canceled. more...

Server-side methods

These calls may be made from the server side only.

Their results are undefined on the client side (may crash).

virtual void
SetFailed(const std::string & reason) = 0
Causes Failed() to return true on the client side. more...
virtual bool
IsCanceled() const = 0
If true, indicates that the client canceled the RPC, so the server may as well give up on replying to it. more...
virtual void
NotifyOnCancel(Closure * callback) = 0
Asks that the given callback be called when the RPC is canceled. more...

virtual void RpcController::Reset() = 0

Resets the RpcController to its initial state so that it may be reused in a new call.

Must not be called while an RPC is in progress.


virtual bool RpcController::Failed() const = 0

After a call has finished, returns true if the call failed.

The possible reasons for failure depend on the RPC implementation. Failed() must not be called before a call has finished. If Failed() returns true, the contents of the response message are undefined.


virtual void RpcController::StartCancel() = 0

Advises the RPC system that the caller desires that the RPC call be canceled.

The RPC system may cancel it immediately, may wait awhile and then cancel it, or may not even cancel the call at all. If the call is canceled, the "done" callback will still be called and the RpcController will indicate that the call failed at that time.


virtual void RpcController::SetFailed(
        const std::string & reason) = 0

Causes Failed() to return true on the client side.

"reason" will be incorporated into the message returned by ErrorText(). If you find you need to return machine-readable information about failures, you should incorporate it into your response protocol buffer and should NOT call SetFailed().


virtual bool RpcController::IsCanceled() const = 0

If true, indicates that the client canceled the RPC, so the server may as well give up on replying to it.

The server should still call the final "done" callback.


virtual void RpcController::NotifyOnCancel(
        Closure * callback) = 0

Asks that the given callback be called when the RPC is canceled.

The callback will always be called exactly once. If the RPC completes without being canceled, the callback will be called after completion. If the RPC has already been canceled when NotifyOnCancel() is called, the callback will be called immediately.

NotifyOnCancel() must be called no more than once per request.

class RpcChannel

#include <google/protobuf/service.h>
namespace google::protobuf

Abstract interface for an RPC channel.

An RpcChannel represents a communication line to a Service which can be used to call that Service's methods. The Service may be running on another machine. Normally, you should not call an RpcChannel directly, but instead construct a stub Service wrapping it. Example:

RpcChannel* channel = new MyRpcChannel("remotehost.example.com:1234");
+MyService* service = new MyService::Stub(channel);
+service->MyMethod(request, &response, callback);

Members

RpcChannel()
virtual
~RpcChannel()
virtual void
CallMethod(const MethodDescriptor * method, RpcController * controller, const Message * request, Message * response, Closure * done) = 0
Call the given method of the remote service. more...

virtual void RpcChannel::CallMethod(
        const MethodDescriptor * method,
        RpcController * controller,
        const Message * request,
        Message * response,
        Closure * done) = 0

Call the given method of the remote service.

The signature of this procedure looks the same as Service::CallMethod(), but the requirements are less strict in one important way: the request and response objects need not be of any specific class as long as their descriptors are method->input_type() and method->output_type().

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.text_format/index.html b/reference/cpp/api-docs/google.protobuf.text_format/index.html new file mode 100644 index 000000000..b7be8f6ff --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.text_format/index.html @@ -0,0 +1,8 @@ +text_format.h | Protocol Buffers Documentation +

text_format.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/text_format.h>
namespace google::protobuf

Utilities for printing and parsing protocol messages in a human-readable, text-based format.

Classes in this file

This class implements protocol buffer text format, colloquially known as text proto.
The default printer that converts scalar values from fields into their string representation.
Deprecated: please use FastFieldValuePrinter instead.
Interface that Printers or Parsers can use to find extensions, or types referenced in Any messages.
Data structure which is populated with the locations of each field value parsed from the text.
A location in the parsed text.
For more control over parsing, use this class.
Class for those users which require more fine-grained control over how a protobuffer message is printed out.

class TextFormat

#include <google/protobuf/text_format.h>
namespace google::protobuf

This class implements protocol buffer text format, colloquially known as text proto.

Printing and parsing protocol messages in text format is useful for debugging and human editing of messages.

This class is really a namespace that contains only static methods.

Members

static bool
Print(const Message & message, io::ZeroCopyOutputStream * output)
Outputs a textual representation of the given message to the given output stream. more...
static bool
PrintUnknownFields(const UnknownFieldSet & unknown_fields, io::ZeroCopyOutputStream * output)
Print the fields in an UnknownFieldSet. more...
static bool
PrintToString(const Message & message, std::string * output)
Like Print(), but outputs directly to a string. more...
static bool
PrintUnknownFieldsToString(const UnknownFieldSet & unknown_fields, std::string * output)
Like PrintUnknownFields(), but outputs directly to a string. more...
static void
PrintFieldValueToString(const Message & message, const FieldDescriptor * field, int index, std::string * output)
Outputs a textual representation of the value of the field supplied on the message supplied. more...
static bool
Parse(io::ZeroCopyInputStream * input, Message * output)
Parses a text-format protocol message from the given input stream to the given message object. more...
static bool
ParseFromString(ConstStringParam input, Message * output)
Like Parse(), but reads directly from a string.
static bool
Merge(io::ZeroCopyInputStream * input, Message * output)
Like Parse(), but the data is merged into the given message, as if using Message::MergeFrom().
static bool
MergeFromString(ConstStringParam input, Message * output)
Like Merge(), but reads directly from a string.
static bool
ParseFieldValueFromString(const std::string & input, const FieldDescriptor * field, Message * message)
Parse the given text as a single field value and store it into the given field of the given message. more...

static bool TextFormat::Print(
        const Message & message,
        io::ZeroCopyOutputStream * output)

Outputs a textual representation of the given message to the given output stream.

Returns false if printing fails.


static bool TextFormat::PrintUnknownFields(
        const UnknownFieldSet & unknown_fields,
        io::ZeroCopyOutputStream * output)

Print the fields in an UnknownFieldSet.

They are printed by tag number only. Embedded messages are heuristically identified by attempting to parse them. Returns false if printing fails.


static bool TextFormat::PrintToString(
        const Message & message,
        std::string * output)

Like Print(), but outputs directly to a string.

Note: output will be cleared prior to printing, and will be left empty even if printing fails. Returns false if printing fails.


static bool TextFormat::PrintUnknownFieldsToString(
        const UnknownFieldSet & unknown_fields,
        std::string * output)

Like PrintUnknownFields(), but outputs directly to a string.

Returns false if printing fails.


static void TextFormat::PrintFieldValueToString(
        const Message & message,
        const FieldDescriptor * field,
        int index,
        std::string * output)

Outputs a textual representation of the value of the field supplied on the message supplied.

For non-repeated fields, an index of -1 must be supplied. Note that this method will print the default value for a field if it is not set.


static bool TextFormat::Parse(
        io::ZeroCopyInputStream * input,
        Message * output)

Parses a text-format protocol message from the given input stream to the given message object.

This function parses the human-readable format written by Print(). Returns true on success. The message is cleared first, even if the function fails – See Merge() to avoid this behavior.

Example input: "user {\n id: 123 extra { gender: MALE language: 'en' }\n}"

One use for this function is parsing handwritten strings in test code. Another use is to parse the output from google::protobuf::Message::DebugString() (or ShortDebugString()), because these functions output using google::protobuf::TextFormat::Print().

If you would like to read a protocol buffer serialized in the (non-human-readable) binary wire format, see google::protobuf::MessageLite::ParseFromString().


static bool TextFormat::ParseFieldValueFromString(
        const std::string & input,
        const FieldDescriptor * field,
        Message * message)

Parse the given text as a single field value and store it into the given field of the given message.

If the field is a repeated field, the new value will be added to the end

class TextFormat::BaseTextGenerator

#include <google/protobuf/text_format.h>
namespace google::protobuf

Members

virtual
~BaseTextGenerator()
virtual void
Indent()
virtual void
Outdent()
virtual size_t
GetCurrentIndentationSize() const
Returns the current indentation size in characters.
virtual void
Print(const char * text, size_t size) = 0
Print text to the output stream.
void
PrintString(const std::string & str)
template void
PrintLiteral(const char(&) text)

class TextFormat::FastFieldValuePrinter

#include <google/protobuf/text_format.h>
namespace google::protobuf

The default printer that converts scalar values from fields into their string representation.

You can derive from this FastFieldValuePrinter if you want to have fields to be printed in a different way and register it at the Printer.

Members

FastFieldValuePrinter()
virtual
~FastFieldValuePrinter()
virtual void
PrintBool(bool val, BaseTextGenerator * generator) const
virtual void
PrintInt32(int32 val, BaseTextGenerator * generator) const
virtual void
PrintUInt32(uint32 val, BaseTextGenerator * generator) const
virtual void
PrintInt64(int64 val, BaseTextGenerator * generator) const
virtual void
PrintUInt64(uint64 val, BaseTextGenerator * generator) const
virtual void
PrintFloat(float val, BaseTextGenerator * generator) const
virtual void
PrintDouble(double val, BaseTextGenerator * generator) const
virtual void
PrintString(const std::string & val, BaseTextGenerator * generator) const
virtual void
PrintBytes(const std::string & val, BaseTextGenerator * generator) const
virtual void
PrintEnum(int32 val, const std::string & name, BaseTextGenerator * generator) const
virtual void
PrintFieldName(const Message & message, int field_index, int field_count, const Reflection * reflection, const FieldDescriptor * field, BaseTextGenerator * generator) const
virtual void
PrintFieldName(const Message & message, const Reflection * reflection, const FieldDescriptor * field, BaseTextGenerator * generator) const
virtual void
PrintMessageStart(const Message & message, int field_index, int field_count, bool single_line_mode, BaseTextGenerator * generator) const
virtual bool
PrintMessageContent(const Message & message, int field_index, int field_count, bool single_line_mode, BaseTextGenerator * generator) const
Allows to override the logic on how to print the content of a message. more...
virtual void
PrintMessageEnd(const Message & message, int field_index, int field_count, bool single_line_mode, BaseTextGenerator * generator) const

virtual bool FastFieldValuePrinter::PrintMessageContent(
        const Message & message,
        int field_index,
        int field_count,
        bool single_line_mode,
        BaseTextGenerator * generator) const

Allows to override the logic on how to print the content of a message.

Return false to use the default printing logic. Note that it is legal for this function to print something and then return false to use the default content printing (although at that point it would behave similarly to PrintMessageStart).

class TextFormat::FieldValuePrinter

#include <google/protobuf/text_format.h>
namespace google::protobuf

Deprecated: please use FastFieldValuePrinter instead.

Members

FieldValuePrinter()
virtual
~FieldValuePrinter()
virtual std::string
PrintBool(bool val) const
virtual std::string
PrintInt32(int32 val) const
virtual std::string
PrintUInt32(uint32 val) const
virtual std::string
PrintInt64(int64 val) const
virtual std::string
PrintUInt64(uint64 val) const
virtual std::string
PrintFloat(float val) const
virtual std::string
PrintDouble(double val) const
virtual std::string
PrintString(const std::string & val) const
virtual std::string
PrintBytes(const std::string & val) const
virtual std::string
PrintEnum(int32 val, const std::string & name) const
virtual std::string
PrintFieldName(const Message & message, const Reflection * reflection, const FieldDescriptor * field) const
virtual std::string
PrintMessageStart(const Message & message, int field_index, int field_count, bool single_line_mode) const
virtual std::string
PrintMessageEnd(const Message & message, int field_index, int field_count, bool single_line_mode) const

class TextFormat::Finder

#include <google/protobuf/text_format.h>
namespace google::protobuf

Interface that Printers or Parsers can use to find extensions, or types referenced in Any messages.

Members

virtual
~Finder()
virtual const FieldDescriptor *
FindExtension(Message * message, const std::string & name) const
Try to find an extension of *message by fully-qualified field name. more...
virtual const FieldDescriptor *
FindExtensionByNumber(const Descriptor * descriptor, int number) const
Similar to FindExtension, but uses a Descriptor and the extension number instead of using a Message and the name when doing the look up.
virtual const Descriptor *
FindAnyType(const Message & message, const std::string & prefix, const std::string & name) const
Find the message type for an Any proto. more...
virtual MessageFactory *
FindExtensionFactory(const FieldDescriptor * field) const
Find the message factory for the given extension field. more...

virtual const FieldDescriptor *
    Finder::FindExtension(
        Message * message,
        const std::string & name) const

Try to find an extension of *message by fully-qualified field name.

Returns NULL if no extension is known for this name or number. The base implementation uses the extensions already known by the message.


virtual const Descriptor *
    Finder::FindAnyType(
        const Message & message,
        const std::string & prefix,
        const std::string & name) const

Find the message type for an Any proto.

Returns NULL if no message is known for this name. The base implementation only accepts prefixes of type.googleprod.com/ or type.googleapis.com/, and searches the DescriptorPool of the parent message.


virtual MessageFactory * Finder::FindExtensionFactory(
        const FieldDescriptor * field) const

Find the message factory for the given extension field.

This can be used to generalize the Parser to add extension fields to a message in the same way as the "input" message for the Parser.

class TextFormat::MessagePrinter

#include <google/protobuf/text_format.h>
namespace google::protobuf

Members

MessagePrinter()
virtual
~MessagePrinter()
virtual void
Print(const Message & message, bool single_line_mode, BaseTextGenerator * generator) const = 0

class TextFormat::ParseInfoTree

#include <google/protobuf/text_format.h>
namespace google::protobuf

Data structure which is populated with the locations of each field value parsed from the text.

Members

ParseInfoTree()
ParseInfoTree(const ParseInfoTree & )
ParseInfoTree &
operator=(const ParseInfoTree & )
ParseLocation
GetLocation(const FieldDescriptor * field, int index) const
Returns the parse location for index-th value of the field in the parsed text. more...
ParseInfoTree *
GetTreeForNested(const FieldDescriptor * field, int index) const
Returns the parse info tree for the given field, which must be a message type. more...

ParseLocation ParseInfoTree::GetLocation(
        const FieldDescriptor * field,
        int index) const

Returns the parse location for index-th value of the field in the parsed text.

If none exists, returns a location with line = -1. Index should be -1 for not-repeated fields.


ParseInfoTree * ParseInfoTree::GetTreeForNested(
        const FieldDescriptor * field,
        int index) const

Returns the parse info tree for the given field, which must be a message type.

The nested information tree is owned by the root tree and will be deleted when it is deleted.

struct TextFormat::ParseLocation

#include <google/protobuf/text_format.h>
namespace google::protobuf

A location in the parsed text.

Members

int
line
int
column
ParseLocation()
ParseLocation(int line_param, int column_param)

class TextFormat::Parser

#include <google/protobuf/text_format.h>
namespace google::protobuf

For more control over parsing, use this class.

Members

Parser()
~Parser()
bool
Parse(io::ZeroCopyInputStream * input, Message * output)
bool
ParseFromString(ConstStringParam input, Message * output)
bool
Merge(io::ZeroCopyInputStream * input, Message * output)
bool
MergeFromString(ConstStringParam input, Message * output)
void
RecordErrorsTo(io::ErrorCollector * error_collector)
Set where to report parse errors. more...
void
SetFinder(const Finder * finder)
Set how parser finds extensions. more...
void
WriteLocationsTo(ParseInfoTree * tree)
Sets where location information about the parse will be written. more...
void
AllowPartialMessage(bool allow)
Normally parsing fails if, after parsing, output->IsInitialized() returns false. more...
void
AllowCaseInsensitiveField(bool allow)
Allow field names to be matched case-insensitively. more...
bool
ParseFieldValueFromString(const std::string & input, const FieldDescriptor * field, Message * output)
void
AllowUnknownExtension(bool allow)
When an unknown extension is met, parsing will fail if this option is set to false (the default). more...
void
AllowUnknownField(bool allow)
When an unknown field is met, parsing will fail if this option is set to false (the default). more...
void
AllowFieldNumber(bool allow)
void
SetRecursionLimit(int limit)
Sets maximum recursion depth which parser can use. more...

void Parser::RecordErrorsTo(
        io::ErrorCollector * error_collector)

Set where to report parse errors.

If NULL (the default), errors will be printed to stderr.


void Parser::SetFinder(
        const Finder * finder)

Set how parser finds extensions.

If NULL (the default), the parser will use the standard Reflection object associated with the message being parsed.


void Parser::WriteLocationsTo(
        ParseInfoTree * tree)

Sets where location information about the parse will be written.

If NULL (the default), then no location will be written.


void Parser::AllowPartialMessage(
        bool allow)

Normally parsing fails if, after parsing, output->IsInitialized() returns false.

Call AllowPartialMessage(true) to skip this check.


void Parser::AllowCaseInsensitiveField(
        bool allow)

Allow field names to be matched case-insensitively.

This is not advisable if there are fields that only differ in case, or if you want to enforce writing in the canonical form. This is 'false' by default.


void Parser::AllowUnknownExtension(
        bool allow)

When an unknown extension is met, parsing will fail if this option is set to false (the default).

If true, unknown extensions will be ignored and a warning message will be generated. Beware! Setting this option true may hide some errors (e.g. spelling error on extension name). This allows data loss; unlike binary format, text format cannot preserve unknown extensions. Avoid using this option if possible.


void Parser::AllowUnknownField(
        bool allow)

When an unknown field is met, parsing will fail if this option is set to false (the default).

If true, unknown fields will be ignored and a warning message will be generated. Beware! Setting this option true may hide some errors (e.g. spelling error on field name). This allows data loss; unlike binary format, text format cannot preserve unknown fields. Avoid using this option if possible.


void Parser::SetRecursionLimit(
        int limit)

Sets maximum recursion depth which parser can use.

This is effectively the maximum allowed nesting of proto messages.

class TextFormat::Printer

#include <google/protobuf/text_format.h>
namespace google::protobuf

Class for those users which require more fine-grained control over how a protobuffer message is printed out.

Members

Printer()
bool
Print(const Message & message, io::ZeroCopyOutputStream * output) const
bool
PrintUnknownFields(const UnknownFieldSet & unknown_fields, io::ZeroCopyOutputStream * output) const
bool
PrintToString(const Message & message, std::string * output) const
bool
PrintUnknownFieldsToString(const UnknownFieldSet & unknown_fields, std::string * output) const
void
PrintFieldValueToString(const Message & message, const FieldDescriptor * field, int index, std::string * output) const
void
SetInitialIndentLevel(int indent_level)
Adjust the initial indent level of all output. more...
void
SetSingleLineMode(bool single_line_mode)
If printing in single line mode, then the entire message will be output on a single line with no line breaks.
bool
IsInSingleLineMode() const
void
SetUseFieldNumber(bool use_field_number)
If use_field_number is true, uses field number instead of field name.
void
SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives)
Set true to print repeated primitives in a format like: more...
void
SetUseUtf8StringEscaping(bool as_utf8)
Set true to output UTF-8 instead of ASCII. more...
void
SetDefaultFieldValuePrinter(const FastFieldValuePrinter * printer)
Set the default FastFieldValuePrinter that is used for all fields that don't have a field-specific printer registered. more...
void
SetDefaultFieldValuePrinter(const FieldValuePrinter * printer)
void
SetHideUnknownFields(bool hide)
Sets whether we want to hide unknown fields or not. more...
void
SetPrintMessageFieldsInIndexOrder(bool print_message_fields_in_index_order)
If print_message_fields_in_index_order is true, fields of a proto message will be printed using the order defined in source code instead of the field number, extensions will be printed at the end of the message and their relative order is determined by the extension number. more...
void
SetExpandAny(bool expand)
If expand==true, expand google.protobuf.Any payloads. more...
void
SetFinder(const Finder * finder)
Set how parser finds message for Any payloads.
void
SetTruncateStringFieldLongerThan(const int64 truncate_string_field_longer_than)
If non-zero, we truncate all string fields that are longer than this threshold. more...
bool
RegisterFieldValuePrinter(const FieldDescriptor * field, const FastFieldValuePrinter * printer)
Register a custom field-specific FastFieldValuePrinter for fields with a particular FieldDescriptor. more...
bool
RegisterFieldValuePrinter(const FieldDescriptor * field, const FieldValuePrinter * printer)
bool
RegisterMessagePrinter(const Descriptor * descriptor, const MessagePrinter * printer)
Register a custom message-specific MessagePrinter for messages with a particular Descriptor. more...

void Printer::SetInitialIndentLevel(
        int indent_level)

Adjust the initial indent level of all output.

Each indent level is equal to two spaces.


void Printer::SetUseShortRepeatedPrimitives(
        bool use_short_repeated_primitives)

Set true to print repeated primitives in a format like:

field_name: [1, 2, 3, 4]

instead of printing each value on its own line. Short format applies only to primitive values – i.e. everything except strings and sub-messages/groups.


void Printer::SetUseUtf8StringEscaping(
        bool as_utf8)

Set true to output UTF-8 instead of ASCII.

The only difference is that bytes >= 0x80 in string fields will not be escaped, because they are assumed to be part of UTF-8 multi-byte sequences. This will change the default FastFieldValuePrinter.


void Printer::SetDefaultFieldValuePrinter(
        const FastFieldValuePrinter * printer)

Set the default FastFieldValuePrinter that is used for all fields that don't have a field-specific printer registered.

Takes ownership of the printer.


void Printer::SetHideUnknownFields(
        bool hide)

Sets whether we want to hide unknown fields or not.

Usually unknown fields are printed in a generic way that includes the tag number of the field instead of field name. However, sometimes it is useful to be able to print the message without unknown fields (e.g. for the python protobuf version to maintain consistency between its pure python and c++ implementations).


void Printer::SetPrintMessageFieldsInIndexOrder(
        bool print_message_fields_in_index_order)

If print_message_fields_in_index_order is true, fields of a proto message will be printed using the order defined in source code instead of the field number, extensions will be printed at the end of the message and their relative order is determined by the extension number.

By default, use the field number order.


void Printer::SetExpandAny(
        bool expand)

If expand==true, expand google.protobuf.Any payloads.

The output will be of form

[type_url] { <value_printed_in_text> }

If expand==false, print Any using the default printer. The output will look like

type_url: "<type_url>"  value: "serialized_content"

void Printer::SetTruncateStringFieldLongerThan(
        const int64 truncate_string_field_longer_than)

If non-zero, we truncate all string fields that are longer than this threshold.

This is useful when the proto message has very long strings, e.g., dump of encoded image file.

NOTE(hfgong): Setting a non-zero value breaks round-trip safe property of TextFormat::Printer. That is, from the printed message, we cannot fully recover the original string field any more.


bool Printer::RegisterFieldValuePrinter(
        const FieldDescriptor * field,
        const FastFieldValuePrinter * printer)

Register a custom field-specific FastFieldValuePrinter for fields with a particular FieldDescriptor.

Returns "true" if the registration succeeded, or "false", if there is already a printer for that FieldDescriptor. Takes ownership of the printer on successful registration.


bool Printer::RegisterMessagePrinter(
        const Descriptor * descriptor,
        const MessagePrinter * printer)

Register a custom message-specific MessagePrinter for messages with a particular Descriptor.

Returns "true" if the registration succeeded, or "false" if there is already a printer for that Descriptor.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.unknown_field_set/index.html b/reference/cpp/api-docs/google.protobuf.unknown_field_set/index.html new file mode 100644 index 000000000..f95046992 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.unknown_field_set/index.html @@ -0,0 +1,8 @@ +unknown_field_set.h | Protocol Buffers Documentation +

unknown_field_set.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/unknown_field_set.h>
namespace google::protobuf

Contains classes used to keep track of unrecognized fields seen while parsing a protocol message.

Classes in this file

An UnknownFieldSet contains fields that were encountered while parsing a message but were not defined by its type.
Represents one field in an UnknownFieldSet.

class UnknownFieldSet

#include <google/protobuf/unknown_field_set.h>
namespace google::protobuf

An UnknownFieldSet contains fields that were encountered while parsing a message but were not defined by its type.

Keeping track of these can be useful, especially in that they may be written if the message is serialized again without being cleared in between. This means that software which simply receives messages and forwards them to other servers does not need to be updated every time a new field is added to the message definition.

To get the UnknownFieldSet attached to any message, call Reflection::GetUnknownFields().

This class is necessarily tied to the protocol buffer wire format, unlike the Reflection interface which is independent of any serialization scheme.

Members

UnknownFieldSet()
~UnknownFieldSet()
void
Clear()
Remove all fields.
void
ClearAndFreeMemory()
Remove all fields and deallocate internal data objects.
bool
empty() const
Is this set empty?
void
MergeFrom(const UnknownFieldSet & other)
Merge the contents of some other UnknownFieldSet with this one.
void
MergeFromAndDestroy(UnknownFieldSet * other)
Similar to above, but this function will destroy the contents of other.
void
Swap(UnknownFieldSet * x)
Swaps the contents of some other UnknownFieldSet with this one.
size_t
SpaceUsedExcludingSelfLong() const
Computes (an estimate of) the total number of bytes currently used for storing the unknown fields in memory. more...
int
SpaceUsedExcludingSelf() const
size_t
SpaceUsedLong() const
Version of SpaceUsed() including sizeof(*this).
int
SpaceUsed() const
int
field_count() const
Returns the number of fields present in the UnknownFieldSet.
const UnknownField &
field(int index) const
Get a field in the set, where 0 <= index < field_count(). more...
UnknownField *
mutable_field(int index)
Get a mutable pointer to a field in the set, where 0 <= index < field_count(). more...
static void
MergeToInternalMetadata(const UnknownFieldSet & other, internal::InternalMetadata * metadata)
Merge the contents an UnknownFieldSet with the UnknownFieldSet in *metadata, if there is one. more...

Adding fields

void
AddVarint(int number, uint64 value)
void
AddFixed32(int number, uint32 value)
void
AddFixed64(int number, uint64 value)
void
AddLengthDelimited(int number, const std::string & value)
std::string *
AddLengthDelimited(int number)
UnknownFieldSet *
AddGroup(int number)
void
AddField(const UnknownField & field)
Adds an unknown field from another set.
void
DeleteSubrange(int start, int num)
Delete fields with indices in the range [start . more...
void
DeleteByNumber(int number)
Delete all fields with a specific field number. more...

Parsing helpers

These work exactly like the similarly-named methods of Message.
bool
MergeFromCodedStream(io::CodedInputStream * input)
bool
ParseFromCodedStream(io::CodedInputStream * input)
bool
ParseFromZeroCopyStream(io::ZeroCopyInputStream * input)
bool
ParseFromArray(const void * data, int size)
bool
ParseFromString(const std::string & data)
template bool
MergeFromMessage(const MessageType & message)
Merges this message's unknown field data (if any). more...
static const UnknownFieldSet &
default_instance()

size_t UnknownFieldSet::SpaceUsedExcludingSelfLong() const

Computes (an estimate of) the total number of bytes currently used for storing the unknown fields in memory.

Does NOT include sizeof(*this) in the calculation.


const UnknownField &
    UnknownFieldSet::field(
        int index) const

Get a field in the set, where 0 <= index < field_count().

The fields appear in the order in which they were added.


UnknownField * UnknownFieldSet::mutable_field(
        int index)

Get a mutable pointer to a field in the set, where 0 <= index < field_count().

The fields appear in the order in which they were added.


static void UnknownFieldSet::MergeToInternalMetadata(
        const UnknownFieldSet & other,
        internal::InternalMetadata * metadata)

Merge the contents an UnknownFieldSet with the UnknownFieldSet in *metadata, if there is one.

If *metadata doesn't have an UnknownFieldSet then add one to it and make it be a copy of the first arg.


void UnknownFieldSet::DeleteSubrange(
        int start,
        int num)

Delete fields with indices in the range [start .

. start+num-1]. Caution: implementation moves all fields with indices [start+num .. ].


void UnknownFieldSet::DeleteByNumber(
        int number)

Delete all fields with a specific field number.

The order of left fields is preserved. Caution: implementation moves all fields after the first deleted field.


template bool UnknownFieldSet::MergeFromMessage(
        const MessageType & message)

Merges this message's unknown field data (if any).

This works whether the message is a lite or full proto (for legacy reasons, lite and full return different types for MessageType::unknown_fields()).

class UnknownField

#include <google/protobuf/unknown_field_set.h>
namespace google::protobuf

Represents one field in an UnknownFieldSet.

Members

enum
Type
uint64
varint_
uint32
fixed32_
uint64
fixed64_
union LengthDelimited
length_delimited_
UnknownFieldSet *
group_
int
number() const
The field's field number, as seen on the wire.
Type
type() const
The field type.

Accessors

Each method works only for UnknownFields of the corresponding type.
uint32
number_
uint32
type_
union google::protobuf::UnknownField::@35
data_
uint64
varint() const
uint32
fixed32() const
uint64
fixed64() const
const std::string &
length_delimited() const
const UnknownFieldSet &
group() const
void
set_varint(uint64 value)
void
set_fixed32(uint32 value)
void
set_fixed64(uint64 value)
void
set_length_delimited(const std::string & value)
std::string *
mutable_length_delimited()
UnknownFieldSet *
mutable_group()
void
SerializeLengthDelimitedNoTag(io::CodedOutputStream * output) const
Serialization API. more...
size_t
GetLengthDelimitedSize() const
uint8 *
InternalSerializeLengthDelimitedNoTag(uint8 * target, io::EpsCopyOutputStream * stream) const
void
Delete()
If this UnknownField contains a pointer, delete it.
void
DeepCopy(const UnknownField & other)
Make a deep copy of any pointers in this UnknownField.
void
SetType(Type type)
Set the wire type of this UnknownField. more...

enum UnknownField::Type {
  TYPE_VARINT,
  TYPE_FIXED32,
  TYPE_FIXED64,
  TYPE_LENGTH_DELIMITED,
  TYPE_GROUP
}

TYPE_VARINT
TYPE_FIXED32
TYPE_FIXED64
TYPE_LENGTH_DELIMITED
TYPE_GROUP

void UnknownField::SerializeLengthDelimitedNoTag(
        io::CodedOutputStream * output) const

Serialization API.

These methods can take advantage of the underlying implementation and may achieve a better performance than using getters to retrieve the data and do the serialization yourself.


void UnknownField::SetType(
        Type type)

Set the wire type of this UnknownField.

Should only be used when this UnknownField is being created.

union UnknownField::LengthDelimited

#include <google/protobuf/unknown_field_set.h>
namespace google::protobuf

Members

std::string *
string_value
\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.util.field_comparator/index.html b/reference/cpp/api-docs/google.protobuf.util.field_comparator/index.html new file mode 100644 index 000000000..76526bf71 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.util.field_comparator/index.html @@ -0,0 +1,8 @@ +field_comparator.h | Protocol Buffers Documentation +

field_comparator.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/util/field_comparator.h>
namespace google::protobuf::util

Defines classes for field comparison.

Classes in this file

Base class specifying the interface for comparing protocol buffer fields.
Basic implementation of FieldComparator.

class FieldComparator

#include <google/protobuf/util/field_comparator.h>
namespace google::protobuf::util

Base class specifying the interface for comparing protocol buffer fields.

Regular users should consider using or subclassing DefaultFieldComparator rather than this interface. Currently, this does not support comparing unknown fields.

Known subclasses:

Members

enum
ComparisonResult
FieldComparator()
virtual
~FieldComparator()
virtual ComparisonResult
Compare(const Message & message_1, const Message & message_2, const FieldDescriptor * field, int index_1, int index_2, const util::FieldContext * field_context) = 0
Compares the values of a field in two protocol buffer messages. more...

enum FieldComparator::ComparisonResult {
  SAME,
  DIFFERENT,
  RECURSE
}

SAME

Compared fields are equal.

In case of comparing submessages, user should not recursively compare their contents.

DIFFERENT

Compared fields are different.

In case of comparing submessages, user should not recursively compare their contents.

RECURSE

Compared submessages need to be compared recursively.

FieldComparator does not specify the semantics of recursive comparison. This value should not be returned for simple values.


virtual ComparisonResult FieldComparator::Compare(
        const Message & message_1,
        const Message & message_2,
        const FieldDescriptor * field,
        int index_1,
        int index_2,
        const util::FieldContext * field_context) = 0

Compares the values of a field in two protocol buffer messages.

Returns SAME or DIFFERENT for simple values, and SAME, DIFFERENT or RECURSE for submessages. Returning RECURSE for fields not being submessages is illegal. In case the given FieldDescriptor points to a repeated field, the indices need to be valid. Otherwise they should be ignored.

FieldContext contains information about the specific instances of the fields being compared, versus FieldDescriptor which only contains general type information about the fields.

class SimpleFieldComparator: public FieldComparator

#include <google/protobuf/util/field_comparator.h>
namespace google::protobuf::util

Basic implementation of FieldComparator.

Supports three modes of floating point value comparison: exact, approximate using MathUtil::AlmostEqual method, and arbitrarily precise using MathUtil::WithinFractionOrMargin.

Known subclasses:

Members

enum
FloatComparison
SimpleFieldComparator()
Creates new comparator with float comparison set to EXACT.
~SimpleFieldComparator()
void
set_float_comparison(FloatComparison float_comparison)
FloatComparison
float_comparison() const
void
set_treat_nan_as_equal(bool treat_nan_as_equal)
Set whether the FieldComparator shall treat floats or doubles that are both NaN as equal (treat_nan_as_equal = true) or as different (treat_nan_as_equal = false). more...
bool
treat_nan_as_equal() const
void
SetFractionAndMargin(const FieldDescriptor * field, double fraction, double margin)
Sets the fraction and margin for the float comparison of a given field. more...
void
SetDefaultFractionAndMargin(double fraction, double margin)
Sets the fraction and margin for the float comparison of all float and double fields, unless a field has been given a specific setting via SetFractionAndMargin() above. more...
protected ComparisonResult
SimpleCompare(const Message & message_1, const Message & message_2, const FieldDescriptor * field, int index_1, int index_2, const util::FieldContext * field_context)
Returns the comparison result for the given field in two messages. more...
protected bool
CompareWithDifferencer(MessageDifferencer * differencer, const Message & message1, const Message & message2, const util::FieldContext * field_context)
Compare using the provided message_differencer. more...
protected ComparisonResult
ResultFromBoolean(bool boolean_result) const
Returns FieldComparator::SAME if boolean_result is true and FieldComparator::DIFFERENT otherwise.

enum SimpleFieldComparator::FloatComparison {
  EXACT,
  APPROXIMATE
}

EXACTFloats and doubles are compared exactly.
APPROXIMATEFloats and doubles are compared using the MathUtil::AlmostEqual method or MathUtil::WithinFractionOrMargin method.

void SimpleFieldComparator::set_treat_nan_as_equal(
        bool treat_nan_as_equal)

Set whether the FieldComparator shall treat floats or doubles that are both NaN as equal (treat_nan_as_equal = true) or as different (treat_nan_as_equal = false).

Default is treating NaNs always as different.


void SimpleFieldComparator::SetFractionAndMargin(
        const FieldDescriptor * field,
        double fraction,
        double margin)

Sets the fraction and margin for the float comparison of a given field.

Uses MathUtil::WithinFractionOrMargin to compare the values.

REQUIRES: field->cpp_type == FieldDescriptor::CPPTYPE_DOUBLE or

field->cpp_type == FieldDescriptor::CPPTYPE_FLOAT

REQUIRES: float_comparison_ == APPROXIMATE


void SimpleFieldComparator::SetDefaultFractionAndMargin(
        double fraction,
        double margin)

Sets the fraction and margin for the float comparison of all float and double fields, unless a field has been given a specific setting via SetFractionAndMargin() above.

Uses MathUtil::WithinFractionOrMargin to compare the values.

REQUIRES: float_comparison_ == APPROXIMATE


protected ComparisonResult SimpleFieldComparator::SimpleCompare(
        const Message & message_1,
        const Message & message_2,
        const FieldDescriptor * field,
        int index_1,
        int index_2,
        const util::FieldContext * field_context)

Returns the comparison result for the given field in two messages.

This function is called directly by DefaultFieldComparator::Compare. Subclasses can call this function to compare fields they do not need to handle specially.


protected bool SimpleFieldComparator::CompareWithDifferencer(
        MessageDifferencer * differencer,
        const Message & message1,
        const Message & message2,
        const util::FieldContext * field_context)

Compare using the provided message_differencer.

For example, a subclass can use this method to compare some field in a certain way using the same message_differencer instance and the field context.

class DefaultFieldComparator: public SimpleFieldComparator

#include <google/protobuf/util/field_comparator.h>
namespace google::protobuf::util

Members

virtual ComparisonResult
Compare(const Message & message_1, const Message & message_2, const FieldDescriptor * field, int index_1, int index_2, const util::FieldContext * field_context)
Compares the values of a field in two protocol buffer messages. more...

virtual ComparisonResult DefaultFieldComparator::Compare(
        const Message & message_1,
        const Message & message_2,
        const FieldDescriptor * field,
        int index_1,
        int index_2,
        const util::FieldContext * field_context)

Compares the values of a field in two protocol buffer messages.

Returns SAME or DIFFERENT for simple values, and SAME, DIFFERENT or RECURSE for submessages. Returning RECURSE for fields not being submessages is illegal. In case the given FieldDescriptor points to a repeated field, the indices need to be valid. Otherwise they should be ignored.

FieldContext contains information about the specific instances of the fields being compared, versus FieldDescriptor which only contains general type information about the fields.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.util.field_mask_util/index.html b/reference/cpp/api-docs/google.protobuf.util.field_mask_util/index.html new file mode 100644 index 000000000..11f48a007 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.util.field_mask_util/index.html @@ -0,0 +1,11 @@ +field_mask_util.h | Protocol Buffers Documentation +

field_mask_util.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/util/field_mask_util.h>
namespace google::protobuf::util

Defines utilities for the FieldMask well known type.

Classes in this file

class FieldMaskUtil

#include <google/protobuf/util/field_mask_util.h>
namespace google::protobuf::util

Members

static std::string
ToString(const FieldMask & mask)
Converts FieldMask to/from string, formatted by separating each path with a comma (e.g., "foo_bar,baz.quz").
static void
FromString(StringPiece str, FieldMask * out)
template static void
FromFieldNumbers(const std::vector< int64_t > & field_numbers, FieldMask * out)
Populates the FieldMask with the paths corresponding to the fields with the given numbers, after checking that all field numbers are valid.
static bool
ToJsonString(const FieldMask & mask, std::string * out)
Converts FieldMask to/from string, formatted according to proto3 JSON spec for FieldMask (e.g., "fooBar,baz.quz"). more...
static bool
FromJsonString(StringPiece str, FieldMask * out)
static bool
GetFieldDescriptors(const Descriptor * descriptor, StringPiece path, std::vector< const FieldDescriptor * > * field_descriptors)
Get the descriptors of the fields which the given path from the message descriptor traverses, if field_descriptors is not null. more...
template static bool
IsValidPath(StringPiece path)
Checks whether the given path is valid for type T.
template static bool
IsValidFieldMask(const FieldMask & mask)
Checks whether the given FieldMask is valid for type T.
template static void
AddPathToFieldMask(StringPiece path, FieldMask * mask)
Adds a path to FieldMask after checking whether the given path is valid. more...
template static FieldMask
GetFieldMaskForAllFields()
Creates a FieldMask with all fields of type T. more...
template static void
GetFieldMaskForAllFields(FieldMask * out)
static void
GetFieldMaskForAllFields(const Descriptor * descriptor, FieldMask * out)
This flavor takes the protobuf type descriptor as an argument. more...
static void
ToCanonicalForm(const FieldMask & mask, FieldMask * out)
Converts a FieldMask to the canonical form. more...
static void
Union(const FieldMask & mask1, const FieldMask & mask2, FieldMask * out)
Creates an union of two FieldMasks.
static void
Intersect(const FieldMask & mask1, const FieldMask & mask2, FieldMask * out)
Creates an intersection of two FieldMasks.
template static void
Subtract(const FieldMask & mask1, const FieldMask & mask2, FieldMask * out)
Subtracts mask2 from mask1 base of type T.
static void
Subtract(const Descriptor * descriptor, const FieldMask & mask1, const FieldMask & mask2, FieldMask * out)
This flavor takes the protobuf type descriptor as an argument. more...
static bool
IsPathInFieldMask(StringPiece path, const FieldMask & mask)
Returns true if path is covered by the given FieldMask. more...
static void
MergeMessageTo(const Message & source, const FieldMask & mask, const MergeOptions & options, Message * destination)
Merges fields specified in a FieldMask into another message.
static bool
TrimMessage(const FieldMask & mask, Message * message)
Removes from 'message' any field that is not represented in the given FieldMask. more...
static bool
TrimMessage(const FieldMask & mask, Message * message, const TrimOptions & options)
Removes from 'message' any field that is not represented in the given FieldMask with customized TrimOptions. more...

static bool FieldMaskUtil::ToJsonString(
        const FieldMask & mask,
        std::string * out)

Converts FieldMask to/from string, formatted according to proto3 JSON spec for FieldMask (e.g., "fooBar,baz.quz").

If the field name is not style conforming (i.e., not snake_case when converted to string, or not camelCase when converted from string), the conversion will fail.


static bool FieldMaskUtil::GetFieldDescriptors(
        const Descriptor * descriptor,
        StringPiece path,
        std::vector< const FieldDescriptor * > * field_descriptors)

Get the descriptors of the fields which the given path from the message descriptor traverses, if field_descriptors is not null.

Return false if the path is not valid, and the content of field_descriptors is unspecified.


template static void FieldMaskUtil::AddPathToFieldMask(
        StringPiece path,
        FieldMask * mask)

Adds a path to FieldMask after checking whether the given path is valid.

This method check-fails if the path is not a valid path for type T.


template static FieldMask FieldMaskUtil::GetFieldMaskForAllFields()

Creates a FieldMask with all fields of type T.

This FieldMask only contains fields of T but not any sub-message fields.


static void FieldMaskUtil::GetFieldMaskForAllFields(
        const Descriptor * descriptor,
        FieldMask * out)

This flavor takes the protobuf type descriptor as an argument.

Useful when the type is not known at compile time.


static void FieldMaskUtil::ToCanonicalForm(
        const FieldMask & mask,
        FieldMask * out)

Converts a FieldMask to the canonical form.

It will:

1. Remove paths that are covered by another path. For example,
+   "foo.bar" is covered by "foo" and will be removed if "foo"
+   is also in the FieldMask.
+2. Sort all paths in alphabetical order.

static void FieldMaskUtil::Subtract(
        const Descriptor * descriptor,
        const FieldMask & mask1,
        const FieldMask & mask2,
        FieldMask * out)

This flavor takes the protobuf type descriptor as an argument.

Useful when the type is not known at compile time.


static bool FieldMaskUtil::IsPathInFieldMask(
        StringPiece path,
        const FieldMask & mask)

Returns true if path is covered by the given FieldMask.

Note that path "foo.bar" covers all paths like "foo.bar.baz", "foo.bar.quz.x", etc. Also note that parent paths are not covered by explicit child path, i.e. "foo.bar" does NOT cover "foo", even if "bar" is the only child.


static bool FieldMaskUtil::TrimMessage(
        const FieldMask & mask,
        Message * message)

Removes from 'message' any field that is not represented in the given FieldMask.

If the FieldMask is empty, does nothing. Returns true if the message is modified.


static bool FieldMaskUtil::TrimMessage(
        const FieldMask & mask,
        Message * message,
        const TrimOptions & options)

Removes from 'message' any field that is not represented in the given FieldMask with customized TrimOptions.

If the FieldMask is empty, does nothing. Returns true if the message is modified.

class FieldMaskUtil::MergeOptions

#include <google/protobuf/util/field_mask_util.h>
namespace google::protobuf::util

Members

MergeOptions()
void
set_replace_message_fields(bool value)
When merging message fields, the default behavior is to merge the content of two message fields together. more...
bool
replace_message_fields() const
void
set_replace_repeated_fields(bool value)
The default merging behavior will append entries from the source repeated field to the destination repeated field. more...
bool
replace_repeated_fields() const

void MergeOptions::set_replace_message_fields(
        bool value)

When merging message fields, the default behavior is to merge the content of two message fields together.

If you instead want to use the field from the source message to replace the corresponding field in the destination message, set this flag to true. When this flag is set, specified submessage fields that are missing in source will be cleared in destination.


void MergeOptions::set_replace_repeated_fields(
        bool value)

The default merging behavior will append entries from the source repeated field to the destination repeated field.

If you only want to keep the entries from the source repeated field, set this flag to true.

class FieldMaskUtil::TrimOptions

#include <google/protobuf/util/field_mask_util.h>
namespace google::protobuf::util

Members

TrimOptions()
void
set_keep_required_fields(bool value)
When trimming message fields, the default behavior is to trim required fields of the present message if they are not specified in the field mask. more...
bool
keep_required_fields() const

void TrimOptions::set_keep_required_fields(
        bool value)

When trimming message fields, the default behavior is to trim required fields of the present message if they are not specified in the field mask.

If you instead want to keep required fields of the present message even they are not specified in the field mask, set this flag to true.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.util.json_util/index.html b/reference/cpp/api-docs/google.protobuf.util.json_util/index.html new file mode 100644 index 000000000..1e29185ea --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.util.json_util/index.html @@ -0,0 +1,12 @@ +json_util.h | Protocol Buffers Documentation +

json_util.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/util/json_util.h>
namespace google::protobuf::util

Utility functions to convert between protobuf binary format and proto3 JSON format.

Classes in this file

File Members

These definitions are not part of any class.
typedef
JsonPrintOptions JsonOptions
DEPRECATED. Use JsonPrintOptions instead.
util::Status
MessageToJsonString(const Message & message, std::string * output, const JsonOptions & options)
Converts from protobuf message to JSON and appends it to |output|. more...
util::Status
MessageToJsonString(const Message & message, std::string * output)
util::Status
JsonStringToMessage(StringPiece input, Message * message, const JsonParseOptions & options)
Converts from JSON to protobuf message. more...
util::Status
JsonStringToMessage(StringPiece input, Message * message)
util::Status
BinaryToJsonStream(TypeResolver * resolver, const std::string & type_url, io::ZeroCopyInputStream * binary_input, io::ZeroCopyOutputStream * json_output, const JsonPrintOptions & options)
Converts protobuf binary data to JSON. more...
util::Status
BinaryToJsonStream(TypeResolver * resolver, const std::string & type_url, io::ZeroCopyInputStream * binary_input, io::ZeroCopyOutputStream * json_output)
util::Status
BinaryToJsonString(TypeResolver * resolver, const std::string & type_url, const std::string & binary_input, std::string * json_output, const JsonPrintOptions & options)
util::Status
BinaryToJsonString(TypeResolver * resolver, const std::string & type_url, const std::string & binary_input, std::string * json_output)
util::Status
JsonToBinaryStream(TypeResolver * resolver, const std::string & type_url, io::ZeroCopyInputStream * json_input, io::ZeroCopyOutputStream * binary_output, const JsonParseOptions & options)
Converts JSON data to protobuf binary format. more...
util::Status
JsonToBinaryStream(TypeResolver * resolver, const std::string & type_url, io::ZeroCopyInputStream * json_input, io::ZeroCopyOutputStream * binary_output)
util::Status
JsonToBinaryString(TypeResolver * resolver, const std::string & type_url, StringPiece json_input, std::string * binary_output, const JsonParseOptions & options)
util::Status
JsonToBinaryString(TypeResolver * resolver, const std::string & type_url, StringPiece json_input, std::string * binary_output)

util::Status util::MessageToJsonString(
        const Message & message,
        std::string * output,
        const JsonOptions & options)

Converts from protobuf message to JSON and appends it to |output|.

This is a simple wrapper of BinaryToJsonString(). It will use the DescriptorPool of the passed-in message to resolve Any types.


util::Status util::JsonStringToMessage(
        StringPiece input,
        Message * message,
        const JsonParseOptions & options)

Converts from JSON to protobuf message.

This is a simple wrapper of JsonStringToBinary(). It will use the DescriptorPool of the passed-in message to resolve Any types.


util::Status util::BinaryToJsonStream(
        TypeResolver * resolver,
        const std::string & type_url,
        io::ZeroCopyInputStream * binary_input,
        io::ZeroCopyOutputStream * json_output,
        const JsonPrintOptions & options)

Converts protobuf binary data to JSON.

The conversion will fail if:

1. TypeResolver fails to resolve a type.
+2. input is not valid protobuf wire format, or conflicts with the type
+   information returned by TypeResolver.

Note that unknown fields will be discarded silently.


util::Status util::JsonToBinaryStream(
        TypeResolver * resolver,
        const std::string & type_url,
        io::ZeroCopyInputStream * json_input,
        io::ZeroCopyOutputStream * binary_output,
        const JsonParseOptions & options)

Converts JSON data to protobuf binary format.

The conversion will fail if:

1. TypeResolver fails to resolve a type.
+2. input is not valid JSON format, or conflicts with the type
+   information returned by TypeResolver.

struct JsonParseOptions

#include <google/protobuf/util/json_util.h>
namespace google::protobuf::util

Members

bool
ignore_unknown_fields
Whether to ignore unknown JSON fields during parsing.
bool
case_insensitive_enum_parsing
If true, when a lowercase enum value fails to parse, try convert it to UPPER_CASE and see if it matches a valid enum. more...
JsonParseOptions()

bool JsonParseOptions::case_insensitive_enum_parsing

If true, when a lowercase enum value fails to parse, try convert it to UPPER_CASE and see if it matches a valid enum.

WARNING: This option exists only to preserve legacy behavior. Avoid using this option. If your enum needs to support different casing, consider using allow_alias instead.

struct JsonPrintOptions

#include <google/protobuf/util/json_util.h>
namespace google::protobuf::util

Members

bool
add_whitespace
Whether to add spaces, line breaks and indentation to make the JSON output easy to read.
bool
always_print_primitive_fields
Whether to always print primitive fields. more...
bool
always_print_enums_as_ints
Whether to always print enums as ints. more...
bool
preserve_proto_field_names
Whether to preserve proto field names.
JsonPrintOptions()

bool JsonPrintOptions::always_print_primitive_fields

Whether to always print primitive fields.

By default proto3 primitive fields with default values will be omitted in JSON output. For example, an int32 field set to 0 will be omitted. Set this flag to true will override the default behavior and print primitive fields regardless of their values.


bool JsonPrintOptions::always_print_enums_as_ints

Whether to always print enums as ints.

By default they are rendered as strings.

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.util.message_differencer/index.html b/reference/cpp/api-docs/google.protobuf.util.message_differencer/index.html new file mode 100644 index 000000000..004015b19 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.util.message_differencer/index.html @@ -0,0 +1,21 @@ +message_differencer.h | Protocol Buffers Documentation +

message_differencer.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

This file defines static methods and classes for comparing Protocol Messages.

Aug. 2008: Added Unknown Fields Comparison for messages. Aug. 2009: Added different options to compare repeated fields. Apr. 2010: Moved field comparison to FieldComparator Sep. 2020: Added option to output map keys in path

Classes in this file

A basic differencer that can be used to determine the differences between two specified Protocol Messages.
Abstract base class from which all IgnoreCriteria derive.
MapKeyComparator is used to determine if two elements have the same key when comparing elements of a repeated field as a map.
Abstract base class from which all MessageDifferencer reporters derive.
Identifies an individual field in a message instance.
An implementation of the MessageDifferencer Reporter that outputs any differences found in human-readable form to the supplied ZeroCopyOutputStream or Printer.
Class for processing Any deserialization.
This class provides extra information to the FieldComparator::Compare function.

File Members

These definitions are not part of any class.
typedef
std::vector< const FieldDescriptor * > FieldDescriptorArray
Defines a collection of field descriptors. more...

typedef util::FieldDescriptorArray

Defines a collection of field descriptors.

In case of internal google codebase we are using absl::FixedArray instead of vector. It significantly speeds up proto comparison (by ~30%) by reducing the number of malloc/free operations

class MessageDifferencer

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

A basic differencer that can be used to determine the differences between two specified Protocol Messages.

If any differences are found, the Compare method will return false, and any differencer reporter specified via ReportDifferencesTo will have its reporting methods called (see below for implementation of the report). Based off of the original ProtocolDifferencer implementation in //net/proto/protocol-differencer.h (Thanks Todd!).

MessageDifferencer REQUIRES that compared messages be the same type, defined as messages that share the same descriptor. If not, the behavior of this class is undefined.

People disagree on what MessageDifferencer should do when asked to compare messages with different descriptors. Some people think it should always return false. Others expect it to try to look for similar fields and compare them anyway – especially if the descriptors happen to be identical. If we chose either of these behaviors, some set of people would find it surprising, and could end up writing code expecting the other behavior without realizing their error. Therefore, we forbid that usage.

This class is implemented based on the proto2 reflection. The performance should be good enough for normal usages. However, for places where the performance is extremely sensitive, there are several alternatives:

  • Comparing serialized string Downside: false negatives (there are messages that are the same but their serialized strings are different).
  • Equals code generator by compiler plugin (net/proto2/contrib/equals_plugin) Downside: more generated code; maintenance overhead for the additional rule (must be in sync with the original proto_library).

Note on handling of google.protobuf.Any: MessageDifferencer automatically unpacks Any::value into a Message and compares its individual fields. Messages encoded in a repeated Any cannot be compared using TreatAsMap.

Note on thread-safety: MessageDifferencer is not thread-safe. You need to guard it with a lock to use the same MessageDifferencer instance from multiple threads. Note that it's fine to call static comparison methods (like MessageDifferencer::Equals) concurrently, but it's not recommended for performance critical code as it leads to extra allocations.

Members

enum
MessageFieldComparison
enum
Scope
enum
FloatComparison
DEPRECATED. Use FieldComparator::FloatComparison instead. more...
enum
RepeatedFieldComparison
DefaultFieldComparator *
default_impl
FieldComparator *
base
static bool
Equals(const Message & message1, const Message & message2)
Determines whether the supplied messages are equal. more...
static bool
Equivalent(const Message & message1, const Message & message2)
Determines whether the supplied messages are equivalent. more...
static bool
ApproximatelyEquals(const Message & message1, const Message & message2)
Determines whether the supplied messages are approximately equal. more...
static bool
ApproximatelyEquivalent(const Message & message1, const Message & message2)
Determines whether the supplied messages are approximately equivalent. more...
explicit
MessageDifferencer()
To add a Reporter, construct default here, then use ReportDifferencesTo or ReportDifferencesToString.
~MessageDifferencer()
void
TreatAsSet(const FieldDescriptor * field)
The elements of the given repeated field will be treated as a set for diffing purposes, so different orderings of the same elements will be considered equal. more...
void
TreatAsSmartSet(const FieldDescriptor * field)
void
TreatAsList(const FieldDescriptor * field)
The elements of the given repeated field will be treated as a list for diffing purposes, so different orderings of the same elements will NOT be considered equal. more...
void
TreatAsSmartList(const FieldDescriptor * field)
Note that the complexity is similar to treating as SET.
void
TreatAsMap(const FieldDescriptor * field, const FieldDescriptor * key)
The elements of the given repeated field will be treated as a map for diffing purposes, with |key| being the map key. more...
void
TreatAsMapWithMultipleFieldsAsKey(const FieldDescriptor * field, const std::vector< const FieldDescriptor * > & key_fields)
Same as TreatAsMap except that this method will use multiple fields as the key in comparison. more...
void
TreatAsMapWithMultipleFieldPathsAsKey(const FieldDescriptor * field, const std::vector< std::vector< const FieldDescriptor * > > & key_field_paths)
Same as TreatAsMapWithMultipleFieldsAsKey, except that each of the field do not necessarily need to be a direct subfield. more...
void
TreatAsMapUsingKeyComparator(const FieldDescriptor * field, const MapKeyComparator * key_comparator)
Uses a custom MapKeyComparator to determine if two elements have the same key when comparing a repeated field as a map. more...
MapKeyComparator *
CreateMultipleFieldsMapKeyComparator(const std::vector< std::vector< const FieldDescriptor * > > & key_field_paths)
Initiates and returns a new instance of MultipleFieldsMapKeyComparator.
void
AddIgnoreCriteria(IgnoreCriteria * ignore_criteria)
Add a custom ignore criteria that is evaluated in addition to the ignored fields added with IgnoreField. more...
void
IgnoreField(const FieldDescriptor * field)
Indicates that any field with the given descriptor should be ignored for the purposes of comparing two messages. more...
void
set_field_comparator(FieldComparator * comparator)
Sets the field comparator used to determine differences between protocol buffer fields. more...
void
SetFractionAndMargin(const FieldDescriptor * field, double fraction, double margin)
DEPRECATED. more...
void
set_message_field_comparison(MessageFieldComparison comparison)
Sets the type of comparison (as defined in the MessageFieldComparison enumeration above) that is used by this differencer when determining how to compare fields in messages.
void
set_report_matches(bool report_matches)
Tells the differencer whether or not to report matches. more...
void
set_report_moves(bool report_moves)
Tells the differencer whether or not to report moves (in a set or map repeated field). more...
void
set_report_ignores(bool report_ignores)
Tells the differencer whether or not to report ignored values. more...
void
set_scope(Scope scope)
Sets the scope of the comparison (as defined in the Scope enumeration above) that is used by this differencer when determining which fields to compare between the messages.
Scope
scope()
Returns the current scope used by this differencer.
void
set_float_comparison(FloatComparison comparison)
DEPRECATED. more...
void
set_repeated_field_comparison(RepeatedFieldComparison comparison)
Sets the type of comparison for repeated field (as defined in the RepeatedFieldComparison enumeration above) that is used by this differencer when compare repeated fields in messages.
RepeatedFieldComparison
repeated_field_comparison()
Returns the current repeated field comparison used by this differencer.
bool
Compare(const Message & message1, const Message & message2)
Compares the two specified messages, returning true if they are the same, false otherwise. more...
bool
CompareWithFields(const Message & message1, const Message & message2, const std::vector< const FieldDescriptor * > & message1_fields, const std::vector< const FieldDescriptor * > & message2_fields)
Same as above, except comparing only the list of fields specified by the two vectors of FieldDescriptors.
void
ReportDifferencesToString(std::string * output)
Automatically creates a reporter that will output the differences found (if any) to the specified output string pointer. more...
void
ReportDifferencesTo(Reporter * reporter)
Tells the MessageDifferencer to report differences via the specified reporter. more...

enum MessageDifferencer::MessageFieldComparison {
  EQUAL,
  EQUIVALENT
}

EQUALFields must be present in both messages for the messages to be considered the same.
EQUIVALENT

Fields with default values are considered set for comparison purposes even if not explicitly set in the messages themselves.

Unknown fields are ignored.


enum MessageDifferencer::Scope {
  FULL,
  PARTIAL
}

FULLAll fields of both messages are considered in the comparison.
PARTIALOnly fields present in the first message are considered; fields set only in the second message will be skipped during comparison.

enum MessageDifferencer::FloatComparison {
  EXACT,
  APPROXIMATE
}

DEPRECATED. Use FieldComparator::FloatComparison instead.

EXACTFloats and doubles are compared exactly.
APPROXIMATEFloats and doubles are compared using the MathUtil::AlmostEquals method.

enum MessageDifferencer::RepeatedFieldComparison {
  AS_LIST,
  AS_SET,
  AS_SMART_LIST,
  AS_SMART_SET
}

AS_LIST

Repeated fields are compared in order.

Differing values at the same index are reported using ReportModified(). If the repeated fields have different numbers of elements, the unpaired elements are reported using ReportAdded() or ReportDeleted().

AS_SET

Treat all the repeated fields as sets.

See TreatAsSet(), as below.

AS_SMART_LIST

Similar to AS_SET, but preserve the order and find the longest matching sequence from the first matching element.

To use an optimal solution, call SetMatchIndicesForSmartListCallback() to pass it in.

AS_SMART_SETSimilar to AS_SET, but match elements with fewest diffs.

static bool MessageDifferencer::Equals(
        const Message & message1,
        const Message & message2)

Determines whether the supplied messages are equal.

Equality is defined as all fields within the two messages being set to the same value. Primitive fields and strings are compared by value while embedded messages/groups are compared as if via a recursive call. Use Compare() with IgnoreField() if some fields should be ignored in the comparison. Use Compare() with TreatAsSet() if there are repeated fields where ordering does not matter.

This method REQUIRES that the two messages have the same Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).


static bool MessageDifferencer::Equivalent(
        const Message & message1,
        const Message & message2)

Determines whether the supplied messages are equivalent.

Equivalency is defined as all fields within the two messages having the same value. This differs from the Equals method above in that fields with default values are considered set to said value automatically. For details on how default values are defined for each field type, see: static bool MessageDifferencer::ApproximatelyEquals(
        const
Message & message1,
        const Message & message2)

Determines whether the supplied messages are approximately equal.

Approximate equality is defined as all fields within the two messages being approximately equal. Primitive (non-float) fields and strings are compared by value, floats are compared using MathUtil::AlmostEquals() and embedded messages/groups are compared as if via a recursive call. Use IgnoreField() and Compare() if some fields should be ignored in the comparison.

This method REQUIRES that the two messages have the same Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).


static bool MessageDifferencer::ApproximatelyEquivalent(
        const Message & message1,
        const Message & message2)

Determines whether the supplied messages are approximately equivalent.

Approximate equivalency is defined as all fields within the two messages being approximately equivalent. As in MessageDifferencer::ApproximatelyEquals, primitive (non-float) fields and strings are compared by value, floats are compared using MathUtil::AlmostEquals() and embedded messages/groups are compared as if via a recursive call. However, fields with default values are considered set to said value, as per MessageDiffencer::Equivalent. Use IgnoreField() and Compare() if some fields should be ignored in the comparison.

This method REQUIRES that the two messages have the same Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).


void MessageDifferencer::TreatAsSet(
        const FieldDescriptor * field)

The elements of the given repeated field will be treated as a set for diffing purposes, so different orderings of the same elements will be considered equal.

Elements which are present on both sides of the comparison but which have changed position will be reported with ReportMoved(). Elements which only exist on one side or the other are reported with ReportAdded() and ReportDeleted() regardless of their positions. ReportModified() is never used for this repeated field. If the only differences between the compared messages is that some fields have been moved, then the comparison returns true.

Note that despite the name of this method, this is really comparison as multisets: if one side of the comparison has a duplicate in the repeated field but the other side doesn't, this will count as a mismatch.

If the scope of comparison is set to PARTIAL, then in addition to what's above, extra values added to repeated fields of the second message will not cause the comparison to fail.

Note that set comparison is currently O(k * n^2) (where n is the total number of elements, and k is the average size of each element). In theory it could be made O(n * k) with a more complex hashing implementation. Feel free to contribute one if the current implementation is too slow for you. If partial matching is also enabled, the time complexity will be O(k * n^2

  • n^3) in which n^3 is the time complexity of the maximum matching algorithm.

REQUIRES: field->is_repeated() and field not registered with TreatAsMap*


void MessageDifferencer::TreatAsList(
        const FieldDescriptor * field)

The elements of the given repeated field will be treated as a list for diffing purposes, so different orderings of the same elements will NOT be considered equal.

REQUIRES: field->is_repeated() and field not registered with TreatAsMap*


void MessageDifferencer::TreatAsMap(
        const FieldDescriptor * field,
        const FieldDescriptor * key)

The elements of the given repeated field will be treated as a map for diffing purposes, with |key| being the map key.

Thus, elements with the same key will be compared even if they do not appear at the same index. Differences are reported similarly to TreatAsSet(), except that ReportModified() is used to report elements with the same key but different values. Note that if an element is both moved and modified, only ReportModified() will be called. As with TreatAsSet, if the only differences between the compared messages is that some fields have been moved, then the comparison returns true. See TreatAsSet for notes on performance.

REQUIRES: field->is_repeated() REQUIRES: field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE REQUIRES: key->containing_type() == field->message_type()


void MessageDifferencer::TreatAsMapWithMultipleFieldsAsKey(
        const FieldDescriptor * field,
        const std::vector< const FieldDescriptor * > & key_fields)

Same as TreatAsMap except that this method will use multiple fields as the key in comparison.

All specified fields in 'key_fields' should be present in the compared elements. Two elements will be treated as having the same key iff they have the same value for every specified field. There are two steps in the comparison process. The first one is key matching. Every element from one message will be compared to every element from the other message. Only fields in 'key_fields' are compared in this step to decide if two elements have the same key. The second step is value comparison. Those pairs of elements with the same key (with equal value for every field in 'key_fields') will be compared in this step. Time complexity of the first step is O(s * m * n ^ 2) where s is the average size of the fields specified in 'key_fields', m is the number of fields in 'key_fields' and n is the number of elements. If partial matching is enabled, an extra O(n^3) will be incured by the maximum matching algorithm. The second step is O(k * n) where k is the average size of each element.


void MessageDifferencer::TreatAsMapWithMultipleFieldPathsAsKey(
        const FieldDescriptor * field,
        const std::vector< std::vector< const FieldDescriptor * > > & key_field_paths)

Same as TreatAsMapWithMultipleFieldsAsKey, except that each of the field do not necessarily need to be a direct subfield.

Each element in key_field_paths indicate a path from the message being compared, listing successive subfield to reach the key field.

REQUIRES:

for key_field_path in key_field_paths:
+  key_field_path[0]->containing_type() == field->message_type()
+  for i in [0, key_field_path.size() - 1):
+    key_field_path[i+1]->containing_type() ==
+        key_field_path[i]->message_type()
+    key_field_path[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
+    !key_field_path[i]->is_repeated()

void MessageDifferencer::TreatAsMapUsingKeyComparator(
        const FieldDescriptor * field,
        const MapKeyComparator * key_comparator)

Uses a custom MapKeyComparator to determine if two elements have the same key when comparing a repeated field as a map.

The caller is responsible to delete the key_comparator. This method varies from TreatAsMapWithMultipleFieldsAsKey only in the first key matching step. Rather than comparing some specified fields, it will invoke the IsMatch method of the given 'key_comparator' to decide if two elements have the same key.


void MessageDifferencer::AddIgnoreCriteria(
        IgnoreCriteria * ignore_criteria)

Add a custom ignore criteria that is evaluated in addition to the ignored fields added with IgnoreField.

Takes ownership of ignore_criteria.


void MessageDifferencer::IgnoreField(
        const FieldDescriptor * field)

Indicates that any field with the given descriptor should be ignored for the purposes of comparing two messages.

This applies to fields nested in the message structure as well as top level ones. When the MessageDifferencer encounters an ignored field, ReportIgnored is called on the reporter, if one is specified.

The only place where the field's 'ignored' status is not applied is when it is being used as a key in a field passed to TreatAsMap or is one of the fields passed to TreatAsMapWithMultipleFieldsAsKey. In this case it is compared in key matching but after that it's ignored in value comparison.


void MessageDifferencer::set_field_comparator(
        FieldComparator * comparator)

Sets the field comparator used to determine differences between protocol buffer fields.

By default it's set to a DefaultFieldComparator instance. MessageDifferencer doesn't take ownership over the passed object. Note that this method must be called before Compare for the comparator to be used.


void MessageDifferencer::SetFractionAndMargin(
        const FieldDescriptor * field,
        double fraction,
        double margin)

DEPRECATED.

Pass a DefaultFieldComparator instance instead. Sets the fraction and margin for the float comparison of a given field. Uses MathUtil::WithinFractionOrMargin to compare the values. NOTE: this method does nothing if differencer's field comparator has been

set to a custom object.

REQUIRES: field->cpp_type == FieldDescriptor::CPPTYPE_DOUBLE or

field->cpp_type == FieldDescriptor::CPPTYPE_FLOAT

REQUIRES: float_comparison_ == APPROXIMATE


void MessageDifferencer::set_report_matches(
        bool report_matches)

Tells the differencer whether or not to report matches.

This method must be called before Compare. The default for a new differencer is false.


void MessageDifferencer::set_report_moves(
        bool report_moves)

Tells the differencer whether or not to report moves (in a set or map repeated field).

This method must be called before Compare. The default for a new differencer is true.


void MessageDifferencer::set_report_ignores(
        bool report_ignores)

Tells the differencer whether or not to report ignored values.

This method must be called before Compare. The default for a new differencer is true.


void MessageDifferencer::set_float_comparison(
        FloatComparison comparison)

DEPRECATED.

Pass a DefaultFieldComparator instance instead. Sets the type of comparison (as defined in the FloatComparison enumeration above) that is used by this differencer when comparing float (and double) fields in messages. NOTE: this method does nothing if differencer's field comparator has been

set to a custom object.

bool MessageDifferencer::Compare(
        const Message & message1,
        const Message & message2)

Compares the two specified messages, returning true if they are the same, false otherwise.

If this method returns false, any changes between the two messages will be reported if a Reporter was specified via ReportDifferencesTo (see also ReportDifferencesToString).

This method REQUIRES that the two messages have the same Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).


void MessageDifferencer::ReportDifferencesToString(
        std::string * output)

Automatically creates a reporter that will output the differences found (if any) to the specified output string pointer.

Note that this method must be called before Compare.


void MessageDifferencer::ReportDifferencesTo(
        Reporter * reporter)

Tells the MessageDifferencer to report differences via the specified reporter.

Note that this method must be called before Compare for the reporter to be used. It is the responsibility of the caller to delete this object. If the provided pointer equals NULL, the MessageDifferencer stops reporting differences to any previously set reporters or output strings.

class MessageDifferencer::IgnoreCriteria

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

Abstract base class from which all IgnoreCriteria derive.

By adding IgnoreCriteria more complex ignore logic can be implemented. IgnoreCriteria are registered with AddIgnoreCriteria. For each compared field IsIgnored is called on each added IgnoreCriteria until one returns true or all return false. IsIgnored is called for fields where at least one side has a value.

Members

IgnoreCriteria()
virtual
~IgnoreCriteria()
virtual bool
IsIgnored(const Message & , const Message & , const FieldDescriptor * , const std::vector< SpecificField > & ) = 0
Returns true if the field should be ignored.
virtual bool
IsUnknownFieldIgnored(const Message & , const Message & , const SpecificField & , const std::vector< SpecificField > & )
Returns true if the unknown field should be ignored. more...

virtual bool IgnoreCriteria::IsUnknownFieldIgnored(
        const Message & ,
        const Message & ,
        const SpecificField & ,
        const std::vector< SpecificField > & )

Returns true if the unknown field should be ignored.

Note: This will be called for unknown fields as well in which case

field.field will be null.

class MessageDifferencer::MapKeyComparator

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

MapKeyComparator is used to determine if two elements have the same key when comparing elements of a repeated field as a map.

Members

MapKeyComparator()
virtual
~MapKeyComparator()
virtual bool
IsMatch(const Message & , const Message & , const std::vector< SpecificField > & ) const

class MessageDifferencer::Reporter

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

Abstract base class from which all MessageDifferencer reporters derive.

The five Report* methods below will be called when a field has been added, deleted, modified, moved, or matched. The third argument is a vector of FieldDescriptor pointers which describes the chain of fields that was taken to find the current field. For example, for a field found in an embedded message, the vector will contain two FieldDescriptors. The first will be the field of the embedded message itself and the second will be the actual field in the embedded message that was added/deleted/modified. Fields will be reported in PostTraversalOrder. For example, given the following proto, if both baz and mooo are changed.

foo {
+  bar {
+    baz: 1
+    mooo: 2
+  }
+}

ReportModified will be invoked with following order:

  1. foo.bar.baz or foo.bar.mooo
  2. foo.bar.mooo or foo.bar.baz
  3. foo.bar
  4. foo

Known subclasses:

Members

Reporter()
virtual
~Reporter()
virtual void
ReportAdded(const Message & message1, const Message & message2, const std::vector< SpecificField > & field_path) = 0
Reports that a field has been added into Message2.
virtual void
ReportDeleted(const Message & message1, const Message & message2, const std::vector< SpecificField > & field_path) = 0
Reports that a field has been deleted from Message1.
virtual void
ReportModified(const Message & message1, const Message & message2, const std::vector< SpecificField > & field_path) = 0
Reports that the value of a field has been modified.
virtual void
ReportMoved(const Message & , const Message & , const std::vector< SpecificField > & )
Reports that a repeated field has been moved to another location. more...
virtual void
ReportMatched(const Message & , const Message & , const std::vector< SpecificField > & )
Reports that two fields match. more...
virtual void
ReportIgnored(const Message & , const Message & , const std::vector< SpecificField > & )
Reports that two fields would have been compared, but the comparison has been skipped because the field was marked as 'ignored' using IgnoreField(). more...
virtual void
ReportUnknownFieldIgnored(const Message & , const Message & , const std::vector< SpecificField > & )
Report that an unknown field is ignored. more...

virtual void Reporter::ReportMoved(
        const Message & ,
        const Message & ,
        const std::vector< SpecificField > & )

Reports that a repeated field has been moved to another location.

This only applies when using TreatAsSet or TreatAsMap() – see below. Also note that for any given field, ReportModified and ReportMoved are mutually exclusive. If a field has been both moved and modified, then only ReportModified will be called.


virtual void Reporter::ReportMatched(
        const Message & ,
        const Message & ,
        const std::vector< SpecificField > & )

Reports that two fields match.

Useful for doing side-by-side diffs. This function is mutually exclusive with ReportModified and ReportMoved. Note that you must call set_report_matches(true) before calling Compare to make use of this function.


virtual void Reporter::ReportIgnored(
        const Message & ,
        const Message & ,
        const std::vector< SpecificField > & )

Reports that two fields would have been compared, but the comparison has been skipped because the field was marked as 'ignored' using IgnoreField().

This function is mutually exclusive with all the other Report() functions.

The contract of ReportIgnored is slightly different than the other Report() functions, in that |field_path.back().index| is always equal to -1, even if the last field is repeated. This is because while the other Report() functions indicate where in a repeated field the action (Addition, Deletion, etc...) happened, when a repeated field is 'ignored', the differencer simply calls ReportIgnored on the repeated field as a whole and moves on without looking at its individual elements.

Furthermore, ReportIgnored() does not indicate whether the fields were in fact equal or not, as Compare() does not inspect these fields at all. It is up to the Reporter to decide whether the fields are equal or not (perhaps with a second call to Compare()), if it cares.


virtual void Reporter::ReportUnknownFieldIgnored(
        const Message & ,
        const Message & ,
        const std::vector< SpecificField > & )

Report that an unknown field is ignored.

(see comment above). Note this is a different function since the last SpecificField in field path has a null field. This could break existing Reporter.

struct MessageDifferencer::SpecificField

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

Identifies an individual field in a message instance.

Used for field_path, below.

Members

const FieldDescriptor *
field = = nullptr
For known fields, "field" is filled in and "unknown_field_number" is -1. more...
int
unknown_field_number = = -1
UnknownField::Type
unknown_field_type = = UnknownField::Type::TYPE_VARINT
int
index = = -1
If this a repeated field, "index" is the index within it. more...
int
new_index = = -1
If "field" is a repeated field which is being treated as a map or a set (see TreatAsMap() and TreatAsSet(), below), new_index indicates the index the position to which the element has moved. more...
const UnknownFieldSet *
unknown_field_set1 = = nullptr
For unknown fields, these are the pointers to the UnknownFieldSet containing the unknown fields. more...
const UnknownFieldSet *
unknown_field_set2 = = nullptr
int
unknown_field_index1 = = -1
For unknown fields, these are the index of the field within the UnknownFieldSets. more...
int
unknown_field_index2 = = -1

const FieldDescriptor * SpecificField::field = = nullptr

For known fields, "field" is filled in and "unknown_field_number" is -1.

For unknown fields, "field" is NULL, "unknown_field_number" is the field number, and "unknown_field_type" is its type.


int SpecificField::index = = -1

If this a repeated field, "index" is the index within it.

For unknown fields, this is the index of the field among all unknown fields of the same field number and type.


int SpecificField::new_index = = -1

If "field" is a repeated field which is being treated as a map or a set (see TreatAsMap() and TreatAsSet(), below), new_index indicates the index the position to which the element has moved.

If the element has not moved, "new_index" will have the same value as "index".


const UnknownFieldSet * SpecificField::unknown_field_set1 = = nullptr

For unknown fields, these are the pointers to the UnknownFieldSet containing the unknown fields.

In certain cases (e.g. proto1's MessageSet, or nested groups of unknown fields), these may differ from the messages' internal UnknownFieldSets.


int SpecificField::unknown_field_index1 = = -1

For unknown fields, these are the index of the field within the UnknownFieldSets.

One or the other will be -1 when reporting an addition or deletion.

class MessageDifferencer::StreamReporter: public Reporter

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

An implementation of the MessageDifferencer Reporter that outputs any differences found in human-readable form to the supplied ZeroCopyOutputStream or Printer.

If a printer is used, the delimiter must be '$'.

WARNING: this reporter does not necessarily flush its output until it is destroyed. As a result, it is not safe to assume the output is valid or complete until after you destroy the reporter. For example, if you use a StreamReporter to write to a StringOutputStream, the target string may contain uninitialized data until the reporter is destroyed.

Members

explicit
StreamReporter(io::ZeroCopyOutputStream * output)
explicit
StreamReporter(io::Printer * printer)
delimiter '$'
~StreamReporter()
void
set_report_modified_aggregates(bool report)
When set to true, the stream reporter will also output aggregates nodes (i.e. more...
virtual void
ReportAdded(const Message & message1, const Message & message2, const std::vector< SpecificField > & field_path)
Reports that a field has been added into Message2.
virtual void
ReportDeleted(const Message & message1, const Message & message2, const std::vector< SpecificField > & field_path)
Reports that a field has been deleted from Message1.
virtual void
ReportModified(const Message & message1, const Message & message2, const std::vector< SpecificField > & field_path)
Reports that the value of a field has been modified.
virtual void
ReportMoved(const Message & , const Message & , const std::vector< SpecificField > & )
Reports that a repeated field has been moved to another location. more...
virtual void
ReportMatched(const Message & , const Message & , const std::vector< SpecificField > & )
Reports that two fields match. more...
virtual void
ReportIgnored(const Message & , const Message & , const std::vector< SpecificField > & )
Reports that two fields would have been compared, but the comparison has been skipped because the field was marked as 'ignored' using IgnoreField(). more...
virtual void
ReportUnknownFieldIgnored(const Message & , const Message & , const std::vector< SpecificField > & )
Report that an unknown field is ignored. more...
void
SetMessages(const Message & message1, const Message & message2)
Messages that are being compared must be provided to StreamReporter prior to processing.
protected virtual void
PrintPath(const std::vector< SpecificField > & field_path, bool left_side)
Prints the specified path of fields to the buffer.
protected virtual void
PrintValue(const Message & message, const std::vector< SpecificField > & field_path, bool left_side)
Prints the value of fields to the buffer. more...
protected virtual void
PrintUnknownFieldValue(const UnknownField * unknown_field)
Prints the specified path of unknown fields to the buffer.
protected void
Print(const std::string & str)
Just print a string.
protected void
PrintMapKey(const std::vector< SpecificField > & field_path, bool left_side, const SpecificField & specific_field, size_t target_field_index)
helper function for PrintPath that contains logic for printing maps

void StreamReporter::set_report_modified_aggregates(
        bool report)

When set to true, the stream reporter will also output aggregates nodes (i.e.

messages and groups) whose subfields have been modified. When false, will only report the individual subfields. Defaults to false.


virtual void StreamReporter::ReportMoved(
        const Message & ,
        const Message & ,
        const std::vector< SpecificField > & )

Reports that a repeated field has been moved to another location.

This only applies when using TreatAsSet or TreatAsMap() – see below. Also note that for any given field, ReportModified and ReportMoved are mutually exclusive. If a field has been both moved and modified, then only ReportModified will be called.


virtual void StreamReporter::ReportMatched(
        const Message & ,
        const Message & ,
        const std::vector< SpecificField > & )

Reports that two fields match.

Useful for doing side-by-side diffs. This function is mutually exclusive with ReportModified and ReportMoved. Note that you must call set_report_matches(true) before calling Compare to make use of this function.


virtual void StreamReporter::ReportIgnored(
        const Message & ,
        const Message & ,
        const std::vector< SpecificField > & )

Reports that two fields would have been compared, but the comparison has been skipped because the field was marked as 'ignored' using IgnoreField().

This function is mutually exclusive with all the other Report() functions.

The contract of ReportIgnored is slightly different than the other Report() functions, in that |field_path.back().index| is always equal to -1, even if the last field is repeated. This is because while the other Report() functions indicate where in a repeated field the action (Addition, Deletion, etc...) happened, when a repeated field is 'ignored', the differencer simply calls ReportIgnored on the repeated field as a whole and moves on without looking at its individual elements.

Furthermore, ReportIgnored() does not indicate whether the fields were in fact equal or not, as Compare() does not inspect these fields at all. It is up to the Reporter to decide whether the fields are equal or not (perhaps with a second call to Compare()), if it cares.


virtual void StreamReporter::ReportUnknownFieldIgnored(
        const Message & ,
        const Message & ,
        const std::vector< SpecificField > & )

Report that an unknown field is ignored.

(see comment above). Note this is a different function since the last SpecificField in field path has a null field. This could break existing Reporter.


protected virtual void StreamReporter::PrintValue(
        const Message & message,
        const std::vector< SpecificField > & field_path,
        bool left_side)

Prints the value of fields to the buffer.

left_side is true if the given message is from the left side of the comparison, false if it was the right. This is relevant only to decide whether to follow unknown_field_index1 or unknown_field_index2 when an unknown field is encountered in field_path.

class MessageDifferencer::UnpackAnyField

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

Class for processing Any deserialization.

This logic is used by both the MessageDifferencer and StreamReporter classes.

Members

UnpackAnyField()
~UnpackAnyField()
bool
UnpackAny(const Message & any, std::unique_ptr< Message > * data)
If "any" is of type google.protobuf.Any, extract its payload using DynamicMessageFactory and store in "data".

class FieldContext

#include <google/protobuf/util/message_differencer.h>
namespace google::protobuf::util

This class provides extra information to the FieldComparator::Compare function.

Members

explicit
FieldContext(std::vector< MessageDifferencer::SpecificField > * parent_fields)
std::vector< MessageDifferencer::SpecificField > *
parent_fields() const
\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.util.time_util/index.html b/reference/cpp/api-docs/google.protobuf.util.time_util/index.html new file mode 100644 index 000000000..6490873f2 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.util.time_util/index.html @@ -0,0 +1,8 @@ +time_util.h | Protocol Buffers Documentation +

time_util.h

This section contains reference documentation for working with protocol buffer classes in C++.

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

Defines utilities for the Timestamp and Duration well known types.

Classes in this file

Utility functions for Timestamp and Duration.

class TimeUtil

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

Utility functions for Timestamp and Duration.

Members

const int64_t
kTimestampMinSeconds = = -62135596800LL
The min/max Timestamp/Duration values we support. more...
const int64_t
kTimestampMaxSeconds = = 253402300799LL
For "9999-12-31T23:59:59.999999999Z".
const int64_t
kDurationMinSeconds = = -315576000000LL
const int64_t
kDurationMaxSeconds = = 315576000000LL
static std::string
ToString(const Timestamp & timestamp)
Converts Timestamp to/from RFC 3339 date string format. more...
static bool
FromString(const std::string & value, Timestamp * timestamp)
static std::string
ToString(const Duration & duration)
Converts Duration to/from string format. more...
static bool
FromString(const std::string & value, Duration * timestamp)
static Timestamp
GetCurrentTime()
Gets the current UTC time.
static Timestamp
GetEpoch()
Returns the Time representing "1970-01-01 00:00:00".
static Duration
NanosecondsToDuration(int64_t nanos)
Converts between Duration and integer types. more...
static Duration
MicrosecondsToDuration(int64_t micros)
static Duration
MillisecondsToDuration(int64_t millis)
static Duration
SecondsToDuration(int64_t seconds)
static Duration
MinutesToDuration(int64_t minutes)
static Duration
HoursToDuration(int64_t hours)
static int64_t
DurationToNanoseconds(const Duration & duration)
Result will be truncated towards zero. more...
static int64_t
DurationToMicroseconds(const Duration & duration)
static int64_t
DurationToMilliseconds(const Duration & duration)
static int64_t
DurationToSeconds(const Duration & duration)
static int64_t
DurationToMinutes(const Duration & duration)
static int64_t
DurationToHours(const Duration & duration)
static Timestamp
NanosecondsToTimestamp(int64_t nanos)
Creates Timestamp from integer types. more...
static Timestamp
MicrosecondsToTimestamp(int64_t micros)
static Timestamp
MillisecondsToTimestamp(int64_t millis)
static Timestamp
SecondsToTimestamp(int64_t seconds)
static int64_t
TimestampToNanoseconds(const Timestamp & timestamp)
Result will be truncated down to the nearest integer value. more...
static int64_t
TimestampToMicroseconds(const Timestamp & timestamp)
static int64_t
TimestampToMilliseconds(const Timestamp & timestamp)
static int64_t
TimestampToSeconds(const Timestamp & timestamp)
static Timestamp
TimeTToTimestamp(time_t value)
Conversion to/from other time/date types. more...
static time_t
TimestampToTimeT(const Timestamp & value)
static Timestamp
TimevalToTimestamp(const timeval & value)
Conversion to/from timeval.
static timeval
TimestampToTimeval(const Timestamp & value)
static Duration
TimevalToDuration(const timeval & value)
static timeval
DurationToTimeval(const Duration & value)

const int64_t TimeUtil::kTimestampMinSeconds = = -62135596800LL

The min/max Timestamp/Duration values we support.

For "0001-01-01T00:00:00Z".


static std::string TimeUtil::ToString(
        const Timestamp & timestamp)

Converts Timestamp to/from RFC 3339 date string format.

Generated output will always be Z-normalized and uses 3, 6 or 9 fractional digits as required to represent the exact time. When parsing, any fractional digits (or none) and any offset are accepted as long as they fit into nano-seconds precision. Note that Timestamp can only represent time from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. Converting a Timestamp outside of this range is undefined behavior. See https://www.ietf.org/rfc/rfc3339.txt.

Example of generated format:

"1972-01-01T10:00:20.021Z"

Example of accepted format:

"1972-01-01T10:00:20.021-05:00"

static std::string TimeUtil::ToString(
        const Duration & duration)

Converts Duration to/from string format.

The string format will contains 3, 6, or 9 fractional digits depending on the precision required to represent the exact Duration value. For example:

"1s", "1.010s", "1.000000100s", "-3.100s"

The range that can be represented by Duration is from -315,576,000,000 to +315,576,000,000 inclusive (in seconds).


static Duration TimeUtil::NanosecondsToDuration(
        int64_t nanos)

Converts between Duration and integer types.

The behavior is undefined if the input value is not in the valid range of Duration.


static int64_t TimeUtil::DurationToNanoseconds(
        const Duration & duration)

Result will be truncated towards zero.

For example, "-1.5s" will be truncated to "-1s", and "1.5s" to "1s" when converting to seconds. It's undefined behavior if the input duration is not valid or the result exceeds the range of int64. A duration is not valid if it's not in the valid range of Duration, or have an invalid nanos value (i.e., larger than 999999999, less than -999999999, or have a different sign from the seconds part).


static Timestamp TimeUtil::NanosecondsToTimestamp(
        int64_t nanos)

Creates Timestamp from integer types.

The integer value indicates the time elapsed from Epoch time. The behavior is undefined if the input value is not in the valid range of Timestamp.


static int64_t TimeUtil::TimestampToNanoseconds(
        const Timestamp & timestamp)

Result will be truncated down to the nearest integer value.

For example, with "1969-12-31T23:59:59.9Z", TimestampToMilliseconds() returns -100 and TimestampToSeconds() returns -1. It's undefined behavior if the input Timestamp is not valid (i.e., its seconds part or nanos part does not fall in the valid range) or the return value doesn't fit into int64.


static Timestamp TimeUtil::TimeTToTimestamp(
        time_t value)

Conversion to/from other time/date types.

Note that these types may have a different precision and time range from Timestamp/Duration. When converting to a lower precision type, the value will be truncated to the nearest value that can be represented. If the value is out of the range of the result type, the return value is undefined.

Conversion to/from time_t

\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.util.type_resolver/index.html b/reference/cpp/api-docs/google.protobuf.util.type_resolver/index.html new file mode 100644 index 000000000..001c2d5d9 --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.util.type_resolver/index.html @@ -0,0 +1,8 @@ +type_resolver.h | Protocol Buffers Documentation +

type_resolver.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/util/type_resolver.h>
namespace google::protobuf::util

Defines a TypeResolver for the Any message.

Classes in this file

Abstract interface for a type resolver.

class TypeResolver

#include <google/protobuf/util/type_resolver.h>
namespace google::protobuf::util

Abstract interface for a type resolver.

Implementations of this interface must be thread-safe.

Members

TypeResolver()
virtual
~TypeResolver()
virtual util::Status
ResolveMessageType(const std::string & type_url, google::protobuf::Type * message_type) = 0
Resolves a type url for a message type.
virtual util::Status
ResolveEnumType(const std::string & type_url, google::protobuf::Enum * enum_type) = 0
Resolves a type url for an enum type.
\ No newline at end of file diff --git a/reference/cpp/api-docs/google.protobuf.util.type_resolver_util/index.html b/reference/cpp/api-docs/google.protobuf.util.type_resolver_util/index.html new file mode 100644 index 000000000..f3480c96a --- /dev/null +++ b/reference/cpp/api-docs/google.protobuf.util.type_resolver_util/index.html @@ -0,0 +1,8 @@ +type_resolver_util.h | Protocol Buffers Documentation +

type_resolver_util.h

This section contains reference documentation for working with protocol buffer classes in C++.

#include <google/protobuf/util/type_resolver_util.h>
namespace google::protobuf::util

Defines utilities for the TypeResolver.

Classes in this file

File Members

These definitions are not part of any class.
TypeResolver *
NewTypeResolverForDescriptorPool(const std::string & url_prefix, const DescriptorPool * pool)
Creates a TypeResolver that serves type information in the given descriptor pool. more...

TypeResolver * util::NewTypeResolverForDescriptorPool(
        const std::string & url_prefix,
        const DescriptorPool * pool)

Creates a TypeResolver that serves type information in the given descriptor pool.

Caller takes ownership of the returned TypeResolver.

\ No newline at end of file diff --git a/content/reference/cpp/api-docs/includes/stylesheet.css b/reference/cpp/api-docs/includes/stylesheet.css similarity index 100% rename from content/reference/cpp/api-docs/includes/stylesheet.css rename to reference/cpp/api-docs/includes/stylesheet.css diff --git a/reference/cpp/api-docs/index.html b/reference/cpp/api-docs/index.html new file mode 100644 index 000000000..f8a1da139 --- /dev/null +++ b/reference/cpp/api-docs/index.html @@ -0,0 +1,8 @@ +C++ Reference | Protocol Buffers Documentation +

C++ Reference

This section contains reference documentation for working with protocol buffer classes in C++.

Packages

Auxiliary classes used for I/O.
Utility classes.
Implementation of the Protocol Buffer compiler.

google::protobuf

Files

This file defines an Arena allocator for better allocation performance.
This file contains classes which describe a type of protocol message.
Protocol buffer representations of descriptors.
Interface for manipulating databases of descriptors.
Defines an implementation of Message which can emulate types which are not known at compile-time.
This file defines the map container and its helpers to support protobuf maps.
Defines Message, the abstract interface implemented by non-lite protocol message objects.
Defines MessageLite, the abstract interface implemented by all (lite and non-lite) protocol message objects.
RepeatedField and RepeatedPtrField are used by generated protocol message classes to manipulate repeated fields.
DEPRECATED: This module declares the abstract interfaces underlying proto2 RPC services.
Utilities for printing and parsing protocol messages in a human-readable, text-based format.
Contains classes used to keep track of unrecognized fields seen while parsing a protocol message.

google::protobuf::io

Auxiliary classes used for I/O.

The Protocol Buffer library uses the classes in this package to deal with I/O and encoding/decoding raw bytes. Most users will not need to deal with this package. However, users who want to adapt the system to work with their own I/O abstractions – e.g., to allow Protocol Buffers to be read from a different kind of input stream without the need for a temporary buffer – should take a closer look.

Files

This file contains the CodedInputStream and CodedOutputStream classes, which wrap a ZeroCopyInputStream or ZeroCopyOutputStream, respectively, and allow you to read or write individual pieces of data in various formats.
Utility class for writing text to a ZeroCopyOutputStream.
Class for parsing tokenized text from a ZeroCopyInputStream.
This file contains the ZeroCopyInputStream and ZeroCopyOutputStream interfaces, which represent abstract I/O streams to and from which protocol buffers can be read and written.
This file contains common implementations of the interfaces defined in zero_copy_stream.h which are only included in the full (non-lite) protobuf library.
This file contains common implementations of the interfaces defined in zero_copy_stream.h which are included in the "lite" protobuf library.

google::protobuf::util

Utility classes.

This package contains various utilities for message comparison, JSON conversion, well known types, etc.

Files

Defines classes for field comparison.
Defines utilities for the FieldMask well known type.
Utility functions to convert between protobuf binary format and proto3 JSON format.
This file defines static methods and classes for comparing Protocol Messages.
Defines utilities for the Timestamp and Duration well known types.
Defines a TypeResolver for the Any message.
Defines utilities for the TypeResolver.

google::protobuf::compiler

Implementation of the Protocol Buffer compiler.

This package contains code for parsing .proto files and generating code based on them. There are two reasons you might be interested in this package:

  • You want to parse .proto files at runtime. In this case, you should look at importer.h. Since this functionality is widely useful, it is included in the libprotobuf base library; you do not have to link against libprotoc.
  • You want to write a custom protocol compiler which generates different kinds of code, e.g. code in a different language which is not supported by the official compiler. For this purpose, command_line_interface.h provides you with a complete compiler front-end, so all you need to do is write a custom implementation of CodeGenerator and a trivial main() function. You can even make your compiler support the official languages in addition to your own. Since this functionality is only useful to those writing custom compilers, it is in a separate library called "libprotoc" which you will have to link against.

Files

Defines the abstract interface implemented by each of the language-specific code generators.
Implements the Protocol Compiler front-end such that it may be reused by custom compilers written to support other languages.
This file is the public interface to the .proto file parser.
Implements parsing of .proto files to FileDescriptorProtos.
Front-end for protoc code generator plugins written in C++.
API for protoc plugins.
Generates C++ code for a given .proto file.
Generates C# code for a given .proto file.
Provides a mechanism for mapping a descriptor to the fully-qualified name of the corresponding C# class.
Generates Java code for a given .proto file.
Provides a mechanism for mapping a descriptor to the fully-qualified name of the corresponding Java class.
Generates JavaScript code for a given .proto file.
Generates ObjectiveC code for a given .proto file.
Helper functions for generating ObjectiveC code.
Generates Python code for a given .proto file.
Generates Ruby code for a given .proto file.

arena.h

This section contains reference documentation for working with protocol buffer classes in C++.

common.h

This section contains reference documentation for working with protocol buffer classes in C++.

code_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

command_line_interface.h

This section contains reference documentation for working with protocol buffer classes in C++.

cpp_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

csharp_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

csharp_names.h

This section contains reference documentation for working with protocol buffer classes in C++.

importer.h

This section contains reference documentation for working with protocol buffer classes in C++.

java_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

java_names.h

This section contains reference documentation for working with protocol buffer classes in C++.

javanano_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

js_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

objectivec_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

objectivec_helpers.h

This section contains reference documentation for working with protocol buffer classes in C++.

parser.h

This section contains reference documentation for working with protocol buffer classes in C++.

plugin.h

This section contains reference documentation for working with protocol buffer classes in C++.

plugin.pb.h

This section contains reference documentation for working with protocol buffer classes in C++.

python_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

ruby_generator.h

This section contains reference documentation for working with protocol buffer classes in C++.

descriptor.h

This section contains reference documentation for working with protocol buffer classes in C++.

descriptor.pb.h

This section contains reference documentation for working with protocol buffer classes in C++.

descriptor_database.h

This section contains reference documentation for working with protocol buffer classes in C++.

dynamic_message.h

This section contains reference documentation for working with protocol buffer classes in C++.

coded_stream.h

This section contains reference documentation for working with protocol buffer classes in C++.

gzip_stream.h

This section contains reference documentation for working with protocol buffer classes in C++.

printer.h

This section contains reference documentation for working with protocol buffer classes in C++.

tokenizer.h

This section contains reference documentation for working with protocol buffer classes in C++.

zero_copy_stream.h

This section contains reference documentation for working with protocol buffer classes in C++.

zero_copy_stream_impl.h

This section contains reference documentation for working with protocol buffer classes in C++.

zero_copy_stream_iml_lite.h

This section contains reference documentation for working with protocol buffer classes in C++.

map.h

This section contains reference documentation for working with protocol buffer classes in C++.

message.h

This section contains reference documentation for working with protocol buffer classes in C++.

message_lite.h

This section contains reference documentation for working with protocol buffer classes in C++.

repeated_field.h

This section contains reference documentation for working with protocol buffer classes in C++.

service.h

This section contains reference documentation for working with protocol buffer classes in C++.

text_format.h

This section contains reference documentation for working with protocol buffer classes in C++.

unknown_field_set.h

This section contains reference documentation for working with protocol buffer classes in C++.

field_comparator.h

This section contains reference documentation for working with protocol buffer classes in C++.

field_mask_util.h

This section contains reference documentation for working with protocol buffer classes in C++.

json_util.h

This section contains reference documentation for working with protocol buffer classes in C++.

message_differencer.h

This section contains reference documentation for working with protocol buffer classes in C++.

time_util.h

This section contains reference documentation for working with protocol buffer classes in C++.

type_resolver.h

This section contains reference documentation for working with protocol buffer classes in C++.

type_resolver_util.h

This section contains reference documentation for working with protocol buffer classes in C++.

\ No newline at end of file diff --git a/reference/cpp/api-docs/index.xml b/reference/cpp/api-docs/index.xml new file mode 100644 index 000000000..79f17de8f --- /dev/null +++ b/reference/cpp/api-docs/index.xml @@ -0,0 +1,146 @@ +C++ Reference on Protocol Buffers Documentationhttps://protobuf.dev/reference/cpp/api-docs/Recent content in C++ Reference on Protocol Buffers DocumentationHugoenarena.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.arena/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.arena/#include &lt;google/protobuf/arena.h&gt; +namespace google::protobuf +This file defines an Arena allocator for better allocation performance. Classes in this fileArenaOptionsArenaOptions provides optional additional parameters to arena construction that control its block-allocation behavior. ArenaArena allocator. Arena::InternalHelperArena::is_arena_constructableHelper typetraits that indicates support for arenas in a type T at compile time. Arena::is_destructor_skippablestruct ArenaOptions#include &lt;google/protobuf/arena.h&gt; +namespace google::protobuf +ArenaOptions provides optional additional parameters to arena construction that control its block-allocation behavior. Memberssize_tstart_block_sizeThis defines the size of the first block requested from the system malloc.common.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.common/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.common/#include &lt;google/protobuf/stubs/common.h&gt; +namespace google::protobuf +Contains basic types and utilities used by the rest of the library. Classes in this filecode_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.code_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.code_generator/#include &lt;google/protobuf/compiler/code_generator.h&gt; +namespace google::protobuf::compiler +Defines the abstract interface implemented by each of the language-specific code generators. Classes in this fileCodeGeneratorThe abstract interface to a class which generates code implementing a particular proto file in a particular language. GeneratorContextCodeGenerators generate one or more files in a given directory. File MembersThese definitions are not part of any class.typedefGeneratorContext OutputDirectoryThe type GeneratorContext was once called OutputDirectory. more...voidParseGeneratorParameter(const std::string &amp; , std::vector&lt; std::pair&lt; std::string, std::string &gt; &gt; * )Several code generators treat the parameter argument as holding a list of options separated by commas.command_line_interface.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.command_line_interface/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.command_line_interface/#include &lt;google/protobuf/compiler/command_line_interface.h&gt; +namespace google::protobuf::compiler +Implements the Protocol Compiler front-end such that it may be reused by custom compilers written to support other languages. Classes in this fileCommandLineInterfaceThis class implements the command-line interface to the protocol compiler. class CommandLineInterface#include &lt;google/protobuf/compiler/command_line_interface.h&gt; +namespace google::protobuf::compiler +This class implements the command-line interface to the protocol compiler. It is designed to make it very easy to create a custom protocol compiler supporting the languages of your choice.cpp_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.cpp_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.cpp_generator/#include &lt;google/protobuf/compiler/cpp/cpp_generator.h&gt; +namespace google::protobuf::compiler::cpp +Generates C++ code for a given .proto file. Classes in this fileCppGeneratorCodeGenerator implementation which generates a C++ source file and header. class CppGenerator: public CodeGenerator#include &lt;google/protobuf/compiler/cpp/cpp_generator.h&gt; +namespace google::protobuf::compiler::cpp +CodeGenerator implementation which generates a C++ source file and header. If you create your own protocol compiler binary and you want it to support C++ output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.csharp_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.csharp_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.csharp_generator/#include &lt;google/protobuf/compiler/csharp/csharp_generator.h&gt; +namespace google::protobuf::compiler::csharp +Generates C# code for a given .proto file. Classes in this fileGeneratorCodeGenerator implementation which generates a C# source file and header. class Generator: public CodeGenerator#include &lt;google/protobuf/compiler/csharp/csharp_generator.h&gt; +namespace google::protobuf::compiler::csharp +CodeGenerator implementation which generates a C# source file and header. If you create your own protocol compiler binary and you want it to support C# output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.csharp_names.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.csharp_names/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.csharp_names/#include &lt;google/protobuf/compiler/csharp/csharp_names.h&gt; +namespace google::protobuf::compiler::csharp +Provides a mechanism for mapping a descriptor to the fully-qualified name of the corresponding C# class. Classes in this fileFile MembersThese definitions are not part of any class.std::stringGetFileNamespace(const FileDescriptor * descriptor)Requires: more...std::stringGetClassName(const Descriptor * descriptor)Requires: more...std::stringGetReflectionClassName(const FileDescriptor * descriptor)Requires: more...std::stringGetOutputFile(const FileDescriptor * descriptor, const std::string file_extension, const bool generate_directories, const std::string base_namespace, std::string * error)Generates output file name for given file descriptor. more... std::string csharp::GetFileNamespace( +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const FileDescriptor * descriptor)Requires: descriptor !importer.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.importer/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.importer/#include &lt;google/protobuf/compiler/importer.h&gt; +namespace google::protobuf::compiler +This file is the public interface to the .proto file parser. Classes in this fileSourceTreeDescriptorDatabaseAn implementation of DescriptorDatabase which loads files from a SourceTree and parses them. ImporterSimple interface for parsing .proto files. MultiFileErrorCollectorIf the importer encounters problems while trying to import the proto files, it reports them to a MultiFileErrorCollector. SourceTreeAbstract interface which represents a directory tree containing proto files. DiskSourceTreeAn implementation of SourceTree which loads files from locations on disk.java_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.java_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.java_generator/#include &lt;google/protobuf/compiler/java/java_generator.h&gt; +namespace google::protobuf::compiler::java +Generates Java code for a given .proto file. Classes in this fileJavaGeneratorCodeGenerator implementation which generates Java code. class JavaGenerator: public CodeGenerator#include &lt;google/protobuf/compiler/java/java_generator.h&gt; +namespace google::protobuf::compiler::java +CodeGenerator implementation which generates Java code. If you create your own protocol compiler binary and you want it to support Java output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function. MembersJavaGenerator()~JavaGenerator()implements CodeGeneratorvirtual boolGenerate(const FileDescriptor * file, const std::string &amp; parameter, GeneratorContext * generator_context, std::string * error) constGenerates code for the given proto file, generating one or more files in the given output directory.java_names.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.java_names/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.java_names/#include &lt;google/protobuf/compiler/java/java_names.h&gt; +namespace google::protobuf::compiler::java +Provides a mechanism for mapping a descriptor to the fully-qualified name of the corresponding Java class. Classes in this fileFile MembersThese definitions are not part of any class.std::stringClassName(const Descriptor * descriptor)Requires: more...std::stringClassName(const EnumDescriptor * descriptor)Requires: more...std::stringClassName(const FileDescriptor * descriptor)Requires: more...std::stringClassName(const ServiceDescriptor * descriptor)Requires: more...std::stringFileJavaPackage(const FileDescriptor * descriptor)Requires: more...std::stringCapitalizedFieldName(const FieldDescriptor * descriptor)Requires: more... std::string java::ClassName( +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const Descriptor * descriptor)Requires: descriptor != NULL Returns: The fully-qualified Java class name.javanano_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.javanano_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.javanano_generator/#include &lt;google/protobuf/compiler/javanano/javanano_generator.h&gt; +namespace google::protobuf::compiler::javanano +Generates Java nano code for a given .proto file. Classes in this fileJavaNanoGeneratorCodeGenerator implementation which generates Java nano code. class JavaNanoGenerator: public CodeGenerator#include &lt;google/protobuf/compiler/javanano/javanano_generator.h&gt; +namespace google::protobuf::compiler::javanano +CodeGenerator implementation which generates Java nano code. If you create your own protocol compiler binary and you want it to support Java output for the nano runtime, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.js_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.js_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.js_generator/#include &lt;google/protobuf/compiler/js/js_generator.h&gt; +namespace google::protobuf::compiler::js +Generates JavaScript code for a given .proto file. Classes in this fileGeneratorOptionsGeneratorCodeGenerator implementation which generates a JavaScript source file and header. struct GeneratorOptions#include &lt;google/protobuf/compiler/js/js_generator.h&gt; +namespace google::protobuf::compiler::js +MembersenumImportStyleWhat style of imports should be used. more...enumOutputMode more...std::stringoutput_dirOutput path. std::stringnamespace_prefixNamespace prefix. boolbinaryEnable binary-format support? enum google::protobuf::compiler::js::GeneratorOptions::ImportStyleimport_stylebooladd_require_for_enumsAdd a goog.requires() call for each enum type used. more...booltestonlySet this as a test-only module via goog.setTestOnly();. std::stringlibraryCreate a library with name &lt;name&gt;_lib.js rather than a separate .objectivec_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.objectivec_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.objectivec_generator/#include &lt;google/protobuf/compiler/objectivec/objectivec_generator.h&gt; +namespace google::protobuf::compiler::objectivec +Generates ObjectiveC code for a given .proto file. Classes in this fileObjectiveCGeneratorCodeGenerator implementation which generates a ObjectiveC source file and header. class ObjectiveCGenerator: public CodeGenerator#include &lt;google/protobuf/compiler/objectivec/objectivec_generator.h&gt; +namespace google::protobuf::compiler::objectivec +CodeGenerator implementation which generates a ObjectiveC source file and header. If you create your own protocol compiler binary and you want it to support ObjectiveC output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.objectivec_helpers.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.objectivec_helpers/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.objectivec_helpers/#include &lt;google/protobuf/compiler/objectivec/objectivec_helpers.h&gt; +namespace google::protobuf::compiler::objectivec +Helper functions for generating ObjectiveC code. Classes in this fileOptionsGenerator options (see objectivec_generator.cc for a description of each): TextFormatDecodeDataGenerate decode data needed for ObjC's GPBDecodeTextFormatName() to transform the input into the expected output. LineConsumerHelper for parsing simple files. ImportWriterHelper class for parsing framework import mappings and generating import statements. File MembersThese definitions are not part of any class.enumObjectiveCType more...enumFlagType more...const char *constProtobufLibraryFrameworkNameThe name the commonly used by the library when built as a framework.parser.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.parser/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.parser/#include &lt;google/protobuf/compiler/parser.h&gt; +namespace google::protobuf::compiler +Implements parsing of .proto files to FileDescriptorProtos. Classes in this fileParserImplements parsing of protocol definitions (such as .proto files). SourceLocationTableA table mapping (descriptor, ErrorLocation) pairs &ndash; as reported by DescriptorPool when validating descriptors &ndash; to line and column numbers within the original source code. class Parser#include &lt;google/protobuf/compiler/parser.h&gt; +namespace google::protobuf::compiler +Implements parsing of protocol definitions (such as .proto files). Note that most users will be more interested in the Importer class.plugin.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.plugin/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.plugin/#include &lt;google/protobuf/compiler/plugin.h&gt; +namespace google::protobuf::compiler +Front-end for protoc code generator plugins written in C++. To implement a protoc plugin in C++, simply write an implementation of CodeGenerator, then create a main() function like: int main(int argc, char* argv[]) { MyCodeGenerator generator; return google::protobuf::compiler::PluginMain(argc, argv, &amp;generator); } You must link your plugin against libprotobuf and libprotoc. +The core part of PluginMain is to invoke the given CodeGenerator on a CodeGeneratorRequest to generate a CodeGeneratorResponse.plugin.pb.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb/#include &lt;google/protobuf/compiler/plugin.pb.h&gt; +namespace google::protobuf::compiler +API for protoc plugins. +This file defines a set of protocol message classes which make up the API to protoc code generator plugins. Plugins written in C++ should probably build on the API in plugin.h instead of dealing with the protobuf-level API, but plugins in other languages will need to deal with the raw messages as defined below. +The protocol compiler currently doesn't support auto-generated documentation, hence this page contains no descriptions.python_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.python_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.python_generator/#include &lt;google/protobuf/compiler/python/python_generator.h&gt; +namespace google::protobuf::compiler::python +Generates Python code for a given .proto file. Classes in this fileGeneratorCodeGenerator implementation for generated Python protocol buffer classes. class Generator: public CodeGenerator#include &lt;google/protobuf/compiler/python/python_generator.h&gt; +namespace google::protobuf::compiler::python +CodeGenerator implementation for generated Python protocol buffer classes. If you create your own protocol compiler binary and you want it to support Python output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.ruby_generator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.ruby_generator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.ruby_generator/#include &lt;google/protobuf/compiler/ruby/ruby_generator.h&gt; +namespace google::protobuf::compiler::ruby +Generates Ruby code for a given .proto file. Classes in this fileGeneratorCodeGenerator implementation for generated Ruby protocol buffer classes. class Generator: public CodeGenerator#include &lt;google/protobuf/compiler/ruby/ruby_generator.h&gt; +namespace google::protobuf::compiler::ruby +CodeGenerator implementation for generated Ruby protocol buffer classes. If you create your own protocol compiler binary and you want it to support Ruby output, you can do so by registering an instance of this CodeGenerator with the CommandLineInterface in your main() function.descriptor.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.descriptor/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.descriptor/#include &lt;google/protobuf/descriptor.h&gt; +namespace google::protobuf +This file contains classes which describe a type of protocol message. You can use a message's descriptor to learn at runtime what fields it contains and what the types of those fields are. The Message interface also allows you to dynamically access and modify individual fields by passing the FieldDescriptor of the field you are interested in. +Most users will not care about descriptors, because they will write code specific to certain protocol types and will simply use the classes generated by the protocol compiler directly.descriptor.pb.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.descriptor.pb/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.descriptor.pb/#include &lt;google/protobuf/descriptor.pb.h&gt; +namespace google::protobuf +Protocol buffer representations of descriptors. +This file defines a set of protocol message classes which represent the same information represented by the classes defined in descriptor.h. You can convert a FileDescriptorProto to a FileDescriptor using the DescriptorPool class. Thus, the classes in this file allow protocol type definitions to be communicated efficiently between processes. +The protocol compiler currently doesn't support auto-generated documentation, hence this page contains no descriptions.descriptor_database.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.descriptor_database/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.descriptor_database/#include &lt;google/protobuf/descriptor_database.h&gt; +namespace google::protobuf +Interface for manipulating databases of descriptors. Classes in this fileDescriptorDatabaseAbstract interface for a database of descriptors. SimpleDescriptorDatabaseA DescriptorDatabase into which you can insert files manually. EncodedDescriptorDatabaseVery similar to SimpleDescriptorDatabase, but stores all the descriptors as raw bytes and generally tries to use as little memory as possible. DescriptorPoolDatabaseA DescriptorDatabase that fetches files from a given pool. MergedDescriptorDatabaseA DescriptorDatabase that wraps two or more others. class DescriptorDatabase#include &lt;google/protobuf/descriptor_database.dynamic_message.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.dynamic_message/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.dynamic_message/#include &lt;google/protobuf/dynamic_message.h&gt; +namespace google::protobuf +Defines an implementation of Message which can emulate types which are not known at compile-time. Classes in this fileDynamicMessageFactoryConstructs implementations of Message which can emulate types which are not known at compile-time. DynamicMapSorterHelper for computing a sorted list of map entries via reflection. class DynamicMessageFactory: public MessageFactory#include &lt;google/protobuf/dynamic_message.h&gt; +namespace google::protobuf +Constructs implementations of Message which can emulate types which are not known at compile-time. Sometimes you want to be able to manipulate protocol types that you don't know about at compile time.coded_stream.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.coded_stream/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.coded_stream/#include &lt;google/protobuf/io/coded_stream.h&gt; +namespace google::protobuf::io +This file contains the CodedInputStream and CodedOutputStream classes, which wrap a ZeroCopyInputStream or ZeroCopyOutputStream, respectively, and allow you to read or write individual pieces of data in various formats. In particular, these implement the varint encoding for integers, a simple variable-length encoding in which smaller numbers take fewer bytes. +Typically these classes will only be used internally by the protocol buffer library in order to encode and decode protocol buffers.gzip_stream.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.gzip_stream/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.gzip_stream/#include &lt;google/protobuf/io/gzip_stream.h&gt; +namespace google::protobuf::io +This file contains the definition for classes GzipInputStream and GzipOutputStream. GzipInputStream decompresses data from an underlying ZeroCopyInputStream and provides the decompressed data as a ZeroCopyInputStream. +GzipOutputStream is an ZeroCopyOutputStream that compresses data to an underlying ZeroCopyOutputStream. Classes in this fileGzipInputStreamA ZeroCopyInputStream that reads compressed data through zlib. GzipOutputStreamGzipOutputStream::Optionsclass GzipInputStream: public ZeroCopyInputStream#include &lt;google/protobuf/io/gzip_stream.h&gt; +namespace google::protobuf::io +A ZeroCopyInputStream that reads compressed data through zlib. MembersenumFormatFormat key for constructor. more.printer.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.printer/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.printer/#include &lt;google/protobuf/io/printer.h&gt; +namespace google::protobuf::io +Utility class for writing text to a ZeroCopyOutputStream. Classes in this fileAnnotationCollectorRecords annotations about a Printer's output. AnnotationProtoCollectorRecords annotations about a Printer's output to the given protocol buffer, assuming that the buffer has an ::Annotation message exposing path, source_file, begin and end fields. Printerclass AnnotationCollector#include &lt;google/protobuf/io/printer.h&gt; +namespace google::protobuf::io +Records annotations about a Printer's output. Known subclasses: +AnnotationProtoCollector< AnnotationProto >Memberstypedefstd::pair&lt; std::pair&lt; size_t, size_t &gt;, std::string &gt; AnnotationAnnotation is a offset range and a payload pair.tokenizer.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.tokenizer/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.tokenizer/#include &lt;google/protobuf/io/tokenizer.h&gt; +namespace google::protobuf::io +Class for parsing tokenized text from a ZeroCopyInputStream. Classes in this fileErrorCollectorAbstract interface for an object which collects the errors that occur during parsing. TokenizerThis class converts a stream of raw text into a stream of tokens for the protocol definition parser to parse. Tokenizer::TokenStructure representing a token read from the token stream. File MembersThese definitions are not part of any class.typedefint ColumnNumberBy "column number", the proto compiler refers to a count of the number of bytes before a given byte, except that a tab character advances to the next multiple of 8 bytes.zero_copy_stream.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream/#include &lt;google/protobuf/io/zero_copy_stream.h&gt; +namespace google::protobuf::io +This file contains the ZeroCopyInputStream and ZeroCopyOutputStream interfaces, which represent abstract I/O streams to and from which protocol buffers can be read and written. For a few simple implementations of these interfaces, see zero_copy_stream_impl.h. +These interfaces are different from classic I/O streams in that they try to minimize the amount of data copying that needs to be done. To accomplish this, responsibility for allocating buffers is moved to the stream object, rather than being the responsibility of the caller.zero_copy_stream_impl.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl/#include &lt;google/protobuf/io/zero_copy_stream_impl.h&gt; +namespace google::protobuf::io +This file contains common implementations of the interfaces defined in zero_copy_stream.h which are only included in the full (non-lite) protobuf library. These implementations include Unix file descriptors and C++ iostreams. See also: zero_copy_stream_impl_lite.h Classes in this fileFileInputStreamA ZeroCopyInputStream which reads from a file descriptor. FileOutputStreamA ZeroCopyOutputStream which writes to a file descriptor. IstreamInputStreamA ZeroCopyInputStream which reads from a C++ istream. OstreamOutputStreamA ZeroCopyOutputStream which writes to a C++ ostream.zero_copy_stream_iml_lite.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl_lite/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl_lite/#include &lt;google/protobuf/io/zero_copy_stream_impl_lite.h&gt; +namespace google::protobuf::io +This file contains common implementations of the interfaces defined in zero_copy_stream.h which are included in the "lite" protobuf library. These implementations cover I/O on raw arrays and strings, as well as adaptors which make it easy to implement streams based on traditional streams. Of course, many users will probably want to write their own implementations of these interfaces specific to the particular I/O abstractions they prefer to use, but these should cover the most common cases.map.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.map/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.map/#include &lt;google/protobuf/map.h&gt; +namespace google::protobuf +This file defines the map container and its helpers to support protobuf maps. The Map and MapIterator types are provided by this header file. Please avoid using other types defined here, unless they are public types within Map or MapIterator, such as Map::value_type. Classes in this fileMapPairThis is the class for Map's internal value_type. MapMap is an associative container type used to store protobuf map fields. Map::const_iteratorIterators.message.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.message/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.message/#include &lt;google/protobuf/message.h&gt; +namespace google::protobuf +Defines Message, the abstract interface implemented by non-lite protocol message objects. Although it's possible to implement this interface manually, most users will use the protocol compiler to generate implementations. +Example usage: +Say you have a message defined as: +message Foo { optional string text = 1; repeated int32 numbers = 2; } Then, if you used the protocol compiler to generate a class from the above definition, you could use it like so:message_lite.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.message_lite/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.message_lite/#include &lt;google/protobuf/message_lite.h&gt; +namespace google::protobuf +Defines MessageLite, the abstract interface implemented by all (lite and non-lite) protocol message objects. Classes in this fileMessageLiteInterface to light weight protocol messages. File MembersThese definitions are not part of any class.voidShutdownProtobufLibrary()Shut down the entire protocol buffers library, deleting all static-duration objects allocated by the library or by generated .pb.cc files. more... void protobuf::ShutdownProtobufLibrary()Shut down the entire protocol buffers library, deleting all static-duration objects allocated by the library or by generated .repeated_field.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.repeated_field/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.repeated_field/#include &lt;google/protobuf/repeated_field.h&gt; +namespace google::protobuf +RepeatedField and RepeatedPtrField are used by generated protocol message classes to manipulate repeated fields. These classes are very similar to STL's vector, but include a number of optimizations found to be useful specifically in the case of Protocol Buffers. RepeatedPtrField is particularly different from STL vector as it manages ownership of the pointers that it contains. +Typically, clients should not need to access RepeatedField objects directly, but should instead use the accessor functions generated automatically by the protocol compiler.service.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.service/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.service/#include &lt;google/protobuf/service.h&gt; +namespace google::protobuf +DEPRECATED: This module declares the abstract interfaces underlying proto2 RPC services. These are intended to be independent of any particular RPC implementation, so that proto2 services can be used on top of a variety of implementations. Starting with version 2.3.0, RPC implementations should not try to build on these, but should instead provide code generator plugins which generate code specific to the particular RPC implementation. This way the generated code can be more appropriate for the implementation in use and can avoid unnecessary layers of indirection.text_format.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.text_format/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.text_format/#include &lt;google/protobuf/text_format.h&gt; +namespace google::protobuf +Utilities for printing and parsing protocol messages in a human-readable, text-based format. Classes in this fileTextFormatThis class implements protocol buffer text format, colloquially known as text proto. TextFormat::BaseTextGeneratorTextFormat::FastFieldValuePrinterThe default printer that converts scalar values from fields into their string representation. TextFormat::FieldValuePrinterDeprecated: please use FastFieldValuePrinter instead. TextFormat::FinderInterface that Printers or Parsers can use to find extensions, or types referenced in Any messages. TextFormat::MessagePrinterTextFormat::ParseInfoTreeData structure which is populated with the locations of each field value parsed from the text.unknown_field_set.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.unknown_field_set/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.unknown_field_set/#include &lt;google/protobuf/unknown_field_set.h&gt; +namespace google::protobuf +Contains classes used to keep track of unrecognized fields seen while parsing a protocol message. Classes in this fileUnknownFieldSetAn UnknownFieldSet contains fields that were encountered while parsing a message but were not defined by its type. UnknownFieldRepresents one field in an UnknownFieldSet. UnknownField::LengthDelimitedclass UnknownFieldSet#include &lt;google/protobuf/unknown_field_set.h&gt; +namespace google::protobuf +An UnknownFieldSet contains fields that were encountered while parsing a message but were not defined by its type. Keeping track of these can be useful, especially in that they may be written if the message is serialized again without being cleared in between.field_comparator.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.field_comparator/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.field_comparator/#include &lt;google/protobuf/util/field_comparator.h&gt; +namespace google::protobuf::util +Defines classes for field comparison. Classes in this fileFieldComparatorBase class specifying the interface for comparing protocol buffer fields. SimpleFieldComparatorBasic implementation of FieldComparator. DefaultFieldComparatorclass FieldComparator#include &lt;google/protobuf/util/field_comparator.h&gt; +namespace google::protobuf::util +Base class specifying the interface for comparing protocol buffer fields. Regular users should consider using or subclassing DefaultFieldComparator rather than this interface. Currently, this does not support comparing unknown fields. Known subclasses: +SimpleFieldComparatorMembersenumComparisonResult more...FieldComparator()virtual ~FieldComparator()virtual ComparisonResultCompare(const Message &amp; message_1, const Message &amp; message_2, const FieldDescriptor * field, int index_1, int index_2, const util::FieldContext * field_context) = 0Compares the values of a field in two protocol buffer messages.field_mask_util.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.field_mask_util/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.field_mask_util/#include &lt;google/protobuf/util/field_mask_util.h&gt; +namespace google::protobuf::util +Defines utilities for the FieldMask well known type. Classes in this fileFieldMaskUtilFieldMaskUtil::MergeOptionsFieldMaskUtil::TrimOptionsclass FieldMaskUtil#include &lt;google/protobuf/util/field_mask_util.h&gt; +namespace google::protobuf::util +Membersstatic std::stringToString(const FieldMask &amp; mask)Converts FieldMask to/from string, formatted by separating each path with a comma (e.g., "foo_bar,baz.quz"). static voidFromString(StringPiece str, FieldMask * out)template static voidFromFieldNumbers(const std::vector&lt; int64_t &gt; &amp; field_numbers, FieldMask * out)Populates the FieldMask with the paths corresponding to the fields with the given numbers, after checking that all field numbers are valid.json_util.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.json_util/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.json_util/#include &lt;google/protobuf/util/json_util.h&gt; +namespace google::protobuf::util +Utility functions to convert between protobuf binary format and proto3 JSON format. Classes in this fileJsonParseOptionsJsonPrintOptionsFile MembersThese definitions are not part of any class.typedefJsonPrintOptions JsonOptionsDEPRECATED. Use JsonPrintOptions instead. util::StatusMessageToJsonString(const Message &amp; message, std::string * output, const JsonOptions &amp; options)Converts from protobuf message to JSON and appends it to |output|. more...util::StatusMessageToJsonString(const Message &amp; message, std::string * output)util::StatusJsonStringToMessage(StringPiece input, Message * message, const JsonParseOptions &amp; options)Converts from JSON to protobuf message.message_differencer.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.message_differencer/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.message_differencer/#include &lt;google/protobuf/util/message_differencer.h&gt; +namespace google::protobuf::util +This file defines static methods and classes for comparing Protocol Messages. Aug. 2008: Added Unknown Fields Comparison for messages. Aug. 2009: Added different options to compare repeated fields. Apr. 2010: Moved field comparison to FieldComparator Sep. 2020: Added option to output map keys in path Classes in this fileMessageDifferencerA basic differencer that can be used to determine the differences between two specified Protocol Messages. MessageDifferencer::IgnoreCriteriaAbstract base class from which all IgnoreCriteria derive.time_util.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.time_util/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.time_util/#include &lt;google/protobuf/util/time_util.h&gt; +namespace google::protobuf::util +Defines utilities for the Timestamp and Duration well known types. Classes in this fileTimeUtilUtility functions for Timestamp and Duration. class TimeUtil#include &lt;google/protobuf/util/time_util.h&gt; +namespace google::protobuf::util +Utility functions for Timestamp and Duration. Membersconst int64_tkTimestampMinSeconds = = -62135596800LLThe min/max Timestamp/Duration values we support. more...const int64_tkTimestampMaxSeconds = = 253402300799LLFor "9999-12-31T23:59:59.999999999Z". const int64_tkDurationMinSeconds = = -315576000000LLconst int64_tkDurationMaxSeconds = = 315576000000LLstatic std::stringToString(const Timestamp &amp; timestamp)Converts Timestamp to/from RFC 3339 date string format. more.type_resolver.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.type_resolver/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.type_resolver/#include &lt;google/protobuf/util/type_resolver.h&gt; +namespace google::protobuf::util +Defines a TypeResolver for the Any message. Classes in this fileTypeResolverAbstract interface for a type resolver. class TypeResolver#include &lt;google/protobuf/util/type_resolver.h&gt; +namespace google::protobuf::util +Abstract interface for a type resolver. Implementations of this interface must be thread-safe. MembersTypeResolver()virtual ~TypeResolver()virtual util::StatusResolveMessageType(const std::string &amp; type_url, google::protobuf::Type * message_type) = 0Resolves a type url for a message type. virtual util::StatusResolveEnumType(const std::string &amp; type_url, google::protobuf::Enum * enum_type) = 0Resolves a type url for an enum type.type_resolver_util.hhttps://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.type_resolver_util/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.type_resolver_util/#include &lt;google/protobuf/util/type_resolver_util.h&gt; +namespace google::protobuf::util +Defines utilities for the TypeResolver. Classes in this fileFile MembersThese definitions are not part of any class.TypeResolver *NewTypeResolverForDescriptorPool(const std::string &amp; url_prefix, const DescriptorPool * pool)Creates a TypeResolver that serves type information in the given descriptor pool. more... TypeResolver * util::NewTypeResolverForDescriptorPool( +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const std::string &amp; url_prefix, +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const DescriptorPool * pool)Creates a TypeResolver that serves type information in the given descriptor pool. Caller takes ownership of the returned TypeResolver. \ No newline at end of file diff --git a/reference/cpp/arenas/index.html b/reference/cpp/arenas/index.html new file mode 100644 index 000000000..75d33ba63 --- /dev/null +++ b/reference/cpp/arenas/index.html @@ -0,0 +1,342 @@ +C++ Arena Allocation Guide | Protocol Buffers Documentation +

C++ Arena Allocation Guide

Arena allocation is a C++-only feature that helps you optimize your memory usage and improve performance when working with protocol buffers.

This page describes exactly what C++ code the protocol +buffer compiler generates in addition to the code described in the +C++ Generated Code Guide +when arena allocation is enabled. It assumes that you are familiar with the +material in the +language guide and the +C++ Generated Code Guide.

Why Use Arena Allocation?

Memory allocation and deallocation constitutes a significant fraction of CPU +time spent in protocol buffers code. By default, protocol buffers performs heap +allocations for each message object, each of its subobjects, and several field +types, such as strings. These allocations occur in bulk when parsing a message +and when building new messages in memory, and associated deallocations happen +when messages and their subobject trees are freed.

Arena-based allocation has been designed to reduce this performance cost. With +arena allocation, new objects are allocated out of a large piece of preallocated +memory called the arena. Objects can all be freed at once by discarding the +entire arena, ideally without running destructors of any contained object +(though an arena can still maintain a “destructor list” when required). This +makes object allocation faster by reducing it to a simple pointer increment, and +makes deallocation almost free. Arena allocation also provides greater cache +efficiency: when messages are parsed, they are more likely to be allocated in +continuous memory, which makes traversing messages more likely to hit hot cache +lines.

To get these benefits you’ll need to be aware of object lifetimes and find a +suitable granularity at which to use arenas (for servers, this is often +per-request). You can find out more about how to get the most from arena +allocation in Usage patterns and best practices.

This table summarizes the typical performance advantages and disadvantages of +using arenas:

OperationHeap-allocated proto messagesArena-allocated proto messages
Message allocationSlower on averageFaster on average
Message destructionSlower on averageFaster on average
Message movesAlways a move (equivalent to a shallow copy in cost)Sometimes a deep copy

Getting Started

The protocol buffer compiler generates code for arena allocation for the +messages in your file, as used in the following example.

#include <google/protobuf/arena.h>
+{
+  google::protobuf::Arena arena;
+  MyMessage* message = google::protobuf::Arena::Create<MyMessage>(&arena);
+  // ...
+}
+

The message object created by Create() exists for as long as arena exists, +and you should not delete the returned message pointer. All of the message +object’s internal storage (with a few exceptions1) and submessages (for +example, submessages in a repeated field within MyMessage) are allocated on +the arena as well.

For the most part, the rest of your code will be the same as if you weren’t +using arena allocation.

We’ll look at the arena API in more detail in the following sections, and you +can see a more extensive example at the end of the document.

Arena Class API

You create message objects on the arena using the +google::protobuf::Arena +class. This class implements the following public methods.

Constructors

  • Arena(): Creates a new arena with default parameters, tuned for average +use cases.
  • Arena(const ArenaOptions& options): Creates a new arena that uses the +specified allocation options. The options available in ArenaOptions +include the ability to use an initial block of user-provided memory for +allocations before resorting to the system allocator, control over the +initial and maximum request sizes for blocks of memory, and allowing you to +pass in custom block allocation and deallocation function pointers to build +freelists and others on top of the blocks.

Allocation Methods

  • template<typename T> static T* Create(Arena* arena) or template<typename T> static T* Create(Arena* arena, args...)

    • If T is fully compatible2, then the method creates a new +protocol buffer object of type T and its subobjects on the arena.

      If arena is not NULL, the returned object is allocated on the arena, +its internal storage and sub-types (if any) will be allocated on the +same arena, and its lifetime is the same as that of the arena. The +object must not be deleted/freed manually: the arena owns the object for +lifetime purposes.

      If arena is NULL, the returned object is allocated on the heap, and +the caller owns the object upon return.

    • If T is a user-type, the method lets you create an object but not the +subobjects on the arena. For example, let’s say you have this C++ class:

      class MyCustomClass {
      +    MyCustomClass(int arg1, int arg2);
      +    // ...
      +};
      +

      …you can create an instance of it on the arena like this:

      void func() {
      +    // ...
      +    google::protobuf::Arena arena;
      +    MyCustomClass* c = google::protobuf::Arena::Create<MyCustomClass>(&arena, constructor_arg1, constructor_arg2);
      +    // ...
      +}
      +
  • template<typename T> static T* CreateArray(Arena* arena, size_t n): If +arena is not NULL, this method allocates raw storage for n elements of +type T and returns it. The arena owns the returned memory and will free it +on its own destruction. If arena is NULL, this method allocates storage on +the heap and the caller receives ownership.

    T must have a trivial constructor: constructors are not called when the +array is created on the arena.

“Owned list” Methods

The following methods let you specify that particular objects or destructors are +“owned” by the arena, ensuring that they are deleted or called when the arena +itself is deleted

  • template<typename T> void Own(T* object): Adds object to the arena’s +list of owned heap objects. When the arena is destroyed, it traverses this +list and frees each object using operator delete, i.e., the system memory +allocator. This method is useful in cases when an object’s lifetime should +be tied to the arena but, for whatever reason, the object itself cannot be +or was not already allocated on the arena.
  • template<typename T> void OwnDestructor(T* object): Adds the destructor of +object to the arena’s list of destructors to call. When the arena is +destroyed, it traverses this list and calls each destructor in turn. It does +not attempt to free the underlying memory of object. This method is useful +when an object is embedded in arena-allocated storage but its destructor +will not otherwise be called, for example because its containing class is a +protobuf message whose destructor won’t be called, or because it was +manually constructed in a block allocated by AllocateArray().

Other Methods

  • uint64 SpaceUsed() const: Returns the total size of the arena, which is +the sum of the sizes of the underlying blocks. This method is thread-safe; +however, if there are concurrent allocations from multiple threads this +method’s return value may not include the sizes of those new blocks.
  • uint64 Reset(): Destroys the arena’s storage, first calling all registered +destructors and freeing all registered heap objects and then discarding all +arena blocks. This teardown procedure is equivalent to that which occurs +when the arena’s destructor runs, except the arena is reusable for new +allocations after this method returns. Returns the total size used by the +arena: this information is useful for tuning performance.
  • template<typename T> Arena* GetArena(): Returns a pointer to this arena. +Not directly very useful but allows Arena to be used in template +instantiations that expect GetArena() methods to be present.

Thread Safety

google::protobuf::Arena’s allocation methods are thread-safe, and the +underlying implementation goes to some length to make multithreaded allocation +fast. The Reset() method is not thread-safe: the thread performing the arena +reset must synchronize with all threads performing allocations or using objects +allocated from that arena first.

Generated Message Class

The following message class members are changed or added when you enable arena +allocation.

Message Class Methods

  • Message(Message&& other): If the source message is not on arena, the move +constructor efficiently moves all fields from one message to another +without making copies or heap allocations (the time complexity of this +operation is O(number-of-declared-fields)). However, if the source message +is on arena, it performs a deep copy of the underlying data. In both cases +the source message is left in a valid but unspecified state.
  • Message& operator=(Message&& other): If both messages are not on arena or +are on the same arena, the move-assignment operator efficiently moves +all fields from one message to another without making copies or heap +allocations (the time complexity of this operation is +O(number-of-declared-fields)). However, if only one message is on arena, +or the messages are on different arenas, it performs a deep copy of the +underlying data. In both cases the source message is left in a valid but +unspecified state.
  • void Swap(Message* other): If both messages to be swapped are not on +arenas or are on the same arena, +Swap() +behaves as it does without having arena allocation enabled: it efficiently +swaps the message objects’ contents, almost exclusively through cheap +pointer swaps, avoiding copies. However, if only one message is on an arena, +or the messages are on different arenas, Swap() performs deep copies of +the underlying data. This new behavior is necessary because otherwise the +swapped sub-objects could have differing lifetimes, leading potentially to +use-after-free bugs.
  • Message* New(Arena* arena): An alternate override for the standard New() +method. It allows a new message object of this type to be created on the +given arena. Its semantics are identical to Arena::Create<T>(arena) if the +concrete message type on which it is called is generated with arena +allocation enabled. If the message type is not generated with arena +allocation enabled, then it is equivalent to an ordinary allocation followed +by arena->Own(message) if arena is not NULL.
  • Arena* GetArena(): Returns the arena on which this message object was +allocated, if any.
  • void UnsafeArenaSwap(Message* other): Identical to Swap(), except it +assumes both objects are on the same arena (or not on arenas at all) and +always uses the efficient pointer-swapping implementation of this operation. +Using this method can improve performance as, unlike Swap(), it doesn’t +need to check which messages live on which arena before performing the swap. +As the Unsafe prefix suggests, you should only use this method if you are +sure the messages you want to swap aren’t on different arenas; otherwise +this method could have unpredictable results.

Embedded Message Fields

When you allocate a message object on an arena, its embedded message field +objects (submessages) are automatically owned by the arena as well. How these +message objects are allocated depends on where they are defined:

  • If the message type is also defined in a .proto file with arena allocation +enabled, the object is allocated on the arena directly.
  • If the message type is from another .proto without arena allocation +enabled, the object is heap-allocated but is “owned” by the parent message’s +arena. This means that when the arena is destroyed, the object will be freed +along with the objects on the arena itself.

For the field definition:

Bar foo = 1;
+

The following methods are added or have some special behavior when arena +allocation is enabled. Otherwise, accessor methods just use the +default behavior.

  • Bar* mutable_foo(): Returns a mutable pointer to the submessage instance. +If the parent object is on an arena then the returned object will be as +well.
  • void set_allocated_foo(Bar* bar): Takes a new object and adopts it as the +new value for the field. Arena support adds additional copying semantics to +maintain proper ownership when objects cross arena/arena or arena/heap +boundaries:
    • If the parent object is on the heap and bar is on the heap, or if the +parent and message are on the same arena, this method’s behavior is +unchanged.
    • If the parent is on an arena and bar is on the heap, the parent +message adds bar to its arena’s ownership list with arena->Own().
    • If the parent is on an arena and bar is on a different arena, this +method makes a copy of message and takes the copy as the new field +value.
  • Bar* release_foo(): Returns the existing submessage instance of the field, +if set, or a NULL pointer if not set, releasing ownership of this instance +to the caller and clearing the parent message’s field. Arena support adds +additional copying semantics to maintain the contract that the returned +object is always heap-allocated:
    • If the parent message is on an arena, this method will make a copy of +the submessage on the heap, clear the field value, and return the copy.
    • If the parent message is on the heap, the method behavior is unchanged.
  • void unsafe_arena_set_allocated_foo(Bar* bar): Identical to +set_allocated_foo, but assumes both parent and submessage are on the same +arena. Using this version of the method can improve performance as it +doesn’t need to check whether the messages are on a particular arena or the +heap. See allocated/release patterns for details on safe +ways to use this.
  • Bar* unsafe_arena_release_foo(): Similar to release_foo(), but skips all +ownership checking. See allocated/release patterns for +details on safe ways to use this.

String Fields

String fields store their data on the heap even when their parent message is on the arena. Because of this, string accessor methods use the default behavior even when arena allocation is enabled.

Repeated Fields

Repeated fields allocate their internal array storage on the arena when the +containing message is arena-allocated, and also allocate their elements on the +arena when these elements are separate objects retained by pointer (messages or +strings). At the message-class level, generated methods for repeated fields do +not change. However, the RepeatedField and RepeatedPtrField objects that are +returned by accessors do have new methods and modified semantics when arena +support is enabled.

Repeated Numeric Fields

RepeatedField objects that contain primitive types have the following +new/changed methods when arena allocation is enabled:

  • void UnsafeArenaSwap(RepeatedField* other): Performs a swap of +RepeatedField contents without validating that this repeated field and +other are on the same arena. If they are not, the two repeated field objects +must be on arenas with equivalent lifetimes. The case where one is on an +arena and one is on the heap is checked and disallowed.
  • void Swap(RepeatedField* other): Checks each repeated field object’s +arena, and if one is on an arena while one is on the heap or if both are on +arenas but on different ones, the underlying arrays are copied before the +swap occurs. This means that after the swap, each repeated field object +holds an array on its own arena or heap, as appropriate.

Repeated Embedded Message Fields

RepeatedPtrField objects that contain messages have the following new/changed +methods when arena allocation is enabled.

  • void UnsafeArenaSwap(RepeatedPtrField* other): Performs a swap of +RepeatedPtrField contents without validating that this repeated field and +other have the same arena pointer. If they do not, the two repeated field +objects must have arena pointers with equivalent lifetimes. The case where +one has a non-NULL arena pointer and one has a NULL arena pointer is checked +and disallowed.

  • void Swap(RepeatedPtrField* other): Checks each repeated field object’s +arena pointer, and if one is non-NULL (contents on arena) while one is NULL +(contents on heap) or if both are non-NULL but have different values, the +underlying arrays and their pointed-to objects are copied before the swap +occurs. This means that after the swap, each repeated field object holds an +array on its own arena or on the heap, as appropriate.

  • void AddAllocated(SubMessageType* value): Checks that the provided message +object is on the same arena as the repeated field’s arena pointer.

    • The source and destination are both arena-allocated and on the same +arena: the object pointer is added directly to the underlying array.
    • The source and destination are both arena-allocated and on different +arenas: a copy is made, the original is freed if it was heap-allocated, +and the copy is placed on the array.
    • The source is heap-allocated and the destination is arena-allocated: No +copy is made.
    • The source is arena-allocated and the destination is heap-allocated: A +copy is made and placed on the array.
    • Both source and destination are heap allocated: The object pointer is +added directly to the underlying array.

    This maintains the invariant that all objects pointed to by a repeated field +are in the same ownership domain (heap or specific arena) as indicated by +the repeated field’s arena pointer.

  • SubMessageType* ReleaseLast(): Returns a heap-allocated message equivalent +to the last message in the repeated field, removing it from the repeated +field. If the repeated field itself has a NULL arena pointer (and thus, all +of its pointed-to messages are heap-allocated), then this method simply +returns a pointer to the original object. Otherwise, if the repeated field +has a non-NULL arena pointer, this method makes a copy that is +heap-allocated and returns that copy. In both cases, the caller receives +ownership of a heap-allocated object and is responsible for deleting the +object.

  • void UnsafeArenaAddAllocated(SubMessageType* value): Like +AddAllocated(), but does not perform heap/arena checks or any message +copies. It adds the provided pointer directly to the internal array of +pointers for this repeated field. See +allocated/release patterns for details on safe ways to use +this.

  • SubMessageType* UnsafeArenaReleaseLast(): Like ReleaseLast() but +performs no copies, even if the repeated field has a non-NULL arena pointer. +Instead, it directly returns the pointer to the object as it was in the +repeated field. See allocated/release patterns for details +on safe ways to use this.

  • void ExtractSubrange(int start, int num, SubMessageType** elements): +Removes num elements from the repeated field, starting from index start, +and returns them in elements if it is not NULL. If the repeated field is +on an arena, and elements are being returned, the elements are copied to the +heap first. In both cases (arena or no arena), the caller owns the returned +objects on the heap.

  • void UnsafeArenaExtractSubrange(int start, int num, SubMessageType** elements): Removes num elements from the repeated field, starting from +index start, and returns them in elements if it is not NULL. Unlike +ExtractSubrange(), this method never copies the extracted elements. See +allocated/release patterns for details on safe ways to use +this.

Repeated String Fields

Repeated fields of strings have the same new methods and modified semantics as +repeated fields of messages, because they also maintain their underlying objects +(namely, strings) by pointer reference.

Usage Patterns and Best Practices

When using arena-allocated messages, several usage patterns can result in +unintended copies or other negative performance effects. You should be aware of +the following common patterns that may need to be altered when adapting code for +arenas. (Note that we have taken care in the API design to ensure that correct +behavior still occurs — but higher-performance solutions may require some +reworking.)

Unintended Copies

Several methods that never create object copies when not using arena allocation +may end up doing so when arena support is enabled. These unwanted copies can be +avoided if you make sure that your objects are allocated appropriately and/or +use provided arena-specific method versions, as described in more detail below.

Set Allocated/Add Allocated/Release

By default, the release_field() and set_allocated_field() methods (for +singular message fields), and the ReleaseLast() and AddAllocated() methods +(for repeated message fields) allow user code to directly attach and detach +submessages, passing ownership of pointers without copying any data.

However, when the parent message is on an arena, these methods now sometimes +need to copy the passed in or returned object to maintain compatibility with +existing ownership contracts. More specifically, methods that take ownership +(set_allocated_field() and AddAllocated()) may copy data if the parent is on +an arena and the new subobject is not, or vice versa, or they are on different +arenas. Methods that release ownership (release_field() and ReleaseLast()) +may copy data if the parent is on the arena, because the returned object must be +on the heap, by contract.

To avoid such copies, we have added corresponding “unsafe arena” versions of +these methods where copies are never performed: +unsafe_arena_set_allocated_field(), unsafe_arena_release_field(), +UnsafeArenaAddAllocated(), and UnsafeArenaRelease() for singular and +repeated fields, respectively. These methods should be used only when you know +they are safe to do so. There are two common patterns for these methods:

  • Moving messages trees between parts of the same arena. Note that the +messages must be on the same arena for this case to be safe.
  • Temporarily loaning an owned message to a tree to avoid copies. Pairing an +unsafe add/set method with an unsafe release method performs the loan +in the cheapest way possible regardless of how either message is owned (this +pattern works when they are on the same arena, different arena, or no arena +at all). Note that between the unsafe add/set and its corresponding +release, the borrower must not be swapped, moved, cleared or destroyed; +the loaned message must not be swapped or moved; the loaned message must not +be cleared or released by the borrower; and the loaned message must not be +destroyed.

Here’s an example of how you can avoid unnecessary copies with these methods. +Let’s say you have created the following messages on an arena.

Arena* arena = new google::protobuf::Arena();
+MyFeatureMessage* arena_message_1 =
+  google::protobuf::Arena::Create<MyFeatureMessage>(arena);
+arena_message_1->mutable_nested_message()->set_feature_id(11);
+
+MyFeatureMessage* arena_message_2 =
+  google::protobuf::Arena::Create<MyFeatureMessage>(arena);
+

The following code makes inefficient usage of the release_...() API:

arena_message_2->set_allocated_nested_message(arena_message_1->release_nested_message());
+
+arena_message_1->release_message(); // returns a copy of the underlying nested_message and deletes underlying pointer
+

Using the “unsafe arena” version instead avoids the copy:

arena_message_2->unsafe_arena_set_allocated_nested_message(
+   arena_message_1->unsafe_arena_release_nested_message());
+

You can find out more about these methods in the +Embedded message fields section above.

Swap

When two messages’ contents are swapped with Swap(), the underlying subobjects +may be copied if the two messages live on different arenas, or if one is on the +arena and the other is on the heap. If you want to avoid this copy and either +(i) know that the two messages are on the same arena or different arenas but the +arenas have equivalent lifetimes, or (ii) know that the two messages are on the +heap, you can use a new method, UnsafeArenaSwap(). This method both avoids the +overhead of performing the arena check and avoids the copy if one would have +occurred.

For example, the following code incurs a copy in the Swap() call:

MyFeatureMessage* message_1 =
+  google::protobuf::Arena::Create<MyFeatureMessage>(arena);
+message_1->mutable_nested_message()->set_feature_id(11);
+
+MyFeatureMessage* message_2 = new MyFeatureMessage;
+message_2->mutable_nested_message()->set_feature_id(22);
+
+message_1->Swap(message_2); // Inefficient swap!
+

To avoid the copy in this code, you allocate message_2 on the same arena as +message_1:

MyFeatureMessage* message_2 =
+   google::protobuf::Arena::Create<MyFeatureMessage>(arena);
+

Granularity

We have found in most application server use cases that an “arena-per-request” +model works well. You may be tempted to divide arena use further, either to +reduce heap overhead (by destroying smaller arenas more often) or to reduce +perceived thread-contention issues. However, the use of more fine-grained arenas +may lead to unintended message copying, as we describe above. We have also spent +effort to optimize the Arena implementation for the multithreaded use-case, so +a single arena should be appropriate for use throughout a request lifetime even +if multiple threads process that request.

Example

Here’s a simple complete example demonstrating some of the features of the arena +allocation API.

// my_feature.proto
+edition = "2023";
+
+import "nested_message.proto";
+
+package feature_package;
+
+// NEXT Tag to use: 4
+message MyFeatureMessage {
+  string feature_name = 1;
+  repeated int32 feature_data = 2;
+  NestedMessage nested_message = 3;
+};
+
// nested_message.proto
+edition = "2023";
+
+package feature_package;
+
+// NEXT Tag to use: 2
+message NestedMessage {
+  int32 feature_id = 1;
+};
+

Message construction and deallocation:

#include <google/protobuf/arena.h>
+
+Arena arena;
+
+MyFeatureMessage* arena_message =
+   google::protobuf::Arena::Create<MyFeatureMessage>(&arena);
+
+arena_message->set_feature_name("Editions Arena");
+arena_message->mutable_feature_data()->Add(2);
+arena_message->mutable_feature_data()->Add(4);
+arena_message->mutable_nested_message()->set_feature_id(247);
+

  1. Currently, string fields store their data on the heap even when the +containing message is on the arena. Unknown fields are also +heap-allocated. ↩︎

  2. What it takes to be a “fully compatible” type is internal to the +protobuf library, and should not be assumed to be reliable. ↩︎

\ No newline at end of file diff --git a/reference/cpp/cpp-generated/index.html b/reference/cpp/cpp-generated/index.html new file mode 100644 index 000000000..3d761c912 --- /dev/null +++ b/reference/cpp/cpp-generated/index.html @@ -0,0 +1,705 @@ +C++ Generated Code Guide | Protocol Buffers Documentation +

C++ Generated Code Guide

Describes exactly what C++ code the protocol buffer compiler generates for any given protocol definition.

Any differences between proto2, proto3, and editions generated code are +highlighted. Note that these differences are in the generated code as described +in this document, not the base message classes/interfaces, which are the same in +all versions. You should read the +proto2 language guide, +proto3 language guide, or +edition 2023 language guide +before reading this document.

Compiler Invocation

The protocol buffer compiler produces C++ output when invoked with the +--cpp_out= command-line flag. The parameter to the --cpp_out= option is the +directory where you want the compiler to write your C++ output. The compiler +creates a header file and an implementation file for each .proto file input. +The names of the output files are computed by taking the name of the .proto +file and making two changes:

  • The extension (.proto) is replaced with either .pb.h or .pb.cc for the +header or implementation file, respectively.
  • The proto path (specified with the --proto_path= or -I command-line +flag) is replaced with the output path (specified with the --cpp_out= +flag).

So, for example, let’s say you invoke the compiler as follows:

protoc --proto_path=src --cpp_out=build/gen src/foo.proto src/bar/baz.proto
+

The compiler will read the files src/foo.proto and src/bar/baz.proto and +produce four output files: build/gen/foo.pb.h, build/gen/foo.pb.cc, +build/gen/bar/baz.pb.h, build/gen/bar/baz.pb.cc. The compiler will +automatically create the directory build/gen/bar if necessary, but it will +not create build or build/gen; they must already exist.

Packages

If a .proto file contains a package declaration, the entire contents of the +file will be placed in a corresponding C++ namespace. For example, given the +package declaration:

package foo.bar;
+

All declarations in the file will reside in the foo::bar namespace.

Messages

Given a simple message declaration:

message Foo {}
+

The protocol buffer compiler generates a class called Foo, which publicly +derives from +google::protobuf::Message. +The class is a concrete class; no pure-virtual methods are left unimplemented. +Methods that are virtual in Message but not pure-virtual may or may not be +overridden by Foo, depending on the optimization mode. By default, Foo +implements specialized versions of all methods for maximum speed. However, if +the .proto file contains the line:

option optimize_for = CODE_SIZE;
+

then Foo will override only the minimum set of methods necessary to function +and rely on reflection-based implementations of the rest. This significantly +reduces the size of the generated code, but also reduces performance. +Alternatively, if the .proto file contains:

option optimize_for = LITE_RUNTIME;
+

then Foo will include fast implementations of all methods, but will implement +the +google::protobuf::MessageLite +interface, which only contains a subset of the methods of Message. In +particular, it does not support descriptors or reflection. However, in this +mode, the generated code only needs to link against libprotobuf-lite.so +(libprotobuf-lite.lib on Windows) instead of libprotobuf.so +(libprotobuf.lib). The “lite” library is much smaller than the full library, +and is more appropriate for resource-constrained systems such as mobile phones.

You should not create your own Foo subclasses. If you subclass this class +and override a virtual method, the override may be ignored, as many generated +method calls are de-virtualized to improve performance.

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(::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 +representation of the proto (should only be used for debugging).

In addition to these methods, the Foo class defines the following methods:

  • Foo(): Default constructor.
  • ~Foo(): Default destructor.
  • Foo(const Foo& other): Copy constructor.
  • Foo(Foo&& other): Move constructor.
  • Foo& operator=(const Foo& other): Assignment operator.
  • Foo& operator=(Foo&& other): Move-assignment operator.
  • void Swap(Foo* other): Swap content with another message.
  • const UnknownFieldSet& unknown_fields() const: Returns the set of unknown +fields encountered while parsing this message. If option optimize_for = LITE_RUNTIME is specified in the .proto file, then the return type +changes to std::string&.
  • UnknownFieldSet* mutable_unknown_fields(): Returns a pointer to the +mutable set of unknown fields encountered while parsing this message. If +option optimize_for = LITE_RUNTIME is specified in the .proto file, then +the return type changes to std::string*.

Note: The copy constructor and assignment operator perform a deep copy of +the message data. This ensures that each message object owns and manages its own +copy of the data, preventing issues like double frees or use-after-free errors. +This behavior is consistent with standard C++ practice for objects that own +their data, such as std::vector. For developers coming from languages with +different copy semantics (such as JavaScript or TypeScript, where shallow copies +might be more common), it is important to note that modifications to a copied +message will not affect the original message, and vice-versa.

The class also defines the following static methods:

  • static const Descriptor* descriptor(): Returns the type’s descriptor. This +contains information about the type, including what fields it has and what +their types are. This can be used with +reflection +to inspect fields programmatically.
  • static const Foo& default_instance(): Returns a const singleton instance +of Foo which is identical to a newly-constructed instance of Foo (so all +singular fields are unset and all repeated fields are empty). Note that the +default instance of a message can be used as a factory by calling its +New() method.

Abseil flag support

Message objects have native support for Abseil’s flag parse/unparse logic. +They can be used as the type for ABSL_FLAG declarations. The flag syntax is +:format,options...:value where:

  • format is one of text, serialized.
  • options is a possibly-empty list of options. Each format has its supported +options.
  • value is the payload in the specified format.

The valid options are:

  • For text:
    • base64: indicates that value is encoded as base64.
    • ignore_unknown: when specified, unknown field/extensions are dropped. +Otherwise, they cause a parse failure.
  • For serialized:
    • base64: indicates that value is encoded as base64. It is recommended +to use serialized with base64 given that passing binary data in +shells is difficult and error prone.

Note that flag support for message types is not provided for LITE_RUNTIME +configurations.

Example:

ABSL_FLAG(MyProtoType, my_proto_config, {},
+          "This is a proto config description.");
+

Nested Types

A message can be declared inside another message. For example:

message Foo {
+  message Bar {}
+}
+

In this case, the compiler generates two classes: Foo and Foo_Bar. In +addition, the compiler generates a typedef inside Foo as follows:

typedef Foo_Bar Bar;
+

This means that you can use the nested type’s class as if it was the nested +class Foo::Bar. However, note that C++ does not allow nested types to be +forward-declared. If you want to forward-declare Bar in another file and use +that declaration, you must identify it as Foo_Bar.

Fields

In addition to the methods described in the previous section, the protocol +buffer compiler generates a set of accessor methods for each field defined +within the message in the .proto file. These methods are in +lower-case/snake-case, such as has_foo() and clear_foo().

As well as accessor methods, the compiler generates an integer constant for each +field containing its field number. The constant name is the letter k, followed +by the field name converted to camel-case, followed by FieldNumber. For +example, given the field optional int32 foo_bar = 5;, the compiler will +generate the constant static const int kFooBarFieldNumber = 5;.

For field accessors returning a const reference, that reference may be +invalidated when the next modifying access is made to the message. This includes +calling any non-const accessor of any field, calling any non-const method +inherited from Message or modifying the message through other ways (for +example, by using the message as the argument of Swap()). Correspondingly, the +address of the returned reference is only guaranteed to be the same across +different invocations of the accessor if no modifying access was made to the +message in the meantime.

For field accessors returning a pointer, that pointer may be invalidated when +the next modifying or non-modifying access is made to the message. This +includes, regardless of constness, calling any accessor of any field, calling +any method inherited from Message or accessing the message through other ways +(for example, by copying the message using the copy constructor). +Correspondingly, the value of the returned pointer is never guaranteed to be the +same across two different invocations of the accessor.

Generated Fieldnames

Reserved keywords +are appended with an underscore in the generated output.

For example, the following proto3 definition syntax:

message MyMessage {
+  string false = 1;
+  string myFalse = 2;
+}
+

generates the following partial output:

  void clear_false_() ;
+  const std::string& false_() const;
+  void set_false_(Arg_&& arg, Args_... args);
+  std::string* mutable_false_();
+  PROTOBUF_NODISCARD std::string* release_false_();
+  void set_allocated_false_(std::string* ptr);
+
+  void clear_myfalse() ;
+  const std::string& myfalse() const;
+  void set_myfalse(Arg_&& arg, Args_... args);
+  std::string* mutable_myfalse();
+  PROTOBUF_NODISCARD std::string* release_myfalse();
+  void set_allocated_myfalse(std::string* ptr);
+

Explicit Presence Numeric Fields

For field definitions for numeric fields with +explicit presence:

int32 foo = 1;
+

The compiler will generate the following accessor methods:

  • bool has_foo() const: Returns true if the field is set.
  • int32_t foo() const: Returns the current value of the field. If the field +is not set, returns the default value.
  • void set_foo(::int32_t value): Sets the value of the field. After calling +this, has_foo() will return true and foo() will return value.
  • void clear_foo(): Clears the value of the field. After calling this, +has_foo() will return false and foo() will return the default value.

For other numeric field types (including bool), int32_t is replaced with the +corresponding C++ type according to the +scalar value types table.

Implicit Presence Numeric Fields

For field definitions for numeric fields with +implicit presence:

int32 foo = 1;
+

The compiler will generate the following accessor methods:

  • ::int32_t foo() const: Returns the current value of the field. If the +field is not set, returns 0.
  • void set_foo(::int32_t value): Sets the value of the field. After calling +this, foo() will return value.
  • void clear_foo(): Clears the value of the field. After calling this, +foo() will return 0.

For other numeric field types (including bool), int32_t is replaced with the +corresponding C++ type according to the +scalar value types table.

Explicit Presence String/Bytes Fields

Note: As of edition 2023, if +features.(pb.cpp).string_type +is set to VIEW, +string_view +APIs will be generated instead.

For these field definitions with +explicit presence:

string foo = 1;
+bytes foo = 2;
+

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(...): Sets the value of the field. 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 +calling this, has_foo() will return true and foo() will return +whatever value is written into the given string.

    Note: This method will be removed in the new string_view APIs.

  • void clear_foo(): Clears the value of the field. After calling this, +has_foo() will return false and foo() will return the default value.

  • void set_allocated_foo(string* value): +Sets the string +object to the field and frees the previous field value if it exists. If the +string pointer is not NULL, the message takes ownership of the allocated +string object and has_foo() will return true. The message is free to +delete the allocated string object at any time, so references to the +object may be invalidated. Otherwise, if the value is NULL, the behavior +is the same as calling clear_foo().

  • string* release_foo(): +Releases the +ownership of the field and returns the pointer of the string object. After +calling this, caller takes the ownership of the allocated string object, +has_foo() will return false, and foo() will return the default value.

Implicit Presence String/Bytes Fields

Note: As of edition 2023, if +features.(pb.cpp).string_type +is set to VIEW, +string_view +APIs will be generated instead.

For these field definitions with +implicit presence:

string foo = 1 [features.field_presence = IMPLICIT];
+bytes foo = 1 [features.field_presence = IMPLICIT];
+

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(Arg_&& arg, Args_... args): Sets the value of the field. +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 +return whatever value is written into the given string.
  • void clear_foo(): Clears the value of the field. After calling this, +foo() will return the empty string/empty bytes.
  • void set_allocated_foo(string* value): +Sets the string +object to the field and frees the previous field value if it exists. If the +string pointer is not NULL, the message takes ownership of the allocated +string object. The message is free to delete the allocated string object +at any time, so references to the object may be invalidated. Otherwise, if +the value is NULL, the behavior is the same as calling clear_foo().
  • string* release_foo(): +Releases the +ownership of the field and returns the pointer of the string object. After +calling this, caller takes the ownership of the allocated string object +and foo() will return the empty string/empty bytes.

Singular Bytes Fields with Cord Support

v23.0 added support for +absl::Cord +for singular bytes fields (including +oneof fields). Singular string, repeated string, and repeated bytes fields do not support using Cords.

To set a singular bytes field to store data using absl::Cord, use the +following syntax:

// edition (default settings)
+bytes foo = 25 [ctype=CORD];
+bytes foo = 26 [ctype=CORD, features.field_presence = IMPLICIT];
+

Using cord is not available for repeated bytes fields. Protoc ignores +[ctype=CORD] settings on those fields.

The compiler will generate the following accessor methods:

  • const ::absl::Cord& foo() const: Returns the current value of the field. +If the field is not set, returns an empty Cord (proto3) or the default +value (proto2 and editions).
  • void set_foo(const ::absl::Cord& value): Sets the value of the field. +After calling this, foo() will return value.
  • void set_foo(::absl::string_view value): Sets the value of the field. +After calling this, foo() will return value as an absl::Cord.
  • void clear_foo(): Clears the value of the field. After calling this, +foo() will return an empty Cord (proto3) or the default value (proto2 +and editions).
  • bool has_foo(): Returns true if the field is set. Only applies for the +optional field in proto3 and the explicit presence field in editions.

Explicit Presence Enum Fields

Given the enum type:

enum Bar {
+  BAR_UNSPECIFIED = 0;
+  BAR_VALUE = 1;
+  BAR_OTHER_VALUE = 2;
+}
+

For this field definition with +explicit presence:

Bar bar = 1;
+

The compiler will generate the following accessor methods:

  • bool has_bar() const: Returns true if the field is set.
  • Bar bar() const: Returns the current value of the field. If the field is +not set, returns the default value.
  • void set_bar(Bar value): Sets the value of the field. After calling this, +has_bar() will return true and bar() will return value. In debug +mode (i.e. NDEBUG is not defined), if value does not match any of the +values defined for Bar, this method will abort the process.
  • void clear_bar(): Clears the value of the field. After calling this, +has_bar() will return false and bar() will return the default value.

Implicit Presence Enum Fields

Given the enum type:

enum Bar {
+  BAR_UNSPECIFIED = 0;
+  BAR_VALUE = 1;
+  BAR_OTHER_VALUE = 2;
+}
+

For this field definition with +implicit presence:

Bar bar = 1;
+

The compiler will generate the following accessor methods:

  • Bar bar() const: Returns the current value of the field. If the field is +not set, returns the default value (0).
  • void set_bar(Bar value): Sets the value of the field. After calling this, +bar() will return value.
  • void clear_bar(): Clears the value of the field. After calling this, +bar() will return the default value.

Explicit Presence Embedded Message Fields

Given the message type:

message Bar {}
+

For this field definition with +explicit presence:

Bar bar = 1;
+

The compiler will generate the following accessor methods:

  • bool has_bar() const: Returns true if the field is set.
  • const Bar& bar() const: Returns the current value of the field. If the +field is not set, returns a Bar with none of its fields set (possibly +Bar::default_instance()).
  • Bar* mutable_bar(): Returns a pointer to the mutable Bar object that +stores the field’s value. If the field was not set prior to the call, then +the returned Bar will have none of its fields set (i.e. it will be +identical to a newly-allocated Bar). After calling this, has_bar() will +return true and bar() will return a reference to the same instance of +Bar.
  • void clear_bar(): Clears the value of the field. After calling this, +has_bar() will return false and bar() will return the default value.
  • void set_allocated_bar(Bar* value): Sets the Bar object to the field and +frees the previous field value if it exists. If the Bar pointer is not +NULL, the message takes ownership of the allocated Bar object and +has_bar() will return true. Otherwise, if the Bar is NULL, the +behavior is the same as calling clear_bar().
  • Bar* release_bar(): Releases the ownership of the field and returns the +pointer of the Bar object. After calling this, caller takes the ownership +of the allocated Bar object, has_bar() will return false, and bar() +will return the default value.

Repeated Numeric Fields

For this field definition:

repeated int32 foo = 1;
+

The compiler will generate the following accessor methods:

  • int foo_size() const: Returns the number of elements currently in the +field. To check for an empty set, consider using the +empty() +method in the underlying RepeatedField instead of this method.
  • int32_t foo(int index) const: Returns the element at the given zero-based +index. Calling this method with index outside of [0, foo_size()) yields +undefined behavior.
  • void set_foo(int index, int32_t value): Sets the value of the element at +the given zero-based index.
  • void add_foo(int32_t value): Appends a new element to the end of the field +with the given value.
  • void clear_foo(): Removes all elements from the field. After calling this, +foo_size() will return zero.
  • const RepeatedField<int32_t>& foo() const: Returns the underlying +RepeatedField +that stores the field’s elements. This container class provides STL-like +iterators and other methods.
  • RepeatedField<int32_t>* mutable_foo(): Returns a pointer to the underlying +mutable RepeatedField that stores the field’s elements. This container +class provides STL-like iterators and other methods.

For other numeric field types (including bool), int32_t is replaced with the +corresponding C++ type according to the +scalar value types table.

Repeated String Fields

Note: As of edition 2023, if +features.(pb.cpp).string_type +is set to VIEW, +string_view +APIs will be generated instead.

For either of these field definitions:

repeated string foo = 1;
+repeated bytes foo = 1;
+

The compiler will generate the following accessor methods:

  • int foo_size() const: Returns the number of elements currently in the +field. To check for an empty set, consider using the +empty() +method in the underlying RepeatedField instead of this method.
  • 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): 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 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 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, +foo_size() will return zero.
  • const RepeatedPtrField<string>& foo() const: Returns the underlying +RepeatedPtrField +that stores the field’s elements. This container class provides STL-like +iterators and other methods.
  • RepeatedPtrField<string>* 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.

Repeated Enum Fields

Given the enum type:

enum Bar {
+  BAR_UNSPECIFIED = 0;
+  BAR_VALUE = 1;
+  BAR_OTHER_VALUE = 2;
+}
+

For this field definition:

repeated Bar bar = 1;
+

The compiler will generate the following accessor methods:

  • int bar_size() const: Returns the number of elements currently in the +field. To check for an empty set, consider using the +empty() +method in the underlying RepeatedField instead of this method.
  • Bar bar(int index) const: Returns the element at the given zero-based +index. Calling this method with index outside of [0, bar_size()) yields +undefined behavior.
  • void set_bar(int index, Bar value): Sets the value of the element at the +given zero-based index. In debug mode (i.e. NDEBUG is not defined), if +value does not match any of the values defined for Bar and it is a +closed enum, this method will abort the process.
  • void add_bar(Bar value): Appends a new element to the end of the field +with the given value. In debug mode (i.e. NDEBUG is not defined), if value +does not match any of the values defined for Bar, this method will abort +the process.
  • void clear_bar(): Removes all elements from the field. After calling this, +bar_size() will return zero.
  • const RepeatedField<int>& bar() const: Returns the underlying +RepeatedField +that stores the field’s elements. This container class provides STL-like +iterators and other methods.
  • RepeatedField<int>* mutable_bar(): Returns a pointer to the underlying +mutable RepeatedField that stores the field’s elements. This container +class provides STL-like iterators and other methods.

Repeated Embedded Message Fields

Given the message type:

message Bar {}
+

For this field definitions:

repeated Bar bar = 1;
+

The compiler will generate the following accessor methods:

  • int bar_size() const: Returns the number of elements currently in the +field. To check for an empty set, consider using the +empty() +method in the underlying RepeatedField instead of this method.
  • const Bar& bar(int index) const: Returns the element at the given +zero-based index. Calling this method with index outside of [0, bar_size()) +yields undefined behavior.
  • Bar* mutable_bar(int index): Returns a pointer to the mutable Bar object +that stores the value of the element at the given zero-based index. Calling +this method with index outside of [0, bar_size()) yields undefined behavior.
  • Bar* add_bar(): Adds a new element to the end of the field and returns a +pointer to it. The returned Bar is mutable and will have none of its +fields set (i.e. it will be identical to a newly-allocated Bar).
  • void clear_bar(): Removes all elements from the field. After calling this, +bar_size() will return zero.
  • const RepeatedPtrField<Bar>& bar() const: Returns the underlying +RepeatedPtrField +that stores the field’s elements. This container class provides STL-like +iterators and other methods.
  • RepeatedPtrField<Bar>* mutable_bar(): Returns a pointer to the underlying +mutable RepeatedPtrField that stores the field’s elements. This container +class provides STL-like iterators and other methods.

Oneof Numeric Fields

For this oneof field definition:

oneof example_name {
+    int32 foo = 1;
+    ...
+}
+

The compiler will generate the following accessor methods:

  • bool has_foo() const: Returns true if oneof case is kFoo.
  • int32 foo() const: Returns the current value of the field if oneof case is +kFoo. Otherwise, returns the default value.
  • void set_foo(int32 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 value, and +example_name_case() will return kFoo.
  • void clear_foo():
    • Nothing will be changed if oneof case is not kFoo.
    • If oneof case is kFoo, clears the value of the field and oneof case. +has_foo() will return false, foo() will return the default value +and example_name_case() will return EXAMPLE_NAME_NOT_SET.

For other numeric field types (including bool),int32_t is replaced with the +corresponding C++ type according to the +scalar value types table.

Oneof String Fields

Note: As of edition 2023, +string_view APIs +may be generated instead.

For any of these oneof field definitions:

oneof example_name {
+    string foo = 1;
+    ...
+}
+oneof example_name {
+    bytes foo = 1;
+    ...
+}
+

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(::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 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().
    • Sets the oneof case to kFoo and returns a pointer to the mutable +string object that stores the field’s value. If the oneof case was not +kFoo prior to the call, then the returned string will be empty (not +the default value).
    • has_foo() will return true, foo() will return whatever value is +written into the given string and example_name_case() will return +kFoo.
  • 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.
  • void set_allocated_foo(string* value):
    • Calls clear_example_name().
    • If the string pointer is not NULL: Sets the string object to the field +and sets the oneof case to kFoo. The message takes ownership of the +allocated string object, has_foo() will return true and +example_name_case() will return kFoo.
    • If the string pointer is NULL, has_foo() will return false and +example_name_case() will return EXAMPLE_NAME_NOT_SET.
  • string* release_foo():
    • Returns NULL if oneof case is not kFoo.
    • Clears the oneof case, releases the ownership of the field, and returns +the pointer of the string object. After calling this, caller takes the +ownership of the allocated string object, has_foo() will return false, +foo() will return the default value, and example_name_case() will +return EXAMPLE_NAME_NOT_SET.

Oneof Enum Fields

Given the enum type:

enum Bar {
+  BAR_UNSPECIFIED = 0;
+  BAR_VALUE = 1;
+  BAR_OTHER_VALUE = 2;
+}
+

For the oneof field definition:

oneof example_name {
+    Bar bar = 1;
+    ...
+}
+

The compiler will generate the following accessor methods:

  • bool has_bar() const: Returns true if oneof case is kBar.
  • Bar bar() const: Returns the current value of the field if oneof case is +kBar. Otherwise, returns the default value.
  • void set_bar(Bar 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 kBar.
    • has_bar() will return true, bar() will return value and +example_name_case() will return kBar.
    • In debug mode (that is, NDEBUG is not defined), if value does not +match any of the values defined for Bar and it is a closed enum, this +method will abort the process.
  • void clear_bar():
    • Nothing will be changed if the oneof case is not kBar.
    • If the oneof case is kBar, clears the value of the field and the oneof +case. has_bar() will return false, bar() will return the default +value and example_name_case() will return EXAMPLE_NAME_NOT_SET.

Oneof Embedded Message Fields

Given the message type:

message Bar {}
+

For the oneof field definition:

oneof example_name {
+    Bar bar = 1;
+    ...
+}
+

The compiler will generate the following accessor methods:

  • bool has_bar() const: Returns true if oneof case is kBar.
  • const Bar& bar() const: Returns the current value of the field if oneof +case is kBar. Otherwise, returns a Bar with none of its fields set +(possibly Bar::default_instance()).
  • Bar* mutable_bar():
    • If any other oneof field in the same oneof is set, calls +clear_example_name().
    • Sets the oneof case to kBar and returns a pointer to the mutable Bar +object that stores the field’s value. If the oneof case was not kBar +prior to the call, then the returned Bar will have none of its fields +set (that is, it will be identical to a newly-allocated Bar).
    • After calling this, has_bar() will return true, bar() will return +a reference to the same instance of Bar and example_name_case() will +return kBar.
  • void clear_bar():
    • Nothing will be changed if the oneof case is not kBar.
    • If the oneof case equals kBar, frees the field and clears the oneof +case. has_bar() will return false, bar() will return the default +value and example_name_case() will return EXAMPLE_NAME_NOT_SET.
  • void set_allocated_bar(Bar* bar):
    • Calls clear_example_name().
    • If the Bar pointer is not NULL: Sets the Bar object to the field +and sets the oneof case to kBar. The message takes ownership of the +allocated Bar object, has_bar() will return true and +example_name_case() will return kBar.
    • If the pointer is NULL, has_bar() will return false and +example_name_case() will return EXAMPLE_NAME_NOT_SET. (The behavior +is like calling clear_example_name())
  • Bar* release_bar():
    • Returns NULL if oneof case is not kBar.
    • If the oneof case is kBar, clears the oneof case, releases the +ownership of the field and returns the pointer of the Bar object. +After calling this, caller takes the ownership of the allocated Bar +object, has_bar() will return false, bar() will return the default +value, and example_name_case() will return EXAMPLE_NAME_NOT_SET.

Map Fields

For this map field definition:

map<int32, int32> weight = 1;
+

The compiler will generate the following accessor methods:

  • const google::protobuf::Map<int32, int32>& weight();: Returns an immutable +Map.
  • google::protobuf::Map<int32, int32>* mutable_weight();: Returns a mutable +Map.

A +google::protobuf::Map +is a special container type used in protocol buffers to store map fields. As you +can see from its interface below, it uses a commonly-used subset of std::map +and std::unordered_map methods.

template<typename Key, typename T> {
+class Map {
+  // Member types
+  typedef Key key_type;
+  typedef T mapped_type;
+  typedef MapPair< Key, T > value_type;
+
+  // Iterators
+  iterator begin();
+  const_iterator begin() const;
+  const_iterator cbegin() const;
+  iterator end();
+  const_iterator end() const;
+  const_iterator cend() const;
+  // Capacity
+  int size() const;
+  bool empty() const;
+
+  // Element access
+  T& operator[](const Key& key);
+  const T& at(const Key& key) const;
+  T& at(const Key& key);
+
+  // Lookup
+  bool contains(const Key& key) const;
+  int count(const Key& key) const;
+  const_iterator find(const Key& key) const;
+  iterator find(const Key& key);
+
+  // Modifiers
+  pair<iterator, bool> insert(const value_type& value);
+  template<class InputIt>
+  void insert(InputIt first, InputIt last);
+  size_type erase(const Key& Key);
+  iterator erase(const_iterator pos);
+  iterator erase(const_iterator first, const_iterator last);
+  void clear();
+
+  // Copy
+  Map(const Map& other);
+  Map& operator=(const Map& other);
+}
+

The easiest way to add data is to use normal map syntax, for example:

std::unique_ptr<ProtoName> my_enclosing_proto(new ProtoName);
+(*my_enclosing_proto->mutable_weight())[my_key] = my_value;
+

pair<iterator, bool> insert(const value_type& value) will implicitly cause a +deep copy of the value_type instance. The most efficient way to insert a new +value into a google::protobuf::Map is as follows:

T& operator[](const Key& key): map[new_key] = new_mapped;
+

Using google::protobuf::Map with standard maps

google::protobuf::Map supports the same iterator API as std::map and +std::unordered_map. If you don’t want to use google::protobuf::Map directly, +you can convert a google::protobuf::Map to a standard map by doing the +following:

std::map<int32, int32> standard_map(message.weight().begin(),
+                                    message.weight().end());
+

Note that this will make a deep copy of the entire map.

You can also construct a google::protobuf::Map from a standard map as follows:

google::protobuf::Map<int32, int32> weight(standard_map.begin(), standard_map.end());
+

Parsing unknown values

On the wire, a .proto map is equivalent to a map entry message for each +key/value pair, while the map itself is a repeated field of map entries. Like +ordinary message types, it’s possible for a parsed map entry message to have +unknown fields: for example a field of type int64 in a map defined as +map<int32, string>.

If there are unknown fields in the wire format of a map entry message, they will +be discarded.

If there is an unknown enum value in the wire format of a map entry message, +it’s handled differently in proto2, proto3, and editions. In proto2, the whole +map entry message is put into the unknown field set of the containing message. +In proto3, it is put into a map field as if it is a known enum value. With +editions, by default it mirrors the proto3 behavior. If features.enum_type is +set to CLOSED, then it mirrors the proto2 behavior.

Any

Given an Any field +like this:

import "google/protobuf/any.proto";
+
+message ErrorStatus {
+  string message = 1;
+  google.protobuf.Any details = 2;
+}
+

In our generated code, the getter for the details field returns an instance of +google::protobuf::Any. This provides the following special methods to pack and +unpack the Any’s values:

class Any {
+ public:
+  // Packs the given message into this Any using the default type URL
+  // prefix “type.googleapis.com”. Returns false if serializing the message failed.
+  bool PackFrom(const google::protobuf::Message& message);
+
+  // 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,
+                ::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.
+  bool UnpackTo(google::protobuf::Message* message) const;
+
+  // Returns true if this Any represents the given protobuf type.
+  template<typename T> bool Is() const;
+}
+

Oneof

Given a oneof definition like this:

oneof example_name {
+    int32 foo_int = 4;
+    string foo_string = 9;
+    ...
+}
+

The compiler will generate the following C++ enum type:

enum ExampleNameCase {
+  kFooInt = 4,
+  kFooString = 9,
+  EXAMPLE_NAME_NOT_SET = 0
+}
+

In addition, it will generate these methods:

  • ExampleNameCase example_name_case() const: Returns the enum indicating +which field is set. Returns EXAMPLE_NAME_NOT_SET if none of them is set.
  • void clear_example_name(): Frees the object if the oneof field set uses a +pointer (Message or String), and sets the oneof case to +EXAMPLE_NAME_NOT_SET.

Enumerations

Note: As of edition 2024, string_view APIs may be generated with certain +feature settings. See +Enumeration Name Helper +for more on this topic.

Given an enum definition like:

enum Foo {
+  VALUE_A = 0;
+  VALUE_B = 5;
+  VALUE_C = 1234;
+}
+

The protocol buffer compiler will generate a C++ enum type called Foo with the +same set of values. In addition, the compiler will generate the following +functions:

  • const EnumDescriptor* Foo_descriptor(): Returns the type’s descriptor, +which contains information about what values this enum type defines.
  • bool Foo_IsValid(int value): Returns true if the given numeric value +matches one of Foo’s defined values. In the above example, it would return +true if the input were 0, 5, or 1234.
  • const string& 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".
  • 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 +example).
  • const Foo Foo_MAX: the largest valid value of the enum (VALUE_C in the +example).
  • const int Foo_ARRAYSIZE: always defined as Foo_MAX + 1.

Be careful when casting integers to proto2 enums. If an integer is cast to a +proto2 enum value, the integer must be one of the valid values for that enum, +or the results may be undefined. If in doubt, use the generated Foo_IsValid() +function to test if the cast is valid. Setting an enum-typed field of a proto2 +message to an invalid value may cause an assertion failure. If an invalid enum +value is read when parsing a proto2 message, it will be treated as an +unknown field. +These semantics have been changed in proto3. It’s safe to cast any integer to a +proto3 enum value as long as it fits into int32. Invalid enum values will also +be kept when parsing a proto3 message and returned by enum field accessors.

Be careful when using proto3 and editions enums in switch statements. Proto3 +and editions enums are open enum types with possible values outside the range of +specified symbols. (Editions enums may be set to closed enums using the +enum_type feature.) +Unrecognized enum values for open enums types will be kept when parsing a +message and returned by the enum field accessors. A switch statement on an open +enum without a default case will not be able to catch all cases, even if all the +known fields are listed. This could lead to unexpected behavior, including data +corruption and runtime crashes. Always add a default case or explicitly call +Foo_IsValid(int) outside of the switch to handle unknown enum values.

You can define an enum inside a message type. In this case, the protocol buffer +compiler generates code that makes it appear that the enum type itself was +declared nested inside the message’s class. The Foo_descriptor() and +Foo_IsValid() functions are declared as static methods. In reality, the enum +type itself and its values are declared at the global scope with mangled names, +and are imported into the class’s scope with a typedef and a series of +constant definitions. This is done only to get around problems with declaration +ordering. Do not depend on the mangled top-level names; pretend the enum really +is nested in the message class.

Abseil flag support

Generated enum values have native support for Abseil’s flag parse/unparse +logic. They can be used as the type for ABSL_FLAG declarations.

The flag parser supports both labels and numbers. Labels can be lowercase, if +they are unambiguous. Invalid labels/numbers will cause a parse failure.

Extensions (proto2 and editions only)

Given a message with an extension range:

message Foo {
+  extensions 100 to 199;
+}
+

The protocol buffer compiler will generate some additional methods for Foo: +HasExtension(), ExtensionSize(), ClearExtension(), GetExtension(), +SetExtension(), MutableExtension(), AddExtension(), +SetAllocatedExtension() and ReleaseExtension(). Each of these methods takes, +as its first parameter, an extension identifier (described later in this +section), which identifies an extension field. The remaining parameters and the +return value are exactly the same as those for the corresponding accessor +methods that would be generated for a normal (non-extension) field of the same +type as the extension identifier. (GetExtension() corresponds to the accessors +with no special prefix.)

Given an extension definition:

extend Foo {
+  optional int32 bar = 123;
+  repeated int32 repeated_bar = 124;
+  optional Bar message_bar = 125;
+}
+

For the singular extension field bar, the protocol buffer compiler generates +an “extension identifier” called bar, which you can use with Foo’s extension +accessors to access this extension, like so:

Foo foo;
+assert(!foo.HasExtension(bar));
+foo.SetExtension(bar, 1);
+assert(foo.HasExtension(bar));
+assert(foo.GetExtension(bar) == 1);
+foo.ClearExtension(bar);
+assert(!foo.HasExtension(bar));
+

For the message extension field message_bar, if the field is not set +foo.GetExtension(message_bar) returns a Bar with none of its fields set +(possibly Bar::default_instance()).

Similarly, for the repeated extension field repeated_bar, the compiler +generates an extension identifier called repeated_bar, which you can also use +with Foo’s extension accessors:

Foo foo;
+for (int i = 0; i < kSize; ++i) {
+  foo.AddExtension(repeated_bar, i)
+}
+assert(foo.ExtensionSize(repeated_bar) == kSize)
+for (int i = 0; i < kSize; ++i) {
+  assert(foo.GetExtension(repeated_bar, i) == i)
+}
+

(The exact implementation of extension identifiers is complicated and involves +magical use of templates—however, you don’t need to worry about how extension +identifiers work to use them.)

Extensions can be declared nested inside of another type. For example, a common +pattern is to do something like this:

message Baz {
+  extend Foo {
+    optional Baz foo_ext = 124;
+  }
+}
+

In this case, the extension identifier foo_ext is declared nested inside +Baz. It can be used as follows:

Foo foo;
+Baz* baz = foo.MutableExtension(Baz::foo_ext);
+FillInMyBaz(baz);
+

Arena Allocation

Arena allocation is a C++-only feature that helps you optimize your memory usage +and improve performance when working with protocol buffers. Enabling arena +allocation in your .proto adds additional code for working with arenas to your +C++ generated code. You can find out more about the arena allocation API in the +Arena Allocation Guide.

Services

If the .proto file contains the following line:

option cc_generic_services = true;
+

then the protocol buffer compiler will generate code based on the service +definitions found in the file as described in this section. However, the +generated code may be undesirable as it is not tied to any particular RPC +system, and thus requires more levels of indirection than code tailored to one +system. If you do NOT want this code to be generated, add this line to the file:

option cc_generic_services = false;
+

If neither of the above lines are given, the option defaults to false, as +generic services are deprecated. (Note that prior to 2.4.0, the option defaults +to true)

RPC systems based on .proto-language service definitions should provide +plugins +to generate code appropriate for the system. These plugins are likely to require +that abstract services are disabled, so that they can generate their own classes +of the same names.

The remainder of this section describes what the protocol buffer compiler +generates when abstract services are enabled.

Interface

Given a service definition:

service Foo {
+  rpc Bar(FooRequest) returns(FooResponse);
+}
+

The protocol buffer compiler will generate a class Foo to represent this +service. Foo will have a virtual method for each method defined in the service +definition. In this case, the method Bar is defined as:

virtual void Bar(RpcController* controller, const FooRequest* request,
+                 FooResponse* response, Closure* done);
+

The parameters are equivalent to the parameters of Service::CallMethod(), +except that the method argument is implied and request and response +specify their exact type.

These generated methods are virtual, but not pure-virtual. The default +implementations simply call controller->SetFailed() with an error message +indicating that the method is unimplemented, then invoke the done callback. +When implementing your own service, you must subclass this generated service and +implement its methods as appropriate.

Foo subclasses the Service interface. The protocol buffer compiler +automatically generates implementations of the methods of Service as follows:

  • GetDescriptor: Returns the service’s +ServiceDescriptor.
  • CallMethod: Determines which method is being called based on the provided +method descriptor and calls it directly, down-casting the request and +response messages objects to the correct types.
  • GetRequestPrototype and GetResponsePrototype: Returns the default +instance of the request or response of the correct type for the given +method.

The following static method is also generated:

  • static ServiceDescriptor descriptor(): Returns the type’s descriptor, +which contains information about what methods this service has and what +their input and output types are.

Stub

The protocol buffer compiler also generates a “stub” implementation of every +service interface, which is used by clients wishing to send requests to servers +implementing the service. For the Foo service (described earlier), the stub +implementation Foo_Stub will be defined. As with nested message types, a +typedef is used so that Foo_Stub can also be referred to as Foo::Stub.

Foo_Stub is a subclass of Foo which also implements the following methods:

  • Foo_Stub(RpcChannel* channel): Constructs a new stub which sends requests +on the given channel.
  • Foo_Stub(RpcChannel* channel, ChannelOwnership ownership): Constructs a +new stub which sends requests on the given channel and possibly owns that +channel. If ownership is Service::STUB_OWNS_CHANNEL then when the stub +object is deleted it will delete the channel as well.
  • RpcChannel* channel(): Returns this stub’s channel, as passed to the +constructor.

The stub additionally implements each of the service’s methods as a wrapper +around the channel. Calling one of the methods simply calls +channel->CallMethod().

The Protocol Buffer library does not include an RPC implementation. However, it +includes all of the tools you need to hook up a generated service class to any +arbitrary RPC implementation of your choice. You need only provide +implementations of +RpcChannel +and +RpcController. +See the documentation for +service.h +for more information.

Plugin Insertion Points

Code generator plugins +which want to extend the output of the C++ code generator may insert code of the +following types using the given insertion point names. Each insertion point +appears in both the .pb.cc file and the .pb.h file unless otherwise noted.

  • includes: Include directives.
  • namespace_scope: Declarations that belong in the file’s package/namespace, +but not within any particular class. Appears after all other namespace-scope +code.
  • global_scope: Declarations that belong at the top level, outside of the +file’s namespace. Appears at the very end of the file.
  • class_scope:TYPENAME: Member declarations that belong in a message class. +TYPENAME is the full proto name, such as package.MessageType. Appears +after all other public declarations in the class. This insertion point +appears only in the .pb.h file.

Do not generate code which relies on private class members declared by the +standard code generator, as these implementation details may change in future +versions of Protocol Buffers.

\ No newline at end of file diff --git a/reference/cpp/index.html b/reference/cpp/index.html new file mode 100644 index 000000000..392498504 --- /dev/null +++ b/reference/cpp/index.html @@ -0,0 +1,8 @@ +C++ Reference | Protocol Buffers Documentation +

C++ Reference

Reference documentation for working with protocol buffer classes in C++.

C++ Generated Code Guide

Describes exactly what C++ code the protocol buffer compiler generates for any given protocol definition.

String View APIs

Covers various string_view migrations

C++ Arena Allocation Guide

Arena allocation is a C++-only feature that helps you optimize your memory usage and improve performance when working with protocol buffers.

Abseil Support

The C++ implementation of Protocol Buffers has an explicit dependency on Abseil.

C++ API

C++ Reference

This section contains reference documentation for working with protocol buffer classes in C++.

\ No newline at end of file diff --git a/reference/cpp/index.xml b/reference/cpp/index.xml new file mode 100644 index 000000000..801ee5e7c --- /dev/null +++ b/reference/cpp/index.xml @@ -0,0 +1,7 @@ +C++ Reference on Protocol Buffers Documentationhttps://protobuf.dev/reference/cpp/Recent content in C++ Reference on Protocol Buffers DocumentationHugoenC++ Generated Code Guidehttps://protobuf.dev/reference/cpp/cpp-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/cpp-generated/Any differences between proto2, proto3, and editions generated code are highlighted. Note that these differences are in the generated code as described in this document, not the base message classes/interfaces, which are the same in all versions. You should read the proto2 language guide, proto3 language guide, or edition 2023 language guide before reading this document. +Compiler Invocation The protocol buffer compiler produces C++ output when invoked with the --cpp_out= command-line flag.String View APIshttps://protobuf.dev/reference/cpp/string-view/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/string-view/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.C++ Arena Allocation Guidehttps://protobuf.dev/reference/cpp/arenas/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/arenas/This page describes exactly what C++ code the protocol buffer compiler generates in addition to the code described in the C++ Generated Code Guide when arena allocation is enabled. It assumes that you are familiar with the material in the language guide and the C++ Generated Code Guide. +Why Use Arena Allocation? Memory allocation and deallocation constitutes a significant fraction of CPU time spent in protocol buffers code. By default, protocol buffers performs heap allocations for each message object, each of its subobjects, and several field types, such as strings.Abseil Supporthttps://protobuf.dev/reference/cpp/abseil/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/abseil/In version 22.x, C++ protobuf added an explicit dependency on Abseil. +Bazel Support If you are using Bazel, to determine the version of Abseil that your protobuf version supports, you can use the bazel mod command: +$ bazel mod deps abseil-cpp --enable_bzlmod &lt;root&gt; (protobuf@30.0-dev) └───abseil-cpp@20240722.0 ├───bazel_skylib@1.7.1 ├───googletest@1.15.2 └───platforms@0.0.10 bazel mod graph produces the full output: +$ bazel mod graph --enable_bzlmod &lt;root&gt; (protobuf@30.0-dev) ├───abseil-cpp@20240722.0 │ ├───bazel_skylib@1.7.1 (*) │ ├───googletest@1.15.2 (*) │ └───platforms@0.C++ APIhttps://protobuf.dev/reference/cpp/api-docs-link/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/cpp/api-docs-link/ \ No newline at end of file diff --git a/reference/cpp/string-view/index.html b/reference/cpp/string-view/index.html new file mode 100644 index 000000000..d01a05ef5 --- /dev/null +++ b/reference/cpp/string-view/index.html @@ -0,0 +1,89 @@ +String View APIs | Protocol Buffers Documentation +

String View APIs

Covers various string_view migrations

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

As part of edition 2023, the +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 of +string and bytes fields.

Interaction with 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

For either of these field definitions in edition 2023:

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

For either of these field definitions:

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<string>& foo() const: Returns the underlying +RepeatedPtrField +that stores the field’s elements. This container class provides STL-like +iterators and other methods.
  • RepeatedPtrField<string>* 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

For any of these oneof field definitions:

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

Beginning in edition 2024, a new feature enum_name_uses_string_view is +introduced and defaults to true. Unless disabled, for an enum like:

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:

  • ::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:

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).

\ No newline at end of file diff --git a/reference/csharp/api-docs-link/index.html b/reference/csharp/api-docs-link/index.html new file mode 100644 index 000000000..16c16ba98 --- /dev/null +++ b/reference/csharp/api-docs-link/index.html @@ -0,0 +1,4 @@ +C# API | Protocol Buffers Documentation +
\ No newline at end of file diff --git a/content/reference/csharp/api-docs/_doxygen.yaml b/reference/csharp/api-docs/_doxygen.yaml similarity index 100% rename from content/reference/csharp/api-docs/_doxygen.yaml rename to reference/csharp/api-docs/_doxygen.yaml diff --git a/content/reference/csharp/api-docs/class/google/protobuf/byte-string.html b/reference/csharp/api-docs/class/google/protobuf/byte-string.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/byte-string.html rename to reference/csharp/api-docs/class/google/protobuf/byte-string.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/coded-input-stream.html b/reference/csharp/api-docs/class/google/protobuf/coded-input-stream.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/coded-input-stream.html rename to reference/csharp/api-docs/class/google/protobuf/coded-input-stream.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/coded-output-stream.html b/reference/csharp/api-docs/class/google/protobuf/coded-output-stream.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/coded-output-stream.html rename to reference/csharp/api-docs/class/google/protobuf/coded-output-stream.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/coded-output-stream/out-of-space-exception.html b/reference/csharp/api-docs/class/google/protobuf/coded-output-stream/out-of-space-exception.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/coded-output-stream/out-of-space-exception.html rename to reference/csharp/api-docs/class/google/protobuf/coded-output-stream/out-of-space-exception.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/collections/map-field-t-key-t-value-.html b/reference/csharp/api-docs/class/google/protobuf/collections/map-field-t-key-t-value-.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/collections/map-field-t-key-t-value-.html rename to reference/csharp/api-docs/class/google/protobuf/collections/map-field-t-key-t-value-.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/collections/map-field-t-key-t-value-/codec.html b/reference/csharp/api-docs/class/google/protobuf/collections/map-field-t-key-t-value-/codec.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/collections/map-field-t-key-t-value-/codec.html rename to reference/csharp/api-docs/class/google/protobuf/collections/map-field-t-key-t-value-/codec.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/collections/repeated-field-t-.html b/reference/csharp/api-docs/class/google/protobuf/collections/repeated-field-t-.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/collections/repeated-field-t-.html rename to reference/csharp/api-docs/class/google/protobuf/collections/repeated-field-t-.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/field-codec-t-.html b/reference/csharp/api-docs/class/google/protobuf/field-codec-t-.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/field-codec-t-.html rename to reference/csharp/api-docs/class/google/protobuf/field-codec-t-.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/field-codec.html b/reference/csharp/api-docs/class/google/protobuf/field-codec.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/field-codec.html rename to reference/csharp/api-docs/class/google/protobuf/field-codec.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/invalid-json-exception.html b/reference/csharp/api-docs/class/google/protobuf/invalid-json-exception.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/invalid-json-exception.html rename to reference/csharp/api-docs/class/google/protobuf/invalid-json-exception.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/invalid-protocol-buffer-exception.html b/reference/csharp/api-docs/class/google/protobuf/invalid-protocol-buffer-exception.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/invalid-protocol-buffer-exception.html rename to reference/csharp/api-docs/class/google/protobuf/invalid-protocol-buffer-exception.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/json-formatter.html b/reference/csharp/api-docs/class/google/protobuf/json-formatter.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/json-formatter.html rename to reference/csharp/api-docs/class/google/protobuf/json-formatter.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/json-formatter/settings.html b/reference/csharp/api-docs/class/google/protobuf/json-formatter/settings.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/json-formatter/settings.html rename to reference/csharp/api-docs/class/google/protobuf/json-formatter/settings.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/json-parser.html b/reference/csharp/api-docs/class/google/protobuf/json-parser.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/json-parser.html rename to reference/csharp/api-docs/class/google/protobuf/json-parser.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/json-parser/settings.html b/reference/csharp/api-docs/class/google/protobuf/json-parser/settings.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/json-parser/settings.html rename to reference/csharp/api-docs/class/google/protobuf/json-parser/settings.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/message-extensions.html b/reference/csharp/api-docs/class/google/protobuf/message-extensions.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/message-extensions.html rename to reference/csharp/api-docs/class/google/protobuf/message-extensions.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/message-parser-t-.html b/reference/csharp/api-docs/class/google/protobuf/message-parser-t-.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/message-parser-t-.html rename to reference/csharp/api-docs/class/google/protobuf/message-parser-t-.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/message-parser.html b/reference/csharp/api-docs/class/google/protobuf/message-parser.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/message-parser.html rename to reference/csharp/api-docs/class/google/protobuf/message-parser.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/proto-preconditions.html b/reference/csharp/api-docs/class/google/protobuf/proto-preconditions.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/proto-preconditions.html rename to reference/csharp/api-docs/class/google/protobuf/proto-preconditions.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/descriptor-base.html b/reference/csharp/api-docs/class/google/protobuf/reflection/descriptor-base.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/descriptor-base.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/descriptor-base.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/descriptor-proto/types.html b/reference/csharp/api-docs/class/google/protobuf/reflection/descriptor-proto/types.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/descriptor-proto/types.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/descriptor-proto/types.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/descriptor-validation-exception.html b/reference/csharp/api-docs/class/google/protobuf/reflection/descriptor-validation-exception.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/descriptor-validation-exception.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/descriptor-validation-exception.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/enum-descriptor.html b/reference/csharp/api-docs/class/google/protobuf/reflection/enum-descriptor.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/enum-descriptor.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/enum-descriptor.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/enum-value-descriptor.html b/reference/csharp/api-docs/class/google/protobuf/reflection/enum-value-descriptor.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/enum-value-descriptor.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/enum-value-descriptor.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/field-descriptor-proto/types.html b/reference/csharp/api-docs/class/google/protobuf/reflection/field-descriptor-proto/types.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/field-descriptor-proto/types.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/field-descriptor-proto/types.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/field-descriptor.html b/reference/csharp/api-docs/class/google/protobuf/reflection/field-descriptor.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/field-descriptor.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/field-descriptor.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/field-options/types.html b/reference/csharp/api-docs/class/google/protobuf/reflection/field-options/types.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/field-options/types.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/field-options/types.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/file-descriptor.html b/reference/csharp/api-docs/class/google/protobuf/reflection/file-descriptor.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/file-descriptor.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/file-descriptor.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/file-options/types.html b/reference/csharp/api-docs/class/google/protobuf/reflection/file-options/types.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/file-options/types.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/file-options/types.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/generated-clr-type-info.html b/reference/csharp/api-docs/class/google/protobuf/reflection/generated-clr-type-info.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/generated-clr-type-info.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/generated-clr-type-info.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/generated-code-info.html b/reference/csharp/api-docs/class/google/protobuf/reflection/generated-code-info.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/generated-code-info.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/generated-code-info.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/generated-code-info/types.html b/reference/csharp/api-docs/class/google/protobuf/reflection/generated-code-info/types.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/generated-code-info/types.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/generated-code-info/types.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/message-descriptor.html b/reference/csharp/api-docs/class/google/protobuf/reflection/message-descriptor.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/message-descriptor.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/message-descriptor.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/message-descriptor/field-collection.html b/reference/csharp/api-docs/class/google/protobuf/reflection/message-descriptor/field-collection.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/message-descriptor/field-collection.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/message-descriptor/field-collection.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/method-descriptor.html b/reference/csharp/api-docs/class/google/protobuf/reflection/method-descriptor.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/method-descriptor.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/method-descriptor.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/method-options/types.html b/reference/csharp/api-docs/class/google/protobuf/reflection/method-options/types.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/method-options/types.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/method-options/types.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/oneof-accessor.html b/reference/csharp/api-docs/class/google/protobuf/reflection/oneof-accessor.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/oneof-accessor.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/oneof-accessor.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/oneof-descriptor.html b/reference/csharp/api-docs/class/google/protobuf/reflection/oneof-descriptor.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/oneof-descriptor.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/oneof-descriptor.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/original-name-attribute.html b/reference/csharp/api-docs/class/google/protobuf/reflection/original-name-attribute.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/original-name-attribute.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/original-name-attribute.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/service-descriptor.html b/reference/csharp/api-docs/class/google/protobuf/reflection/service-descriptor.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/service-descriptor.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/service-descriptor.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/source-code-info/types.html b/reference/csharp/api-docs/class/google/protobuf/reflection/source-code-info/types.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/source-code-info/types.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/source-code-info/types.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/type-registry.html b/reference/csharp/api-docs/class/google/protobuf/reflection/type-registry.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/type-registry.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/type-registry.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/reflection/uninterpreted-option/types.html b/reference/csharp/api-docs/class/google/protobuf/reflection/uninterpreted-option/types.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/reflection/uninterpreted-option/types.html rename to reference/csharp/api-docs/class/google/protobuf/reflection/uninterpreted-option/types.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/any-reflection.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/any-reflection.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/any-reflection.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/any-reflection.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/any.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/any.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/any.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/any.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/api-reflection.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/api-reflection.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/api-reflection.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/api-reflection.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/api.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/api.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/api.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/api.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/bool-value.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/bool-value.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/bool-value.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/bool-value.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/bytes-value.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/bytes-value.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/bytes-value.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/bytes-value.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/double-value.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/double-value.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/double-value.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/double-value.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/duration-reflection.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/duration-reflection.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/duration-reflection.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/duration-reflection.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/duration.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/duration.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/duration.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/duration.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/empty-reflection.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/empty-reflection.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/empty-reflection.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/empty-reflection.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/empty.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/empty.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/empty.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/empty.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/enum-value.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/enum-value.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/enum-value.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/enum-value.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/enum.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/enum.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/enum.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/enum.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/field-mask-reflection.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/field-mask-reflection.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/field-mask-reflection.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/field-mask-reflection.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/field-mask.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/field-mask.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/field-mask.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/field-mask.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/field.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/field.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/field.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/field.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/field/types.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/field/types.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/field/types.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/field/types.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/float-value.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/float-value.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/float-value.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/float-value.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/int32-value.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/int32-value.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/int32-value.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/int32-value.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/int64-value.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/int64-value.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/int64-value.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/int64-value.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/list-value.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/list-value.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/list-value.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/list-value.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/method.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/method.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/method.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/method.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/mixin.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/mixin.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/mixin.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/mixin.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/option.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/option.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/option.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/option.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/source-context-reflection.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/source-context-reflection.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/source-context-reflection.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/source-context-reflection.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/source-context.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/source-context.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/source-context.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/source-context.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/string-value.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/string-value.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/string-value.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/string-value.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/struct-reflection.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/struct-reflection.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/struct-reflection.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/struct-reflection.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/struct.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/struct.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/struct.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/struct.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/time-extensions.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/time-extensions.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/time-extensions.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/time-extensions.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/timestamp-reflection.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/timestamp-reflection.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/timestamp-reflection.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/timestamp-reflection.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/timestamp.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/timestamp.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/timestamp.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/timestamp.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/type-reflection.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/type-reflection.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/type-reflection.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/type-reflection.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/type.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/type.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/type.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/type.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/u-int32-value.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/u-int32-value.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/u-int32-value.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/u-int32-value.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/u-int64-value.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/u-int64-value.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/u-int64-value.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/u-int64-value.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/value.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/value.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/value.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/value.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/well-known-types/wrappers-reflection.html b/reference/csharp/api-docs/class/google/protobuf/well-known-types/wrappers-reflection.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/well-known-types/wrappers-reflection.html rename to reference/csharp/api-docs/class/google/protobuf/well-known-types/wrappers-reflection.html diff --git a/content/reference/csharp/api-docs/class/google/protobuf/wire-format.html b/reference/csharp/api-docs/class/google/protobuf/wire-format.html similarity index 100% rename from content/reference/csharp/api-docs/class/google/protobuf/wire-format.html rename to reference/csharp/api-docs/class/google/protobuf/wire-format.html diff --git a/content/reference/csharp/api-docs/includes/stylesheet.css b/reference/csharp/api-docs/includes/stylesheet.css similarity index 100% rename from content/reference/csharp/api-docs/includes/stylesheet.css rename to reference/csharp/api-docs/includes/stylesheet.css diff --git a/content/reference/csharp/api-docs/index.html b/reference/csharp/api-docs/index.html similarity index 100% rename from content/reference/csharp/api-docs/index.html rename to reference/csharp/api-docs/index.html diff --git a/content/reference/csharp/api-docs/interface/google/protobuf/i-custom-diagnostic-message.html b/reference/csharp/api-docs/interface/google/protobuf/i-custom-diagnostic-message.html similarity index 100% rename from content/reference/csharp/api-docs/interface/google/protobuf/i-custom-diagnostic-message.html rename to reference/csharp/api-docs/interface/google/protobuf/i-custom-diagnostic-message.html diff --git a/content/reference/csharp/api-docs/interface/google/protobuf/i-deep-cloneable-t-.html b/reference/csharp/api-docs/interface/google/protobuf/i-deep-cloneable-t-.html similarity index 100% rename from content/reference/csharp/api-docs/interface/google/protobuf/i-deep-cloneable-t-.html rename to reference/csharp/api-docs/interface/google/protobuf/i-deep-cloneable-t-.html diff --git a/content/reference/csharp/api-docs/interface/google/protobuf/i-message-t-.html b/reference/csharp/api-docs/interface/google/protobuf/i-message-t-.html similarity index 100% rename from content/reference/csharp/api-docs/interface/google/protobuf/i-message-t-.html rename to reference/csharp/api-docs/interface/google/protobuf/i-message-t-.html diff --git a/content/reference/csharp/api-docs/interface/google/protobuf/i-message.html b/reference/csharp/api-docs/interface/google/protobuf/i-message.html similarity index 100% rename from content/reference/csharp/api-docs/interface/google/protobuf/i-message.html rename to reference/csharp/api-docs/interface/google/protobuf/i-message.html diff --git a/content/reference/csharp/api-docs/interface/google/protobuf/reflection/i-descriptor.html b/reference/csharp/api-docs/interface/google/protobuf/reflection/i-descriptor.html similarity index 100% rename from content/reference/csharp/api-docs/interface/google/protobuf/reflection/i-descriptor.html rename to reference/csharp/api-docs/interface/google/protobuf/reflection/i-descriptor.html diff --git a/content/reference/csharp/api-docs/interface/google/protobuf/reflection/i-field-accessor.html b/reference/csharp/api-docs/interface/google/protobuf/reflection/i-field-accessor.html similarity index 100% rename from content/reference/csharp/api-docs/interface/google/protobuf/reflection/i-field-accessor.html rename to reference/csharp/api-docs/interface/google/protobuf/reflection/i-field-accessor.html diff --git a/content/reference/csharp/api-docs/namespace/google.html b/reference/csharp/api-docs/namespace/google.html similarity index 100% rename from content/reference/csharp/api-docs/namespace/google.html rename to reference/csharp/api-docs/namespace/google.html diff --git a/content/reference/csharp/api-docs/namespace/google/protobuf.html b/reference/csharp/api-docs/namespace/google/protobuf.html similarity index 100% rename from content/reference/csharp/api-docs/namespace/google/protobuf.html rename to reference/csharp/api-docs/namespace/google/protobuf.html diff --git a/content/reference/csharp/api-docs/namespace/google/protobuf/collections.html b/reference/csharp/api-docs/namespace/google/protobuf/collections.html similarity index 100% rename from content/reference/csharp/api-docs/namespace/google/protobuf/collections.html rename to reference/csharp/api-docs/namespace/google/protobuf/collections.html diff --git a/content/reference/csharp/api-docs/namespace/google/protobuf/reflection.html b/reference/csharp/api-docs/namespace/google/protobuf/reflection.html similarity index 100% rename from content/reference/csharp/api-docs/namespace/google/protobuf/reflection.html rename to reference/csharp/api-docs/namespace/google/protobuf/reflection.html diff --git a/content/reference/csharp/api-docs/namespace/google/protobuf/well-known-types.html b/reference/csharp/api-docs/namespace/google/protobuf/well-known-types.html similarity index 100% rename from content/reference/csharp/api-docs/namespace/google/protobuf/well-known-types.html rename to reference/csharp/api-docs/namespace/google/protobuf/well-known-types.html diff --git a/reference/csharp/csharp-generated/index.html b/reference/csharp/csharp-generated/index.html new file mode 100644 index 000000000..4013b11ca --- /dev/null +++ b/reference/csharp/csharp-generated/index.html @@ -0,0 +1,234 @@ +C# Generated Code Guide | Protocol Buffers Documentation +

C# Generated Code Guide

Describes exactly what C# code the protocol buffer compiler generates for protocol definitions using editions syntax.

You should read the +proto2 language guide, +proto3 language guide, or +editions language guide +before reading this document.

Compiler Invocation

The protocol buffer compiler produces C# output when invoked with the +--csharp_out command-line flag. The parameter to the --csharp_out option is +the directory where you want the compiler to write your C# output, although +depending on other options the compiler may create +subdirectories of the specified directory. The compiler creates a single source +file for each .proto file input, defaulting to an extension of .cs but +configurable via compiler options.

C#-specific Options

You can provide further C# options to the protocol buffer compiler using the +--csharp_opt command-line flag. The supported options are:

  • file_extension: Sets the file extension for generated code. This +defaults to .cs, but a common alternative is .g.cs to indicate that the +file contains generated code.

  • base_namespace: When this option is specified, the generator creates a +directory hierarchy for generated source code corresponding to the +namespaces of the generated classes, using the value of the option to +indicate which part of the namespace should be considered as the "base" +for the output directory. For example, with the following command-line:

    protoc --proto_path=bar --csharp_out=src --csharp_opt=base_namespace=Example player.proto
    +

    where player.proto has a csharp_namespace option of Example.Game the +protocol buffer compiler generates a file src/Game/Player.cs being +created. This option would usually correspond with the default namespace +option in a C# project in Visual Studio. If the option is specified but +with an empty value, the full C# namespace as used in the generated file +will be used for the directory hierarchy. If the option is not specified at +all, the generated files are simply written into the directory specified by +--csharp_out without any hierarchy being created.

  • internal_access: When this option is specified, the generator creates +types with the internal access modifier instead of public.

  • serializable: When this option is specified, the generator adds the +[Serializable] attribute to generated message classes.

Multiple options can be specified by separating them with commas, as in the +following example:

protoc --proto_path=src --csharp_out=build/gen --csharp_opt=file_extension=.g.cs,base_namespace=Example,internal_access src/foo.proto
+

File structure

The name of the output file is derived from the .proto filename by converting +it to Pascal-case, treating underscores as word separators. So, for example, a +file called player_record.proto will result in an output file called +PlayerRecord.cs (where the file extension can be specified using +--csharp_opt, as shown above).

Each generated file takes the following form, in terms of public members. (The +implementation is not shown here.)

namespace [...]
+{
+  public static partial class [... descriptor class name ...]
+  {
+    public static FileDescriptor Descriptor { get; }
+  }
+
+  [... Enums ...]
+  [... Message classes ...]
+}
+

The namespace is inferred from the proto’s package, using the same +conversion rules as the file name. For example, a proto package of +example.high_score would result in a namespace of Example.HighScore. You can +override the default generated namespace for a particular .proto using the +csharp_namespace +file option.

Each top-level enum and message results in an enum or class being declared as +members of the namespace. Additionally, a single static partial class is always +generated for the file descriptor. This is used for reflection-based operations. +The descriptor class is given the same name as the file, without the extension. +However, if there is a message with the same name (as is quite common), the +descriptor class is placed in a nested Proto namespace to avoid colliding with +the message.

As an example of all of these rules, consider the timestamp.proto file which +is provided as part of Protocol Buffers. A cut down version of timestamp.proto +looks like this:

edition = "2023";
+
+package google.protobuf;
+option csharp_namespace = "Google.Protobuf.WellKnownTypes";
+
+message Timestamp { ... }
+

The generated Timestamp.cs file has the following structure:

namespace Google.Protobuf.WellKnownTypes
+{
+  namespace Proto
+  {
+    public static partial class Timestamp
+    {
+      public static FileDescriptor Descriptor { get; }
+    }
+  }
+
+  public sealed partial class Timestamp : IMessage<Timestamp>
+  {
+    [...]
+  }
+}
+

Messages

Given a simple message declaration:

message Foo {}
+

The protocol buffer compiler generates a sealed, partial class called Foo, +which implements the IMessage<Foo> interface, as shown below with member +declarations. See the inline comments for more information.

public sealed partial class Foo : IMessage<Foo>
+{
+  // Static properties for parsing and reflection
+  public static MessageParser<Foo> Parser { get; }
+  public static MessageDescriptor Descriptor { get; }
+
+  // Explicit implementation of IMessage.Descriptor, to avoid conflicting with
+  // the static Descriptor property. Typically the static property is used when
+  // referring to a type known at compile time, and the instance property is used
+  // when referring to an arbitrary message, such as during JSON serialization.
+  MessageDescriptor IMessage.Descriptor { get; }
+
+  // Parameterless constructor which calls the OnConstruction partial method if provided.
+  public Foo();
+  // Deep-cloning constructor
+  public Foo(Foo);
+  // Partial method which can be implemented in manually-written code for the same class, to provide
+  // a hook for code which should be run whenever an instance is constructed.
+  partial void OnConstruction();
+
+  // Implementation of IDeepCloneable<T>.Clone(); creates a deep clone of this message.
+  public Foo Clone();
+
+  // Standard equality handling; note that IMessage<T> extends IEquatable<T>
+  public override bool Equals(object other);
+  public bool Equals(Foo other);
+  public override int GetHashCode();
+
+  // Converts the message to a JSON representation
+  public override string ToString();
+
+  // Serializes the message to the protobuf binary format
+  public void WriteTo(CodedOutputStream output);
+  // Calculates the size of the message in protobuf binary format
+  public int CalculateSize();
+
+  // Merges the contents of the given message into this one. Typically
+  // used by generated code and message parsers.
+  public void MergeFrom(Foo other);
+
+  // Merges the contents of the given protobuf binary format stream
+  // into this message. Typically used by generated code and message parsers.
+  public void MergeFrom(CodedInputStream input);
+}
+

Note that all of these members are always present; the optimize_for option +does not affect the output of the C# code generator.

Nested Types

A message can be declared inside another message. For example:

message Foo {
+  message Bar {
+  }
+}
+

In this case—or if a message contains a nested enum—the compiler +generates a nested Types class, and then a Bar class within the Types +class, so the full generated code would be:

namespace [...]
+{
+  public sealed partial class Foo : IMessage<Foo>
+  {
+    public static partial class Types
+    {
+      public sealed partial class Bar : IMessage<Bar> { ... }
+    }
+  }
+}
+

Although the intermediate Types class is inconvenient, it is required to deal +with the common scenario of a nested type having a corresponding field in the +message. You would otherwise end up with both a property and a type with the +same name nested within the same class—and that would be invalid C#.

Fields

The protocol buffer compiler generates a C# property for each field defined +within a message. The exact nature of the property depends on the nature of the +field: its type, and whether it is singular, repeated, or a map field.

Singular Fields

Any singular field generates a read/write property. A string or bytes field +will generate an ArgumentNullException if a null value is specified; fetching +a value from a field which hasn’t been explicitly set will return an empty +string or ByteString. Message fields can be set to null values, which is +effectively clearing the field. This is not equivalent to setting the value to +an "empty" instance of the message type.

Repeated Fields

Each repeated field generates a read-only property of type +Google.Protobuf.Collections.RepeatedField<T> where T is the field’s element +type. For the most part, this acts like List<T>, but it has an additional +Add overload to allow a collection of items to be added in one go. This is +convenient when populating a repeated field in an object initializer. +Additionally, RepeatedField<T> has direct support for serialization, +deserialization and cloning, but this is usually used by generated code instead +of manually-written application code.

Repeated fields cannot contain null values, even of message types, except for +the nullable wrapper types explained below.

Map Fields

Each map field generates a read-only property of type +Google.Protobuf.Collections.MapField<TKey, TValue> where TKey is the field’s +key type and TValue is the field’s value type. For the most part, this acts +like Dictionary<TKey, TValue>, but it has an additional Add overload to +allow another dictionary to be added in one go. This is convenient when +populating a repeated field in an object initializer. Additionally, +MapField<TKey, TValue> has direct support for serialization, deserialization +and cloning, but this is usually used by generated code instead of +manually-written application code. Keys in the map are not permitted to be null; +values may be if the corresponding singular field type would support null +values.

Oneof Fields

Each field within a oneof has a separate property, like a regular +singular field. However, the compiler also generates an additional +property to determine which field in the enum has been set, along with an enum +and a method to clear the oneof. For example, for this oneof field definition

oneof avatar {
+  string image_url = 1;
+  bytes image_data = 2;
+}
+

The compiler will generate these public members:

enum AvatarOneofCase
+{
+  None = 0,
+  ImageUrl = 1,
+  ImageData = 2
+}
+
+public AvatarOneofCase AvatarCase { get; }
+public void ClearAvatar();
+public string ImageUrl { get; set; }
+public ByteString ImageData { get; set; }
+

If a property is the current oneof "case", fetching that property will return +the value set for that property. Otherwise, fetching the property will return +the default value for the property’s type—only one member of a oneof can +be set at a time.

Setting any constituent property of the oneof will change the reported "case" +of the oneof. As with a regular singular field, you cannot set a +oneof field with a string or bytes type to a null value. Setting a +message-type field to null is equivalent to calling the oneof-specific Clear +method.

Wrapper Type Fields

Most of the well-known types do not affect code generation, but the wrapper +types (such as StringWrapper and Int32Wrapper) change the type and behavior +of the properties.

All of the wrapper types that correspond to C# value types (such as +Int32Wrapper, DoubleWrapper, and BoolWrapper) are mapped to Nullable<T> +where T is the corresponding non-nullable type. For example, a field of type +DoubleValue results in a C# property of type Nullable<double>.

Fields of type StringWrapper or BytesWrapper result in C# properties of +type string and ByteString being generated, but with a default value of +null, and allowing null to be set as the property value.

For all wrapper types, null values are not permitted in a repeated field, but +are permitted as the values for map entries.

Enumerations

Given an enumeration definition like:

enum Color {
+  COLOR_UNSPECIFIED = 0;
+  COLOR_RED = 1;
+  COLOR_GREEN = 5;
+  COLOR_BLUE = 1234;
+}
+

The protocol buffer compiler will generate a C# enum type called Color with +the same set of values. The names of the enum values are converted to make them +more idiomatic for C# developers:

  • If the original name starts with the upper-cased form of the enum name +itself, that is removed
  • The result is converted into Pascal case

The Color proto enum above would therefore become the following C# code:

enum Color
+{
+  Unspecified = 0,
+  Red = 1,
+  Green = 5,
+  Blue = 1234
+}
+

This name transformation does not affect the text used within the JSON +representation of messages.

Note that the .proto language allows multiple enum symbols to have the same +numeric value. Symbols with the same numeric value are synonyms. These are +represented in C# in exactly the same way, with multiple names corresponding to +the same numeric value.

A non-nested enumeration leads to a C# enum being generated as a new namespace +member being generated; a nested enumeration lead to a C# enum being generated +in the Types nested class within the class corresponding to the message the +enumeration is nested within.

Services

The C# code generator ignores services entirely.

\ No newline at end of file diff --git a/reference/csharp/index.html b/reference/csharp/index.html new file mode 100644 index 000000000..092d5e459 --- /dev/null +++ b/reference/csharp/index.html @@ -0,0 +1,8 @@ +C# Reference | Protocol Buffers Documentation +

C# Reference

Reference documentation for working with protocol buffer classes in C#

C# Generated Code Guide

Describes exactly what C# code the protocol buffer compiler generates for protocol definitions using editions syntax.

C# API

\ No newline at end of file diff --git a/reference/csharp/index.xml b/reference/csharp/index.xml new file mode 100644 index 000000000..db93f3404 --- /dev/null +++ b/reference/csharp/index.xml @@ -0,0 +1,2 @@ +C# Reference on Protocol Buffers Documentationhttps://protobuf.dev/reference/csharp/Recent content in C# Reference on Protocol Buffers DocumentationHugoenC# Generated Code Guidehttps://protobuf.dev/reference/csharp/csharp-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/csharp/csharp-generated/You should read the proto2 language guide, proto3 language guide, or editions language guide before reading this document. +Compiler Invocation The protocol buffer compiler produces C# output when invoked with the --csharp_out command-line flag. The parameter to the --csharp_out option is the directory where you want the compiler to write your C# output, although depending on other options the compiler may create subdirectories of the specified directory. The compiler creates a single source file for each .C# APIhttps://protobuf.dev/reference/csharp/api-docs-link/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/csharp/api-docs-link/ \ No newline at end of file diff --git a/reference/dart/api-docs-link/index.html b/reference/dart/api-docs-link/index.html new file mode 100644 index 000000000..212df7c00 --- /dev/null +++ b/reference/dart/api-docs-link/index.html @@ -0,0 +1,4 @@ +Dart API | Protocol Buffers Documentation +
\ No newline at end of file diff --git a/reference/dart/dart-generated/index.html b/reference/dart/dart-generated/index.html new file mode 100644 index 000000000..c5910f319 --- /dev/null +++ b/reference/dart/dart-generated/index.html @@ -0,0 +1,226 @@ +Dart Generated Code | Protocol Buffers Documentation +

Dart Generated Code

Describes what Dart code the protocol buffer compiler generates for any given protocol definition.

Any differences between +proto2, proto3, and editions generated code are highlighted - note that these +differences are in the generated code as described in this document, not the +base API, which are the same in both versions. You should read the +proto2 language guide, +proto3 language guide, or +editions language guide +before reading this document.

Compiler Invocation

The protocol buffer compiler requires a +plugin to generate Dart code. +Installing it following the +instructions +provides a protoc-gen-dart binary which protoc uses when invoked with the +--dart_out command-line flag. The --dart_out flag tells the compiler where +to write the Dart source files. For a .proto file input, the compiler produces +among others a .pb.dart file.

The name of the .pb.dart file is computed by taking the name of the .proto +file and making two changes:

  • The extension (.proto) is replaced with .pb.dart. For example, a file +called foo.proto results in an output file called foo.pb.dart.
  • The proto path (specified with the --proto_path or -I command-line flag) +is replaced with the output path (specified with the --dart_out flag).

For example, when you invoke the compiler as follows:

protoc --proto_path=src --dart_out=build/gen src/foo.proto src/bar/baz.proto
+

the compiler will read the files src/foo.proto and src/bar/baz.proto. It +produces: build/gen/foo.pb.dart and build/gen/bar/baz.pb.dart. The compiler +automatically creates the directory build/gen/bar if necessary, but it will +not create build or build/gen; they must already exist.

Messages

Given a simple message declaration:

message Foo {}
+

The protocol buffer compiler generates a class called Foo, which extends the +class GeneratedMessage.

The class GeneratedMessage defines methods that let you check, manipulate, +read, or write the entire message. In addition to these methods, the Foo class +defines the following methods and constructors:

  • Foo(): Default constructor. Creates an instance where all singular fields +are unset and repeated fields are empty.
  • Foo.fromBuffer(...): Creates a Foo from serialized protocol buffer data +representing the message.
  • Foo.fromJson(...): Creates a Foo from a JSON string encoding the +message.
  • Foo clone(): Creates a deep clone of the fields in the message.
  • Foo copyWith(void Function(Foo) updates): Makes a writable copy of this +message, applies the updates to it, and marks the copy read-only before +returning it.
  • static Foo create(): Factory function to create a single Foo.
  • static PbList<Foo> createRepeated(): Factory function to create a List +implementing a mutable repeated field of Foo elements.
  • static Foo getDefault(): Returns a singleton instance of Foo, which is +identical to a newly-constructed instance of Foo (so all singular fields are +unset and all repeated fields are empty).

Nested Types

A message can be declared inside another message. For example:

message Foo {
+  message Bar {
+  }
+}
+

In this case, the compiler generates two classes: Foo and Foo_Bar.

Fields

In addition to the methods described in the previous section, the protocol +buffer compiler generates accessor methods for each field defined within the +message in the .proto file.

Note that the generated names always use camel-case naming, even if the field +name in the .proto file uses lower-case with underscores +(as it should). The +case-conversion works as follows:

  1. For each underscore in the name, the underscore is removed, and the +following letter is capitalized.
  2. If the name will have a prefix attached (e.g. "has"), the first letter is +capitalized. Otherwise, it is lower-cased.

Thus, for the field foo_bar_baz, the getter becomes get fooBarBaz and a +method prefixed with has would be hasFooBarBaz.

Singular Primitive Fields

All fields have +explicit presence +in the Dart implementation.

For the following field definition:

int32 foo = 1;
+

The compiler will generate the following accessor methods in the message class:

  • int get foo: Returns the current value of the field. If the field is not +set, returns the default value.

  • bool hasFoo(): Returns true if the field is set.

  • set foo(int value): Sets the value of the field. After calling this, +hasFoo() will return true and get foo will return value.

  • void clearFoo(): Clears the value of the field. After calling this, +hasFoo() will return false and get foo will return the default value.

  • bool hasFoo(): Returns true if the field is set.

  • void clearFoo(): Clears the value of the field. After calling this, +hasFoo() will return false and get foo will return the default value.

For other simple field types, the corresponding Dart type is chosen according to +the +scalar value types table. +For message and enum types, the value type is replaced with the message or enum +class.

Singular Message Fields

Given the message type:

message Bar {}
+

For a message with a Bar field:

// proto2
+message Baz {
+  optional Bar bar = 1;
+  // The generated code is the same result if required instead of optional.
+}
+
+// proto3 and editions
+message Baz {
+  Bar bar = 1;
+}
+

The compiler will generate the following accessor methods in the message class:

  • Bar get bar: Returns the current value of the field. If the field is not +set, returns the default value.
  • set bar(Bar value): Sets the value of the field. After calling this, +hasBar() will return true and get bar will return value.
  • bool hasBar(): Returns true if the field is set.
  • void clearBar(): Clears the value of the field. After calling this, +hasBar() will return false and get bar will return the default value.
  • Bar ensureBar(): Sets bar to the empty instance if hasBar() returns +false, and then returns the value of bar. After calling this, hasBar() +will return true.

Repeated Fields

For this field definition:

repeated int32 foo = 1;
+

The compiler will generate:

  • List<int> get foo: Returns the list backing the field. If the field is not +set, returns an empty list. Modifications to the list are reflected in the +field.

Int64 Fields

For this field definition:

int64 bar = 1;
+

The compiler will generate:

  • Int64 get bar: Returns an Int64 object containing the field value.

Note that Int64 is not built into the Dart core libraries. To work with these +objects, you may need to import the Dart fixnum library:

import 'package:fixnum/fixnum.dart';
+

Map Fields

Given a map field +definition like this:

map<int32, int32> map_field = 1;
+

The compiler will generate the following getter:

  • Map<int, int> get mapField: Returns the Dart map backing the field. If the +field is not set, returns an empty map. Modifications to the map are +reflected in the field.

Any

Given an Any field +like this:

import "google/protobuf/any.proto";
+
+message ErrorStatus {
+  string message = 1;
+  google.protobuf.Any details = 2;
+}
+

In our generated code, the getter for the details field returns an instance of +com.google.protobuf.Any. This provides the following special methods to pack +and unpack the Any’s values:

    /// Unpacks the message in [value] into [instance].
+    ///
+    /// Throws a [InvalidProtocolBufferException] if [typeUrl] does not correspond
+    /// to the type of [instance].
+    ///
+    /// A typical usage would be `any.unpackInto(new Message())`.
+    ///
+    /// Returns [instance].
+    T unpackInto<T extends GeneratedMessage>(T instance,
+        {ExtensionRegistry extensionRegistry = ExtensionRegistry.EMPTY});
+
+    /// Returns `true` if the encoded message matches the type of [instance].
+    ///
+    /// Can be used with a default instance:
+    /// `any.canUnpackInto(Message.getDefault())`
+    bool canUnpackInto(GeneratedMessage instance);
+
+    /// Creates a new [Any] encoding [message].
+    ///
+    /// The [typeUrl] will be [typeUrlPrefix]/`fullName` where `fullName` is
+    /// the fully qualified name of the type of [message].
+    static Any pack(GeneratedMessage message,
+        {String typeUrlPrefix = 'type.googleapis.com'});
+

Oneof

Given a oneof +definition like this:

message Foo {
+  oneof test {
+    string name = 1;
+    SubMessage sub_message = 2;
+  }
+}
+

The compiler will generate the following Dart enum type:

 enum Foo_Test { name, subMessage, notSet }
+

In addition, it will generate these methods:

  • Foo_Test whichTest(): Returns the enum indicating which field is set. +Returns Foo_Test.notSet if none of them is set.
  • void clearTest(): Clears the value of the oneof field which is currently +set (if any), and sets the oneof case to Foo_Test.notSet.

For each field inside the oneof definition the regular field accessor methods +are generated. For instance for name:

  • String get name: Returns the current value of the field if the oneof case +is Foo_Test.name. Otherwise, returns the default value.
  • set name(String value): Sets the value of the field and sets the oneof +case to Foo_Test.name. After calling this, get name will return value +and whichTest() will return Foo_Test.name.
  • void clearName(): Nothing will be changed if the oneof case is not +Foo_Test.name. Otherwise, clears the value of the field. After calling +this, get name will return the default value and whichTest() will return +Foo_Test.notSet.

Enumerations

Given an enum definition like:

enum Color {
+  COLOR_UNSPECIFIED = 0;
+  COLOR_RED = 1;
+  COLOR_GREEN = 2;
+  COLOR_BLUE = 3;
+}
+

The protocol buffer compiler will generate a class called Color, which extends +the ProtobufEnum class. The class will include a static const Color for each +of the four values, as well as a static const List<Color> that contains the +values.

static const List<Color> values = <Color> [
+  COLOR_UNSPECIFIED,
+  COLOR_RED,
+  COLOR_GREEN,
+  COLOR_BLUE,
+];
+

It will also include the following method:

  • static Color? valueOf(int value): Returns the Color corresponding to the +given numeric value.

Each value will have the following properties:

  • name: The enum’s name, as specified in the .proto file.
  • value: The enum’s integer value, as specified in the .proto file.

Note that the .proto language allows multiple enum symbols to have the same +numeric value. Symbols with the same numeric value are synonyms. For example:

enum Foo {
+  BAR = 0;
+  BAZ = 0;
+}
+

In this case, BAZ is a synonym for BAR and will be defined like so:

static const Foo BAZ = BAR;
+

An enum can be defined nested within a message type. For instance, given an enum +definition like:

message Bar {
+  enum Color {
+    COLOR_UNSPECIFIED = 0;
+    COLOR_RED = 1;
+    COLOR_GREEN = 2;
+    COLOR_BLUE = 3;
+  }
+}
+

The protocol buffer compiler will generate a class called Bar, which extends +GeneratedMessage, and a class called Bar_Color, which extends +ProtobufEnum.

Extensions (not available in proto3)

Given a file foo_test.proto including a message with an +extension range +and a top-level extension definition:

message Foo {
+  extensions 100 to 199;
+}
+
+extend Foo {
+  optional int32 bar = 101;
+}
+

The protocol buffer compiler will generate, in addition to the Foo class, a +class Foo_test which will contain a static Extension for each extension +field in the file along with a method for registering all the extensions in an +ExtensionRegistry :

  • static final Extension bar
  • static void registerAllExtensions(ExtensionRegistry registry) : Registers +all the defined extensions in the given registry.

The extension accessors of Foo can be used as follows:

Foo foo = Foo();
+foo.setExtension(Foo_test.bar, 1);
+assert(foo.hasExtension(Foo_test.bar));
+assert(foo.getExtension(Foo_test.bar)) == 1);
+

Extensions can also be declared nested inside of another message:

message Baz {
+  extend Foo {
+    int32 bar = 124;
+  }
+}
+

In this case, the extension bar is instead declared as a static member of the +Baz class.

When parsing a message that might have extensions, you must provide an +ExtensionRegistry in which you have registered any extensions that you want to +be able to parse. Otherwise, those extensions will just be treated like unknown +fields. For example:

ExtensionRegistry registry = ExtensionRegistry();
+registry.add(Baz.bar);
+Foo foo = Foo.fromBuffer(input, registry);
+

If you already have a parsed message with unknown fields, you can use +reparseMessage on an ExtensionRegistry to reparse the message. If the set of +unknown fields contains extensions that are present in the registry, these +extensions are parsed and removed from the unknown field set. Extensions already +present in the message are preserved.

Foo foo = Foo.fromBuffer(input);
+ExtensionRegistry registry = ExtensionRegistry();
+registry.add(Baz.bar);
+Foo reparsed = registry.reparseMessage(foo);
+

Be aware that this method to retrieve extensions is more expensive overall. +Where possible we recommend using ExtensionRegistry with all the needed +extensions when doing GeneratedMessage.fromBuffer.

Services

Given a service definition:

service Foo {
+  rpc Bar(FooRequest) returns(FooResponse);
+}
+

The protocol buffer compiler can be invoked with the `grpc` option (e.g. +--dart_out=grpc:output_folder), in which case it will generate code to support +gRPC. See the +gRPC Dart Quickstart guide +for more details.

\ No newline at end of file diff --git a/reference/dart/index.html b/reference/dart/index.html new file mode 100644 index 000000000..9ab9631f3 --- /dev/null +++ b/reference/dart/index.html @@ -0,0 +1,8 @@ +Dart Reference | Protocol Buffers Documentation +

Dart Reference

Reference documentation for working with protocol buffer classes in Dart

Dart Generated Code

Describes what Dart code the protocol buffer compiler generates for any given protocol definition.

Dart API

\ No newline at end of file diff --git a/reference/dart/index.xml b/reference/dart/index.xml new file mode 100644 index 000000000..06c1f6b85 --- /dev/null +++ b/reference/dart/index.xml @@ -0,0 +1,2 @@ +Dart Reference on Protocol Buffers Documentationhttps://protobuf.dev/reference/dart/Recent content in Dart Reference on Protocol Buffers DocumentationHugoenDart Generated Codehttps://protobuf.dev/reference/dart/dart-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/dart/dart-generated/Any differences between proto2, proto3, and editions generated code are highlighted - note that these differences are in the generated code as described in this document, not the base API, which are the same in both versions. You should read the proto2 language guide, proto3 language guide, or editions language guide before reading this document. +Compiler Invocation The protocol buffer compiler requires a plugin to generate Dart code. Installing it following the instructions provides a protoc-gen-dart binary which protoc uses when invoked with the --dart_out command-line flag.Dart APIhttps://protobuf.dev/reference/dart/api-docs-link/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/dart/api-docs-link/ \ No newline at end of file diff --git a/reference/go/api-docs-link/index.html b/reference/go/api-docs-link/index.html new file mode 100644 index 000000000..9388eb37b --- /dev/null +++ b/reference/go/api-docs-link/index.html @@ -0,0 +1,4 @@ +Go API | Protocol Buffers Documentation +
\ No newline at end of file diff --git a/reference/go/faq/index.html b/reference/go/faq/index.html new file mode 100644 index 000000000..a3a6214a0 --- /dev/null +++ b/reference/go/faq/index.html @@ -0,0 +1,164 @@ +Go FAQ | Protocol Buffers Documentation +

Go FAQ

A list of frequently asked questions about implementing protocol buffers in Go, with answer for each.

Versions

What’s the difference between github.com/golang/protobuf and google.golang.org/protobuf?

The +github.com/golang/protobuf +module is the original Go protocol buffer API.

The +google.golang.org/protobuf +module is an updated version of this API designed for simplicity, ease of use, +and safety. The flagship features of the updated API are support for reflection +and a separation of the user-facing API from the underlying implementation.

We recommend that you use google.golang.org/protobuf in new code.

Version v1.4.0 and higher of github.com/golang/protobuf wrap the new +implementation and permit programs to adopt the new API incrementally. For +example, the well-known types defined in github.com/golang/protobuf/ptypes are +simply aliases of those defined in the newer module. Thus, +google.golang.org/protobuf/types/known/emptypb +and +github.com/golang/protobuf/ptypes/empty +may be used interchangeably.

What are proto1, proto2, proto3, and editions?

These are revisions of the protocol buffer language. It is different from the +Go implementation of protobufs.

  • Editions are the newest and recommended way of writing Protocol Buffers. +New features will be released as part of new editions. For more information, +see Protocol Buffer Editions.

  • proto3 is a legacy version of the language. We encourage new code to use +editions.

  • proto2 is a legacy version of the language. Despite being superseded by +proto3 and editions, proto2 is still fully supported.

  • proto1 is an obsolete version of the language. It was never released as +open source.

There are several different Message types. Which should I use?

Common problems

go install”: working directory is not part of a module

On Go 1.15 and below, you have set the environment variable GO111MODULE=on and +are running the go install command outside of a module directory. Set +GO111MODULE=auto, or unset the environment variable.

On Go 1.16 and above, go install can be invoked outside of a module by +specifying an explicit version: go install google.golang.org/protobuf/cmd/protoc-gen-go@latest

constant -1 overflows protoimpl.EnforceVersion

You are using a generated .pb.go file which requires a newer version of the +"google.golang.org/protobuf" module.

Update to a newer version with:

go get -u google.golang.org/protobuf/proto
+

undefined: "github.com/golang/protobuf/proto".ProtoPackageIsVersion4

You are using a generated .pb.go file which requires a newer version of the +"github.com/golang/protobuf" module.

Update to a newer version with:

go get -u github.com/golang/protobuf/proto
+

What is a protocol buffer namespace conflict?

All protocol buffers declarations linked into a Go binary are inserted into a +global registry.

Every protobuf declaration (for example, enums, enum values, or messages) has an +absolute name, which is the concatenation of the +package name with +the relative name of the declaration in the .proto source file (for example, +my.proto.package.MyMessage.NestedMessage). The protobuf language assumes that +all declarations are universally unique.

If two protobuf declarations linked into a Go binary have the same name, then +this leads to a namespace conflict, and it is impossible for the registry to +properly resolve that declaration by name. Depending on which version of Go +protobufs is being used, this will either panic at init-time or silently drop +the conflict and lead to a potential bug later during runtime.

How do I fix a protocol buffer namespace conflict?

The way to best fix a namespace conflict depends on the reason why a conflict is +occurring.

Common ways that namespace conflicts occur:

  • Vendored .proto files. When a single .proto file is generated into two +or more Go packages and linked into the same Go binary, it conflicts on +every protobuf declaration in the generated Go packages. This typically +occurs when a .proto file is vendored and a Go package is generated from +it, or the generated Go package itself is vendored. Users should avoid +vendoring and instead depend on a centralized Go package for that .proto +file.

    • If a .proto file is owned by an external party and is lacking a +go_package option, then you should coordinate with the owner of that +.proto file to specify a centralized Go package that a plurality of +users can all depend on.
  • Missing or generic proto package names. If a .proto file does not +specify a package name or uses an overly generic package name (for example, +“my_service”), then there is a high probability that declarations within +that file will conflict with other declarations elsewhere in the universe. +We recommend that every .proto file have a package name that is +deliberately chosen to be universally unique (for example, prefixed with the +name of a company).

Starting with v1.26.0 of the google.golang.org/protobuf module, a hard error +will be reported when a Go program starts up that has multiple conflicting +protobuf names linked into it. While it is preferable that the source of the +conflict be fixed, the fatal error can be immediately worked around in one of +two ways:

  1. At compile time. The default behavior for handling conflicts can be +specified at compile time with a linker-initialized variable: go build -ldflags "-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn"

  2. At program execution. The behavior for handling conflicts when executing +a particular Go binary can be set with an environment variable: +GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn ./main

How do I use protocol buffer editions?

To use a protobuf edition, you must specify the edition in your .proto file. +For example, to use the 2023 edition, add the following to the top of your +.proto file:

edition = "2023";
+

The protocol buffer compiler will then generate Go code that is compatible with +the specified edition. With editions, you can also enable or disable specific +features for your .proto file. For more information, see +Protocol Buffer Editions.

How do I control the behavior of my generated Go code?

With editions, you can control the behavior of the generated Go code by enabling +or disabling specific features in your .proto file. For example, to set the +API behavior for your implementation, you would add the following to your +.proto file:

edition = "2023";
+
+option features.(pb.go).api_level = API_OPAQUE;
+

When api_level is set to API_OPAQUE, the Go code generated by the protocol +buffer compiler hides struct fields so they can no longer be directly accessed. +Instead, new accessor methods are created for getting, setting, or clearing a +field.

For a complete list of available features and their descriptions, see +Features for Editions.

Why does reflect.DeepEqual behave unexpectedly with protobuf messages?

Generated protocol buffer message types include internal state which can vary +even between equivalent messages.

In addition, the reflect.DeepEqual function is not aware of the semantics of +protocol buffer messages, and can report differences where none exist. For +example, a map field containing a nil map and one containing a zero-length, +non-nil map are semantically equivalent, but will be reported as unequal by +reflect.DeepEqual.

Use the +proto.Equal +function to compare message values.

In tests, you can also use the +"github.com/google/go-cmp/cmp" +package with the +protocmp.Transform() +option. The cmp package can compare arbitrary data structures, and +cmp.Diff produces +human-readable reports of the differences between values.

if diff := cmp.Diff(a, b, protocmp.Transform()); diff != "" {
+  t.Errorf("unexpected difference:\n%v", diff)
+}
+

Hyrum’s Law

What is Hyrum’s Law, and why is it in this FAQ?

Hyrum’s Law states:

With a sufficient number of users of an API, it does not matter what you +promise in the contract: all observable behaviors of your system will be +depended on by somebody.

A design goal of the latest version of the Go protocol buffer API is to avoid, +where possible, providing observable behaviors that we cannot promise to keep +stable in the future. It is our philosophy that deliberate instability in areas +where we make no promises is better than giving the illusion of stability, only +for that to change in the future after a project has potentially been long +depending on that false assumption.

Why does the text of errors keep changing?

Tests depending on the exact text of errors are brittle and break often when +that text changes. To discourage unsafe use of error text in tests, the text of +errors produced by this module is deliberately unstable.

If you need to identify whether an error is produced by the +protobuf module, we +guarantee that all errors will match +proto.Error +according to errors.Is.

Why does the output of protojson keep changing?

We make no promises about the long-term stability of Go’s implementation of the +JSON format for protocol buffers. +The specification only specifies what is valid JSON, but provides no +specification for a canonical format for how a marshaler ought to exactly +format a given message. To avoid giving the illusion that the output is stable, +we deliberately introduce minor differences so that byte-for-byte comparisons +are likely to fail.

To gain some degree of output stability, we recommend running the output through +a JSON formatter.

Why does the output of prototext keep changing?

We make no promises about the long-term stability of Go’s implementation of the +text format. There is no canonical specification of the protobuf text format, +and we would like to preserve the ability to make improvements in the +prototext package output in the future. Since we don’t promise stability in +the package’s output, we’ve deliberately introduced instability to discourage +users from depending on it.

To obtain some degree of stability, we recommend passing the output of +prototext through the +txtpbfmt program. The formatter +can be directly invoked in Go using +parser.Format.

Miscellaneous

How do I use a protocol buffer message as a hash key?

You need canonical serialization, where the marshaled output of a protocol +buffer message is guaranteed to be stable over time. Unfortunately, no +specification for canonical serialization exists at this time. You’ll need to +write your own or find a way to avoid needing one.

Can I add a new feature to the Go protocol buffer implementation?

Maybe. We always like suggestions, but we’re very cautious about adding new +things.

The Go implementation of protocol buffers strives to be consistent with the +other language implementations. As such, we tend to shy away from feature that +are overly specialized to just Go. Go-specific features hinder the goal of +protocol buffers being a language-neutral data interchange format.

Unless your idea is specific to the Go implementation, you should join the +protobuf discussion group and suggest +it there.

If you have an idea for the Go implementation, file an issue on our issue +tracker: +https://github.com/golang/protobuf/issues

Can I add an option to Marshal or Unmarshal to customize it?

Only if that option exists in other implementations (e.g., C++, Java). The +encoding of protocol buffers (binary, JSON, and text) must be consistent across +implementations, so a program written in one language is able to read messages +written by another one.

We will not add any options to the Go implementation that affect the data output +by Marshal functions or read by Unmarshal functions unless an equivalent +option exist in at least one other supported implementation.

Can I customize the code generated by protoc-gen-go?

In general, no. Protocol buffers are intended to be a language-agnostic data +interchange format, and implementation-specific customizations run counter to +that intent.

\ No newline at end of file diff --git a/reference/go/go-generated-opaque/index.html b/reference/go/go-generated-opaque/index.html new file mode 100644 index 000000000..c3ca236a7 --- /dev/null +++ b/reference/go/go-generated-opaque/index.html @@ -0,0 +1,375 @@ +Go Generated Code Guide (Opaque) | Protocol Buffers Documentation +

Go Generated Code Guide (Opaque)

Describes exactly what Go code the protocol buffer compiler generates for any given protocol definition.

Any differences between +proto2 and proto3 generated code are highlighted - note that these differences +are in the generated code as described in this document, not the base API, which +are the same in both versions. You should read the +proto2 language guide +and/or the +proto3 language guide +before reading this document.

Compiler Invocation

The protocol buffer compiler requires a plugin to generate Go code. Install it +using Go 1.16 or higher by running:

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
+

This will install a protoc-gen-go binary in $GOBIN. Set the $GOBIN +environment variable to change the installation location. It must be in your +$PATH for the protocol buffer compiler to find it.

The protocol buffer compiler produces Go output when invoked with the go_out +flag. The argument to the go_out flag is the directory where you want the +compiler to write your Go output. The compiler creates a single source file for +each .proto file input. The name of the output file is created by replacing +the .proto extension with .pb.go.

Where in the output directory the generated .pb.go file is placed depends on +the compiler flags. There are several output modes:

  • If the paths=import flag is specified, the output file is placed in a +directory named after the Go package’s import path (such as one provided by +the go_package option within the .proto file). For example, an input +file protos/buzz.proto with a Go import path of +example.com/project/protos/fizz results in an output file at +example.com/project/protos/fizz/buzz.pb.go. This is the default output +mode if a paths flag is not specified.
  • If the module=$PREFIX flag is specified, the output file is placed in a +directory named after the Go package’s import path (such as one provided by +the go_package option within the .proto file), but with the specified +directory prefix removed from the output filename. For example, an input +file protos/buzz.proto with a Go import path of +example.com/project/protos/fizz and example.com/project specified as the +module prefix results in an output file at protos/fizz/buzz.pb.go. +Generating any Go packages outside the module path results in an error. This +mode is useful for outputting generated files directly into a Go module.
  • If the paths=source_relative flag is specified, the output file is placed +in the same relative directory as the input file. For example, an input file +protos/buzz.proto results in an output file at protos/buzz.pb.go.

Flags specific to protoc-gen-go are provided by passing a go_opt flag when +invoking protoc. Multiple go_opt flags may be passed. For example, when +running:

protoc --proto_path=src --go_out=out --go_opt=paths=source_relative foo.proto bar/baz.proto
+

the compiler will read input files foo.proto and bar/baz.proto from within +the src directory, and write output files foo.pb.go and bar/baz.pb.go to +the out directory. The compiler automatically creates nested output +sub-directories if necessary, but will not create the output directory itself.

Packages

In order to generate Go code, the Go package’s import path must be provided for +every .proto file (including those transitively depended upon by the .proto +files being generated). There are two ways to specify the Go import path:

  • by declaring it within the .proto file, or
  • by declaring it on the command line when invoking protoc.

We recommend declaring it within the .proto file so that the Go packages for +.proto files can be centrally identified with the .proto files themselves +and to simplify the set of flags passed when invoking protoc. If the Go import +path for a given .proto file is provided by both the .proto file itself and +on the command line, then the latter takes precedence over the former.

The Go import path is locally specified in a .proto file by declaring a +go_package option with the full import path of the Go package. Example usage:

option go_package = "example.com/project/protos/fizz";
+

The Go import path may be specified on the command line when invoking the +compiler, by passing one or more M${PROTO_FILE}=${GO_IMPORT_PATH} flags. +Example usage:

protoc --proto_path=src \
+  --go_opt=Mprotos/buzz.proto=example.com/project/protos/fizz \
+  --go_opt=Mprotos/bar.proto=example.com/project/protos/foo \
+  protos/buzz.proto protos/bar.proto
+

Since the mapping of all .proto files to their Go import paths can be quite +large, this mode of specifying the Go import paths is generally performed by +some build tool (e.g., Bazel) that has +control over the entire dependency tree. If there are duplicate entries for a +given .proto file, then the last one specified takes precedence.

For both the go_package option and the M flag, the value may include an +explicit package name separated from the import path by a semicolon. For +example: "example.com/protos/foo;package_name". This usage is discouraged +since the package name will be derived by default from the import path in a +reasonable manner.

The import path is used to determine which import statements must be generated +when one .proto file imports another .proto file. For example, if a.proto +imports b.proto, then the generated a.pb.go file needs to import the Go +package which contains the generated b.pb.go file (unless both files are in +the same package). The import path is also used to construct output filenames. +See the "Compiler Invocation" section above for details.

There is no correlation between the Go import path and the +package specifier +in the .proto file. The latter is only relevant to the protobuf namespace, +while the former is only relevant to the Go namespace. Also, there is no +correlation between the Go import path and the .proto import path.

API level

The generated code either uses the Open Struct API or the Opaque API. See the +Go Protobuf: The new Opaque API +blog post for an introduction.

Depending on the syntax your .proto file uses, here is which API will be used:

.proto syntaxAPI level
proto2Open Struct API
proto3Open Struct API
edition 2023Open Struct API
edition 2024+Opaque API

You can select the API by setting the api_level editions feature in your +.proto file. This can be set per file or per message:

edition = "2023";
+
+package log;
+
+import "google/protobuf/go_features.proto";
+option features.(pb.go).api_level = API_OPAQUE;
+
+message LogEntry {  }
+

For your convenience, you can also override the default API level with a +protoc command-line flag:

protoc […] --go_opt=default_api_level=API_HYBRID
+

To override the default API level for a specific file (instead of all files), +use the apilevelM mapping flag (similar to the M flag for import +paths):

protoc […] --go_opt=apilevelMhello.proto=API_HYBRID
+

The command-line flags also work for .proto files still using proto2 or proto3 +syntax, but if you want to select the API level from within the .proto file, +you need to migrate said file to editions first.

Messages

Given a simple message declaration:

message Artist {}
+

the protocol buffer compiler generates a struct called Artist. An *Artist +implements the +proto.Message +interface.

The +proto package +provides functions which operate on messages, including conversion to and from +binary format.

The proto.Message interface defines a ProtoReflect method. This method +returns a +protoreflect.Message +which provides a reflection-based view of the message.

The optimize_for option does not affect the output of the Go code generator.

When multiple goroutines concurrently access the same message, the following +rules apply:

  • Accessing (reading) fields concurrently is safe, with one exception:
    • Accessing a lazy field +for the first time is a modification.
  • Modifying different fields in the same message is safe.
  • Modifying a field concurrently is not safe.
  • Modifying a message in any way concurrently with functions of the +proto package, +such as +proto.Marshal +or proto.Size +is not safe.

Nested Types

A message can be declared inside another message. For example:

message Artist {
+  message Name {
+  }
+}
+

In this case, the compiler generates two structs: Artist and Artist_Name.

Fields

The protocol buffer compiler generates accessor methods (setters and getters) +for each field defined within a message.

Note that the generated Go accessor methods always use camel-case naming, even +if the field name in the .proto file uses lower-case with underscores +(as it should). The +case-conversion works as follows:

  1. The first letter is capitalized for export. If the first character is an +underscore, it is removed and a capital X is prepended.
  2. If an interior underscore is followed by a lower-case letter, the underscore +is removed, and the following letter is capitalized.

Thus, you can access the proto field birth_year using the GetBirthYear() +method in Go, and _birth_year_2 using GetXBirthYear_2().

Singular Fields

For this field definition:

// proto2 and proto3
+message Artist {
+  optional int32 birth_year = 1;
+}
+
+// editions
+message Artist {
+  int32 birth_year = 1 [features.field_presence = EXPLICIT];
+}
+

the compiler generates a Go struct with the following accessor methods:

func (m *Artist) GetBirthYear() int32
+func (m *Artist) SetBirthYear(v int32)
+

With implicit presence, the getter returns the int32 value in birth_year or +the zero value of that +type if the field is unset (0 for numbers, the empty string for strings). With +explicit presence, the getter returns the int32 value in birth_year or the +default value if the field is unset. If the default is not explicitly set, the +zero value is used instead.

For other scalar field types (including bool, bytes, and string), int32 +is replaced with the corresponding Go type according to the +scalar value types table.

In fields with explicit presence, you can also use these methods:

func (m *Artist) HasBirthYear() bool
+func (m *Artist) ClearBirthYear()
+

Singular Message Fields

Given the message type:

message Band {}
+

For a message with a Band field:

// proto2
+message Concert {
+  optional Band headliner = 1;
+  // The generated code is the same result if required instead of optional.
+}
+
+// proto3 and editions
+message Concert {
+  Band headliner = 1;
+}
+

The compiler will generate a Go struct with the following accessor methods:

type Concert struct { ... }
+
+func (m *Concert) GetHeadliner() *Band { ... }
+func (m *Concert) SetHeadliner(v *Band) { ... }
+func (m *Concert) HasHeadliner() bool { ... }
+func (m *Concert) ClearHeadliner() { ... }
+

The GetHeadliner() accessor method is safe to call even if m is nil. This +makes it possible to chain get calls without intermediate nil checks:

var m *Concert // defaults to nil
+log.Infof("GetFoundingYear() = %d (no panic!)", m.GetHeadliner().GetFoundingYear())
+

If the field is unset, the getter will return the default value of the field. +For messages, the default value is a nil pointer.

Contrary to getters, setters do not perform nil checks for you. Therefore, you +cannot safely call setters on possibly-nil messages.

Repeated Fields

For repeated fields, the accessor methods use a slice type. For this message +with a repeated field:

message Concert {
+  // Best practice: use pluralized names for repeated fields:
+  // /programming-guides/style#repeated-fields
+  repeated Band support_acts = 1;
+}
+

the compiler generates a Go struct with the following accessor methods:

type Concert struct { ... }
+
+func (m *Concert) GetSupportActs() []*Band { ... }
+func (m *Concert) SetSupportActs(v []*Band) { ... }
+

Likewise, for the field definition repeated bytes band_promo_images = 1; the +compiler will generate accessors working with the [][]byte type. For a +repeated enumeration repeated MusicGenre genres = 2;, the compiler +generates accessors working with the []MusicGenre type.

The following example shows how to construct a Concert message using a +builder.

concert := Concert_builder{
+  SupportActs: []*Band{
+    {}, // First element.
+    {}, // Second element.
+  },
+}.Build()
+

Alternatively, you can use setters:

concert := &Concert{}
+concert.SetSupportActs([]*Band{
+    {}, // First element.
+    {}, // Second element.
+})
+

To access the field, you can do the following:

support := concert.GetSupportActs() // support type is []*Band.
+b1 := support[0] // b1 type is *Band, the first element in support_acts.
+

Map Fields

Each map field generates accessors working with type map[TKey]TValue where +TKey is the field’s key type and TValue is the field’s value type. For this +message with a map field:

message MerchItem {}
+
+message MerchBooth {
+  // items maps from merchandise item name ("Signed T-Shirt") to
+  // a MerchItem message with more details about the item.
+  map<string, MerchItem> items = 1;
+}
+

the compiler generates a Go struct with the following accessor methods:

type MerchBooth struct { ... }
+
+func (m *MerchBooth) GetItems() map[string]*MerchItem { ... }
+func (m *MerchBooth) SetItems(v map[string]*MerchItem) { ... }
+

Oneof Fields

For a oneof field, the protobuf compiler generates accessors for each of the +singular fields within the oneof.

For this message with a oneof field:

package account;
+message Profile {
+  oneof avatar {
+    string image_url = 1;
+    bytes image_data = 2;
+  }
+}
+

the compiler generates a Go struct with the following accessor methods:

type Profile struct { ... }
+
+func (m *Profile) WhichAvatar() case_Profile_Avatar { ... }
+func (m *Profile) GetImageUrl() string { ... }
+func (m *Profile) GetImageData() []byte { ... }
+
+func (m *Profile) SetImageUrl(v string) { ... }
+func (m *Profile) SetImageData(v []byte) { ... }
+
+func (m *Profile) HasAvatar() bool { ... }
+func (m *Profile) HasImageUrl() bool { ... }
+func (m *Profile) HasImageData() bool { ... }
+
+func (m *Profile) ClearAvatar() { ... }
+func (m *Profile) ClearImageUrl() { ... }
+func (m *Profile) ClearImageData() { ... }
+

The following example shows how to set the field using a builder:

p1 := accountpb.Profile_builder{
+  ImageUrl: proto.String("https://example.com/image.png"),
+}.Build()
+

…or, equivalently, using a setter:

// imageData is []byte
+imageData := getImageData()
+p2 := &accountpb.Profile{}
+p2.SetImageData(imageData)
+

To access the field, you can use a switch statement on the WhichAvatar() +result:

switch m.WhichAvatar() {
+case accountpb.Profile_ImageUrl_case:
+    // Load profile image based on URL
+    // using m.GetImageUrl()
+
+case accountpb.Profile_ImageData_case:
+    // Load profile image based on bytes
+    // using m.GetImageData()
+
+case accountpb.Profile_Avatar_not_set_case:
+    // The field is not set.
+
+default:
+    return fmt.Errorf("Profile.Avatar has an unexpected new oneof field %v", x)
+}
+

Builders

Builders are a convenient way to construct and initialize a message within a +single expression, especially when working with nested messages like unit tests.

Contrary to builders in other languages (like Java), Go protobuf builders are +not meant to be passed around between functions. Instead, call Build() +immediately and pass the resulting proto message instead, using setters to +modify fields.

Here is an example for using builders to create a Band message, which is the +only repeated field inside the enclosing Concert message:

concert := Concert_builder{
+  SupportActs: []*Band{
+    Band_builder{
+      Name: proto.String("Varint and the Marshals"),
+    }.Build()
+  },
+}.Build()
+

Enumerations

Given an enumeration like:

message Venue {
+  enum Kind {
+    KIND_UNSPECIFIED = 0;
+    KIND_CONCERT_HALL = 1;
+    KIND_STADIUM = 2;
+    KIND_BAR = 3;
+    KIND_OPEN_AIR_FESTIVAL = 4;
+  }
+  Kind kind = 1;
+  // ...
+}
+

the protocol buffer compiler generates a type and a series of constants with +that type:

type Venue_Kind int32
+
+const (
+    Venue_KIND_UNSPECIFIED       Venue_Kind = 0
+    Venue_KIND_CONCERT_HALL      Venue_Kind = 1
+    Venue_KIND_STADIUM           Venue_Kind = 2
+    Venue_KIND_BAR               Venue_Kind = 3
+    Venue_KIND_OPEN_AIR_FESTIVAL Venue_Kind = 4
+)
+

For enums within a message (like the one above), the type name begins with the +message name:

type Venue_Kind int32
+

For a package-level enum:

enum Genre {
+  GENRE_UNSPECIFIED = 0;
+  GENRE_ROCK = 1;
+  GENRE_INDIE = 2;
+  GENRE_DRUM_AND_BASS = 3;
+  // ...
+}
+

the Go type name is unmodified from the proto enum name:

type Genre int32
+

This type has a String() method that returns the name of a given value.

The Enum() method initializes freshly allocated memory with a given value and +returns the corresponding pointer:

func (Genre) Enum() *Genre
+

The protocol buffer compiler generates a constant for each value in the enum. +For enums within a message, the constants begin with the enclosing message’s +name:

const (
+    Venue_KIND_UNSPECIFIED       Venue_Kind = 0
+    Venue_KIND_CONCERT_HALL      Venue_Kind = 1
+    Venue_KIND_STADIUM           Venue_Kind = 2
+    Venue_KIND_BAR               Venue_Kind = 3
+    Venue_KIND_OPEN_AIR_FESTIVAL Venue_Kind = 4
+)
+

For a package-level enum, the constants begin with the enum name instead:

const (
+    Genre_GENRE_UNSPECIFIED   Genre = 0
+    Genre_GENRE_ROCK          Genre = 1
+    Genre_GENRE_INDIE         Genre = 2
+    Genre_GENRE_DRUM_AND_BASS Genre = 3
+)
+

The protobuf compiler also generates a map from integer values to the string +names and a map from the names to the values:

var Genre_name = map[int32]string{
+    0: "GENRE_UNSPECIFIED",
+    1: "GENRE_ROCK",
+    2: "GENRE_INDIE",
+    3: "GENRE_DRUM_AND_BASS",
+}
+var Genre_value = map[string]int32{
+    "GENRE_UNSPECIFIED":   0,
+    "GENRE_ROCK":          1,
+    "GENRE_INDIE":         2,
+    "GENRE_DRUM_AND_BASS": 3,
+}
+

Note that the .proto language allows multiple enum symbols to have the same +numeric value. Symbols with the same numeric value are synonyms. These are +represented in Go in exactly the same way, with multiple names corresponding to +the same numeric value. The reverse mapping contains a single entry for the +numeric value to the name which appears first in the .proto file.

Extensions (proto2)

Given an extension definition:

extend Concert {
+  optional int32 promo_id = 123;
+}
+

The protocol buffer compiler will generate a +protoreflect.ExtensionType +value named E_Promo_id. This value may be used with the +proto.GetExtension, +proto.SetExtension, +proto.HasExtension, +and +proto.ClearExtension +functions to access an extension in a message. The GetExtension function and +SetExtension functions respectively return and accept an interface{} value +containing the extension value type.

For singular scalar extension fields, the extension value type is the +corresponding Go type from the +scalar value types table.

For singular embedded message extension fields, the extension value type is +*M, where M is the field message type.

For repeated extension fields, the extension value type is a slice of the +singular type.

For example, given the following definition:

extend Concert {
+  optional int32 singular_int32 = 1;
+  repeated bytes repeated_strings = 2;
+  optional Band singular_message = 3;
+}
+

Extension values may be accessed as:

m := &somepb.Concert{}
+proto.SetExtension(m, extpb.E_SingularInt32, int32(1))
+proto.SetExtension(m, extpb.E_RepeatedString, []string{"a", "b", "c"})
+proto.SetExtension(m, extpb.E_SingularMessage, &extpb.Band{})
+
+v1 := proto.GetExtension(m, extpb.E_SingularInt32).(int32)
+v2 := proto.GetExtension(m, extpb.E_RepeatedString).([][]byte)
+v3 := proto.GetExtension(m, extpb.E_SingularMessage).(*extpb.Band)
+

Extensions can be declared nested inside of another type. For example, a common +pattern is to do something like this:

message Promo {
+  extend Concert {
+    optional int32 promo_id = 124;
+  }
+}
+

In this case, the ExtensionType value is named E_Promo_Concert.

Services

The Go code generator does not produce output for services by default. If you +enable the gRPC plugin (see the +gRPC Go Quickstart guide) +then code will be generated to support gRPC.

\ No newline at end of file diff --git a/reference/go/go-generated/index.html b/reference/go/go-generated/index.html new file mode 100644 index 000000000..a2b34dcdc --- /dev/null +++ b/reference/go/go-generated/index.html @@ -0,0 +1,358 @@ +Go Generated Code Guide (Open) | Protocol Buffers Documentation +

Go Generated Code Guide (Open)

Describes exactly what Go code the protocol buffer compiler generates for any given protocol definition.

Any differences between +proto2, proto3, and editions generated code are highlighted - note that these +differences are in the generated code as described in this document, not the +base API, which are the same in both versions. You should read the +proto2 language guide, +proto3 language guide, or +editions language guide +before reading this document.

Compiler Invocation

The protocol buffer compiler requires a plugin to generate Go code. Install it +using Go 1.16 or higher by running:

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
+

This will install a protoc-gen-go binary in $GOBIN. Set the $GOBIN +environment variable to change the installation location. It must be in your +$PATH for the protocol buffer compiler to find it.

The protocol buffer compiler produces Go output when invoked with the go_out +flag. The argument to the go_out flag is the directory where you want the +compiler to write your Go output. The compiler creates a single source file for +each .proto file input. The name of the output file is created by replacing +the .proto extension with .pb.go.

Where in the output directory the generated .pb.go file is placed depends on +the compiler flags. There are several output modes:

  • If the paths=import flag is specified, the output file is placed in a +directory named after the Go package’s import path (such as one provided by +the go_package option within the .proto file). For example, an input +file protos/buzz.proto with a Go import path of +example.com/project/protos/fizz results in an output file at +example.com/project/protos/fizz/buzz.pb.go. This is the default output +mode if a paths flag is not specified.
  • If the module=$PREFIX flag is specified, the output file is placed in a +directory named after the Go package’s import path (such as one provided by +the go_package option within the .proto file), but with the specified +directory prefix removed from the output filename. For example, an input +file protos/buzz.proto with a Go import path of +example.com/project/protos/fizz and example.com/project specified as the +module prefix results in an output file at protos/fizz/buzz.pb.go. +Generating any Go packages outside the module path results in an error. This +mode is useful for outputting generated files directly into a Go module.
  • If the paths=source_relative flag is specified, the output file is placed +in the same relative directory as the input file. For example, an input file +protos/buzz.proto results in an output file at protos/buzz.pb.go.

Flags specific to protoc-gen-go are provided by passing a go_opt flag when +invoking protoc. Multiple go_opt flags may be passed. For example, when +running:

protoc --proto_path=src --go_out=out --go_opt=paths=source_relative foo.proto bar/baz.proto
+

the compiler will read input files foo.proto and bar/baz.proto from within +the src directory, and write output files foo.pb.go and bar/baz.pb.go to +the out directory. The compiler automatically creates nested output +sub-directories if necessary, but will not create the output directory itself.

Packages

In order to generate Go code, the Go package’s import path must be provided for +every .proto file (including those transitively depended upon by the .proto +files being generated). There are two ways to specify the Go import path:

  • by declaring it within the .proto file, or
  • by declaring it on the command line when invoking protoc.

We recommend declaring it within the .proto file so that the Go packages for +.proto files can be centrally identified with the .proto files themselves +and to simplify the set of flags passed when invoking protoc. If the Go import +path for a given .proto file is provided by both the .proto file itself and +on the command line, then the latter takes precedence over the former.

The Go import path is locally specified in a .proto file by declaring a +go_package option with the full import path of the Go package. Example usage:

option go_package = "example.com/project/protos/fizz";
+

The Go import path may be specified on the command line when invoking the +compiler, by passing one or more M${PROTO_FILE}=${GO_IMPORT_PATH} flags. +Example usage:

protoc --proto_path=src \
+  --go_opt=Mprotos/buzz.proto=example.com/project/protos/fizz \
+  --go_opt=Mprotos/bar.proto=example.com/project/protos/foo \
+  protos/buzz.proto protos/bar.proto
+

Since the mapping of all .proto files to their Go import paths can be quite +large, this mode of specifying the Go import paths is generally performed by +some build tool (e.g., Bazel) that has +control over the entire dependency tree. If there are duplicate entries for a +given .proto file, then the last one specified takes precedence.

For both the go_package option and the M flag, the value may include an +explicit package name separated from the import path by a semicolon. For +example: "example.com/protos/foo;package_name". This usage is discouraged +since the package name will be derived by default from the import path in a +reasonable manner.

The import path is used to determine which import statements must be generated +when one .proto file imports another .proto file. For example, if a.proto +imports b.proto, then the generated a.pb.go file needs to import the Go +package which contains the generated b.pb.go file (unless both files are in +the same package). The import path is also used to construct output filenames. +See the "Compiler Invocation" section above for details.

There is no correlation between the Go import path and the +package specifier +in the .proto file. The latter is only relevant to the protobuf namespace, +while the former is only relevant to the Go namespace. Also, there is no +correlation between the Go import path and the .proto import path.

API level

The generated code either uses the Open Struct API or the Opaque API. See the +Go Protobuf: The new Opaque API +blog post for an introduction.

Depending on the syntax your .proto file uses, here is which API will be used:

.proto syntaxAPI level
proto2Open Struct API
proto3Open Struct API
edition 2023Open Struct API
edition 2024+Opaque API

You can select the API by setting the api_level editions feature in your +.proto file. This can be set per file or per message:

edition = "2023";
+
+package log;
+
+import "google/protobuf/go_features.proto";
+option features.(pb.go).api_level = API_OPAQUE;
+
+message LogEntry {  }
+

For your convenience, you can also override the default API level with a +protoc command-line flag:

protoc […] --go_opt=default_api_level=API_HYBRID
+

To override the default API level for a specific file (instead of all files), +use the apilevelM mapping flag (similar to the M flag for import +paths):

protoc […] --go_opt=apilevelMhello.proto=API_HYBRID
+

The command-line flags also work for .proto files still using proto2 or proto3 +syntax, but if you want to select the API level from within the .proto file, +you need to migrate said file to editions first.

Messages

Given a simple message declaration:

message Artist {}
+

the protocol buffer compiler generates a struct called Artist. An *Artist +implements the +proto.Message +interface.

The +proto package +provides functions which operate on messages, including conversion to and from +binary format.

The proto.Message interface defines a ProtoReflect method. This method +returns a +protoreflect.Message +which provides a reflection-based view of the message.

The optimize_for option does not affect the output of the Go code generator.

When multiple goroutines concurrently access the same message, the following +rules apply:

  • Accessing (reading) fields concurrently is safe, with one exception:
    • Accessing a lazy field +for the first time is a modification.
  • Modifying different fields in the same message is safe.
  • Modifying a field concurrently is not safe.
  • Modifying a message in any way concurrently with functions of the +proto package, +such as +proto.Marshal +or proto.Size +is not safe.

Nested Types

A message can be declared inside another message. For example:

message Artist {
+  message Name {
+  }
+}
+

In this case, the compiler generates two structs: Artist and Artist_Name.

Fields

The protocol buffer compiler generates a struct field for each field defined +within a message. The exact nature of this field depends on its type and whether +it is a singular, repeated, map, or oneof field.

Note that the generated Go field names always use camel-case naming, even if the +field name in the .proto file uses lower-case with underscores +(as it should). +The case-conversion works as follows:

  1. The first letter is capitalized for export. If the first character is an +underscore, it is removed and a capital X is prepended.
  2. If an interior underscore is followed by a lower-case letter, the underscore +is removed, and the following letter is capitalized.

Thus, the proto field birth_year becomes BirthYear in Go, and +_birth_year_2 becomes XBirthYear_2.

Singular Explicit Presence Scalar Fields

For the field definition:

int32 birth_year = 1;
+

the compiler generates a struct with an *int32 field named BirthYear and an +accessor method GetBirthYear() which returns the int32 value in Artist or +the default value if the field is unset. If the default is not explicitly set, +the zero value of that +type is used instead (0 for numbers, the empty string for strings).

For other scalar field types (including bool, bytes, and string), *int32 +is replaced with the corresponding Go type according to the +scalar value types table.

Singular Implicit Presence Scalar Fields

For this field definition:

int32 birth_year = 1;
+

The compiler will generate a struct with an int32 field named BirthYear and +an accessor method GetBirthYear() which returns the int32 value in +birth_year or the +zero value of that type +if the field is unset (0 for numbers, the empty string for strings).

The FirstActiveYear struct field will be of type *int32, because it is +marked optional.

For other scalar field types (including bool, bytes, and string), int32 +is replaced with the corresponding Go type according to the +scalar value types table. +Unset values in the proto will be represented as the +zero value of that type (0 for +numbers, the empty string for strings).

Singular Message Fields

Given the message type:

message Band {}
+

For a message with a Band field:

// proto2
+message Concert {
+  optional Band headliner = 1;
+  // The generated code is the same result if required instead of optional.
+}
+
+// proto3
+message Concert {
+  Band headliner = 1;
+}
+
+// editions
+message Concer {
+  Band headliner = 1;
+}
+

The compiler will generate a Go struct

type Concert struct {
+    Headliner *Band
+}
+

Message fields can be set to nil, which means that the field is unset, +effectively clearing the field. This is not equivalent to setting the value to +an "empty" instance of the message struct.

The compiler also generates a func (m *Concert) GetHeadliner() *Band helper +function. This function returns a nil *Band if m is nil or headliner is +unset. This makes it possible to chain get calls without intermediate nil +checks:

var m *Concert // defaults to nil
+log.Infof("GetFoundingYear() = %d (no panic!)", m.GetHeadliner().GetFoundingYear())
+

Repeated Fields

Each repeated field generates a slice of T field in the struct in Go, where +T is the field’s element type. For this message with a repeated field:

message Concert {
+  // Best practice: use pluralized names for repeated fields:
+  // /programming-guides/style#repeated-fields
+  repeated Band support_acts = 1;
+}
+

the compiler generates the Go struct:

type Concert struct {
+    SupportActs []*Band
+}
+

Likewise, for the field definition repeated bytes band_promo_images = 1; the +compiler will generate a Go struct with a [][]byte field named +BandPromoImage. For a repeated enumeration like repeated MusicGenre genres = 2;, the compiler generates a struct with a []MusicGenre field called +Genre.

The following example shows how to set the field:

concert := &Concert{
+  SupportActs: []*Band{
+    {}, // First element.
+    {}, // Second element.
+  },
+}
+

To access the field, you can do the following:

support := concert.GetSupportActs() // support type is []*Band.
+b1 := support[0] // b1 type is *Band, the first element in support_acts.
+

Map Fields

Each map field generates a field in the struct of type map[TKey]TValue where +TKey is the field’s key type and TValue is the field’s value type. For this +message with a map field:

message MerchItem {}
+
+message MerchBooth {
+  // items maps from merchandise item name ("Signed T-Shirt") to
+  // a MerchItem message with more details about the item.
+  map<string, MerchItem> items = 1;
+}
+

the compiler generates the Go struct:

type MerchBooth struct {
+    Items map[string]*MerchItem
+}
+

Oneof Fields

For a oneof field, the protobuf compiler generates a single field with an +interface type isMessageName_MyField. It also generates a struct for each of +the singular fields within the oneof. These all +implement this isMessageName_MyField interface.

For this message with a oneof field:

package account;
+message Profile {
+  oneof avatar {
+    string image_url = 1;
+    bytes image_data = 2;
+  }
+}
+

the compiler generates the structs:

type Profile struct {
+    // Types that are valid to be assigned to Avatar:
+    //  *Profile_ImageUrl
+    //  *Profile_ImageData
+    Avatar isProfile_Avatar `protobuf_oneof:"avatar"`
+}
+
+type Profile_ImageUrl struct {
+        ImageUrl string
+}
+type Profile_ImageData struct {
+        ImageData []byte
+}
+

Both *Profile_ImageUrl and *Profile_ImageData implement isProfile_Avatar +by providing an empty isProfile_Avatar() method.

The following example shows how to set the field:

p1 := &account.Profile{
+  Avatar: &account.Profile_ImageUrl{ImageUrl: "http://example.com/image.png"},
+}
+
+// imageData is []byte
+imageData := getImageData()
+p2 := &account.Profile{
+  Avatar: &account.Profile_ImageData{ImageData: imageData},
+}
+

To access the field, you can use a type switch on the value to handle the +different message types.

switch x := m.Avatar.(type) {
+case *account.Profile_ImageUrl:
+    // Load profile image based on URL
+    // using x.ImageUrl
+case *account.Profile_ImageData:
+    // Load profile image based on bytes
+    // using x.ImageData
+case nil:
+    // The field is not set.
+default:
+    return fmt.Errorf("Profile.Avatar has unexpected type %T", x)
+}
+

The compiler also generates get methods func (m *Profile) GetImageUrl() string +and func (m *Profile) GetImageData() []byte. Each get function returns the +value for that field or the zero value if it is not set.

Enumerations

Given an enumeration like:

message Venue {
+  enum Kind {
+    KIND_UNSPECIFIED = 0;
+    KIND_CONCERT_HALL = 1;
+    KIND_STADIUM = 2;
+    KIND_BAR = 3;
+    KIND_OPEN_AIR_FESTIVAL = 4;
+  }
+  Kind kind = 1;
+  // ...
+}
+

the protocol buffer compiler generates a type and a series of constants with +that type:

type Venue_Kind int32
+
+const (
+    Venue_KIND_UNSPECIFIED       Venue_Kind = 0
+    Venue_KIND_CONCERT_HALL      Venue_Kind = 1
+    Venue_KIND_STADIUM           Venue_Kind = 2
+    Venue_KIND_BAR               Venue_Kind = 3
+    Venue_KIND_OPEN_AIR_FESTIVAL Venue_Kind = 4
+)
+

For enums within a message (like the one above), the type name begins with the +message name:

type Venue_Kind int32
+

For a package-level enum:

enum Genre {
+  GENRE_UNSPECIFIED = 0;
+  GENRE_ROCK = 1;
+  GENRE_INDIE = 2;
+  GENRE_DRUM_AND_BASS = 3;
+  // ...
+}
+

the Go type name is unmodified from the proto enum name:

type Genre int32
+

This type has a String() method that returns the name of a given value.

The Enum() method initializes freshly allocated memory with a given value and +returns the corresponding pointer:

func (Genre) Enum() *Genre
+

The protocol buffer compiler generates a constant for each value in the enum. +For enums within a message, the constants begin with the enclosing message’s +name:

const (
+    Venue_KIND_UNSPECIFIED       Venue_Kind = 0
+    Venue_KIND_CONCERT_HALL      Venue_Kind = 1
+    Venue_KIND_STADIUM           Venue_Kind = 2
+    Venue_KIND_BAR               Venue_Kind = 3
+    Venue_KIND_OPEN_AIR_FESTIVAL Venue_Kind = 4
+)
+

For a package-level enum, the constants begin with the enum name instead:

const (
+    Genre_GENRE_UNSPECIFIED   Genre = 0
+    Genre_GENRE_ROCK          Genre = 1
+    Genre_GENRE_INDIE         Genre = 2
+    Genre_GENRE_DRUM_AND_BASS Genre = 3
+)
+

The protobuf compiler also generates a map from integer values to the string +names and a map from the names to the values:

var Genre_name = map[int32]string{
+    0: "GENRE_UNSPECIFIED",
+    1: "GENRE_ROCK",
+    2: "GENRE_INDIE",
+    3: "GENRE_DRUM_AND_BASS",
+}
+var Genre_value = map[string]int32{
+    "GENRE_UNSPECIFIED":   0,
+    "GENRE_ROCK":          1,
+    "GENRE_INDIE":         2,
+    "GENRE_DRUM_AND_BASS": 3,
+}
+

Note that the .proto language allows multiple enum symbols to have the same +numeric value. Symbols with the same numeric value are synonyms. These are +represented in Go in exactly the same way, with multiple names corresponding to +the same numeric value. The reverse mapping contains a single entry for the +numeric value to the name which appears first in the .proto file.

Extensions

Given an extension definition:

extend Concert {
+  int32 promo_id = 123;
+}
+

The protocol buffer compiler will generate a +protoreflect.ExtensionType +value named E_Promo_id. This value may be used with the +proto.GetExtension, +proto.SetExtension, +proto.HasExtension, +and +proto.ClearExtension +functions to access an extension in a message. The GetExtension function and +SetExtension functions respectively return and accept an interface{} value +containing the extension value type.

For singular scalar extension fields, the extension value type is the +corresponding Go type from the +scalar value types table.

For singular embedded message extension fields, the extension value type is +*M, where M is the field message type.

For repeated extension fields, the extension value type is a slice of the +singular type.

For example, given the following definition:

extend Concert {
+  int32 singular_int32 = 1;
+  repeated bytes repeated_strings = 2;
+  Band singular_message = 3;
+}
+

Extension values may be accessed as:

m := &somepb.Concert{}
+proto.SetExtension(m, extpb.E_SingularInt32, int32(1))
+proto.SetExtension(m, extpb.E_RepeatedString, []string{"a", "b", "c"})
+proto.SetExtension(m, extpb.E_SingularMessage, &extpb.Band{})
+
+v1 := proto.GetExtension(m, extpb.E_SingularInt32).(int32)
+v2 := proto.GetExtension(m, extpb.E_RepeatedString).([][]byte)
+v3 := proto.GetExtension(m, extpb.E_SingularMessage).(*extpb.Band)
+

Extensions can be declared nested inside of another type. For example, a common +pattern is to do something like this:

message Promo {
+  extend Concert {
+    int32 promo_id = 124;
+  }
+}
+

In this case, the ExtensionType value is named E_Promo_Concert.

Services

The Go code generator does not produce output for services by default. If you +enable the gRPC plugin (see the +gRPC Go Quickstart guide) +then code will be generated to support gRPC.

\ No newline at end of file diff --git a/reference/go/index.html b/reference/go/index.html new file mode 100644 index 000000000..7c967479f --- /dev/null +++ b/reference/go/index.html @@ -0,0 +1,8 @@ +Go Reference | Protocol Buffers Documentation +

Go Reference

Reference documentation for working with protocol buffer classes in Go

Go Generated Code Guide (Open)

Describes exactly what Go code the protocol buffer compiler generates for any given protocol definition.

Go Generated Code Guide (Opaque)

Describes exactly what Go code the protocol buffer compiler generates for any given protocol definition.

Go FAQ

A list of frequently asked questions about implementing protocol buffers in Go, with answer for each.

Go Size Semantics

Explains how (not) to use proto.Size

Go API

Go Opaque API Migration

Describes the automated migration to the Opaque API.

Go Opaque API: Manual Migration

Describes a manual migration to the Opaque API.

Go Opaque API FAQ

A list of frequently asked questions about the Opaque API.

\ No newline at end of file diff --git a/reference/go/index.xml b/reference/go/index.xml new file mode 100644 index 000000000..4c320ba85 --- /dev/null +++ b/reference/go/index.xml @@ -0,0 +1,14 @@ +Go Reference on Protocol Buffers Documentationhttps://protobuf.dev/reference/go/Recent content in Go Reference on Protocol Buffers DocumentationHugoenGo Generated Code Guide (Open)https://protobuf.dev/reference/go/go-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/go/go-generated/Any differences between proto2, proto3, and editions generated code are highlighted - note that these differences are in the generated code as described in this document, not the base API, which are the same in both versions. You should read the proto2 language guide, proto3 language guide, or editions language guide before reading this document. +Note You are looking at documentation for the old generated code API (Open Struct API). See Go Generated Code (Opaque) for the corresponding documentation of the (new) Opaque API.Go Generated Code Guide (Opaque)https://protobuf.dev/reference/go/go-generated-opaque/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/go/go-generated-opaque/Any differences between proto2 and proto3 generated code are highlighted - note that these differences are in the generated code as described in this document, not the base API, which are the same in both versions. You should read the proto2 language guide and/or the proto3 language guide before reading this document. +Note You are looking at documentation for the Opaque API, which is the current version. If you are working with .Go FAQhttps://protobuf.dev/reference/go/faq/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/go/faq/Versions What&rsquo;s the difference between github.com/golang/protobuf and google.golang.org/protobuf? The github.com/golang/protobuf module is the original Go protocol buffer API. +The google.golang.org/protobuf module is an updated version of this API designed for simplicity, ease of use, and safety. The flagship features of the updated API are support for reflection and a separation of the user-facing API from the underlying implementation. +We recommend that you use google.golang.org/protobuf in new code. +Version v1.4.0 and higher of github.Go Size Semanticshttps://protobuf.dev/reference/go/size/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/go/size/The proto.Size function returns the size in bytes of the wire-format encoding of a proto.Message by traversing all its fields (including submessages). +In particular, it returns the size of how Go Protobuf will encode the message. +A note on Protobuf Editions With Protobuf Editions, .proto files can enable features that change serialization behavior. This can affect the value returned by proto.Size. For example, setting features.field_presence = IMPLICIT will cause scalar fields that are set to their defaults to not be serialized, and therefore don&rsquo;t contribute to the size of the message.Go APIhttps://protobuf.dev/reference/go/api-docs-link/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/go/api-docs-link/Go Opaque API Migrationhttps://protobuf.dev/reference/go/opaque-migration/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/go/opaque-migration/The Opaque API is the latest version of the Protocol Buffers implementation for the Go programming language. The old version is now called Open Struct API. See the Go Protobuf: Releasing the Opaque API blog post for an introduction. +The migration to the Opaque API happens incrementally, on a per-proto-message or per-.proto-file basis, by setting the api_level feature to one of its possible values: +API_OPEN selects the Open Struct API. This was backported into edition 2023, so older versions of the Go plugin may not honor it.Go Opaque API: Manual Migrationhttps://protobuf.dev/reference/go/opaque-migration-manual/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/go/opaque-migration-manual/The Opaque API is the latest version of the Protocol Buffers implementation for the Go programming language. The old version is now called Open Struct API. See the Go Protobuf: Releasing the Opaque API blog post for an introduction. +This is a user guide for migrating Go Protobuf usages from the older Open Struct API to the new Opaque API. +Warning You are looking at the manual migration guide. Typically you’re better off using the open2opaque tool to automate the migration.Go Opaque API FAQhttps://protobuf.dev/reference/go/opaque-faq/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/go/opaque-faq/The Opaque API is the latest version of the Protocol Buffers implementation for the Go programming language. The old version is now called Open Struct API. See the Go Protobuf: The new Opaque API blog post for an introduction. +This FAQ answers common questions about the new API and the migration process. +Which API Should I Use When Creating a New .proto File? We recommend you select the Opaque API for new development. \ No newline at end of file diff --git a/reference/go/opaque-faq/index.html b/reference/go/opaque-faq/index.html new file mode 100644 index 000000000..346436518 --- /dev/null +++ b/reference/go/opaque-faq/index.html @@ -0,0 +1,180 @@ +Go Opaque API FAQ | Protocol Buffers Documentation +

Go Opaque API FAQ

A list of frequently asked questions about the Opaque API.

The Opaque API is the latest version of the Protocol Buffers implementation for +the Go programming language. The old version is now called Open Struct API. See +the Go Protobuf: The new Opaque API blog +post for an introduction.

This FAQ answers common questions about the new API and the migration process.

Which API Should I Use When Creating a New .proto File?

We recommend you select the Opaque API for new development.

Protobuf Edition 2024 (see Protobuf Editions Overview) made the Opaque API the default.

How Do I Enable the New Opaque API for My Messages?

Starting with Protobuf Edition 2023, you can select the Opaque API by setting +the api_level editions feature to API_OPAQUE in your .proto file. This can +be set per file or per message:

edition = "2023";
+
+package log;
+
+import "google/protobuf/go_features.proto";
+option features.(pb.go).api_level = API_OPAQUE;
+
+message LogEntry {  }
+

Protobuf Edition 2024 defaults to the Opaque API, meaning you will not need +extra imports or options anymore:

edition = "2024";
+
+package log;
+
+message LogEntry {  }
+

For your convenience, you can also override the default API level with a +protoc command-line flag:

protoc […] --go_opt=default_api_level=API_HYBRID
+

To override the default API level for a specific file (instead of all files), +use the apilevelM mapping flag (similar to +the M flag for import paths):

protoc […] --go_opt=apilevelMhello.proto=API_HYBRID
+

The command-line flags also work for .proto files still using proto2 or proto3 +syntax, but if you want to select the API level from within the .proto file, +you need to migrate said file to editions first.

How Do I Enable Lazy Decoding?

  1. Migrate your code to use the opaque implementation.
  2. Set the [lazy = true] option on the proto submessage fields that should be +lazily decoded.
  3. Run your unit and integration tests, and then roll out to a staging +environment.

Are Errors Ignored with Lazy Decoding?

No. +proto.Marshal +will always validate the wire format data, even when decoding is deferred until +first access.

Where Can I Ask Questions or Report Issues?

If you found an issue with the open2opaque migration tool (such as incorrectly +rewritten code), please report it in the +open2opaque issue tracker.

If you found an issue with Go Protobuf, please report it in the +Go Protobuf issue tracker.

What Are the Benefits of the Opaque API?

The Opaque API comes with numerous benefits:

  • It uses a more efficient memory representation, thereby reducing memory and +Garbage Collection cost.
  • It makes lazy decoding possible, which can significantly improve +performance.
  • It fixes a number of sharp edges. Bugs resulting from pointer address +comparison, accidental sharing, or undesired use of Go reflection are all +prevented when using the Opaque API.
  • It makes the ideal memory layout possible by enabling profile-driven +optimizations.

See +the Go Protobuf: The new Opaque API blog post +for more details on these points.

Which Is Faster, Builders or Setters?

Generally, code using builders:

_ = pb.M_builder{
+  F: &val,
+}.Build()
+

is slower than the following equivalent:

m := &pb.M{}
+m.SetF(val)
+

for the following reasons:

  1. The Build() call iterates over all fields in the message (even ones that +are not explicitly set) and copies their values (if any) to the final +message. This linear performance matters for messages with many fields.
  2. There’s a potential extra heap allocation (&val).
  3. The builder can be significantly larger and use more memory in presence of +oneof fields. Builders have a field per oneof union member while the message +can store the oneof itself as a single field.

Aside from runtime performance, if binary size is a concern for you, avoiding +builders will result in less code.

How Do I Use Builders?

Builders are designed to be used as values and with an immediate Build() +call. Avoid using pointers to builders or storing builders in variables.

m := pb.M_builder{
+    // ...
+}.Build()
+
// BAD: Avoid using a pointer
+m := (&pb.M_builder{
+    // ...
+}).Build()
+
// BAD: avoid storing in a variable
+b := pb.M_builder{
+    // ...
+}
+m := b.Build()
+

Proto messages are immutable in some other languages, hence users tend to pass +the builder type into function calls when constructing a proto message. Go proto +messages are mutable, hence there’s no need for passing the builder into +function calls. Simply pass the proto message.

// BAD: avoid passing a builder around
+func populate(mb *pb.M_builder) {
+  mb.Field1 = proto.Int32(4711)
+  //...
+}
+// ...
+mb := pb.M_builder{}
+populate(&mb)
+m := mb.Build()
+
func populate(mb *pb.M) {
+  mb.SetField1(4711)
+  //...
+}
+// ...
+m := &pb.M{}
+populate(m)
+

Builders are designed to imitate the composite literal construction of the Open +Struct API, not as an alternative representation of a proto message.

The recommended pattern is also more performant. The intended use of Build() +where it is called directly on the builder struct literal can be optimized well. +A separate call to Build() is much harder to optimize, as the compiler may not +easily identify which fields are populated. If the builder lives longer, there’s +also a high chance that small objects like scalars have to be heap allocated and +later need to be freed by the garbage collector.

Should I Use Builders or Setters?

When constructing an empty protocol buffer, you should use new or an empty +composite literals. Both are equivalently idiomatic to construct a zero +initialized value in Go and are more performant than an empty builder.

m1 := new(pb.M)
+m2 := &pb.M{}
+
// BAD: avoid: unnecessarily complex
+m1 := pb.M_builder{}.Build()
+

In cases where you need to construct non-empty protocol buffers, you have the +choice between using setters or using builders. Either is fine, but most people +will find builders more readable. If the code you are writing needs to perform +well, +setters are generally slightly more performant than builders.

// Recommended: using builders
+m1 := pb.M1_builder{
+    Submessage: pb.M2_builder{
+        Submessage: pb.M3_builder{
+            String: proto.String("hello world"),
+            Int:    proto.Int32(42),
+        }.Build(),
+        Bytes: []byte("hello"),
+    }.Build(),
+}.Build()
+
// Also okay: using setters
+m3 := &pb.M3{}
+m3.SetString("hello world")
+m3.SetInt(42)
+m2 := &pb.M2{}
+m2.SetSubmessage(m3)
+m2.SetBytes([]byte("hello"))
+m1 := &pb.M1{}
+m1.SetSubmessage(m2)
+

You can combine the use of builder and setters if certain fields require +conditional logic before setting.

m1 := pb.M1_builder{
+    Field1: value1,
+}.Build()
+if someCondition() {
+    m1.SetField2(value2)
+    m1.SetField3(value3)
+}
+

How Can I Influence open2opaque’s Builder Behavior?

The open2opaque tool’s --use_builders flag can have the following values:

  • --use_builders=everywhere: always use builders, no exceptions.
  • --use_builders=tests: use builders only in tests, setters otherwise.
  • --use_builders=nowhere: never use builders.

How Much Performance Benefit Can I Expect?

This depends heavily on your workload. The following questions can guide your +performance exploration:

  • How big a percentage of your CPU usage is Go Protobuf? Some workloads, like +logs analysis pipelines that compute statistics based on Protobuf input +records, can spend about 50% of their CPU usage in Go Protobuf. Performance +improvements will likely be clearly visible in such workloads. On the other +end of the spectrum, in programs that only spend 3-5% of their CPU usage in +Go Protobuf, performance improvements will often be insignificant compared +to other opportunities.
  • How amenable to lazy decoding is your program? If large portions of the +input messages are never accessed, lazy decoding can save a lot of work. +This pattern is usually encountered in jobs like proxy servers (which pass +through the input as-is), or logs analysis pipelines with high selectivity +(which discard many records based on a high-level predicate).
  • Do your message definitions contain many elementary fields with explicit +presence? The Opaque API uses a more efficient memory representation for +elementary fields like integers, booleans, enums and floats, but not +strings, repeated fields or submessages.

How Does Proto2, Proto3, and Editions Relate to the Opaque API?

The terms proto2 and proto3 refer to different syntax versions in your .proto +files. Protobuf Editions is the +successor to both proto2 and proto3.

The Opaque API affects only the generated code in .pb.go files, not what you +write in your .proto files.

The Opaque API works the same, independent of which syntax or edition your +.proto files use. However, if you want to select the Opaque API on a per-file +basis (as opposed to using a command-line flag when you are running protoc), +you must migrate the file to editions first. See +How Do I Enable the New Opaque API for My Messages? for details.

Why Only Change the Memory Layout of Elementary Fields?

The +announcement blog post’s “Opaque structs use less memory” section +explains:

This performance improvement [modeling field presence more efficiently] +depends heavily on your protobuf message shape: The change only affects +elementary fields like integers, booleans, enums and floats, but not strings, +repeated fields or submessages.

A natural follow-up question is why strings, repeated fields, and submessages +remain pointers in the Opaque API. The answer is twofold.

Consideration 1: Memory Usage

Representing submessages as values instead of pointers would increase memory +usage: each Protobuf message type carries internal state, which would consume +memory even when the submessage is not actually set.

For strings and repeated fields, the situation is more nuanced. Let’s compare +the memory usage of using a string value compared to a string pointer:

Go variable typeset?words#bytes
stringyes2 (data, len)16
stringno2 (data, len)16
*stringyes1 (data) + 2 (data, len)24
*stringno1 (data)8

(The situation is similar for slices, but slice headers need 3 words: data, len, +cap.)

If your string fields are overwhelmingly not set, using a pointer saves RAM. Of +course, this saving comes at the cost of introducing more allocations and +pointers into the program, which increases load on the Garbage Collector.

The advantage of the Opaque API is that we can change the representation without +any changes to user code. The current memory layout was optimal for us when we +introduced it, but if we measured today or 5 years into the future, maybe we +would have chosen a different layout.

As described in the +announcement blog post’s “Making the ideal memory layout possible” section, +we aim to make these optimization decisions on a per-workload basis in the +future.

Consideration 2: Lazy Decoding

Aside from the memory usage consideration, there is another restriction: fields +for which lazy decoding is enabled must be represented by +pointers.

Protobuf messages are safe for concurrent access (but not concurrent mutation), +so if two different goroutines trigger lazy decoding, they need to coordinate +somehow. This coordination is implemented through using the +sync/atomic package, which can update +pointers atomically, but not slice headers (which exceed a word).

While protoc currently only permits lazy decoding for (non-repeated) +submessages, this reasoning holds for all field types.

\ No newline at end of file diff --git a/reference/go/opaque-migration-manual/index.html b/reference/go/opaque-migration-manual/index.html new file mode 100644 index 000000000..2d9774a34 --- /dev/null +++ b/reference/go/opaque-migration-manual/index.html @@ -0,0 +1,360 @@ +Go Opaque API: Manual Migration | Protocol Buffers Documentation +

Go Opaque API: Manual Migration

Describes a manual migration to the Opaque API.

The Opaque API is the latest version of the Protocol Buffers implementation for +the Go programming language. The old version is now called Open Struct API. See +the Go Protobuf: Releasing the Opaque API +blog post for an introduction.

This is a user guide for migrating Go Protobuf usages from the older Open Struct +API to the new Opaque API.

The +Generated Code Guide +provides more detail. This guide compares the old and new API side-by-side.

Message Construction

Suppose there is a protobuf message defined like this:

message Foo {
+  uint32 uint32 = 1;
+  bytes bytes = 2;
+  oneof union {
+    string    string = 4;
+    MyMessage message = 5;
+  }
+  enum Kind {  };
+  Kind kind = 9;
+}
+

Here is an example of how to construct this message from literal values:

Open Struct API (old)Opaque API (new)
m := &pb.Foo{
+  Uint32: proto.Uint32(5),
+  Bytes:  []byte("hello"),
+}
+
m := pb.Foo_builder{
+  Uint32: proto.Uint32(5),
+  Bytes:  []byte("hello"),
+}.Build()
+

As you can see, the builder structs allow for an almost 1:1 translation between +Open Struct API (old) and Opaque API (new).

Generally, prefer using builders for readability. Only in rare cases, like +creating Protobuf messages in a hot inner loop, might it be preferable to use +setters instead of builders. See +the Opaque API FAQ: Should I use builders or setters? +for more detail.

An exception to the above example is when working with oneofs: The +Open Struct API (old) uses a wrapper struct type for each oneof case, whereas +the Opaque API (new) treats oneof fields like regular message fields:

Open Struct API (old)Opaque API (new)
m := &pb.Foo{
+  Uint32: myScalar,  // could be nil
+  Union:  &pb.Foo_String{myString},
+  Kind:   pb.Foo_SPECIAL_KIND.Enum(),
+}
+
m := pb.Foo_builder{
+  Uint32: myScalar,
+  String: myString,
+  Kind:   pb.Foo_SPECIAL_KIND.Enum(),
+}.Build()
+

For the set of Go struct fields associated with a oneof union, only one field +may be populated. If multiple oneof case fields are populated, the last one (in +field declaration order in your .proto file) wins.

Scalar fields

Suppose there is a message defined with a scalar field:

message Artist {
+  int32 birth_year = 1;
+}
+

Protobuf message fields for which Go uses scalar types (bool, int32, int64, +uint32, uint64, float32, float64, string, []byte, and enum) will have Get and +Set accessor methods. Fields with +explicit presence +will also have Has and Clear methods.

For a field of type int32 named birth_year, the following accessor methods +will be generated for it:

func (m *Artist) GetBirthYear() int32
+func (m *Artist) SetBirthYear(v int32)
+func (m *Artist) HasBirthYear() bool
+func (m *Artist) ClearBirthYear()
+

Get returns a value for the field. If the field is not set or the message +receiver is nil, it returns the default value. The default value is the +zero value, unless explicitly set with +the default option.

Set stores the provided value into the field. It panics when called on a nil +message receiver.

For bytes fields, calling Set with a nil []byte will be considered set. For +example, calling Has immediately after returns true. Calling Get immediately +after will return a zero-length slice (can either be nil or empty slice). Users +should use Has for determining presence and not rely on whether Get returns +nil.

Has reports whether the field is populated. It returns false when called on a +nil message receiver.

Clear clears the field. It panics when called on a nil message receiver.

Example code snippets using a string field in:

Open Struct API (old)Opaque API (new)
// Getting the value.
+s := m.GetBirthYear()
+
+// Setting the field.
+m.BirthYear = proto.Int32(1989)
+
+// Check for presence.
+if s.BirthYear != nil {  }
+
+// Clearing the field.
+m.BirthYear = nil
+
// Getting the field value.
+s := m.GetBirthYear()
+
+// Setting the field.
+m.SetBirthYear(1989)
+
+// Check for presence.
+if m.HasBirthYear() {  }
+
+// Clearing the field
+m.ClearBirthYear()
+

Message fields

Suppose there is a message defined with a message-typed field:

message Band {}
+
+message Concert {
+  Band headliner = 1;
+}
+

Protobuf message fields of type message will have Get, Set, Has and +Clear methods.

For a message-typed field named headliner, the following accessor methods will +be generated for it:

func (m *Concert) GetHeadliner() *Band
+func (m *Concert) SetHeadliner(*Band)
+func (m *Concert) HasHeadliner() bool
+func (m *Concert) ClearHeadliner()
+

Get returns a value for the field. It returns nil if not set or when called on +a nil message receiver. Checking if Get returns nil is equivalent to checking +if Has returns false.

Set stores the provided value into the field. It panics when called on a nil +message receiver. Calling Set with a nil pointer is equivalent to calling +Clear.

Has reports whether the field is populated. It returns false when called on a +nil message receiver.

Clear clears the field. It panics when called on a nil message receiver.

Example code snippets

Open Struct API (old)Opaque (new)
// Getting the value.
+b := m.GetHeadliner()
+
+// Setting the field.
+m.Headliner = &pb.Band{}
+
+// Check for presence.
+if s.Headliner != nil {  }
+
+// Clearing the field.
+m.Headliner = nil
+
// Getting the value.
+s := m.GetHeadliner()
+
+// Setting the field.
+m.SetHeadliner(&pb.Band{})
+
+// Check for presence.
+if m.HasHeadliner() {  }
+
+// Clearing the field
+m.ClearHeadliner()
+

Repeated fields

Suppose there is a message defined with a repeated message-typed field:

message Concert {
+  repeated Band support_acts = 2;
+}
+

Repeated fields will have Get and Set methods.

Get returns a value for the field. It returns nil if the field is not set or +the message receiver is nil.

Set stores the provided value into the field. It panics when called on a nil +message receiver. Set will store a copy of the slice header that is provided. +Changes to the slice contents are observable in the repeated field. Hence, if +Set is called with an empty slice, calling Get immediately after will return +the same slice. For the wire or text marshaling output, a passed-in nil slice is +indistinguishable from an empty slice.

For a repeated message-typed field named support_acts on message Concert, +the following accessor methods will be generated for it:

func (m *Concert) GetSupportActs() []*Band
+func (m *Concert) SetSupportActs([]*Band)
+

Example code snippets

Open Struct API (old)Opaque API (new)
// Getting the entire repeated value.
+v := m.GetSupportActs()
+
+// Setting the field.
+m.SupportActs = v
+
+// Get an element in a repeated field.
+e := m.SupportActs[i]
+
+// Set an element in a repeated field.
+m.SupportActs[i] = e
+
+// Get the length of a repeated field.
+n := len(m.GetSupportActs())
+
+// Truncate a repeated field.
+m.SupportActs = m.SupportActs[:i]
+
+// Append to a repeated field.
+m.SupportActs = append(m.GetSupportActs(), e)
+m.SupportActs = append(m.GetSupportActs(), v...)
+
+// Clearing the field.
+m.SupportActs = nil
+
// Getting the entire repeated value.
+v := m.GetSupportActs()
+
+// Setting the field.
+m.SetSupportActs(v)
+
+// Get an element in a repeated field.
+e := m.GetSupportActs()[i]
+
+// Set an element in a repeated field.
+m.GetSupportActs()[i] = e
+
+// Get the length of a repeated field.
+n := len(m.GetSupportActs())
+
+// Truncate a repeated field.
+m.SetSupportActs(m.GetSupportActs()[:i])
+
+// Append to a repeated field.
+m.SetSupportActs(append(m.GetSupportActs(), e))
+m.SetSupportActs(append(m.GetSupportActs(), v...))
+
+// Clearing the field.
+m.SetSupportActs(nil)
+

Maps

Suppose there is a message defined with a map-typed field:

message MerchBooth {
+  map<string, MerchItems> items = 1;
+}
+

Map fields will have Get and Set methods.

Get returns a value for the field. It returns nil if the field is not set or +the message receiver is nil.

Set stores the provided value into the field. It panics when called on a nil +message receiver. Set will store a copy of the provided map reference. Changes +to the provided map are observable in the map field.

For a map field named items on message MerchBooth, the following accessor +methods will be generated for it:

func (m *MerchBooth) GetItems() map[string]*MerchItem
+func (m *MerchBooth) SetItems(map[string]*MerchItem)
+

Example code snippets

Open Struct API (old)Opaque API (new)
// Getting the entire map value.
+v := m.GetItems()
+
+// Setting the field.
+m.Items = v
+
+// Get an element in a map field.
+v := m.Items[k]
+
+// Set an element in a map field.
+// This will panic if m.Items is nil.
+// You should check m.Items for nil
+// before doing the assignment to ensure
+// it won't panic.
+m.Items[k] = v
+
+// Delete an element in a map field.
+delete(m.Items, k)
+
+// Get the size of a map field.
+n := len(m.GetItems())
+
+// Clearing the field.
+m.Items = nil
+
// Getting the entire map value.
+v := m.GetItems()
+
+// Setting the field.
+m.SetItems(v)
+
+// Get an element in a map field.
+v := m.GetItems()[k]
+
+// Set an element in a map field.
+// This will panic if m.GetItems() is nil.
+// You should check m.GetItems() for nil
+// before doing the assignment to ensure
+// it won't panic.
+m.GetItems()[k] = v
+
+// Delete an element in a map field.
+delete(m.GetItems(), k)
+
+// Get the size of a map field.
+n := len(m.GetItems())
+
+// Clearing the field.
+m.SetItems(nil)
+

Oneofs

For each oneof union grouping, there will be a Which, Has and Clear method +on the message. There will also be a Get, Set, Has, and Clear method on +each oneof case field in that union.

Suppose there is a message defined with oneof fields image_url and +image_data in oneof avatar like:

message Profile {
+  oneof avatar {
+    string image_url = 1;
+    bytes image_data = 2;
+  }
+}
+

The generated Opaque API for this oneof will be:

func (m *Profile) WhichAvatar() case_Profile_Avatar {  }
+func (m *Profile) HasAvatar() bool {  }
+func (m *Profile) ClearAvatar() {  }
+
+type case_Profile_Avatar protoreflect.FieldNumber
+
+const (
+  Profile_Avatar_not_set_case case_Profile_Avatar = 0
+  Profile_ImageUrl_case case_Profile_Avatar = 1
+  Profile_ImageData_case case_Profile_Avatar = 2
+)
+

Which reports which case field is set by returning the field number. It +returns 0 when none are set or when called on a nil message receiver.

Has reports whether any of the fields within the oneof is set. It returns +false when called on a nil message receiver.

Clear clears the currently set case field in the oneof. It panics on a nil +message receiver.

The generated Opaque API for each oneof case field will be:

func (m *Profile) GetImageUrl() string {  }
+func (m *Profile) GetImageData() []byte {  }
+
+func (m *Profile) SetImageUrl(v string) {  }
+func (m *Profile) SetImageData(v []byte) {  }
+
+func (m *Profile) HasImageUrl() bool {  }
+func (m *Profile) HasImageData() bool {  }
+
+func (m *Profile) ClearImageUrl() {  }
+func (m *Profile) ClearImageData() {  }
+

Get returns a value for the case field. It will return the zero value if the +case field is not set or when called on a nil message receiver.

Set stores the provided value into the case field. It also implicitly clears +the case field that was previously populated within the oneof union. Calling +Set on a oneof message case field with nil value will set the field to an +empty message. It panics when called on a nil message receiver.

Has reports whether the case field is set or not. It returns false when called +on a nil message receiver.

Clear clears the case field. If it was previously set, the oneof union is also +cleared. If the oneof union is set to different field, it will not clear the +oneof union. It panics when called on a nil message receiver.

Example code snippets

Open Struct API (old)Opaque API (new)
// Getting the oneof field that is set.
+switch m.GetAvatar().(type) {
+case *pb.Profile_ImageUrl:
+   = m.GetImageUrl()
+case *pb.Profile_ImageData:
+   = m.GetImageData()
+}
+
+// Setting the fields.
+m.Avatar = &pb.Profile_ImageUrl{"http://"}
+m.Avatar = &pb.Profile_ImageData{img}
+
+// Checking whether any oneof field is set
+if m.Avatar != nil {  }
+
+// Clearing the field.
+m.Avatar = nil
+
+// Checking if a specific field is set.
+_, ok := m.GetAvatar().(*pb.Profile_ImageUrl)
+if ok {  }
+
+// Clearing a specific field
+_, ok := m.GetAvatar().(*pb.Profile_ImageUrl)
+if ok {
+  m.Avatar = nil
+}
+
+// Copy a oneof field.
+m.Avatar = src.Avatar
+
// Getting the oneof field that is set.
+switch m.WhichAvatar() {
+case pb.Profile_ImageUrl_case:
+   = m.GetImageUrl()
+case pb.Profile_ImageData_case:
+   = m.GetImageData()
+}
+
+// Setting the fields.
+m.SetImageUrl("http://")
+m.SetImageData([]byte("…"))
+
+// Checking whether any oneof field is set
+if m.HasAvatar() {  }
+
+// Clearing the field.
+m.ClearAvatar()
+
+// Checking if a specific field is set.
+if m.HasImageUrl() {  }
+
+// Clearing a specific field.
+m.ClearImageUrl()
+
+// Copy a oneof field
+switch src.WhichAvatar() {
+case pb.Profile_ImageUrl_case:
+  m.SetImageUrl(src.GetImageUrl())
+case pb.Profile_ImageData_case:
+  m.SetImageData(src.GetImageData())
+}
+

Reflection

Code that use Go reflect package on proto message types to access struct +fields and tags will no longer work when migrating away from the Open Struct +API. Code will need to migrate to use +protoreflect

Some common libraries do use Go reflect under the hood, examples are:

\ No newline at end of file diff --git a/reference/go/opaque-migration/index.html b/reference/go/opaque-migration/index.html new file mode 100644 index 000000000..57de11a96 --- /dev/null +++ b/reference/go/opaque-migration/index.html @@ -0,0 +1,98 @@ +Go Opaque API Migration | Protocol Buffers Documentation +

Go Opaque API Migration

Describes the automated migration to the Opaque API.

The Opaque API is the latest version of the Protocol Buffers implementation for +the Go programming language. The old version is now called Open Struct API. See +the Go Protobuf: Releasing the Opaque API +blog post for an introduction.

The migration to the Opaque API happens incrementally, on a per-proto-message or +per-.proto-file basis, by setting the api_level feature to one of its +possible values:

  • API_OPEN selects the Open Struct API. This was backported into edition +2023, so older versions of the Go plugin may not honor it.
  • API_HYBRID is a step between Open and Opaque: The Hybrid API also includes +accessor methods (so you can update your code), but still exports the struct +fields as before. There is no performance difference; this API level only +helps with the migration.
  • API_OPAQUE selects the Opaque API; this is the default for Edition 2024 +and newer.

To override the default for a specific .proto file, set the api_level +feature:

edition = "2024";
+
+package log;
+
+import "google/protobuf/go_features.proto";
+option features.(pb.go).api_level = API_OPEN;
+
+message LogEntry {  }
+

Before you can change the api_level to API_OPAQUE for existing files, all +existing usages of the generated proto code need to be updated. The +open2opaque tool helps with this.

For your convenience, you can also override the default API level with a +protoc command-line flag:

protoc […] --go_opt=default_api_level=API_OPEN
+

To override the default API level for a specific file (instead of all files), +use the apilevelM mapping flag (similar to +the M flag for import paths):

protoc […] --go_opt=apilevelMhello.proto=API_OPEN
+

Automated Migration

We try to make migrating existing projects to the Opaque API as easy as possible +for you: our open2opaque tool does most of the work!

To install the migration tool, use:

go install google.golang.org/open2opaque@latest
+go install golang.org/x/tools/cmd/goimports@latest
+

Project Preparation

Ensure your build environment and project are using recent-enough versions of +Protocol Buffers and Go Protobuf:

  1. Update the protobuf compiler (protoc) from +the protobuf release page +to version 29.0 or newer.

  2. Update the protobuf compiler Go plugin (protoc-gen-go) to version 1.36.0 or +newer:

    go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
    +
  3. In each project, update the go.mod file to use the protobuf module in +version 1.36.0 or newer:

    go get google.golang.org/protobuf@latest
    +

Step 1. Switch to the Hybrid API

Use the open2opaque tool to switch your .proto files to the Hybrid API:

open2opaque setapi -api HYBRID $(find . -name "*.proto")
+

Then, +re-compile +your protocol buffers.

Your existing code will continue to build. The Hybrid API is a step between the +Open and Opaque API which adds the new accessor methods but keeps struct fields +visible.

Step 2. open2opaque rewrite

To rewrite your Go code to use the Opaque API, run the open2opaque rewrite +command:

open2opaque rewrite -levels=red github.com/robustirc/robustirc/...
+

You can specify one or more +packages or patterns.

As an example, if you had code like this:

logEntry := &logpb.LogEntry{}
+if req.IPAddress != nil {
+    logEntry.IPAddress = redactIP(req.IPAddress)
+}
+logEntry.BackendServer = proto.String(host)
+

The tool would rewrite it to use accessors:

logEntry := &logpb.LogEntry{}
+if req.HasIPAddress() {
+    logEntry.SetIPAddress(redactIP(req.GetIPAddress()))
+}
+logEntry.SetBackendServer(host)
+

Another common example is to initialize a protobuf message with a struct +literal:

return &logpb.LogEntry{
+    BackendServer: proto.String(host),
+}
+

In the Opaque API, the equivalent is to use a Builder:

return logpb.LogEntry_builder{
+    BackendServer: proto.String(host),
+}.Build()
+

The tool classifies its available rewrites into different levels. The +-levels=red argument enables all rewrites, including those that require human +review. The following levels are available:

  • green: Safe rewrites (high +confidence). Includes most changes the tool makes. These changes do not +require a close look and could even be submitted by automation, without any +human oversight.
  • yellow: (reasonable +confidence) These rewrites require human review. They should be correct, but +please review them.
  • red: Potentially dangerous +rewrites, changing rare and complicated patterns. These require careful +human review. For example, when an existing function takes a *string +parameter, the typical fix of using proto.String(msg.GetFoo()) does not +work if the function meant to change the field value by writing to the +pointer (*foo = "value").

Many programs can be fully migrated with only green changes. Before you can +migrate a proto message or file to the Opaque API, you need to complete all +rewrites of all levels, at which point no direct struct access remains in your +code.

Step 3. Migrate and Verify

To complete the migration, use the open2opaque tool to switch your .proto +files to the Opaque API:

open2opaque setapi -api OPAQUE $(find . -name "*.proto")
+

Now, any remaining code that was not rewritten to the Opaque API yet will no +longer compile.

Run your unit tests, integration tests and other verification steps, if any.

Questions? Issues?

First, check out the +Opaque API FAQ. If that +doesn’t answer your question or resolve your issue, see +Where can I ask questions or report issues?

\ No newline at end of file diff --git a/reference/go/size/index.html b/reference/go/size/index.html new file mode 100644 index 000000000..85512cb74 --- /dev/null +++ b/reference/go/size/index.html @@ -0,0 +1,92 @@ +Go Size Semantics | Protocol Buffers Documentation +

Go Size Semantics

Explains how (not) to use proto.Size

The proto.Size +function returns the size in bytes of the wire-format encoding of a +proto.Message by traversing all its fields (including submessages).

In particular, it returns the size of how Go Protobuf will encode the +message.

A note on Protobuf Editions

With Protobuf Editions, .proto files can enable features that change +serialization behavior. This can affect the value returned by proto.Size. For +example, setting features.field_presence = IMPLICIT will cause scalar fields +that are set to their defaults to not be serialized, and therefore don’t +contribute to the size of the message.

Typical usages

Identifying empty messages

Checking if +proto.Size returns +0 is a common way to check for empty messages:

if proto.Size(m) == 0 {
+    // No fields set; skip processing this message,
+    // or return an error, or similar.
+}
+

Size-limiting program output

Let’s say you’re writing a batch processing pipeline which produces work tasks +for another system that we’ll call “downstream system” in this example. The +downstream system is provisioned for handling small to medium-sized tasks, but +load testing has shown that the system runs into a cascading failure when +presented with a work task of over 500 MB.

The best fix is to add protection to the downstream system (see +https://cloud.google.com/blog/products/gcp/using-load-shedding-to-survive-a-success-disaster-cre-life-lessons), +but when implementing load-shedding is infeasible, you could decide to add a +quick fix to your pipeline:

func (*beamFn) ProcessElement(key string, value []byte, emit func(proto.Message)) {
+  task := produceWorkTask(value)
+  if proto.Size(task) > 500 * 1024 * 1024 {
+    // Skip every work task over 500 MB to not overwhelm
+    // the brittle downstream system.
+    return
+  }
+  emit(task)
+}
+

Incorrect usage: no relation to Unmarshal

Because proto.Size +returns the number of bytes for how Go Protobuf will encode the message, it is +not safe to use proto.Size when unmarshaling (decoding) a stream of incoming +Protobuf messages:

func bytesToSubscriptionList(data []byte) ([]*vpb.EventSubscription, error) {
+    subList := []*vpb.EventSubscription{}
+    for len(data) > 0 {
+        subscription := &vpb.EventSubscription{}
+        if err := proto.Unmarshal(data, subscription); err != nil {
+            return nil, err
+        }
+        subList = append(subList, subscription)
+        data = data[:len(data)-proto.Size(subscription)]
+    }
+    return subList, nil
+}
+

When data contains a message in non-minimal wire format, +proto.Size can return a different size than was actually unmarshaled, +resulting in a parsing error (best case) or incorrectly parsed data in the worst +case.

Hence, this example only works reliably as long as all input messages are +generated by (the same version of) Go Protobuf. This is surprising and likely +not intended.

Tip: Use the +protodelim package +instead to read/write size-delimited streams of Protobuf messages.

Advanced usage: pre-sizing buffers

An advanced usage of +proto.Size is to +determine the required size for a buffer before marshaling:

opts := proto.MarshalOptions{
+    // Possibly avoid an extra proto.Size in Marshal itself (see docs):
+    UseCachedSize: true,
+}
+// DO NOT SUBMIT without implementing this Optimization opportunity:
+// instead of allocating, grab a sufficiently-sized buffer from a pool.
+// Knowing the size of the buffer means we can discard
+// outliers from the pool to prevent uncontrolled
+// memory growth in long-running RPC services.
+buf := make([]byte, 0, opts.Size(m))
+var err error
+buf, err = opts.MarshalAppend(buf, m) // does not allocate
+// Note that len(buf) might be less than cap(buf)! Read below:
+

Note that when lazy decoding is enabled, proto.Size might return more bytes +than proto.Marshal (and variants like proto.MarshalAppend) will write! So +when you are placing encoded bytes on the wire (or on disk), be sure to work +with len(buf) and discard any previous proto.Size results.

Specifically, a (sub-)message can “shrink” between proto.Size and +proto.Marshal when:

  1. Lazy decoding is enabled
  2. and the message arrived in non-minimal wire format
  3. and the message is not accessed before proto.Size is called, meaning it is +not decoded yet
  4. and the message is accessed after proto.Size (but before proto.Marshal), +causing it to be lazily decoded

The decoding results in any subsequent proto.Marshal calls encoding the +message (as opposed to merely copying its wire format), which results in +implicit normalization to how Go encodes messages, which is currently in minimal +wire format (but don’t rely on that!).

As you can see, the scenario is rather specific, but nevertheless it is best +practice to treat proto.Size results as an upper bound and never assume that +the result matches the actually encoded message size.

Background: Non-minimal wire format

When encoding Protobuf messages, there is one minimal wire format size and a +number of larger non-minimal wire formats that decode to the same message.

Non-minimal wire format (also called “denormalized wire format” sometimes) +refers to scenarios like non-repeated fields appearing multiple times, +non-optimal varint encoding, packed repeated fields that appear non-packed on +the wire and others.

We can encounter non-minimal wire format in different scenarios:

  • Intentionally. Protobuf supports concatenating messages by concatenating +their wire format.
  • Accidentally. A (possibly third-party) Protobuf encoder does not encode +ideally (e.g. uses more space than necessary when encoding a varint).
  • Maliciously. An attacker could craft Protobuf messages specifically to +trigger crashes over the network.
\ No newline at end of file diff --git a/reference/index.html b/reference/index.html new file mode 100644 index 000000000..2f7eebf28 --- /dev/null +++ b/reference/index.html @@ -0,0 +1,13 @@ +Reference Guides | Protocol Buffers Documentation +

Reference Guides

Reference documentation for working with protocol buffer classes in C++, Java, Python, Go, C#, Objective-C, Ruby, PHP, and Dart, as well as some reference documentation for Protocol Buffers itself.

This section contains reference documentation for working with protocol buffer +classes in C++, Java, Python, Go, C#, Objective-C, Ruby, PHP, and Dart, as well +as some reference documentation for Protocol Buffers itself. The documentation +for each language includes (where available):

  • A reference guide to the code generated by the protocol buffer compiler from +your .proto files.
  • Generated API documentation for the provided source code.

Note that there are APIs for several more languages in the pipeline – for +details, see Other Languages.


C++ Reference

Reference documentation for working with protocol buffer classes in C++.

C# Reference

Reference documentation for working with protocol buffer classes in C#

Dart Reference

Reference documentation for working with protocol buffer classes in Dart

Go Reference

Reference documentation for working with protocol buffer classes in Go

Java Reference

Reference documentation for working with protocol buffer classes in Java.

Kotlin Reference

Reference documentation for working with protocol buffer classes in Kotlin.

Objective-C Reference

Reference documentation for working with protocol buffer classes in Objective-C.

PHP Reference

Reference documentation for working with protocol buffer classes in PHP.

Python Reference

Reference documentation for working with protocol buffer classes in Python.

Ruby Reference

Reference documentation for working with protocol buffer classes in Ruby.

Rust Reference

Reference documentation for working with protocol buffer classes in Rust.

Protocol Buffers Reference

Language-agnostic information about how to use protocol buffers.

Other Languages

protoc, the Protocol Buffers Compiler, can be extended to support new languages via plugins.

\ No newline at end of file diff --git a/reference/index.xml b/reference/index.xml new file mode 100644 index 000000000..57656b059 --- /dev/null +++ b/reference/index.xml @@ -0,0 +1,3 @@ +Reference Guides on Protocol Buffers Documentationhttps://protobuf.dev/reference/Recent content in Reference Guides on Protocol Buffers DocumentationHugoenOther Languageshttps://protobuf.dev/reference/other/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/other/While the current release includes compilers and APIs for C++, Java, Go, Ruby, C#, and Python, the compiler code is designed so that it&rsquo;s easy to add support for other languages. There are several ongoing projects to add new language implementations to Protocol Buffers, including C, Haskell, Perl, Rust, and more. +For a list of links to projects we know about, see the third-party add-ons wiki page. +Compiler Plugins protoc, the Protocol Buffers Compiler, can be extended to support new languages via plugins. \ No newline at end of file diff --git a/reference/java/api-docs-link/index.html b/reference/java/api-docs-link/index.html new file mode 100644 index 000000000..2d4d6604f --- /dev/null +++ b/reference/java/api-docs-link/index.html @@ -0,0 +1,4 @@ +Java API | Protocol Buffers Documentation +
\ No newline at end of file diff --git a/content/reference/java/api-docs/allclasses-frame.html b/reference/java/api-docs/allclasses-frame.html similarity index 100% rename from content/reference/java/api-docs/allclasses-frame.html rename to reference/java/api-docs/allclasses-frame.html diff --git a/content/reference/java/api-docs/allclasses-noframe.html b/reference/java/api-docs/allclasses-noframe.html similarity index 100% rename from content/reference/java/api-docs/allclasses-noframe.html rename to reference/java/api-docs/allclasses-noframe.html diff --git a/content/reference/java/api-docs/com/google/protobuf/AbstractMessage.Builder.html b/reference/java/api-docs/com/google/protobuf/AbstractMessage.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/AbstractMessage.Builder.html rename to reference/java/api-docs/com/google/protobuf/AbstractMessage.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/AbstractMessage.html b/reference/java/api-docs/com/google/protobuf/AbstractMessage.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/AbstractMessage.html rename to reference/java/api-docs/com/google/protobuf/AbstractMessage.html diff --git a/content/reference/java/api-docs/com/google/protobuf/AbstractMessageLite.Builder.html b/reference/java/api-docs/com/google/protobuf/AbstractMessageLite.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/AbstractMessageLite.Builder.html rename to reference/java/api-docs/com/google/protobuf/AbstractMessageLite.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/AbstractMessageLite.html b/reference/java/api-docs/com/google/protobuf/AbstractMessageLite.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/AbstractMessageLite.html rename to reference/java/api-docs/com/google/protobuf/AbstractMessageLite.html diff --git a/content/reference/java/api-docs/com/google/protobuf/AbstractParser.html b/reference/java/api-docs/com/google/protobuf/AbstractParser.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/AbstractParser.html rename to reference/java/api-docs/com/google/protobuf/AbstractParser.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Any.Builder.html b/reference/java/api-docs/com/google/protobuf/Any.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Any.Builder.html rename to reference/java/api-docs/com/google/protobuf/Any.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Any.html b/reference/java/api-docs/com/google/protobuf/Any.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Any.html rename to reference/java/api-docs/com/google/protobuf/Any.html diff --git a/content/reference/java/api-docs/com/google/protobuf/AnyOrBuilder.html b/reference/java/api-docs/com/google/protobuf/AnyOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/AnyOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/AnyOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/AnyProto.html b/reference/java/api-docs/com/google/protobuf/AnyProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/AnyProto.html rename to reference/java/api-docs/com/google/protobuf/AnyProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Api.Builder.html b/reference/java/api-docs/com/google/protobuf/Api.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Api.Builder.html rename to reference/java/api-docs/com/google/protobuf/Api.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Api.html b/reference/java/api-docs/com/google/protobuf/Api.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Api.html rename to reference/java/api-docs/com/google/protobuf/Api.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ApiOrBuilder.html b/reference/java/api-docs/com/google/protobuf/ApiOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ApiOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/ApiOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ApiProto.html b/reference/java/api-docs/com/google/protobuf/ApiProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ApiProto.html rename to reference/java/api-docs/com/google/protobuf/ApiProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/BlockingRpcChannel.html b/reference/java/api-docs/com/google/protobuf/BlockingRpcChannel.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/BlockingRpcChannel.html rename to reference/java/api-docs/com/google/protobuf/BlockingRpcChannel.html diff --git a/content/reference/java/api-docs/com/google/protobuf/BlockingService.html b/reference/java/api-docs/com/google/protobuf/BlockingService.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/BlockingService.html rename to reference/java/api-docs/com/google/protobuf/BlockingService.html diff --git a/content/reference/java/api-docs/com/google/protobuf/BoolValue.Builder.html b/reference/java/api-docs/com/google/protobuf/BoolValue.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/BoolValue.Builder.html rename to reference/java/api-docs/com/google/protobuf/BoolValue.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/BoolValue.html b/reference/java/api-docs/com/google/protobuf/BoolValue.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/BoolValue.html rename to reference/java/api-docs/com/google/protobuf/BoolValue.html diff --git a/content/reference/java/api-docs/com/google/protobuf/BoolValueOrBuilder.html b/reference/java/api-docs/com/google/protobuf/BoolValueOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/BoolValueOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/BoolValueOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ByteOutput.html b/reference/java/api-docs/com/google/protobuf/ByteOutput.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ByteOutput.html rename to reference/java/api-docs/com/google/protobuf/ByteOutput.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ByteString.ByteIterator.html b/reference/java/api-docs/com/google/protobuf/ByteString.ByteIterator.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ByteString.ByteIterator.html rename to reference/java/api-docs/com/google/protobuf/ByteString.ByteIterator.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ByteString.Output.html b/reference/java/api-docs/com/google/protobuf/ByteString.Output.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ByteString.Output.html rename to reference/java/api-docs/com/google/protobuf/ByteString.Output.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ByteString.html b/reference/java/api-docs/com/google/protobuf/ByteString.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ByteString.html rename to reference/java/api-docs/com/google/protobuf/ByteString.html diff --git a/content/reference/java/api-docs/com/google/protobuf/BytesValue.Builder.html b/reference/java/api-docs/com/google/protobuf/BytesValue.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/BytesValue.Builder.html rename to reference/java/api-docs/com/google/protobuf/BytesValue.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/BytesValue.html b/reference/java/api-docs/com/google/protobuf/BytesValue.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/BytesValue.html rename to reference/java/api-docs/com/google/protobuf/BytesValue.html diff --git a/content/reference/java/api-docs/com/google/protobuf/BytesValueOrBuilder.html b/reference/java/api-docs/com/google/protobuf/BytesValueOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/BytesValueOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/BytesValueOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/CodedInputStream.html b/reference/java/api-docs/com/google/protobuf/CodedInputStream.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/CodedInputStream.html rename to reference/java/api-docs/com/google/protobuf/CodedInputStream.html diff --git a/content/reference/java/api-docs/com/google/protobuf/CodedOutputStream.OutOfSpaceException.html b/reference/java/api-docs/com/google/protobuf/CodedOutputStream.OutOfSpaceException.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/CodedOutputStream.OutOfSpaceException.html rename to reference/java/api-docs/com/google/protobuf/CodedOutputStream.OutOfSpaceException.html diff --git a/content/reference/java/api-docs/com/google/protobuf/CodedOutputStream.html b/reference/java/api-docs/com/google/protobuf/CodedOutputStream.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/CodedOutputStream.html rename to reference/java/api-docs/com/google/protobuf/CodedOutputStream.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ExtensionRange.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ExtensionRange.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ExtensionRange.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ExtensionRange.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ExtensionRange.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ExtensionRange.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ExtensionRange.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ExtensionRange.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ExtensionRangeOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ExtensionRangeOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ExtensionRangeOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ExtensionRangeOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ReservedRange.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ReservedRange.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ReservedRange.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ReservedRange.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ReservedRange.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ReservedRange.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ReservedRange.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ReservedRange.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ReservedRangeOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ReservedRangeOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ReservedRangeOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.ReservedRangeOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProtoOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProtoOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProtoOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.DescriptorProtoOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.EnumReservedRange.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.EnumReservedRange.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.EnumReservedRange.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.EnumReservedRange.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.EnumReservedRange.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.EnumReservedRange.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.EnumReservedRange.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.EnumReservedRange.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.EnumReservedRangeOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.EnumReservedRangeOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.EnumReservedRangeOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.EnumReservedRangeOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProtoOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProtoOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProtoOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumDescriptorProtoOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumOptions.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumOptions.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumOptions.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumOptions.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumOptions.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumOptions.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumOptions.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumOptions.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumOptionsOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumOptionsOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumOptionsOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumOptionsOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueDescriptorProto.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueDescriptorProto.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueDescriptorProto.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueDescriptorProto.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueDescriptorProto.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueDescriptorProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueDescriptorProto.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueDescriptorProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueDescriptorProtoOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueDescriptorProtoOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueDescriptorProtoOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueDescriptorProtoOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueOptions.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueOptions.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueOptions.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueOptions.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueOptions.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueOptions.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueOptions.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueOptions.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueOptionsOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueOptionsOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueOptionsOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.EnumValueOptionsOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ExtensionRangeOptions.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ExtensionRangeOptions.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ExtensionRangeOptions.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.ExtensionRangeOptions.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ExtensionRangeOptions.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ExtensionRangeOptions.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ExtensionRangeOptions.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.ExtensionRangeOptions.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ExtensionRangeOptionsOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ExtensionRangeOptionsOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ExtensionRangeOptionsOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.ExtensionRangeOptionsOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProto.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProto.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProto.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProto.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProto.Label.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProto.Label.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProto.Label.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProto.Label.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProto.Type.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProto.Type.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProto.Type.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProto.Type.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProto.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProto.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProtoOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProtoOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProtoOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldDescriptorProtoOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptions.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptions.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptions.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptions.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptions.CType.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptions.CType.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptions.CType.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptions.CType.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptions.JSType.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptions.JSType.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptions.JSType.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptions.JSType.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptions.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptions.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptions.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptions.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptionsOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptionsOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptionsOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FieldOptionsOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorProto.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorProto.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorProto.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorProto.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorProto.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorProto.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorProtoOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorProtoOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorProtoOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorProtoOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorSet.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorSet.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorSet.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorSet.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorSet.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorSet.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorSet.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorSet.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorSetOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorSetOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorSetOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileDescriptorSetOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileOptions.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileOptions.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileOptions.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileOptions.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileOptions.OptimizeMode.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileOptions.OptimizeMode.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileOptions.OptimizeMode.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileOptions.OptimizeMode.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileOptions.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileOptions.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileOptions.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileOptions.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileOptionsOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileOptionsOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileOptionsOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.FileOptionsOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.Annotation.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.Annotation.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.Annotation.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.Annotation.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.Annotation.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.Annotation.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.Annotation.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.Annotation.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.AnnotationOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.AnnotationOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.AnnotationOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.AnnotationOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfo.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfoOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfoOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfoOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.GeneratedCodeInfoOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MessageOptions.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MessageOptions.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MessageOptions.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.MessageOptions.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MessageOptions.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MessageOptions.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MessageOptions.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.MessageOptions.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MessageOptionsOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MessageOptionsOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MessageOptionsOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.MessageOptionsOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodDescriptorProto.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodDescriptorProto.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodDescriptorProto.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodDescriptorProto.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodDescriptorProto.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodDescriptorProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodDescriptorProto.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodDescriptorProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodDescriptorProtoOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodDescriptorProtoOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodDescriptorProtoOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodDescriptorProtoOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodOptions.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodOptions.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodOptions.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodOptions.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodOptions.IdempotencyLevel.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodOptions.IdempotencyLevel.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodOptions.IdempotencyLevel.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodOptions.IdempotencyLevel.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodOptions.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodOptions.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodOptions.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodOptions.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodOptionsOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodOptionsOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodOptionsOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.MethodOptionsOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofDescriptorProto.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofDescriptorProto.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofDescriptorProto.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofDescriptorProto.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofDescriptorProto.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofDescriptorProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofDescriptorProto.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofDescriptorProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofDescriptorProtoOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofDescriptorProtoOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofDescriptorProtoOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofDescriptorProtoOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofOptions.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofOptions.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofOptions.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofOptions.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofOptions.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofOptions.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofOptions.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofOptions.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofOptionsOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofOptionsOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofOptionsOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.OneofOptionsOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceDescriptorProto.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceDescriptorProto.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceDescriptorProto.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceDescriptorProto.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceDescriptorProto.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceDescriptorProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceDescriptorProto.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceDescriptorProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceDescriptorProtoOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceDescriptorProtoOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceDescriptorProtoOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceDescriptorProtoOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceOptions.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceOptions.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceOptions.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceOptions.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceOptions.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceOptions.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceOptions.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceOptions.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceOptionsOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceOptionsOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceOptionsOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.ServiceOptionsOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.Location.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.Location.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.Location.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.Location.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.Location.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.Location.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.Location.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.Location.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.LocationOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.LocationOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.LocationOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.LocationOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfo.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfoOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfoOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfoOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.SourceCodeInfoOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.NamePart.Builder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.NamePart.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.NamePart.Builder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.NamePart.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.NamePart.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.NamePart.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.NamePart.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.NamePart.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.NamePartOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.NamePartOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.NamePartOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.NamePartOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOption.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOptionOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOptionOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOptionOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.UninterpretedOptionOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.html b/reference/java/api-docs/com/google/protobuf/DescriptorProtos.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DescriptorProtos.html rename to reference/java/api-docs/com/google/protobuf/DescriptorProtos.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Descriptors.Descriptor.html b/reference/java/api-docs/com/google/protobuf/Descriptors.Descriptor.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Descriptors.Descriptor.html rename to reference/java/api-docs/com/google/protobuf/Descriptors.Descriptor.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Descriptors.DescriptorValidationException.html b/reference/java/api-docs/com/google/protobuf/Descriptors.DescriptorValidationException.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Descriptors.DescriptorValidationException.html rename to reference/java/api-docs/com/google/protobuf/Descriptors.DescriptorValidationException.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Descriptors.EnumDescriptor.html b/reference/java/api-docs/com/google/protobuf/Descriptors.EnumDescriptor.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Descriptors.EnumDescriptor.html rename to reference/java/api-docs/com/google/protobuf/Descriptors.EnumDescriptor.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Descriptors.EnumValueDescriptor.html b/reference/java/api-docs/com/google/protobuf/Descriptors.EnumValueDescriptor.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Descriptors.EnumValueDescriptor.html rename to reference/java/api-docs/com/google/protobuf/Descriptors.EnumValueDescriptor.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Descriptors.FieldDescriptor.JavaType.html b/reference/java/api-docs/com/google/protobuf/Descriptors.FieldDescriptor.JavaType.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Descriptors.FieldDescriptor.JavaType.html rename to reference/java/api-docs/com/google/protobuf/Descriptors.FieldDescriptor.JavaType.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Descriptors.FieldDescriptor.Type.html b/reference/java/api-docs/com/google/protobuf/Descriptors.FieldDescriptor.Type.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Descriptors.FieldDescriptor.Type.html rename to reference/java/api-docs/com/google/protobuf/Descriptors.FieldDescriptor.Type.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Descriptors.FieldDescriptor.html b/reference/java/api-docs/com/google/protobuf/Descriptors.FieldDescriptor.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Descriptors.FieldDescriptor.html rename to reference/java/api-docs/com/google/protobuf/Descriptors.FieldDescriptor.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Descriptors.FileDescriptor.InternalDescriptorAssigner.html b/reference/java/api-docs/com/google/protobuf/Descriptors.FileDescriptor.InternalDescriptorAssigner.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Descriptors.FileDescriptor.InternalDescriptorAssigner.html rename to reference/java/api-docs/com/google/protobuf/Descriptors.FileDescriptor.InternalDescriptorAssigner.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Descriptors.FileDescriptor.Syntax.html b/reference/java/api-docs/com/google/protobuf/Descriptors.FileDescriptor.Syntax.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Descriptors.FileDescriptor.Syntax.html rename to reference/java/api-docs/com/google/protobuf/Descriptors.FileDescriptor.Syntax.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Descriptors.FileDescriptor.html b/reference/java/api-docs/com/google/protobuf/Descriptors.FileDescriptor.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Descriptors.FileDescriptor.html rename to reference/java/api-docs/com/google/protobuf/Descriptors.FileDescriptor.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Descriptors.GenericDescriptor.html b/reference/java/api-docs/com/google/protobuf/Descriptors.GenericDescriptor.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Descriptors.GenericDescriptor.html rename to reference/java/api-docs/com/google/protobuf/Descriptors.GenericDescriptor.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Descriptors.MethodDescriptor.html b/reference/java/api-docs/com/google/protobuf/Descriptors.MethodDescriptor.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Descriptors.MethodDescriptor.html rename to reference/java/api-docs/com/google/protobuf/Descriptors.MethodDescriptor.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Descriptors.OneofDescriptor.html b/reference/java/api-docs/com/google/protobuf/Descriptors.OneofDescriptor.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Descriptors.OneofDescriptor.html rename to reference/java/api-docs/com/google/protobuf/Descriptors.OneofDescriptor.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Descriptors.ServiceDescriptor.html b/reference/java/api-docs/com/google/protobuf/Descriptors.ServiceDescriptor.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Descriptors.ServiceDescriptor.html rename to reference/java/api-docs/com/google/protobuf/Descriptors.ServiceDescriptor.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Descriptors.html b/reference/java/api-docs/com/google/protobuf/Descriptors.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Descriptors.html rename to reference/java/api-docs/com/google/protobuf/Descriptors.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DoubleValue.Builder.html b/reference/java/api-docs/com/google/protobuf/DoubleValue.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DoubleValue.Builder.html rename to reference/java/api-docs/com/google/protobuf/DoubleValue.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DoubleValue.html b/reference/java/api-docs/com/google/protobuf/DoubleValue.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DoubleValue.html rename to reference/java/api-docs/com/google/protobuf/DoubleValue.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DoubleValueOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DoubleValueOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DoubleValueOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DoubleValueOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Duration.Builder.html b/reference/java/api-docs/com/google/protobuf/Duration.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Duration.Builder.html rename to reference/java/api-docs/com/google/protobuf/Duration.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Duration.html b/reference/java/api-docs/com/google/protobuf/Duration.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Duration.html rename to reference/java/api-docs/com/google/protobuf/Duration.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DurationOrBuilder.html b/reference/java/api-docs/com/google/protobuf/DurationOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DurationOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/DurationOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DurationProto.html b/reference/java/api-docs/com/google/protobuf/DurationProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DurationProto.html rename to reference/java/api-docs/com/google/protobuf/DurationProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DynamicMessage.Builder.html b/reference/java/api-docs/com/google/protobuf/DynamicMessage.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DynamicMessage.Builder.html rename to reference/java/api-docs/com/google/protobuf/DynamicMessage.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/DynamicMessage.html b/reference/java/api-docs/com/google/protobuf/DynamicMessage.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/DynamicMessage.html rename to reference/java/api-docs/com/google/protobuf/DynamicMessage.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Empty.Builder.html b/reference/java/api-docs/com/google/protobuf/Empty.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Empty.Builder.html rename to reference/java/api-docs/com/google/protobuf/Empty.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Empty.html b/reference/java/api-docs/com/google/protobuf/Empty.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Empty.html rename to reference/java/api-docs/com/google/protobuf/Empty.html diff --git a/content/reference/java/api-docs/com/google/protobuf/EmptyOrBuilder.html b/reference/java/api-docs/com/google/protobuf/EmptyOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/EmptyOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/EmptyOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/EmptyProto.html b/reference/java/api-docs/com/google/protobuf/EmptyProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/EmptyProto.html rename to reference/java/api-docs/com/google/protobuf/EmptyProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Enum.Builder.html b/reference/java/api-docs/com/google/protobuf/Enum.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Enum.Builder.html rename to reference/java/api-docs/com/google/protobuf/Enum.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Enum.html b/reference/java/api-docs/com/google/protobuf/Enum.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Enum.html rename to reference/java/api-docs/com/google/protobuf/Enum.html diff --git a/content/reference/java/api-docs/com/google/protobuf/EnumOrBuilder.html b/reference/java/api-docs/com/google/protobuf/EnumOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/EnumOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/EnumOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/EnumValue.Builder.html b/reference/java/api-docs/com/google/protobuf/EnumValue.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/EnumValue.Builder.html rename to reference/java/api-docs/com/google/protobuf/EnumValue.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/EnumValue.html b/reference/java/api-docs/com/google/protobuf/EnumValue.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/EnumValue.html rename to reference/java/api-docs/com/google/protobuf/EnumValue.html diff --git a/content/reference/java/api-docs/com/google/protobuf/EnumValueOrBuilder.html b/reference/java/api-docs/com/google/protobuf/EnumValueOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/EnumValueOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/EnumValueOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ExperimentalApi.html b/reference/java/api-docs/com/google/protobuf/ExperimentalApi.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ExperimentalApi.html rename to reference/java/api-docs/com/google/protobuf/ExperimentalApi.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Extension.ExtensionType.html b/reference/java/api-docs/com/google/protobuf/Extension.ExtensionType.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Extension.ExtensionType.html rename to reference/java/api-docs/com/google/protobuf/Extension.ExtensionType.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Extension.MessageType.html b/reference/java/api-docs/com/google/protobuf/Extension.MessageType.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Extension.MessageType.html rename to reference/java/api-docs/com/google/protobuf/Extension.MessageType.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Extension.html b/reference/java/api-docs/com/google/protobuf/Extension.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Extension.html rename to reference/java/api-docs/com/google/protobuf/Extension.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ExtensionLite.html b/reference/java/api-docs/com/google/protobuf/ExtensionLite.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ExtensionLite.html rename to reference/java/api-docs/com/google/protobuf/ExtensionLite.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ExtensionRegistry.ExtensionInfo.html b/reference/java/api-docs/com/google/protobuf/ExtensionRegistry.ExtensionInfo.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ExtensionRegistry.ExtensionInfo.html rename to reference/java/api-docs/com/google/protobuf/ExtensionRegistry.ExtensionInfo.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ExtensionRegistry.html b/reference/java/api-docs/com/google/protobuf/ExtensionRegistry.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ExtensionRegistry.html rename to reference/java/api-docs/com/google/protobuf/ExtensionRegistry.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ExtensionRegistryLite.html b/reference/java/api-docs/com/google/protobuf/ExtensionRegistryLite.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ExtensionRegistryLite.html rename to reference/java/api-docs/com/google/protobuf/ExtensionRegistryLite.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Field.Builder.html b/reference/java/api-docs/com/google/protobuf/Field.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Field.Builder.html rename to reference/java/api-docs/com/google/protobuf/Field.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Field.Cardinality.html b/reference/java/api-docs/com/google/protobuf/Field.Cardinality.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Field.Cardinality.html rename to reference/java/api-docs/com/google/protobuf/Field.Cardinality.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Field.Kind.html b/reference/java/api-docs/com/google/protobuf/Field.Kind.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Field.Kind.html rename to reference/java/api-docs/com/google/protobuf/Field.Kind.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Field.html b/reference/java/api-docs/com/google/protobuf/Field.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Field.html rename to reference/java/api-docs/com/google/protobuf/Field.html diff --git a/content/reference/java/api-docs/com/google/protobuf/FieldMask.Builder.html b/reference/java/api-docs/com/google/protobuf/FieldMask.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/FieldMask.Builder.html rename to reference/java/api-docs/com/google/protobuf/FieldMask.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/FieldMask.html b/reference/java/api-docs/com/google/protobuf/FieldMask.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/FieldMask.html rename to reference/java/api-docs/com/google/protobuf/FieldMask.html diff --git a/content/reference/java/api-docs/com/google/protobuf/FieldMaskOrBuilder.html b/reference/java/api-docs/com/google/protobuf/FieldMaskOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/FieldMaskOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/FieldMaskOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/FieldMaskProto.html b/reference/java/api-docs/com/google/protobuf/FieldMaskProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/FieldMaskProto.html rename to reference/java/api-docs/com/google/protobuf/FieldMaskProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/FieldOrBuilder.html b/reference/java/api-docs/com/google/protobuf/FieldOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/FieldOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/FieldOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/FieldType.html b/reference/java/api-docs/com/google/protobuf/FieldType.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/FieldType.html rename to reference/java/api-docs/com/google/protobuf/FieldType.html diff --git a/content/reference/java/api-docs/com/google/protobuf/FloatValue.Builder.html b/reference/java/api-docs/com/google/protobuf/FloatValue.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/FloatValue.Builder.html rename to reference/java/api-docs/com/google/protobuf/FloatValue.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/FloatValue.html b/reference/java/api-docs/com/google/protobuf/FloatValue.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/FloatValue.html rename to reference/java/api-docs/com/google/protobuf/FloatValue.html diff --git a/content/reference/java/api-docs/com/google/protobuf/FloatValueOrBuilder.html b/reference/java/api-docs/com/google/protobuf/FloatValueOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/FloatValueOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/FloatValueOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.Builder.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessage.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.Builder.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessage.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.BuilderParent.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessage.BuilderParent.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.BuilderParent.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessage.BuilderParent.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.ExtendableBuilder.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessage.ExtendableBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.ExtendableBuilder.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessage.ExtendableBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.ExtendableMessage.ExtensionWriter.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessage.ExtendableMessage.ExtensionWriter.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.ExtendableMessage.ExtensionWriter.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessage.ExtendableMessage.ExtensionWriter.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.ExtendableMessage.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessage.ExtendableMessage.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.ExtendableMessage.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessage.ExtendableMessage.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.ExtendableMessageOrBuilder.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessage.ExtendableMessageOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.ExtendableMessageOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessage.ExtendableMessageOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.FieldAccessorTable.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessage.FieldAccessorTable.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.FieldAccessorTable.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessage.FieldAccessorTable.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.GeneratedExtension.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessage.GeneratedExtension.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.GeneratedExtension.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessage.GeneratedExtension.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessage.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessage.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessage.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.Builder.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.Builder.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.DefaultInstanceBasedParser.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.DefaultInstanceBasedParser.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.DefaultInstanceBasedParser.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.DefaultInstanceBasedParser.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.ExtendableBuilder.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.ExtendableBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.ExtendableBuilder.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.ExtendableBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.ExtendableMessage.ExtensionWriter.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.ExtendableMessage.ExtensionWriter.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.ExtendableMessage.ExtensionWriter.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.ExtendableMessage.ExtensionWriter.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.ExtendableMessage.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.ExtendableMessage.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.ExtendableMessage.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.ExtendableMessage.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.ExtendableMessageOrBuilder.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.ExtendableMessageOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.ExtendableMessageOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.ExtendableMessageOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.GeneratedExtension.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.GeneratedExtension.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.GeneratedExtension.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.GeneratedExtension.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.MethodToInvoke.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.MethodToInvoke.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.MethodToInvoke.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.MethodToInvoke.html diff --git a/content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.html b/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.html rename to reference/java/api-docs/com/google/protobuf/GeneratedMessageLite.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Int32Value.Builder.html b/reference/java/api-docs/com/google/protobuf/Int32Value.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Int32Value.Builder.html rename to reference/java/api-docs/com/google/protobuf/Int32Value.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Int32Value.html b/reference/java/api-docs/com/google/protobuf/Int32Value.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Int32Value.html rename to reference/java/api-docs/com/google/protobuf/Int32Value.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Int32ValueOrBuilder.html b/reference/java/api-docs/com/google/protobuf/Int32ValueOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Int32ValueOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/Int32ValueOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Int64Value.Builder.html b/reference/java/api-docs/com/google/protobuf/Int64Value.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Int64Value.Builder.html rename to reference/java/api-docs/com/google/protobuf/Int64Value.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Int64Value.html b/reference/java/api-docs/com/google/protobuf/Int64Value.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Int64Value.html rename to reference/java/api-docs/com/google/protobuf/Int64Value.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Int64ValueOrBuilder.html b/reference/java/api-docs/com/google/protobuf/Int64ValueOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Int64ValueOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/Int64ValueOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Internal.BooleanList.html b/reference/java/api-docs/com/google/protobuf/Internal.BooleanList.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Internal.BooleanList.html rename to reference/java/api-docs/com/google/protobuf/Internal.BooleanList.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Internal.DoubleList.html b/reference/java/api-docs/com/google/protobuf/Internal.DoubleList.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Internal.DoubleList.html rename to reference/java/api-docs/com/google/protobuf/Internal.DoubleList.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Internal.EnumLite.html b/reference/java/api-docs/com/google/protobuf/Internal.EnumLite.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Internal.EnumLite.html rename to reference/java/api-docs/com/google/protobuf/Internal.EnumLite.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Internal.EnumLiteMap.html b/reference/java/api-docs/com/google/protobuf/Internal.EnumLiteMap.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Internal.EnumLiteMap.html rename to reference/java/api-docs/com/google/protobuf/Internal.EnumLiteMap.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Internal.FloatList.html b/reference/java/api-docs/com/google/protobuf/Internal.FloatList.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Internal.FloatList.html rename to reference/java/api-docs/com/google/protobuf/Internal.FloatList.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Internal.IntList.html b/reference/java/api-docs/com/google/protobuf/Internal.IntList.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Internal.IntList.html rename to reference/java/api-docs/com/google/protobuf/Internal.IntList.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Internal.ListAdapter.Converter.html b/reference/java/api-docs/com/google/protobuf/Internal.ListAdapter.Converter.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Internal.ListAdapter.Converter.html rename to reference/java/api-docs/com/google/protobuf/Internal.ListAdapter.Converter.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Internal.ListAdapter.html b/reference/java/api-docs/com/google/protobuf/Internal.ListAdapter.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Internal.ListAdapter.html rename to reference/java/api-docs/com/google/protobuf/Internal.ListAdapter.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Internal.LongList.html b/reference/java/api-docs/com/google/protobuf/Internal.LongList.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Internal.LongList.html rename to reference/java/api-docs/com/google/protobuf/Internal.LongList.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Internal.MapAdapter.Converter.html b/reference/java/api-docs/com/google/protobuf/Internal.MapAdapter.Converter.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Internal.MapAdapter.Converter.html rename to reference/java/api-docs/com/google/protobuf/Internal.MapAdapter.Converter.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Internal.MapAdapter.html b/reference/java/api-docs/com/google/protobuf/Internal.MapAdapter.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Internal.MapAdapter.html rename to reference/java/api-docs/com/google/protobuf/Internal.MapAdapter.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Internal.ProtobufList.html b/reference/java/api-docs/com/google/protobuf/Internal.ProtobufList.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Internal.ProtobufList.html rename to reference/java/api-docs/com/google/protobuf/Internal.ProtobufList.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Internal.html b/reference/java/api-docs/com/google/protobuf/Internal.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Internal.html rename to reference/java/api-docs/com/google/protobuf/Internal.html diff --git a/content/reference/java/api-docs/com/google/protobuf/InvalidProtocolBufferException.InvalidWireTypeException.html b/reference/java/api-docs/com/google/protobuf/InvalidProtocolBufferException.InvalidWireTypeException.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/InvalidProtocolBufferException.InvalidWireTypeException.html rename to reference/java/api-docs/com/google/protobuf/InvalidProtocolBufferException.InvalidWireTypeException.html diff --git a/content/reference/java/api-docs/com/google/protobuf/InvalidProtocolBufferException.html b/reference/java/api-docs/com/google/protobuf/InvalidProtocolBufferException.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/InvalidProtocolBufferException.html rename to reference/java/api-docs/com/google/protobuf/InvalidProtocolBufferException.html diff --git a/content/reference/java/api-docs/com/google/protobuf/JavaType.html b/reference/java/api-docs/com/google/protobuf/JavaType.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/JavaType.html rename to reference/java/api-docs/com/google/protobuf/JavaType.html diff --git a/content/reference/java/api-docs/com/google/protobuf/LazyField.html b/reference/java/api-docs/com/google/protobuf/LazyField.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/LazyField.html rename to reference/java/api-docs/com/google/protobuf/LazyField.html diff --git a/content/reference/java/api-docs/com/google/protobuf/LazyFieldLite.html b/reference/java/api-docs/com/google/protobuf/LazyFieldLite.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/LazyFieldLite.html rename to reference/java/api-docs/com/google/protobuf/LazyFieldLite.html diff --git a/content/reference/java/api-docs/com/google/protobuf/LazyStringArrayList.html b/reference/java/api-docs/com/google/protobuf/LazyStringArrayList.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/LazyStringArrayList.html rename to reference/java/api-docs/com/google/protobuf/LazyStringArrayList.html diff --git a/content/reference/java/api-docs/com/google/protobuf/LazyStringList.html b/reference/java/api-docs/com/google/protobuf/LazyStringList.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/LazyStringList.html rename to reference/java/api-docs/com/google/protobuf/LazyStringList.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ListValue.Builder.html b/reference/java/api-docs/com/google/protobuf/ListValue.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ListValue.Builder.html rename to reference/java/api-docs/com/google/protobuf/ListValue.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ListValue.html b/reference/java/api-docs/com/google/protobuf/ListValue.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ListValue.html rename to reference/java/api-docs/com/google/protobuf/ListValue.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ListValueOrBuilder.html b/reference/java/api-docs/com/google/protobuf/ListValueOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ListValueOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/ListValueOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/MapEntry.Builder.html b/reference/java/api-docs/com/google/protobuf/MapEntry.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/MapEntry.Builder.html rename to reference/java/api-docs/com/google/protobuf/MapEntry.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/MapEntry.html b/reference/java/api-docs/com/google/protobuf/MapEntry.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/MapEntry.html rename to reference/java/api-docs/com/google/protobuf/MapEntry.html diff --git a/content/reference/java/api-docs/com/google/protobuf/MapEntryLite.Builder.html b/reference/java/api-docs/com/google/protobuf/MapEntryLite.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/MapEntryLite.Builder.html rename to reference/java/api-docs/com/google/protobuf/MapEntryLite.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/MapEntryLite.html b/reference/java/api-docs/com/google/protobuf/MapEntryLite.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/MapEntryLite.html rename to reference/java/api-docs/com/google/protobuf/MapEntryLite.html diff --git a/content/reference/java/api-docs/com/google/protobuf/MapField.html b/reference/java/api-docs/com/google/protobuf/MapField.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/MapField.html rename to reference/java/api-docs/com/google/protobuf/MapField.html diff --git a/content/reference/java/api-docs/com/google/protobuf/MapFieldLite.html b/reference/java/api-docs/com/google/protobuf/MapFieldLite.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/MapFieldLite.html rename to reference/java/api-docs/com/google/protobuf/MapFieldLite.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Message.Builder.html b/reference/java/api-docs/com/google/protobuf/Message.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Message.Builder.html rename to reference/java/api-docs/com/google/protobuf/Message.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Message.html b/reference/java/api-docs/com/google/protobuf/Message.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Message.html rename to reference/java/api-docs/com/google/protobuf/Message.html diff --git a/content/reference/java/api-docs/com/google/protobuf/MessageLite.Builder.html b/reference/java/api-docs/com/google/protobuf/MessageLite.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/MessageLite.Builder.html rename to reference/java/api-docs/com/google/protobuf/MessageLite.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/MessageLite.html b/reference/java/api-docs/com/google/protobuf/MessageLite.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/MessageLite.html rename to reference/java/api-docs/com/google/protobuf/MessageLite.html diff --git a/content/reference/java/api-docs/com/google/protobuf/MessageLiteOrBuilder.html b/reference/java/api-docs/com/google/protobuf/MessageLiteOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/MessageLiteOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/MessageLiteOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/MessageOrBuilder.html b/reference/java/api-docs/com/google/protobuf/MessageOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/MessageOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/MessageOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Method.Builder.html b/reference/java/api-docs/com/google/protobuf/Method.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Method.Builder.html rename to reference/java/api-docs/com/google/protobuf/Method.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Method.html b/reference/java/api-docs/com/google/protobuf/Method.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Method.html rename to reference/java/api-docs/com/google/protobuf/Method.html diff --git a/content/reference/java/api-docs/com/google/protobuf/MethodOrBuilder.html b/reference/java/api-docs/com/google/protobuf/MethodOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/MethodOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/MethodOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Mixin.Builder.html b/reference/java/api-docs/com/google/protobuf/Mixin.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Mixin.Builder.html rename to reference/java/api-docs/com/google/protobuf/Mixin.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Mixin.html b/reference/java/api-docs/com/google/protobuf/Mixin.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Mixin.html rename to reference/java/api-docs/com/google/protobuf/Mixin.html diff --git a/content/reference/java/api-docs/com/google/protobuf/MixinOrBuilder.html b/reference/java/api-docs/com/google/protobuf/MixinOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/MixinOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/MixinOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/NullValue.html b/reference/java/api-docs/com/google/protobuf/NullValue.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/NullValue.html rename to reference/java/api-docs/com/google/protobuf/NullValue.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Option.Builder.html b/reference/java/api-docs/com/google/protobuf/Option.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Option.Builder.html rename to reference/java/api-docs/com/google/protobuf/Option.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Option.html b/reference/java/api-docs/com/google/protobuf/Option.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Option.html rename to reference/java/api-docs/com/google/protobuf/Option.html diff --git a/content/reference/java/api-docs/com/google/protobuf/OptionOrBuilder.html b/reference/java/api-docs/com/google/protobuf/OptionOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/OptionOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/OptionOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Parser.html b/reference/java/api-docs/com/google/protobuf/Parser.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Parser.html rename to reference/java/api-docs/com/google/protobuf/Parser.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ProtoSyntax.html b/reference/java/api-docs/com/google/protobuf/ProtoSyntax.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ProtoSyntax.html rename to reference/java/api-docs/com/google/protobuf/ProtoSyntax.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ProtocolMessageEnum.html b/reference/java/api-docs/com/google/protobuf/ProtocolMessageEnum.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ProtocolMessageEnum.html rename to reference/java/api-docs/com/google/protobuf/ProtocolMessageEnum.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ProtocolStringList.html b/reference/java/api-docs/com/google/protobuf/ProtocolStringList.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ProtocolStringList.html rename to reference/java/api-docs/com/google/protobuf/ProtocolStringList.html diff --git a/content/reference/java/api-docs/com/google/protobuf/RepeatedFieldBuilder.html b/reference/java/api-docs/com/google/protobuf/RepeatedFieldBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/RepeatedFieldBuilder.html rename to reference/java/api-docs/com/google/protobuf/RepeatedFieldBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/RpcCallback.html b/reference/java/api-docs/com/google/protobuf/RpcCallback.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/RpcCallback.html rename to reference/java/api-docs/com/google/protobuf/RpcCallback.html diff --git a/content/reference/java/api-docs/com/google/protobuf/RpcChannel.html b/reference/java/api-docs/com/google/protobuf/RpcChannel.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/RpcChannel.html rename to reference/java/api-docs/com/google/protobuf/RpcChannel.html diff --git a/content/reference/java/api-docs/com/google/protobuf/RpcController.html b/reference/java/api-docs/com/google/protobuf/RpcController.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/RpcController.html rename to reference/java/api-docs/com/google/protobuf/RpcController.html diff --git a/content/reference/java/api-docs/com/google/protobuf/RpcUtil.AlreadyCalledException.html b/reference/java/api-docs/com/google/protobuf/RpcUtil.AlreadyCalledException.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/RpcUtil.AlreadyCalledException.html rename to reference/java/api-docs/com/google/protobuf/RpcUtil.AlreadyCalledException.html diff --git a/content/reference/java/api-docs/com/google/protobuf/RpcUtil.html b/reference/java/api-docs/com/google/protobuf/RpcUtil.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/RpcUtil.html rename to reference/java/api-docs/com/google/protobuf/RpcUtil.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Service.html b/reference/java/api-docs/com/google/protobuf/Service.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Service.html rename to reference/java/api-docs/com/google/protobuf/Service.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ServiceException.html b/reference/java/api-docs/com/google/protobuf/ServiceException.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ServiceException.html rename to reference/java/api-docs/com/google/protobuf/ServiceException.html diff --git a/content/reference/java/api-docs/com/google/protobuf/SingleFieldBuilder.html b/reference/java/api-docs/com/google/protobuf/SingleFieldBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/SingleFieldBuilder.html rename to reference/java/api-docs/com/google/protobuf/SingleFieldBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/SourceContext.Builder.html b/reference/java/api-docs/com/google/protobuf/SourceContext.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/SourceContext.Builder.html rename to reference/java/api-docs/com/google/protobuf/SourceContext.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/SourceContext.html b/reference/java/api-docs/com/google/protobuf/SourceContext.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/SourceContext.html rename to reference/java/api-docs/com/google/protobuf/SourceContext.html diff --git a/content/reference/java/api-docs/com/google/protobuf/SourceContextOrBuilder.html b/reference/java/api-docs/com/google/protobuf/SourceContextOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/SourceContextOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/SourceContextOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/SourceContextProto.html b/reference/java/api-docs/com/google/protobuf/SourceContextProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/SourceContextProto.html rename to reference/java/api-docs/com/google/protobuf/SourceContextProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/StringValue.Builder.html b/reference/java/api-docs/com/google/protobuf/StringValue.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/StringValue.Builder.html rename to reference/java/api-docs/com/google/protobuf/StringValue.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/StringValue.html b/reference/java/api-docs/com/google/protobuf/StringValue.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/StringValue.html rename to reference/java/api-docs/com/google/protobuf/StringValue.html diff --git a/content/reference/java/api-docs/com/google/protobuf/StringValueOrBuilder.html b/reference/java/api-docs/com/google/protobuf/StringValueOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/StringValueOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/StringValueOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Struct.Builder.html b/reference/java/api-docs/com/google/protobuf/Struct.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Struct.Builder.html rename to reference/java/api-docs/com/google/protobuf/Struct.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Struct.html b/reference/java/api-docs/com/google/protobuf/Struct.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Struct.html rename to reference/java/api-docs/com/google/protobuf/Struct.html diff --git a/content/reference/java/api-docs/com/google/protobuf/StructOrBuilder.html b/reference/java/api-docs/com/google/protobuf/StructOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/StructOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/StructOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/StructProto.html b/reference/java/api-docs/com/google/protobuf/StructProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/StructProto.html rename to reference/java/api-docs/com/google/protobuf/StructProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Syntax.html b/reference/java/api-docs/com/google/protobuf/Syntax.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Syntax.html rename to reference/java/api-docs/com/google/protobuf/Syntax.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TextFormat.InvalidEscapeSequenceException.html b/reference/java/api-docs/com/google/protobuf/TextFormat.InvalidEscapeSequenceException.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TextFormat.InvalidEscapeSequenceException.html rename to reference/java/api-docs/com/google/protobuf/TextFormat.InvalidEscapeSequenceException.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TextFormat.ParseException.html b/reference/java/api-docs/com/google/protobuf/TextFormat.ParseException.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TextFormat.ParseException.html rename to reference/java/api-docs/com/google/protobuf/TextFormat.ParseException.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TextFormat.Parser.Builder.html b/reference/java/api-docs/com/google/protobuf/TextFormat.Parser.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TextFormat.Parser.Builder.html rename to reference/java/api-docs/com/google/protobuf/TextFormat.Parser.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TextFormat.Parser.SingularOverwritePolicy.html b/reference/java/api-docs/com/google/protobuf/TextFormat.Parser.SingularOverwritePolicy.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TextFormat.Parser.SingularOverwritePolicy.html rename to reference/java/api-docs/com/google/protobuf/TextFormat.Parser.SingularOverwritePolicy.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TextFormat.Parser.html b/reference/java/api-docs/com/google/protobuf/TextFormat.Parser.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TextFormat.Parser.html rename to reference/java/api-docs/com/google/protobuf/TextFormat.Parser.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TextFormat.Printer.html b/reference/java/api-docs/com/google/protobuf/TextFormat.Printer.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TextFormat.Printer.html rename to reference/java/api-docs/com/google/protobuf/TextFormat.Printer.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TextFormat.UnknownFieldParseException.html b/reference/java/api-docs/com/google/protobuf/TextFormat.UnknownFieldParseException.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TextFormat.UnknownFieldParseException.html rename to reference/java/api-docs/com/google/protobuf/TextFormat.UnknownFieldParseException.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TextFormat.html b/reference/java/api-docs/com/google/protobuf/TextFormat.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TextFormat.html rename to reference/java/api-docs/com/google/protobuf/TextFormat.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TextFormatParseInfoTree.Builder.html b/reference/java/api-docs/com/google/protobuf/TextFormatParseInfoTree.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TextFormatParseInfoTree.Builder.html rename to reference/java/api-docs/com/google/protobuf/TextFormatParseInfoTree.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TextFormatParseInfoTree.html b/reference/java/api-docs/com/google/protobuf/TextFormatParseInfoTree.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TextFormatParseInfoTree.html rename to reference/java/api-docs/com/google/protobuf/TextFormatParseInfoTree.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TextFormatParseLocation.html b/reference/java/api-docs/com/google/protobuf/TextFormatParseLocation.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TextFormatParseLocation.html rename to reference/java/api-docs/com/google/protobuf/TextFormatParseLocation.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Timestamp.Builder.html b/reference/java/api-docs/com/google/protobuf/Timestamp.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Timestamp.Builder.html rename to reference/java/api-docs/com/google/protobuf/Timestamp.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Timestamp.html b/reference/java/api-docs/com/google/protobuf/Timestamp.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Timestamp.html rename to reference/java/api-docs/com/google/protobuf/Timestamp.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TimestampOrBuilder.html b/reference/java/api-docs/com/google/protobuf/TimestampOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TimestampOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/TimestampOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TimestampProto.html b/reference/java/api-docs/com/google/protobuf/TimestampProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TimestampProto.html rename to reference/java/api-docs/com/google/protobuf/TimestampProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Type.Builder.html b/reference/java/api-docs/com/google/protobuf/Type.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Type.Builder.html rename to reference/java/api-docs/com/google/protobuf/Type.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Type.html b/reference/java/api-docs/com/google/protobuf/Type.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Type.html rename to reference/java/api-docs/com/google/protobuf/Type.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TypeOrBuilder.html b/reference/java/api-docs/com/google/protobuf/TypeOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TypeOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/TypeOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TypeProto.html b/reference/java/api-docs/com/google/protobuf/TypeProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TypeProto.html rename to reference/java/api-docs/com/google/protobuf/TypeProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TypeRegistry.Builder.html b/reference/java/api-docs/com/google/protobuf/TypeRegistry.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TypeRegistry.Builder.html rename to reference/java/api-docs/com/google/protobuf/TypeRegistry.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/TypeRegistry.html b/reference/java/api-docs/com/google/protobuf/TypeRegistry.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/TypeRegistry.html rename to reference/java/api-docs/com/google/protobuf/TypeRegistry.html diff --git a/content/reference/java/api-docs/com/google/protobuf/UInt32Value.Builder.html b/reference/java/api-docs/com/google/protobuf/UInt32Value.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/UInt32Value.Builder.html rename to reference/java/api-docs/com/google/protobuf/UInt32Value.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/UInt32Value.html b/reference/java/api-docs/com/google/protobuf/UInt32Value.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/UInt32Value.html rename to reference/java/api-docs/com/google/protobuf/UInt32Value.html diff --git a/content/reference/java/api-docs/com/google/protobuf/UInt32ValueOrBuilder.html b/reference/java/api-docs/com/google/protobuf/UInt32ValueOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/UInt32ValueOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/UInt32ValueOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/UInt64Value.Builder.html b/reference/java/api-docs/com/google/protobuf/UInt64Value.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/UInt64Value.Builder.html rename to reference/java/api-docs/com/google/protobuf/UInt64Value.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/UInt64Value.html b/reference/java/api-docs/com/google/protobuf/UInt64Value.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/UInt64Value.html rename to reference/java/api-docs/com/google/protobuf/UInt64Value.html diff --git a/content/reference/java/api-docs/com/google/protobuf/UInt64ValueOrBuilder.html b/reference/java/api-docs/com/google/protobuf/UInt64ValueOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/UInt64ValueOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/UInt64ValueOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/UninitializedMessageException.html b/reference/java/api-docs/com/google/protobuf/UninitializedMessageException.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/UninitializedMessageException.html rename to reference/java/api-docs/com/google/protobuf/UninitializedMessageException.html diff --git a/content/reference/java/api-docs/com/google/protobuf/UnknownFieldSet.Builder.html b/reference/java/api-docs/com/google/protobuf/UnknownFieldSet.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/UnknownFieldSet.Builder.html rename to reference/java/api-docs/com/google/protobuf/UnknownFieldSet.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/UnknownFieldSet.Field.Builder.html b/reference/java/api-docs/com/google/protobuf/UnknownFieldSet.Field.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/UnknownFieldSet.Field.Builder.html rename to reference/java/api-docs/com/google/protobuf/UnknownFieldSet.Field.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/UnknownFieldSet.Field.html b/reference/java/api-docs/com/google/protobuf/UnknownFieldSet.Field.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/UnknownFieldSet.Field.html rename to reference/java/api-docs/com/google/protobuf/UnknownFieldSet.Field.html diff --git a/content/reference/java/api-docs/com/google/protobuf/UnknownFieldSet.Parser.html b/reference/java/api-docs/com/google/protobuf/UnknownFieldSet.Parser.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/UnknownFieldSet.Parser.html rename to reference/java/api-docs/com/google/protobuf/UnknownFieldSet.Parser.html diff --git a/content/reference/java/api-docs/com/google/protobuf/UnknownFieldSet.html b/reference/java/api-docs/com/google/protobuf/UnknownFieldSet.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/UnknownFieldSet.html rename to reference/java/api-docs/com/google/protobuf/UnknownFieldSet.html diff --git a/content/reference/java/api-docs/com/google/protobuf/UnknownFieldSetLite.Builder.html b/reference/java/api-docs/com/google/protobuf/UnknownFieldSetLite.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/UnknownFieldSetLite.Builder.html rename to reference/java/api-docs/com/google/protobuf/UnknownFieldSetLite.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/UnknownFieldSetLite.html b/reference/java/api-docs/com/google/protobuf/UnknownFieldSetLite.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/UnknownFieldSetLite.html rename to reference/java/api-docs/com/google/protobuf/UnknownFieldSetLite.html diff --git a/content/reference/java/api-docs/com/google/protobuf/UnmodifiableLazyStringList.html b/reference/java/api-docs/com/google/protobuf/UnmodifiableLazyStringList.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/UnmodifiableLazyStringList.html rename to reference/java/api-docs/com/google/protobuf/UnmodifiableLazyStringList.html diff --git a/content/reference/java/api-docs/com/google/protobuf/UnsafeByteOperations.html b/reference/java/api-docs/com/google/protobuf/UnsafeByteOperations.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/UnsafeByteOperations.html rename to reference/java/api-docs/com/google/protobuf/UnsafeByteOperations.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Value.Builder.html b/reference/java/api-docs/com/google/protobuf/Value.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Value.Builder.html rename to reference/java/api-docs/com/google/protobuf/Value.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Value.KindCase.html b/reference/java/api-docs/com/google/protobuf/Value.KindCase.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Value.KindCase.html rename to reference/java/api-docs/com/google/protobuf/Value.KindCase.html diff --git a/content/reference/java/api-docs/com/google/protobuf/Value.html b/reference/java/api-docs/com/google/protobuf/Value.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/Value.html rename to reference/java/api-docs/com/google/protobuf/Value.html diff --git a/content/reference/java/api-docs/com/google/protobuf/ValueOrBuilder.html b/reference/java/api-docs/com/google/protobuf/ValueOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/ValueOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/ValueOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/WireFormat.FieldType.html b/reference/java/api-docs/com/google/protobuf/WireFormat.FieldType.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/WireFormat.FieldType.html rename to reference/java/api-docs/com/google/protobuf/WireFormat.FieldType.html diff --git a/content/reference/java/api-docs/com/google/protobuf/WireFormat.JavaType.html b/reference/java/api-docs/com/google/protobuf/WireFormat.JavaType.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/WireFormat.JavaType.html rename to reference/java/api-docs/com/google/protobuf/WireFormat.JavaType.html diff --git a/content/reference/java/api-docs/com/google/protobuf/WireFormat.html b/reference/java/api-docs/com/google/protobuf/WireFormat.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/WireFormat.html rename to reference/java/api-docs/com/google/protobuf/WireFormat.html diff --git a/content/reference/java/api-docs/com/google/protobuf/WrappersProto.html b/reference/java/api-docs/com/google/protobuf/WrappersProto.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/WrappersProto.html rename to reference/java/api-docs/com/google/protobuf/WrappersProto.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorRequest.Builder.html b/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorRequest.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorRequest.Builder.html rename to reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorRequest.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorRequest.html b/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorRequest.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorRequest.html rename to reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorRequest.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorRequestOrBuilder.html b/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorRequestOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorRequestOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorRequestOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.Builder.html b/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.Builder.html rename to reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.Feature.html b/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.Feature.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.Feature.html rename to reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.Feature.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.File.Builder.html b/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.File.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.File.Builder.html rename to reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.File.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.File.html b/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.File.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.File.html rename to reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.File.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.FileOrBuilder.html b/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.FileOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.FileOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.FileOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.html b/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.html rename to reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponse.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponseOrBuilder.html b/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponseOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponseOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.CodeGeneratorResponseOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.Version.Builder.html b/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.Version.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.Version.Builder.html rename to reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.Version.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.Version.html b/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.Version.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.Version.html rename to reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.Version.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.VersionOrBuilder.html b/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.VersionOrBuilder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.VersionOrBuilder.html rename to reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.VersionOrBuilder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.html b/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.html rename to reference/java/api-docs/com/google/protobuf/compiler/PluginProtos.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/package-frame.html b/reference/java/api-docs/com/google/protobuf/compiler/package-frame.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/package-frame.html rename to reference/java/api-docs/com/google/protobuf/compiler/package-frame.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/package-summary.html b/reference/java/api-docs/com/google/protobuf/compiler/package-summary.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/package-summary.html rename to reference/java/api-docs/com/google/protobuf/compiler/package-summary.html diff --git a/content/reference/java/api-docs/com/google/protobuf/compiler/package-tree.html b/reference/java/api-docs/com/google/protobuf/compiler/package-tree.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/compiler/package-tree.html rename to reference/java/api-docs/com/google/protobuf/compiler/package-tree.html diff --git a/content/reference/java/api-docs/com/google/protobuf/package-frame.html b/reference/java/api-docs/com/google/protobuf/package-frame.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/package-frame.html rename to reference/java/api-docs/com/google/protobuf/package-frame.html diff --git a/content/reference/java/api-docs/com/google/protobuf/package-summary.html b/reference/java/api-docs/com/google/protobuf/package-summary.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/package-summary.html rename to reference/java/api-docs/com/google/protobuf/package-summary.html diff --git a/content/reference/java/api-docs/com/google/protobuf/package-tree.html b/reference/java/api-docs/com/google/protobuf/package-tree.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/package-tree.html rename to reference/java/api-docs/com/google/protobuf/package-tree.html diff --git a/content/reference/java/api-docs/com/google/protobuf/util/Durations.html b/reference/java/api-docs/com/google/protobuf/util/Durations.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/util/Durations.html rename to reference/java/api-docs/com/google/protobuf/util/Durations.html diff --git a/content/reference/java/api-docs/com/google/protobuf/util/FieldMaskUtil.MergeOptions.html b/reference/java/api-docs/com/google/protobuf/util/FieldMaskUtil.MergeOptions.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/util/FieldMaskUtil.MergeOptions.html rename to reference/java/api-docs/com/google/protobuf/util/FieldMaskUtil.MergeOptions.html diff --git a/content/reference/java/api-docs/com/google/protobuf/util/FieldMaskUtil.html b/reference/java/api-docs/com/google/protobuf/util/FieldMaskUtil.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/util/FieldMaskUtil.html rename to reference/java/api-docs/com/google/protobuf/util/FieldMaskUtil.html diff --git a/content/reference/java/api-docs/com/google/protobuf/util/JsonFormat.Parser.html b/reference/java/api-docs/com/google/protobuf/util/JsonFormat.Parser.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/util/JsonFormat.Parser.html rename to reference/java/api-docs/com/google/protobuf/util/JsonFormat.Parser.html diff --git a/content/reference/java/api-docs/com/google/protobuf/util/JsonFormat.Printer.html b/reference/java/api-docs/com/google/protobuf/util/JsonFormat.Printer.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/util/JsonFormat.Printer.html rename to reference/java/api-docs/com/google/protobuf/util/JsonFormat.Printer.html diff --git a/content/reference/java/api-docs/com/google/protobuf/util/JsonFormat.TypeRegistry.Builder.html b/reference/java/api-docs/com/google/protobuf/util/JsonFormat.TypeRegistry.Builder.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/util/JsonFormat.TypeRegistry.Builder.html rename to reference/java/api-docs/com/google/protobuf/util/JsonFormat.TypeRegistry.Builder.html diff --git a/content/reference/java/api-docs/com/google/protobuf/util/JsonFormat.TypeRegistry.html b/reference/java/api-docs/com/google/protobuf/util/JsonFormat.TypeRegistry.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/util/JsonFormat.TypeRegistry.html rename to reference/java/api-docs/com/google/protobuf/util/JsonFormat.TypeRegistry.html diff --git a/content/reference/java/api-docs/com/google/protobuf/util/JsonFormat.html b/reference/java/api-docs/com/google/protobuf/util/JsonFormat.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/util/JsonFormat.html rename to reference/java/api-docs/com/google/protobuf/util/JsonFormat.html diff --git a/content/reference/java/api-docs/com/google/protobuf/util/Structs.html b/reference/java/api-docs/com/google/protobuf/util/Structs.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/util/Structs.html rename to reference/java/api-docs/com/google/protobuf/util/Structs.html diff --git a/content/reference/java/api-docs/com/google/protobuf/util/TimeUtil.html b/reference/java/api-docs/com/google/protobuf/util/TimeUtil.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/util/TimeUtil.html rename to reference/java/api-docs/com/google/protobuf/util/TimeUtil.html diff --git a/content/reference/java/api-docs/com/google/protobuf/util/Timestamps.html b/reference/java/api-docs/com/google/protobuf/util/Timestamps.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/util/Timestamps.html rename to reference/java/api-docs/com/google/protobuf/util/Timestamps.html diff --git a/content/reference/java/api-docs/com/google/protobuf/util/Values.html b/reference/java/api-docs/com/google/protobuf/util/Values.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/util/Values.html rename to reference/java/api-docs/com/google/protobuf/util/Values.html diff --git a/content/reference/java/api-docs/com/google/protobuf/util/package-frame.html b/reference/java/api-docs/com/google/protobuf/util/package-frame.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/util/package-frame.html rename to reference/java/api-docs/com/google/protobuf/util/package-frame.html diff --git a/content/reference/java/api-docs/com/google/protobuf/util/package-summary.html b/reference/java/api-docs/com/google/protobuf/util/package-summary.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/util/package-summary.html rename to reference/java/api-docs/com/google/protobuf/util/package-summary.html diff --git a/content/reference/java/api-docs/com/google/protobuf/util/package-tree.html b/reference/java/api-docs/com/google/protobuf/util/package-tree.html similarity index 100% rename from content/reference/java/api-docs/com/google/protobuf/util/package-tree.html rename to reference/java/api-docs/com/google/protobuf/util/package-tree.html diff --git a/content/reference/java/api-docs/constant-values.html b/reference/java/api-docs/constant-values.html similarity index 100% rename from content/reference/java/api-docs/constant-values.html rename to reference/java/api-docs/constant-values.html diff --git a/content/reference/java/api-docs/deprecated-list.html b/reference/java/api-docs/deprecated-list.html similarity index 100% rename from content/reference/java/api-docs/deprecated-list.html rename to reference/java/api-docs/deprecated-list.html diff --git a/content/reference/java/api-docs/help-doc.html b/reference/java/api-docs/help-doc.html similarity index 100% rename from content/reference/java/api-docs/help-doc.html rename to reference/java/api-docs/help-doc.html diff --git a/content/reference/java/api-docs/includes/stylesheet.css b/reference/java/api-docs/includes/stylesheet.css similarity index 100% rename from content/reference/java/api-docs/includes/stylesheet.css rename to reference/java/api-docs/includes/stylesheet.css diff --git a/content/reference/java/api-docs/index-all.html b/reference/java/api-docs/index-all.html similarity index 100% rename from content/reference/java/api-docs/index-all.html rename to reference/java/api-docs/index-all.html diff --git a/content/reference/java/api-docs/overview-frame.html b/reference/java/api-docs/overview-frame.html similarity index 100% rename from content/reference/java/api-docs/overview-frame.html rename to reference/java/api-docs/overview-frame.html diff --git a/content/reference/java/api-docs/overview-summary.html b/reference/java/api-docs/overview-summary.html similarity index 100% rename from content/reference/java/api-docs/overview-summary.html rename to reference/java/api-docs/overview-summary.html diff --git a/content/reference/java/api-docs/overview-tree.html b/reference/java/api-docs/overview-tree.html similarity index 100% rename from content/reference/java/api-docs/overview-tree.html rename to reference/java/api-docs/overview-tree.html diff --git a/content/reference/java/api-docs/package-list b/reference/java/api-docs/package-list similarity index 100% rename from content/reference/java/api-docs/package-list rename to reference/java/api-docs/package-list diff --git a/content/reference/java/api-docs/resources/background.gif b/reference/java/api-docs/resources/background.gif similarity index 100% rename from content/reference/java/api-docs/resources/background.gif rename to reference/java/api-docs/resources/background.gif diff --git a/content/reference/java/api-docs/resources/tab.gif b/reference/java/api-docs/resources/tab.gif similarity index 100% rename from content/reference/java/api-docs/resources/tab.gif rename to reference/java/api-docs/resources/tab.gif diff --git a/content/reference/java/api-docs/resources/titlebar.gif b/reference/java/api-docs/resources/titlebar.gif similarity index 100% rename from content/reference/java/api-docs/resources/titlebar.gif rename to reference/java/api-docs/resources/titlebar.gif diff --git a/content/reference/java/api-docs/resources/titlebar_end.gif b/reference/java/api-docs/resources/titlebar_end.gif similarity index 100% rename from content/reference/java/api-docs/resources/titlebar_end.gif rename to reference/java/api-docs/resources/titlebar_end.gif diff --git a/content/reference/java/api-docs/script.js b/reference/java/api-docs/script.js similarity index 100% rename from content/reference/java/api-docs/script.js rename to reference/java/api-docs/script.js diff --git a/content/reference/java/api-docs/serialized-form.html b/reference/java/api-docs/serialized-form.html similarity index 100% rename from content/reference/java/api-docs/serialized-form.html rename to reference/java/api-docs/serialized-form.html diff --git a/content/reference/java/api-docs/stylesheet.css b/reference/java/api-docs/stylesheet.css similarity index 100% rename from content/reference/java/api-docs/stylesheet.css rename to reference/java/api-docs/stylesheet.css diff --git a/reference/java/index.html b/reference/java/index.html new file mode 100644 index 000000000..59b2191a9 --- /dev/null +++ b/reference/java/index.html @@ -0,0 +1,8 @@ +Java Reference | Protocol Buffers Documentation +

Java Reference

Reference documentation for working with protocol buffer classes in Java.

Java Generated Code Guide

Describes exactly what Java code the protocol buffer compiler generates for any given protocol definition.

Java Proto Names

Names that are generated by the Java protoc plugin.

Java API

\ No newline at end of file diff --git a/reference/java/index.xml b/reference/java/index.xml new file mode 100644 index 000000000..563b9a862 --- /dev/null +++ b/reference/java/index.xml @@ -0,0 +1,5 @@ +Java Reference on Protocol Buffers Documentationhttps://protobuf.dev/reference/java/Recent content in Java Reference on Protocol Buffers DocumentationHugoenJava Generated Code Guidehttps://protobuf.dev/reference/java/java-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/java/java-generated/Any differences between proto2, proto3, and Editions generated code are highlighted—note that these differences are in the generated code as described in this document, not the base message classes/interfaces, which are the same in all versions. You should read the proto2 language guide, proto3 language guide, and/or Editions language guide before reading this document. +Note that no Java protocol buffer methods accept or return nulls unless otherwise specified. +Compiler Invocation The protocol buffer compiler produces Java output when invoked with the --java_out= command-line flag.Java Proto Nameshttps://protobuf.dev/reference/java/java-proto-names/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/java/java-proto-names/This document contains information on what the fully-qualified Java name of a proto is, based on the different proto options. This name corresponds to the package you need to import to use that message. +Recommendation Starting with Edition 2024, best practice is to: +Set option java_package = &quot;com.example.package&quot; Do not set java_outer_classname or features.(pb.java).nest_in_file_class = YES. Starting with Edition 2024, the default behaviors have otherwise been improved so that now the default behavior is considered current best practice.Java APIhttps://protobuf.dev/reference/java/api-docs-link/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/java/api-docs-link/ \ No newline at end of file diff --git a/reference/java/java-generated/index.html b/reference/java/java-generated/index.html new file mode 100644 index 000000000..49275602c --- /dev/null +++ b/reference/java/java-generated/index.html @@ -0,0 +1,520 @@ +Java Generated Code Guide | Protocol Buffers Documentation +

Java Generated Code Guide

Describes exactly what Java code the protocol buffer compiler generates for any given protocol definition.

Any +differences between proto2, proto3, and Editions generated code are +highlighted—note that these differences are in the generated code as +described in this document, not the base message classes/interfaces, which are +the same in all versions. You should read the +proto2 language guide, +proto3 language guide, +and/or +Editions language guide +before reading this document.

Note that no Java protocol buffer methods accept or return nulls unless +otherwise specified.

Compiler Invocation

The protocol buffer compiler produces Java output when invoked with the +--java_out= command-line flag. The parameter to the --java_out= option is +the directory where you want the compiler to write your Java output. For each +.proto file input, the compiler creates a wrapper .java file containing a +Java class that represents the .proto file itself.

If the .proto file contains a line like the following:

option java_multiple_files = true;
+

Then the compiler will also create separate .java files for each of the +classes/enums which it will generate for each top-level message, enumeration, +and service declared in the .proto file.

Otherwise (when the java_multiple_files option is disabled, which is the +default), the aforementioned wrapper class will also be used as an outer class, +and the generated classes/enums for each top-level message, enumeration, and +service declared in the .proto file will all be nested within the outer +wrapper class. Thus the compiler will only generate a single .java file for +the entire .proto file, and it will have an extra layer in the package

The wrapper class’s name is chosen as follows: If the .proto file contains a +line like the following:

option java_outer_classname = "Foo";
+

Then the wrapper class name will be Foo. Otherwise, the wrapper class name is +determined by converting the .proto file base name to camel case. For example, +foo_bar.proto will generate a class name of FooBar. If there’s a service, +enum, or message (including nested types) in the file with the same name, +“OuterClass” will be appended to the wrapper class’s name. Examples:

  • If foo_bar.proto contains a message called FooBar, the wrapper class +will generate a class name of FooBarOuterClass.
  • If foo_bar.proto contains a service called FooService, and +java_outer_classname is also set to the string FooService, then the +wrapper class will generate a class name of FooServiceOuterClass.

In addition to any nested classes, the wrapper class itself will have the +following API (assuming the wrapper class is named Foo and was generated from +foo.proto):

public final class Foo {
+  private Foo() {}  // Not instantiable.
+
+  /** Returns a FileDescriptor message describing the contents of {@code foo.proto}. */
+  public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor();
+  /** Adds all extensions defined in {@code foo.proto} to the given registry. */
+  public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry registry);
+  public static void registerAllExtensions(com.google.protobuf.ExtensionRegistryLite registry);
+
+  // (Nested classes omitted)
+}
+

The Java package name is chosen as described under Packages, below.

The output file is chosen by concatenating the parameter to --java_out=, the +package name (with .s replaced with /s), and the .java file name.

So, for example, let’s say you invoke the compiler as follows:

protoc --proto_path=src --java_out=build/gen src/foo.proto
+

If foo.proto’s Java package is com.example and it doesn’t enable +java_multiple_files and its outer classname is FooProtos, then the protocol +buffer compiler will generate the file build/gen/com/example/FooProtos.java. +The protocol buffer compiler will automatically create the build/gen/com and +build/gen/com/example directories if needed. However, it will not create +build/gen or build; they must already exist. You can specify multiple +.proto files in a single invocation; all output files will be generated at +once.

When outputting Java code, the protocol buffer compiler’s ability to output +directly to JAR archives is particularly convenient, as many Java tools are able +to read source code directly from JAR files. To output to a JAR file, simply +provide an output location ending in .jar. Note that only the Java source code +is placed in the archive; you must still compile it separately to produce Java +class files.

Packages

The generated class is placed in a Java package based on the java_package +option. If the option is omitted, the package declaration is used instead.

For example, if the .proto file contains:

package foo.bar;
+

Then the resulting Java class will be placed in Java package +foo.bar. However, if the .proto file also +contains a java_package option, like so:

package foo.bar;
+option java_package = "com.example.foo.bar";
+

Then the class is placed in the com.example.foo.bar package instead. The +java_package option is provided because normal .proto package declarations +are not expected to start with a backwards domain name.

Messages

If you are designing a new protocol buffer schema, see +the recommendations for Java proto names.

Given a simple message declaration:

message Foo {}
+

The protocol buffer compiler generates a class called Foo, which implements +the Message interface. The class is declared final; no further subclassing +is allowed. Foo extends GeneratedMessage, but this should be considered an +implementation detail. By default, Foo overrides many methods of +GeneratedMessage with specialized versions for maximum speed. However, if the +.proto file contains the line:

option optimize_for = CODE_SIZE;
+

then Foo will override only the minimum set of methods necessary to function +and rely on GeneratedMessage’s reflection-based implementations of the rest. +This significantly reduces the size of the generated code, but also reduces +performance. Alternatively, if the .proto file contains:

option optimize_for = LITE_RUNTIME;
+

then Foo will include fast implementations of all methods, but will implement +the MessageLite interface, which contains a subset of the methods of +Message. In particular, it does not support descriptors, nested builders, or +reflection. However, in this mode, the generated code only needs to link against +libprotobuf-lite.jar instead of libprotobuf.jar. The “lite” library is much +smaller than the full library, and is more appropriate for resource-constrained +systems such as mobile phones.

The Message interface defines methods that let you check, manipulate, read, or +write the entire message. In addition to these methods, the Foo class defines +the following static methods:

  • static Foo getDefaultInstance(): Returns the singleton instance of +Foo. This instance’s contents are identical to what you’d get if you +called Foo.newBuilder().build() (so all singular fields are unset and all +repeated fields are empty). Note that the default instance of a message can +be used as a factory by calling its newBuilderForType() method.
  • static Descriptor getDescriptor(): Returns the type’s descriptor. This +contains information about the type, including what fields it has and what +their types are. This can be used with the reflection methods of the +Message, such as getField().
  • static Foo parseFrom(...): Parses a message of type Foo from the given +source and returns it. There is one parseFrom method corresponding to each +variant of mergeFrom() in the Message.Builder interface. Note that +parseFrom() never throws UninitializedMessageException; it throws +InvalidProtocolBufferException if the parsed message is missing required +fields. This makes it subtly different from calling +Foo.newBuilder().mergeFrom(...).build().
  • static Parser parser(): Returns an instance of the Parser, which +implements various parseFrom() methods.
  • Foo.Builder newBuilder(): Creates a new builder (described below).
  • Foo.Builder newBuilder(Foo prototype): Creates a new builder with all +fields initialized to the same values that they have in prototype. Since +embedded message and string objects are immutable, they are shared between +the original and the copy.

Builders

Message objects—such as instances of the Foo class described +above—are immutable, just like a Java String. To construct a message +object, you need to use a builder. Each message class has its own builder +class—so in our Foo example, the protocol buffer compiler generates a +nested class Foo.Builder which can be used to build a Foo. Foo.Builder +implements the Message.Builder interface. It extends the +GeneratedMessage.Builder class, but, again, this should be considered an +implementation detail. Like Foo, Foo.Builder may rely on generic method +implementations in GeneratedMessage.Builder or, when the optimize_for option +is used, generated custom code that is much faster. You can get a Foo.Builder +by calling the static method Foo.newBuilder().

Foo.Builder does not define any static methods. Its interface is exactly as +defined by the Message.Builder interface, with the exception that return types +are more specific: methods of Foo.Builder that modify the builder return type +Foo.Builder, and build() returns type Foo.

Methods that modify the contents of a builder—including field +setters—always return a reference to the builder (i.e. they “return this;”). This allows multiple method calls to be chained together in one line. +For example: builder.mergeFrom(obj).setFoo(1).setBar("abc").clearBaz();

Note that builders are not thread-safe, so Java synchronization should be used +whenever it is necessary for multiple different threads to be modifying the +contents of a single builder.

Sub-Builders

For messages containing sub-messages, the compiler also generates sub-builders. +This allows you to repeatedly modify deep-nested sub-messages without rebuilding +them. For example:

message Foo {
+  int32 val = 1;
+  // some other fields.
+}
+
+message Bar {
+  Foo foo = 1;
+  // some other fields.
+}
+
+message Baz {
+  Bar bar = 1;
+  // some other fields.
+}
+

If you have a Baz message already, and want to change the deeply nested val +in Foo. Instead of:

baz = baz.toBuilder().setBar(
+    baz.getBar().toBuilder().setFoo(
+        baz.getBar().getFoo().toBuilder().setVal(10).build()
+    ).build()).build();
+

You can write:

Baz.Builder builder = baz.toBuilder();
+builder.getBarBuilder().getFooBuilder().setVal(10);
+baz = builder.build();
+

Nested Types

A message can be declared inside another message. For example:

message Foo {
+  message Bar { }
+}
+

In this case, the compiler simply generates Bar as an inner class nested +inside Foo.

Fields

In addition to the methods described in the previous section, the protocol +buffer compiler generates a set of accessor methods for each field defined +within the message in the .proto file. The methods that read the field value +are defined both in the message class and its corresponding builder; the methods +that modify the value are defined in the builder only.

Note that method names always use camel-case naming, even if the field name in +the .proto file uses lower-case with underscores +(as it should). The +case-conversion works as follows:

  • For each underscore in the name, the underscore is removed, and the +following letter is capitalized.
  • If the name will have a prefix attached (e.g. “get”), the first letter is +capitalized. Otherwise, it is lower-cased.
  • The letter following the last digit in each number in a method name is +capitalized.

Thus, the field foo_bar_baz becomes fooBarBaz. If prefixed with get, it +would be getFooBarBaz. And foo_ba23r_baz becomes fooBa23RBaz.

As well as accessor methods, the compiler generates an integer constant for each +field containing its field number. The constant name is the field name converted +to upper-case followed by _FIELD_NUMBER. For example, given the field int32 foo_bar = 5;, the compiler will generate the constant public static final int FOO_BAR_FIELD_NUMBER = 5;.

The following sections are divided between explicit and implicit presence. +Proto2 has explicit presence and proto3 defaults to implicit presence. Editions +defaults to explicit presence, but you can override that using +features.field_presence.

Singular Fields with Explicit Presence

For any of these field definitions:

optional int32 foo = 1;
+required int32 foo = 1;
+

The compiler will generate the following accessor methods in both the message +class and its builder:

  • boolean hasFoo(): Returns true if the field is set.
  • int getFoo(): Returns the current value of the field. If the field is not +set, returns the default value.

The compiler will generate the following methods only in the message’s builder:

  • Builder setFoo(int value): Sets the value of the field. After calling +this, hasFoo() will return true and getFoo() will return value.
  • Builder clearFoo(): Clears the value of the field. After calling this, +hasFoo() will return false and getFoo() will return the default value.

For other simple field types, the corresponding Java type is chosen according to +the +scalar value types table. +For message and enum types, the value type is replaced with the message or enum +class.

Embedded Message Fields

For message types, setFoo() also accepts an instance of the message’s builder +type as the parameter. This is just a shortcut which is equivalent to calling +.build() on the builder and passing the result to the method. Further +modifying the sub-builder passed to setFoo will not be reflected in the +message class’s builder. The message class’s builder “takes ownership” of the +sub-message.

If the field is not set, getFoo() will return a Foo instance with none of its +fields set (possibly the instance returned by Foo.getDefaultInstance()).

In addition, the compiler generates two accessor methods that allow you to +access the relevant sub-builders for message types. The following method is +generated in both the message class and its builder:

  • FooOrBuilder getFooOrBuilder(): Returns the builder for the field, if it +already exists, or the message if not. Calling this method on builders will +not create a sub-builder for the field.

The compiler generates the following method only in the message’s builder.

  • Builder getFooBuilder(): Returns the builder for the field.

Singular Fields with Implicit Presence

For this field definition:

int32 foo = 1;
+

The compiler will generate the following accessor method in both the message +class and its builder:

  • int getFoo(): Returns the current value of the field. If the field is not +set, returns the default value for the field’s type.

The compiler will generate the following methods only in the message’s builder:

  • Builder setFoo(int value): Sets the value of the field. After calling +this, getFoo() will return value.
  • Builder clearFoo(): Clears the value of the field. After calling this, +getFoo() will return the default value for the field’s type.

For other simple field types, the corresponding Java type is chosen according to +the +scalar value types table. +For message and enum types, the value type is replaced with the message or enum +class.

Enum Fields

For enum field types, an additional accessor method is generated in both the +message class and its builder:

  • int getFooValue(): Returns the integer value of the enum.

The compiler will generate the following additional method only in the message’s +builder:

  • Builder setFooValue(int value): Sets the integer value of the enum.

In addition, getFoo() will return UNRECOGNIZED if the enum value is +unknown—this is a special additional value added by the proto3 compiler to +the generated enum type.

Repeated Fields

For this field definition:

repeated string foos = 1;
+

The compiler will generate the following accessor methods in both the message +class and its builder:

  • int getFoosCount(): Returns the number of elements currently in the field.
  • String getFoos(int index): Returns the element at the given zero-based +index.
  • ProtocolStringList getFoosList(): Returns the entire field as a +ProtocolStringList. If the field is not set, returns an empty list.

The compiler will generate the following methods only in the message’s builder:

  • Builder setFoos(int index, String value): Sets the value of the element at +the given zero-based index.
  • Builder addFoos(String value): Appends a new element to the field with the +given value.
  • Builder addAllFoos(Iterable<? extends String> value): Appends all elements +in the given Iterable to the field.
  • Builder clearFoos(): Removes all elements from the field. After calling +this, getFoosCount() will return zero.

For other simple field types, the corresponding Java type is chosen according to +the +scalar value types table. +For message and enum types, the type is the message or enum class.

Repeated Embedded Message Fields

For message types, setFoos() and addFoos() also accept an instance of the +message’s builder type as the parameter. This is just a shortcut which is +equivalent to calling .build() on the builder and passing the result to the +method. There is also an additional generated method:

  • Builder addFoos(int index, Field value): Inserts a new element at the +given zero-based index. Shifts the element currently at that position (if +any) and any subsequent elements to the right (adds one to their indices).

In addition, the compiler generates the following additional accessor methods in +both the message class and its builder for message types, allowing you to access +the relevant sub-builders:

  • FooOrBuilder getFoosOrBuilder(int index): Returns the builder for the +specified element, if it already exists, or throws +IndexOutOfBoundsException if not. If this is called from a message class, +it will always return a message (or throw an exception) rather than a +builder. Calling this method on builders will not create a sub-builder for +the field.
  • List<FooOrBuilder> getFoosOrBuilderList(): Returns the entire field as an +unmodifiable list of builders (if available) or messages if not. If this is +called from a message class, it will always return an immutable list of +messages rather than an unmodifiable list of builders.

The compiler will generate the following methods only in the message’s builder:

  • Builder getFoosBuilder(int index): Returns the builder for the element at +the specified index, or throws IndexOutOfBoundsException if the index is +out of bounds.
  • Builder addFoosBuilder(int index): Inserts and returns a builder for a +default message instance of the repeated message at the specified index. The +existing entries are shifted to higher indices to make room for the inserted +builder.
  • Builder addFoosBuilder(): Appends and returns a builder for a default +message instance of the repeated message.
  • Builder removeFoos(int index): Removes the element at the given zero-based +index.
  • List<Builder> getFoosBuilderList(): Returns the entire field as an +unmodifiable list of builders.

Repeated Enum Fields (proto3 only)

The compiler will generate the following additional methods in both the message +class and its builder:

  • int getFoosValue(int index): Returns the integer value of the enum at the +specified index.
  • List<java.lang.Integer> getFoosValueList(): Returns the entire field as a +list of Integers.

The compiler will generate the following additional method only in the message’s +builder:

  • Builder setFoosValue(int index, int value): Sets the integer value of the +enum at the specified index.

Name Conflicts

If another non-repeated field has a name that conflicts with one of the repeated +field’s generated methods, then both field names will have their protobuf field +number appended to the end.

For these field definitions:

int32 foos_count = 1;
+repeated string foos = 2;
+

The compiler will first rename them to the following:

int32 foos_count_1 = 1;
+repeated string foos_2 = 2;
+

The accessor methods will subsequently be generated as described above.

Oneof Fields

For this oneof field definition:

oneof choice {
+    int32 foo_int = 4;
+    string foo_string = 9;
+    ...
+}
+

All the fields in the choice oneof will use a single private field for their +value. In addition, the protocol buffer compiler will generate a Java enum type +for the oneof case, as follows:

public enum ChoiceCase
+        implements com.google.protobuf.Internal.EnumLite {
+      FOO_INT(4),
+      FOO_STRING(9),
+      ...
+      CHOICE_NOT_SET(0);
+      ...
+    };
+

The values of this enum type have the following special methods:

  • int getNumber(): Returns the object’s numeric value as defined in the +.proto file.
  • static ChoiceCase forNumber(int value): Returns the enum object +corresponding to the given numeric value (or null for other numeric +values).

The compiler will generate the following accessor methods in both the message +class and its builder:

  • boolean hasFooInt(): Returns true if the oneof case is FOO_INT.
  • int getFooInt(): Returns the current value of foo if the oneof case is +FOO_INT. Otherwise, returns the default value of this field.
  • ChoiceCase getChoiceCase(): Returns the enum indicating which field is +set. Returns CHOICE_NOT_SET if none of them is set.

The compiler will generate the following methods only in the message’s builder:

  • Builder setFooInt(int value): Sets Foo to this value and sets the oneof +case to FOO_INT. After calling this, hasFooInt() will return true, +getFooInt() will return value and getChoiceCase() will return +FOO_INT.
  • Builder clearFooInt():
    • Nothing will be changed if the oneof case is not FOO_INT.
    • If the oneof case is FOO_INT, sets Foo to null and the oneof case to +CHOICE_NOT_SET. After calling this, hasFooInt() will return false, +getFooInt() will return the default value and getChoiceCase() will +return CHOICE_NOT_SET.
  • Builder.clearChoice(): Resets the value for choice, returning the +builder.

For other simple field types, the corresponding Java type is chosen according to +the +scalar value types table. +For message and enum types, the value type is replaced with the message or enum +class.

Map Fields

For this map field definition:

map<int32, int32> weight = 1;
+

The compiler will generate the following accessor methods in both the message +class and its builder:

  • Map<Integer, Integer> getWeightMap();: Returns an unmodifiable Map.
  • int getWeightOrDefault(int key, int default);: Returns the value for key +or the default value if not present.
  • int getWeightOrThrow(int key);: Returns the value for key or throws +IllegalArgumentException if not present.
  • boolean containsWeight(int key);: Indicates if the key is present in this +field.
  • int getWeightCount();: Returns the number of elements in the map.

The compiler will generate the following methods only in the message’s builder:

  • Builder putWeight(int key, int value);: Add the weight to this field.
  • Builder putAllWeight(Map<Integer, Integer> value);: Adds all entries in +the given map to this field.
  • Builder removeWeight(int key);: Removes the weight from this field.
  • Builder clearWeight();: Removes all weights from this field.
  • @Deprecated Map<Integer, Integer> getMutableWeight();: Returns a mutable +Map. Note that multiple calls to this method may return different map +instances. The returned map reference may be invalidated by any subsequent +method calls to the Builder.

Message Value Map Fields

For maps with message types as values, the compiler will generate an additional +method in the message’s builder:

  • Foo.Builder putFooBuilderIfAbsent(int key);: Ensures that key is present +in the mapping, and inserts a new Foo.Builder if one does not already +exist. Changes to the returned Foo.Builder will be reflected in the final +message.

Any

Given an Any field +like this:

import "google/protobuf/any.proto";
+
+message ErrorStatus {
+  string message = 1;
+  google.protobuf.Any details = 2;
+}
+

In our generated code, the getter for the details field returns an instance of +com.google.protobuf.Any. This provides the following special methods to pack +and unpack the Any’s values:

class Any {
+  // Packs the given message into an Any using the default type URL
+  // prefix “type.googleapis.com”.
+  public static Any pack(Message message);
+  // Packs the given message into an Any using the given type URL
+  // prefix.
+  public static Any pack(Message message,
+                         String typeUrlPrefix);
+
+  // Checks whether this Any message’s payload is the given type.
+  public <T extends Message> boolean is(class<T> clazz);
+
+  // Checks whether this Any message’s payload has the same type as the given
+  // message.
+  public boolean isSameTypeAs(Message message);
+
+  // Unpacks Any into a message with the same type as the given messsage.
+  // Throws exception if the type doesn’t match or parsing the payload fails.
+  public <T extends Message> T unpackSameTypeAs(T message)
+      throws InvalidProtocolBufferException;
+
+  // Unpacks Any into the given message type. Throws exception if
+  // the type doesn’t match or parsing the payload has failed.
+  public <T extends Message> T unpack(class<T> clazz)
+      throws InvalidProtocolBufferException;
+}
+

Enumerations

Given an enum definition like:

enum Foo {
+  VALUE_A = 0;
+  VALUE_B = 5;
+  VALUE_C = 1234;
+}
+

The protocol buffer compiler will generate a Java enum type called Foo with +the same set of values. If you are using proto3, it also adds the special value +UNRECOGNIZED to the enum type. In Editions, OPEN enums also have a +UNRECOGNIZED value, while CLOSED enums do not. The values of the generated +enum type have the following special methods:

  • int getNumber(): Returns the object’s numeric value as defined in the +.proto file.
  • EnumValueDescriptor getValueDescriptor(): Returns the value’s descriptor, +which contains information about the value’s name, number, and type.
  • EnumDescriptor getDescriptorForType(): Returns the enum type’s descriptor, +which contains e.g. information about each defined value.

Additionally, the Foo enum type contains the following static methods:

  • static Foo forNumber(int value): Returns the enum object corresponding to +the given numeric value. Returns null when there is no corresponding enum +object.
  • static Foo valueOf(int value): Returns the enum object corresponding to +the given numeric value. This method is deprecated in favor of +forNumber(int value) and will be removed in an upcoming release.
  • static Foo valueOf(EnumValueDescriptor descriptor): Returns the enum +object corresponding to the given value descriptor. May be faster than +valueOf(int). In proto3 and OPEN enums, returns UNRECOGNIZED if passed +an unknown value descriptor.
  • EnumDescriptor getDescriptor(): Returns the enum type’s descriptor, which +contains e.g. information about each defined value. (This differs from +getDescriptorForType() only in that it is a static method.)

An integer constant is also generated with the suffix _VALUE for each enum +value.

Note that the .proto language allows multiple enum symbols to have the same +numeric value. Symbols with the same numeric value are synonyms. For example:

enum Foo {
+  BAR = 0;
+  BAZ = 0;
+}
+

In this case, BAZ is a synonym for BAR. In Java, BAZ will be defined as a +static final field like so:

static final Foo BAZ = BAR;
+

Thus, BAR and BAZ compare equal, and BAZ should never appear in switch +statements. The compiler always chooses the first symbol defined with a given +numeric value to be the “canonical” version of that symbol; all subsequent +symbols with the same number are just aliases.

An enum can be defined nested within a message type. The compiler generates the +Java enum definition nested within that message type’s class.

Caution: when generating Java code, the maximum number of values in a protobuf +enum may be surprisingly low—in the worst case, the maximum is slightly +over 1,700 values. This limit is due to per-method size limits for Java +bytecode, and it varies across Java implementations, different versions of the +protobuf suite, and any options set on the enum in the .proto file.

Extensions

Given a message with an extension range:

edition = "2023";
+
+message Foo {
+  extensions 100 to 199;
+}
+

The protocol buffer compiler will make Foo extend +GeneratedMessage.ExtendableMessage instead of the usual GeneratedMessage. +Similarly, Foo’s builder will extend GeneratedMessage.ExtendableBuilder. You +should never refer to these base types by name (GeneratedMessage is considered +an implementation detail). However, these superclasses define a number of +additional methods that you can use to manipulate extensions.

In particular Foo and Foo.Builder will inherit the methods hasExtension(), +getExtension(), and getExtensionCount(). Additionally, Foo.Builder will +inherit methods setExtension() and clearExtension(). Each of these methods +takes, as its first parameter, an extension identifier (described below), which +identifies an extension field. The remaining parameters and the return value are +exactly the same as those for the corresponding accessor methods that would be +generated for a normal (non-extension) field of the same type as the extension +identifier.

Given an extension definition:

edition = "2023";
+
+import "foo.proto";
+
+extend Foo {
+  int32 bar = 123;
+}
+

The protocol buffer compiler generates an “extension identifier” called bar, +which you can use with Foo’s extension accessors to access this extension, +like so:

Foo foo =
+  Foo.newBuilder()
+     .setExtension(bar, 1)
+     .build();
+assert foo.hasExtension(bar);
+assert foo.getExtension(bar) == 1;
+

(The exact implementation of extension identifiers is complicated and involves +magical use of generics—however, you don’t need to worry about how +extension identifiers work to use them.)

Note that bar would be declared as a static field of the wrapper class for the +.proto file, as described above; we have omitted the wrapper class name in the +example.

Extensions can be declared inside the scope of another type to prefix their +generated symbol names. For example, a common pattern is to extend a message by +a field inside the declaration of the field’s type:

edition = "2023";
+
+import "foo.proto";
+
+message Baz {
+  extend Foo {
+    Baz foo_ext = 124;
+  }
+}
+

In this case, an extension with identifier foo_ext and type Baz is declared +inside the declaration of Baz, and referring to foo_ext requires the +addition of a Baz. prefix:

Baz baz = createMyBaz();
+Foo foo =
+  Foo.newBuilder()
+     .setExtension(Baz.fooExt, baz)
+     .build();
+assert foo.hasExtension(Baz.fooExt);
+assert foo.getExtension(Baz.fooExt) == baz;
+

When parsing a message that might have extensions, you must provide an +ExtensionRegistry +in which you have registered any extensions that you want to be able to parse. +Otherwise, those extensions will be treated like unknown fields and the methods +observing extensions will behave as if they don’t exist.

ExtensionRegistry registry = ExtensionRegistry.newInstance();
+registry.add(Baz.fooExt);
+Foo foo = Foo.parseFrom(input, registry);
+assert foo.hasExtension(Baz.fooExt);
+
ExtensionRegistry registry = ExtensionRegistry.newInstance();
+Foo foo = Foo.parseFrom(input, registry);
+assert foo.hasExtension(Baz.fooExt) == false;
+

Services

If the .proto file contains the following line:

option java_generic_services = true;
+

Then the protocol buffer compiler will generate code based on the service +definitions found in the file as described in this section. However, the +generated code may be undesirable as it is not tied to any particular RPC +system, and thus requires more levels of indirection than code tailored to one +system. If you do NOT want this code to be generated, add this line to the file:

option java_generic_services = false;
+

If neither of the above lines are given, the option defaults to false, as +generic services are deprecated. (Note that prior to 2.4.0, the option defaults +to true)

RPC systems based on .proto-language service definitions should provide +plugins +to generate code appropriate for the system. These plugins are likely to require +that abstract services are disabled, so that they can generate their own classes +of the same names.

The remainder of this section describes what the protocol buffer compiler +generates when abstract services are enabled.

Interface

Given a service definition:

service Foo {
+  rpc Bar(FooRequest) returns(FooResponse);
+}
+

The protocol buffer compiler will generate an abstract class Foo to represent +this service. Foo will have an abstract method for each method defined in the +service definition. In this case, the method Bar is defined as:

abstract void bar(RpcController controller, FooRequest request,
+                  RpcCallback<FooResponse> done);
+

The parameters are equivalent to the parameters of Service.CallMethod(), +except that the method argument is implied and request and done specify +their exact type.

Foo subclasses the Service interface. The protocol buffer compiler +automatically generates implementations of the methods of Service as follows:

  • getDescriptorForType: Returns the service’s ServiceDescriptor.
  • callMethod: Determines which method is being called based on the provided +method descriptor and calls it directly, down-casting the request message +and callback to the correct types.
  • getRequestPrototype and getResponsePrototype: Returns the default +instance of the request or response of the correct type for the given +method.

The following static method is also generated:

  • static ServiceDescriptor getServiceDescriptor(): Returns the type’s +descriptor, which contains information about what methods this service has +and what their input and output types are.

Foo will also contain a nested interface Foo.Interface. This is a pure +interface that again contains methods corresponding to each method in your +service definition. However, this interface does not extend the Service +interface. This is a problem because RPC server implementations are usually +written to use abstract Service objects, not your particular service. To solve +this problem, if you have an object impl implementing Foo.Interface, you can +call Foo.newReflectiveService(impl) to construct an instance of Foo that +simply delegates to impl, and implements Service.

To recap, when implementing your own service, you have two options:

  • Subclass Foo and implement its methods as appropriate, then hand instances +of your subclass directly to the RPC server implementation. This is usually +easiest, but some consider it less “pure”.
  • Implement Foo.Interface and use Foo.newReflectiveService(Foo.Interface) +to construct a Service wrapping it, then pass the wrapper to your RPC +implementation.

Stub

The protocol buffer compiler also generates a “stub” implementation of every +service interface, which is used by clients wishing to send requests to servers +implementing the service. For the Foo service (above), the stub implementation +Foo.Stub will be defined as a nested class.

Foo.Stub is a subclass of Foo which also implements the following methods:

  • Foo.Stub(RpcChannel channel): Constructs a new stub which sends requests +on the given channel.
  • RpcChannel getChannel(): Returns this stub’s channel, as passed to the +constructor.

The stub additionally implements each of the service’s methods as a wrapper +around the channel. Calling one of the methods simply calls +channel.callMethod().

The Protocol Buffer library does not include an RPC implementation. However, it +includes all of the tools you need to hook up a generated service class to any +arbitrary RPC implementation of your choice. You need only provide +implementations of RpcChannel and RpcController.

Blocking Interfaces

The RPC classes described above all have non-blocking semantics: when you call a +method, you provide a callback object which will be invoked once the method +completes. Often it is easier (though possibly less scalable) to write code +using blocking semantics, where the method simply doesn’t return until it is +done. To accommodate this, the protocol buffer compiler also generates blocking +versions of your service class. Foo.BlockingInterface is equivalent to +Foo.Interface except that each method simply returns the result rather than +call a callback. So, for example, bar is defined as:

abstract FooResponse bar(RpcController controller, FooRequest request)
+                         throws ServiceException;
+

Analogous to non-blocking services, +Foo.newReflectiveBlockingService(Foo.BlockingInterface) returns a +BlockingService wrapping some Foo.BlockingInterface. Finally, +Foo.BlockingStub returns a stub implementation of Foo.BlockingInterface that +sends requests to a particular BlockingRpcChannel.

Plugin Insertion Points

Code generator plugins +that want to extend the output of the Java code generator may insert code of the +following types using the given insertion point names.

  • outer_class_scope: Member declarations that belong in the file’s wrapper +class.
  • class_scope:TYPENAME: Member declarations that belong in a message class. +TYPENAME is the full proto name, e.g. package.MessageType.
  • builder_scope:TYPENAME: Member declarations that belong in a message’s +builder class. TYPENAME is the full proto name, e.g. +package.MessageType.
  • enum_scope:TYPENAME: Member declarations that belong in an enum class. +TYPENAME is the full proto enum name, e.g. package.EnumType.
  • message_implements:TYPENAME: Class implementation declarations for a +message class. TYPENAME is the full proto name, e.g. +package.MessageType.
  • builder_implements:TYPENAME: Class implementation declarations for a +builder class. TYPENAME is the full proto name, e.g. +package.MessageType.

Generated code cannot contain import statements, as these are prone to conflict +with type names defined within the generated code itself. Instead, when +referring to an external class, you must always use its fully-qualified name.

The logic for determining output file names in the Java code generator is fairly +complicated. You should probably look at the protoc source code, particularly +java_headers.cc, to make sure you have covered all cases.

Do not generate code which relies on private class members declared by the +standard code generator, as these implementation details may change in future +versions of Protocol Buffers.

Utility Classes

Protocol buffer provides +utility classes +for message comparison, JSON conversion and working with +well-known types (predefined protocol buffer messages for common use-cases).

\ No newline at end of file diff --git a/reference/java/java-proto-names/index.html b/reference/java/java-proto-names/index.html new file mode 100644 index 000000000..c072882b6 --- /dev/null +++ b/reference/java/java-proto-names/index.html @@ -0,0 +1,38 @@ +Java Proto Names | Protocol Buffers Documentation +

Java Proto Names

Names that are generated by the Java protoc plugin.

This document contains information on what the fully-qualified Java name of a +proto is, based on the different proto options. This name corresponds to the +package you need to import to use that message.

Recommendation

Starting with Edition 2024, best practice is to:

  • Set option java_package = "com.example.package"
  • Do not set java_outer_classname or +features.(pb.java).nest_in_file_class = YES.

Starting with Edition 2024, the default behaviors have otherwise been improved +so that now the default behavior is considered current best practice.

When using Proto2, Proto3, or Edition 2023, best practice is to:

  • Set option java_multiple_files = true;
  • Set option java_outer_classname = "FileNameProto";
  • Set option java_package = "com.google.package";

Explanation

Multiple Files

With java_multiple_files = true, the generated Java class for each message +will be placed in a separate .java file. This makes it much easier to move +messages from one .proto file to another.

Starting in Edition 2024 this has been replaced by the feature +features.(pb.java).nest_in_file_class which has default value of NO, +matching the java_multiple_files = true behavior in older syntax.

Outer Classname

There is a Java class generated for the .proto file itself. The name of the +class for the file will be automatically generated if not specified. However, +the rules for how that name is generated are overly-complicated and non-obvious. +The best policy is to explicitly set the java_outer_classname option to the +.proto file name converted to PascalCase with the '.' removed. For example:

  • The file student_record_request.proto should set:

    option java_outer_classname = "StudentRecordRequestProto";
    +

Starting in Edition 2024, java_outer_classname is still available, but the +default behavior has been changed to match this recommendation and so does not +need to be set.

Java Package

The Java package for generated bindings will be automatically set to the proto +package. However, this is usually not conformant with Java conventions. To +ensure a conventional Java package name, we recommend explicitly setting the +java_package option. For example, within Google, the convention is to prepend +com.google. to the proto package.

Immutable API Message Names

The Java plugin for protoc will generate names according to this table.

java_multiple_filesjava_packagejava_outer_classnameGenerated full message name
trueNot definedignoredcom.google.protos.$package.$message
trueDefinedignored$java_package.$message
falseNot definedNot definedcom.google.protos.$package.$derived_outer_class.$message
falseNot definedDefinedcom.google.protos.$package.$java_outer_classname.$message
falseDefinedNot defined$java_package.$derived_outer_class.$message
falseDefinedDefined$java_package.$java_outer_classname.$message

Legend

  • $message is the actual name of the proto message.

  • $package is the name of the proto package. This is the name specified by +the package directive in the proto file, which is usually at the top of +the file.

  • $derived_outer_class is a name generated from the proto file name. +Generally it’s computed by removing punctuation from the file name and +converting it to PascalCase. For example, if the proto is foo_bar.proto, +the $derived_outer_class value is FooBar.

    If the generated class name would be the same as one of the messages defined +in the proto file, derived_outer_class has OuterClass appended to it. +For example, if the proto is foo_bar.proto and contains a FooBar +message, the $derived_outer_class value is FooBarOuterClass. The same is +true when using the v1 API, whether or not the class name would be the same +as one of the messages defined.

  • All other $names are the values of the corresponding file options defined +in the .proto file.

\ No newline at end of file diff --git a/content/reference/kotlin/api-docs/_kotlin_toc.yaml b/reference/kotlin/api-docs/_kotlin_toc.yaml similarity index 100% rename from content/reference/kotlin/api-docs/_kotlin_toc.yaml rename to reference/kotlin/api-docs/_kotlin_toc.yaml diff --git a/content/reference/kotlin/api-docs/includes/stylesheet.css b/reference/kotlin/api-docs/includes/stylesheet.css similarity index 100% rename from content/reference/kotlin/api-docs/includes/stylesheet.css rename to reference/kotlin/api-docs/includes/stylesheet.css diff --git a/reference/kotlin/api-docs/index.html b/reference/kotlin/api-docs/index.html new file mode 100644 index 000000000..ac5de71a4 --- /dev/null +++ b/reference/kotlin/api-docs/index.html @@ -0,0 +1,8 @@ +Kotlin Reference | Protocol Buffers Documentation +

Kotlin Reference

This section contains reference documentation for working with protocol buffers in Kotlin.

Packages

Name
com.google.protobuf.kotlin

\ No newline at end of file diff --git a/reference/kotlin/api-docs/index.xml b/reference/kotlin/api-docs/index.xml new file mode 100644 index 000000000..eb3128b33 --- /dev/null +++ b/reference/kotlin/api-docs/index.xml @@ -0,0 +1 @@ +Kotlin Reference on Protocol Buffers Documentationhttps://protobuf.dev/reference/kotlin/api-docs/Recent content in Kotlin Reference on Protocol Buffers DocumentationHugoen \ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/-dsl-list/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/-dsl-list/index.html new file mode 100644 index 000000000..4cc20a72b --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/-dsl-list/index.html @@ -0,0 +1,9 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/DslList/DslList

DslList

[JVM]
Content
fun <E> DslList(delegate: +List<E>)

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/equals/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/equals/index.html new file mode 100644 index 000000000..503bd7160 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/equals/index.html @@ -0,0 +1,10 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/DslList/equals

equals

[JVM]
Content
open operator override fun equals(other: +Any?): +Boolean

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/hash-code/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/hash-code/index.html new file mode 100644 index 000000000..6788e5c0b --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/hash-code/index.html @@ -0,0 +1,9 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/DslList/hashCode

hashCode

[JVM]
Content
open override fun hashCode(): +Int

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/index.html new file mode 100644 index 000000000..d0d071edd --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/index.html @@ -0,0 +1,15 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/DslList

DslList

[JVM] class DslList<E, P : +DslProxy>constructor(delegate: +List<E>) : +List<E>

A simple wrapper around a +List +with an extra generic parameter that can be used to disambiguate extension +methods.

This class is used by Kotlin protocol buffer extensions, and its constructor +is public only because generated message code is in a different compilation +unit. Others should not use this class directly in any way.

Constructors

NameSummary
DslList[JVM] fun <E> DslList(delegate: List<E>)

Functions

NameSummary
contains[JVM]
Content
open operator override fun contains(element: E): Boolean


containsAll[JVM]
Content
open override fun containsAll(elements: Collection<E>): Boolean


equals[JVM]
Content
open operator override fun equals(other: Any?): Boolean


forEach[JVM]
Content
open fun forEach(p0: Consumer<in E>)


get[JVM]
Content
open operator override fun get(index: Int): E


hashCode[JVM]
Content
open override fun hashCode(): Int


indexOf[JVM]
Content
open override fun indexOf(element: E): Int


isEmpty[JVM]
Content
open override fun isEmpty(): Boolean


iterator[JVM]
Content
open operator override fun iterator(): Iterator<E>


lastIndexOf[JVM]
Content
open override fun lastIndexOf(element: E): Int


listIterator[JVM]
Content
open override fun listIterator(): ListIterator<E>
open override fun listIterator(index: Int): ListIterator<E>


parallelStream[JVM]
Content
open fun parallelStream(): Stream<E>


spliterator[JVM]
Content
open override fun spliterator(): Spliterator<E>


stream[JVM]
Content
open fun stream(): Stream<E>


subList[JVM]
Content
open override fun subList(fromIndex: Int, toIndex: Int): List<E>


toArray[JVM]
Content
open fun <T : Any> toArray(p0: IntFunction<Array<T»)~~~~: Array<T>


toString[JVM]
Content
open override fun toString(): String


Properties

NameSummary
size[JVM] open override val size: Int
\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/index.xml b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/index.xml new file mode 100644 index 000000000..910e5d58a --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/index.xml @@ -0,0 +1,7 @@ +Protocol Buffers Documentationhttps://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/Recent content on Protocol Buffers DocumentationHugoen<link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/-dsl-list/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/-dsl-list/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslList/DslList +DslList [JVM] Content fun &lt;E&gt; DslList(delegate: List&lt;E&gt;)</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/equals/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/equals/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslList/equals +equals [JVM] Content open operator override fun equals(other: Any?): Boolean</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/hash-code/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/hash-code/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslList/hashCode +hashCode [JVM] Content open override fun hashCode(): Int</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/iterator/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/iterator/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslList/iterator +iterator [JVM] Content open operator override fun iterator(): Iterator&lt;E&gt;</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/list-iterator/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/list-iterator/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslList/listIterator +listIterator [JVM] Content open override fun listIterator(): ListIterator&lt;E&gt; open override fun listIterator(index: Int): ListIterator&lt;E&gt;</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/to-string/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/to-string/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslList/toString +toString [JVM] Content open override fun toString(): String</description></item></channel></rss> \ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/iterator/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/iterator/index.html new file mode 100644 index 000000000..f55b2362a --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/iterator/index.html @@ -0,0 +1,9 @@ +<!doctype html><html itemscope itemtype=http://schema.org/WebPage lang=en class=no-js><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name=robots content="index, follow"><link rel="shortcut icon" href=/favicons/favicon.ico><link rel=apple-touch-icon href=/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=icon type=image/png href=/favicons/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=/favicons/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=/favicons/android-36x36.png sizes=36x36><link rel=icon type=image/png href=/favicons/android-48x48.png sizes=48x48><link rel=icon type=image/png href=/favicons/android-72x72.png sizes=72x72><link rel=icon type=image/png href=/favicons/android-96x96.png sizes=96x96><link rel=icon type=image/png href=/favicons/android-144x144.png sizes=144x144><link rel=icon type=image/png href=/favicons/android-192x192.png sizes=192x192><title>Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/DslList/iterator

iterator

[JVM]
Content
open operator override fun iterator(): +Iterator<E>

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/list-iterator/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/list-iterator/index.html new file mode 100644 index 000000000..8995c8d7a --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/list-iterator/index.html @@ -0,0 +1,11 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/DslList/listIterator

listIterator

[JVM]
Content
open override fun listIterator(): +ListIterator<E>
open override fun listIterator(index: +Int): +ListIterator<E>

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/to-string/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/to-string/index.html new file mode 100644 index 000000000..9ddd8a343 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/to-string/index.html @@ -0,0 +1,9 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/DslList/toString

toString

[JVM]
Content
open override fun toString(): +String

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/-dsl-map/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/-dsl-map/index.html new file mode 100644 index 000000000..c196ae2ff --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/-dsl-map/index.html @@ -0,0 +1,10 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/DslMap

DslMap

[JVM]
Content
fun <K, V> DslMap(delegate: +Map<K, +V>)

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/entries/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/entries/index.html new file mode 100644 index 000000000..086f69352 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/entries/index.html @@ -0,0 +1,10 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/entries

entries

[JVM]
Content
open override val entries: +Set<Map.Entry<K, +V»

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/equals/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/equals/index.html new file mode 100644 index 000000000..21ebb8e7b --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/equals/index.html @@ -0,0 +1,10 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/equals

equals

[JVM]
Content
open operator override fun equals(other: +Any?): +Boolean

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/hash-code/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/hash-code/index.html new file mode 100644 index 000000000..588cb5d01 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/hash-code/index.html @@ -0,0 +1,9 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/hashCode

hashCode

[JVM]
Content
open override fun hashCode(): +Int

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/index.html new file mode 100644 index 000000000..ab2bd6be3 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/index.html @@ -0,0 +1,17 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/DslMap

DslMap

[JVM] class DslMap<K, V, P : +DslProxy>constructor(delegate: +Map<K, +V>) : +Map<K, +V>

A simple wrapper around a +Map +with an extra generic parameter that can be used to disambiguate extension +methods.

This class is used by Kotlin protocol buffer extensions, and its constructor +is public only because generated message code is in a different compilation +unit. Others should not use this class directly in any way.

Constructors

NameSummary
[DslMap])[JVM] fun <K, V> DslMap(delegate: Map<K, V>)

Functions

NameSummary
containsKey[JVM]
Content
open override fun containsKey(key: K): Boolean


containsValue[JVM]
Content
open override fun containsValue(value: V): Boolean


equals[JVM]
Content
open operator override fun equals(other: Any?): Boolean


forEach[JVM]
Content
open fun forEach(p0: BiConsumer<in K, in V>)


get[JVM]
Content
open operator override fun get(key: K): V?


getOrDefault[JVM]
Content
open fun getOrDefault(key: K, defaultValue: V): V


hashCode[JVM]
Content
open override fun hashCode(): Int


isEmpty[JVM]
Content
open override fun isEmpty(): Boolean


toString[JVM]
Content
open override fun toString(): String


Properties

NameSummary
entries[JVM] open override val entries: Set<Map.Entry<K, V»
keys[JVM] open override val keys: Set<K>
size[JVM] open override val size: Int
values[JVM] open override val values: Collection<V>
\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/index.xml b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/index.xml new file mode 100644 index 000000000..bc05943f0 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/index.xml @@ -0,0 +1,8 @@ +Protocol Buffers Documentationhttps://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/Recent content on Protocol Buffers DocumentationHugoen<link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/-dsl-map/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/-dsl-map/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/DslMap +DslMap [JVM] Content fun &lt;K, V&gt; DslMap(delegate: Map&lt;K, V&gt;)</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/entries/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/entries/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/entries +entries [JVM] Content open override val entries: Set&lt;Map.Entry&lt;K, V&raquo;</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/equals/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/equals/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/equals +equals [JVM] Content open operator override fun equals(other: Any?): Boolean</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/hash-code/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/hash-code/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/hashCode +hashCode [JVM] Content open override fun hashCode(): Int</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/keys/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/keys/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/keys +keys [JVM] Content open override val keys: Set&lt;K&gt;</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/to-string/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/to-string/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/toString +toString [JVM] Content open override fun toString(): String</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/values/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/values/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/values +values [JVM] Content open override val values: Collection&lt;V&gt;</description></item></channel></rss> \ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/keys/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/keys/index.html new file mode 100644 index 000000000..b7ada9537 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/keys/index.html @@ -0,0 +1,9 @@ +<!doctype html><html itemscope itemtype=http://schema.org/WebPage lang=en class=no-js><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name=robots content="index, follow"><link rel="shortcut icon" href=/favicons/favicon.ico><link rel=apple-touch-icon href=/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=icon type=image/png href=/favicons/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=/favicons/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=/favicons/android-36x36.png sizes=36x36><link rel=icon type=image/png href=/favicons/android-48x48.png sizes=48x48><link rel=icon type=image/png href=/favicons/android-72x72.png sizes=72x72><link rel=icon type=image/png href=/favicons/android-96x96.png sizes=96x96><link rel=icon type=image/png href=/favicons/android-144x144.png sizes=144x144><link rel=icon type=image/png href=/favicons/android-192x192.png sizes=192x192><title>Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/keys

keys

[JVM]
Content
open override val keys: +Set<K>

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/to-string/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/to-string/index.html new file mode 100644 index 000000000..a0c3d7eb4 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/to-string/index.html @@ -0,0 +1,9 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/toString

toString

[JVM]
Content
open override fun toString(): +String

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/values/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/values/index.html new file mode 100644 index 000000000..154095613 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/values/index.html @@ -0,0 +1,9 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/DslMap/values

values

[JVM]
Content
open override val values: +Collection<V>

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-proxy/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-proxy/index.html new file mode 100644 index 000000000..ad9171f23 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-proxy/index.html @@ -0,0 +1,8 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/DslProxy

DslProxy

[JVM] abstract class DslProxy

A type meaningful only for its existence, never intended to be instantiated. For +example, a DslList<Int, FooProxy> can be given different extension methods than +a DslList<Int, BarProxy>.

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-proxy/index.xml b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-proxy/index.xml new file mode 100644 index 000000000..a77094e13 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-proxy/index.xml @@ -0,0 +1 @@ +Protocol Buffers Documentationhttps://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-proxy/Recent content on Protocol Buffers DocumentationHugoen \ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/-extension-list/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/-extension-list/index.html new file mode 100644 index 000000000..fd29f20ea --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/-extension-list/index.html @@ -0,0 +1,14 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/ExtensionList

ExtensionList

[JVM]
Content
fun <E, M : +MessageLite> +ExtensionList(extension: +ExtensionLite<M, +List<E», +delegate: +List<E>)

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/equals/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/equals/index.html new file mode 100644 index 000000000..049a1538d --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/equals/index.html @@ -0,0 +1,10 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/equals

equals

[JVM]
Content
open operator override fun equals(other: +Any?): +Boolean

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/extension/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/extension/index.html new file mode 100644 index 000000000..ad4524a42 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/extension/index.html @@ -0,0 +1,10 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/extension

extension

[JVM]
Content
val extension: +ExtensionLite<M, +List<E»

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/hash-code/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/hash-code/index.html new file mode 100644 index 000000000..0e4bdb730 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/hash-code/index.html @@ -0,0 +1,9 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/hashCode

hashCode

[JVM]
Content
open override fun hashCode(): +Int

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/index.html new file mode 100644 index 000000000..2b73868ce --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/index.html @@ -0,0 +1,16 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList

ExtensionList

[JVM] class ExtensionList<E, M : +MessageLite>constructor(extension: +ExtensionLite<M, +List<E», +delegate: +List<E>) : +List<E>

Implementation for ExtensionList and ExtensionListLite. Like +DslList, represents an unmodifiable view of a repeated proto +field – in this case, an extension field – but supports querying the +extension.

Constructors

NameSummary
ExtensionList[JVM] fun <E, M : MessageLite> ExtensionList(extension: ExtensionLite<M, List<E>>, delegate: List<E>)

Functions

NameSummary
contains[JVM]
Content
open operator override fun contains(element: E): Boolean


containsAll[JVM]
Content
open override fun containsAll(elements: Collection<E>): Boolean


equals[JVM]
Content
open operator override fun equals(other: Any?): Boolean


forEach[JVM]
Content
open fun forEach(p0: Consumer<in E>)


get[JVM]
Content
open operator override fun get(index: Int): E


hashCode[JVM]
Content
open override fun hashCode(): Int


indexOf[JVM]
Content
open override fun indexOf(element: E): Int


isEmpty[JVM]
Content
open override fun isEmpty(): Boolean


iterator[JVM]
Content
open operator override fun iterator(): Iterator<E>


lastIndexOf[JVM]
Content
open override fun lastIndexOf(element: E): Int


listIterator[JVM]
Content
open override fun listIterator(): ListIterator<E>
open override fun listIterator(index: Int): ListIterator<E>


parallelStream[JVM]
Content
open fun parallelStream(): Stream<E>


spliterator[JVM]
Content
open override fun spliterator(): Spliterator<E>


stream[JVM]
Content
open fun stream(): Stream<E>


subList[JVM]
Content
open override fun subList(fromIndex: Int, toIndex: Int): List<E>


toArray[JVM]
Content
open fun <T : Any> toArray(p0: IntFunction<Array<T»)~~~~: Array<T>


toString[JVM]
Content
open override fun toString(): String


Properties

NameSummary
extension[JVM] val extension: ExtensionLite<M, List<E»
size[JVM] open override val size: Int
\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/index.xml b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/index.xml new file mode 100644 index 000000000..bc3809903 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/index.xml @@ -0,0 +1,8 @@ +Protocol Buffers Documentationhttps://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/Recent content on Protocol Buffers DocumentationHugoen<link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/-extension-list/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/-extension-list/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/ExtensionList +ExtensionList [JVM] Content fun &lt;E, M : MessageLite&gt; ExtensionList(extension: ExtensionLite&lt;M, List&lt;E&raquo;, delegate: List&lt;E&gt;)</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/equals/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/equals/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/equals +equals [JVM] Content open operator override fun equals(other: Any?): Boolean</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/extension/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/extension/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/extension +extension [JVM] Content val extension: ExtensionLite&lt;M, List&lt;E&raquo;</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/hash-code/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/hash-code/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/hashCode +hashCode [JVM] Content open override fun hashCode(): Int</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/iterator/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/iterator/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/iterator +iterator [JVM] Content open operator override fun iterator(): Iterator&lt;E&gt;</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/list-iterator/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/list-iterator/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/listIterator +listIterator [JVM] Content open override fun listIterator(): ListIterator&lt;E&gt; open override fun listIterator(index: Int): ListIterator&lt;E&gt;</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/to-string/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/to-string/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/toString +toString [JVM] Content open override fun toString(): String</description></item></channel></rss> \ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/iterator/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/iterator/index.html new file mode 100644 index 000000000..b47fa6e3c --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/iterator/index.html @@ -0,0 +1,9 @@ +<!doctype html><html itemscope itemtype=http://schema.org/WebPage lang=en class=no-js><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name=robots content="index, follow"><link rel="shortcut icon" href=/favicons/favicon.ico><link rel=apple-touch-icon href=/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=icon type=image/png href=/favicons/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=/favicons/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=/favicons/android-36x36.png sizes=36x36><link rel=icon type=image/png href=/favicons/android-48x48.png sizes=48x48><link rel=icon type=image/png href=/favicons/android-72x72.png sizes=72x72><link rel=icon type=image/png href=/favicons/android-96x96.png sizes=96x96><link rel=icon type=image/png href=/favicons/android-144x144.png sizes=144x144><link rel=icon type=image/png href=/favicons/android-192x192.png sizes=192x192><title>Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/iterator

iterator

[JVM]
Content
open operator override fun iterator(): +Iterator<E>

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/list-iterator/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/list-iterator/index.html new file mode 100644 index 000000000..4ce8ccf8a --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/list-iterator/index.html @@ -0,0 +1,11 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/listIterator

listIterator

[JVM]
Content
open override fun listIterator(): +ListIterator<E>
open override fun listIterator(index: +Int): +ListIterator<E>

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/to-string/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/to-string/index.html new file mode 100644 index 000000000..e7c88bca3 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/to-string/index.html @@ -0,0 +1,9 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/ExtensionList/toString

toString

[JVM]
Content
open override fun toString(): +String

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/-only-for-use-by-generated-proto-code/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/-only-for-use-by-generated-proto-code/index.html new file mode 100644 index 000000000..c1e4e8ab0 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/-only-for-use-by-generated-proto-code/index.html @@ -0,0 +1,8 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/OnlyForUseByGeneratedProtoCode/OnlyForUseByGeneratedProtoCode

OnlyForUseByGeneratedProtoCode

[JVM]
Content
fun OnlyForUseByGeneratedProtoCode()

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/index.html new file mode 100644 index 000000000..b0b322c4f --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/index.html @@ -0,0 +1,14 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/OnlyForUseByGeneratedProtoCode

OnlyForUseByGeneratedProtoCode

[JVM] +@Target(allowedTargets = +[AnnotationTarget.CONSTRUCTOR, +AnnotationTarget.ANNOTATION_CLASS])

annotation class OnlyForUseByGeneratedProtoCode

Opt-in annotation to make it difficult to accidentally use APIs only intended +for use by proto generated code. See +https://kotlinlang.org/docs/reference/opt-in-requirements.html for details on +how this API works.

Constructors

NameSummary
OnlyForUseByGeneratedProtoCode[JVM] fun OnlyForUseByGeneratedProtoCode()
\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/index.xml b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/index.xml new file mode 100644 index 000000000..25564954b --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/index.xml @@ -0,0 +1,2 @@ +Protocol Buffers Documentationhttps://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/Recent content on Protocol Buffers DocumentationHugoen<link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/-only-for-use-by-generated-proto-code/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/-only-for-use-by-generated-proto-code/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/OnlyForUseByGeneratedProtoCode/OnlyForUseByGeneratedProtoCode +OnlyForUseByGeneratedProtoCode [JVM] Content fun OnlyForUseByGeneratedProtoCode()</description></item></channel></rss> \ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/-proto-dsl-marker/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/-proto-dsl-marker/index.html new file mode 100644 index 000000000..914b39acf --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/-proto-dsl-marker/index.html @@ -0,0 +1,8 @@ +<!doctype html><html itemscope itemtype=http://schema.org/WebPage lang=en class=no-js><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name=robots content="index, follow"><link rel="shortcut icon" href=/favicons/favicon.ico><link rel=apple-touch-icon href=/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=icon type=image/png href=/favicons/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=/favicons/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=/favicons/android-36x36.png sizes=36x36><link rel=icon type=image/png href=/favicons/android-48x48.png sizes=48x48><link rel=icon type=image/png href=/favicons/android-72x72.png sizes=72x72><link rel=icon type=image/png href=/favicons/android-96x96.png sizes=96x96><link rel=icon type=image/png href=/favicons/android-144x144.png sizes=144x144><link rel=icon type=image/png href=/favicons/android-192x192.png sizes=192x192><title>Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/ProtoDslMarker/ProtoDslMarker

ProtoDslMarker

[JVM]
Content
fun ProtoDslMarker()

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/index.html new file mode 100644 index 000000000..0be08c2e9 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/index.html @@ -0,0 +1,10 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/ProtoDslMarker

ProtoDslMarker

[JVM] +@DslMarker()
@Target(allowedTargets = +[AnnotationTarget.CLASS])

annotation class ProtoDslMarker

Indicates an API that is part of a DSL to generate protocol buffer messages.

Constructors

NameSummary
ProtoDslMarker[JVM] fun ProtoDslMarker()
\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/index.xml b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/index.xml new file mode 100644 index 000000000..eb1967e7b --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/index.xml @@ -0,0 +1,2 @@ +Protocol Buffers Documentationhttps://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/Recent content on Protocol Buffers DocumentationHugoen<link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/-proto-dsl-marker/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/-proto-dsl-marker/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/ProtoDslMarker/ProtoDslMarker +ProtoDslMarker [JVM] Content fun ProtoDslMarker()</description></item></channel></rss> \ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/contains/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/contains/index.html new file mode 100644 index 000000000..8da8fb680 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/contains/index.html @@ -0,0 +1,19 @@ +<!doctype html><html itemscope itemtype=http://schema.org/WebPage lang=en class=no-js><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name=robots content="index, follow"><link rel="shortcut icon" href=/favicons/favicon.ico><link rel=apple-touch-icon href=/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=icon type=image/png href=/favicons/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=/favicons/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=/favicons/android-36x36.png sizes=36x36><link rel=icon type=image/png href=/favicons/android-48x48.png sizes=48x48><link rel=icon type=image/png href=/favicons/android-72x72.png sizes=72x72><link rel=icon type=image/png href=/favicons/android-96x96.png sizes=96x96><link rel=icon type=image/png href=/favicons/android-144x144.png sizes=144x144><link rel=icon type=image/png href=/favicons/android-192x192.png sizes=192x192><title>Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/contains

contains

[JVM]
Content
operator fun <M : +GeneratedMessageV3.ExtendableMessage<M>, +MorBT : +GeneratedMessageV3.ExtendableMessageOrBuilder<M» +MorBT.contains(extension: +ExtensionLite<M, +*>): +Boolean

Returns true if the specified extension is set on this builder.

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/get/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/get/index.html new file mode 100644 index 000000000..fc698dff0 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/get/index.html @@ -0,0 +1,31 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/get

get

[JVM]
Content
operator fun +ByteString.get(index: +Int): +Byte

Gets the byte at index.

[JVM]
Content
operator fun <M : +GeneratedMessageV3.ExtendableMessage<M>, +MorBT : +GeneratedMessageV3.ExtendableMessageOrBuilder<M>, +T : +Any> +MorBT.get(extension: +ExtensionLite<M, +T>): T

Gets the current value of the proto extension.

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/index.html new file mode 100644 index 000000000..6b32f742a --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/index.html @@ -0,0 +1,5 @@ +Protocol Buffers Documentation +

Package com.google.protobuf.kotlin

//protobuf-kotlin/com.google.protobuf.kotlin

Types

NameSummary
DslList[JVM]
Content
class DslList<E, P : DslProxy>constructor(delegate: List<E>) : List<E>
A simple wrapper around a List with an extra generic parameter that can be used to disambiguate extension methods.


DslMap[JVM]
Content
class DslMap<K, V, P : DslProxy>constructor(delegate: Map<K, V>) : Map<K, V>
A simple wrapper around a Map with an extra generic parameter that can be used to disambiguate extension methods.


DslProxy[JVM]
Content
abstract class DslProxy
A type meaningful only for its existence, never intended to be instantiated.


ExtensionList[JVM]
Content
class ExtensionList<E, M : MessageLite>constructor(extension: ExtensionLite<M, List<E», delegate: List<E>) : List<E>
Implementation for ExtensionList and ExtensionListLite.


OnlyForUseByGeneratedProtoCode[JVM]
Content
@Target(allowedTargets = [AnnotationTarget.CONSTRUCTOR, AnnotationTarget.ANNOTATION_CLASS])

annotation class OnlyForUseByGeneratedProtoCode
Opt-in annotation to make it difficult to accidentally use APIs only intended for use by proto generated code.


ProtoDslMarker[JVM]
Content
@DslMarker()
@Target(allowedTargets = [AnnotationTarget.CLASS])

annotation class ProtoDslMarker
Indicates an API that is part of a DSL to generate protocol buffer messages.


Functions

NameSummary
contains[JVM]
Content
operator fun <M : GeneratedMessageV3.ExtendableMessage<M>, MorBT : GeneratedMessageV3.ExtendableMessageOrBuilder<M» MorBT.contains(extension: ExtensionLite<M, *>): Boolean
Returns true if the specified extension is set on this builder.


get[JVM]
Content
operator fun <M : GeneratedMessageV3.ExtendableMessage<M>, MorBT : GeneratedMessageV3.ExtendableMessageOrBuilder<M>, T : Any> MorBT.get(extension: ExtensionLite<M, T>): T
Gets the current value of the proto extension.


[JVM]
Content
operator fun ByteString.get(index: Int): Byte
Gets the byte at index.


isA[JVM]
Content
inline fun <T : Message> Any.isA(): Boolean
Returns true if this com.google.protobuf.Any contains a message of type T.


plus[JVM]
Content
operator fun ByteString.plus(other: ByteString): ByteString
Concatenates the given ByteString to this one.


set[JVM]
Content
operator fun <M : GeneratedMessageV3.ExtendableMessage<M>, B : GeneratedMessageV3.ExtendableBuilder<M, B>, T : Any> B.set(extension: ExtensionLite<M, T>, value: T)
Sets the current value of the proto extension in this builder.


toByteString[JVM]
Content
fun ByteBuffer.toByteString(): ByteString
Copies the remaining bytes from this ByteBuffer to a ByteString.


[JVM]
Content
fun ByteArray.toByteString(): ByteString
Returns a copy of this ByteArray as an immutable ByteString.


toByteStringUtf8[JVM]
Content
fun String.toByteStringUtf8(): ByteString
Encodes this String into a sequence of UTF-8 bytes and returns the result as a ByteString.


unpack[JVM]
Content
inline fun <T : Message> Any.unpack(): T
Returns the message of type T encoded in this com.google.protobuf.Any.


\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/index.xml b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/index.xml new file mode 100644 index 000000000..10b96a54e --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/index.xml @@ -0,0 +1,22 @@ +Protocol Buffers Documentationhttps://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/Recent content on Protocol Buffers DocumentationHugoen<link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/contains/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/contains/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/contains +contains [JVM] Content operator fun &lt;M : GeneratedMessageV3.ExtendableMessage&lt;M&gt;, MorBT : GeneratedMessageV3.ExtendableMessageOrBuilder&lt;M&raquo; MorBT.contains(extension: ExtensionLite&lt;M, *&gt;): Boolean +Returns true if the specified extension is set on this builder.</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/get/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/get/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/get +get [JVM] Content operator fun ByteString.get(index: Int): Byte +Gets the byte at index. +[JVM] Content operator fun &lt;M : GeneratedMessageV3.ExtendableMessage&lt;M&gt;, MorBT : GeneratedMessageV3.ExtendableMessageOrBuilder&lt;M&gt;, T : Any&gt; MorBT.get(extension: ExtensionLite&lt;M, T&gt;): T +Gets the current value of the proto extension.</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/is-a/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/is-a/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/isA +isA [JVM] Content inline fun &lt;T : Message&gt; Any.isA(): Boolean +Returns true if this com.google.protobuf.Any contains a message of type T.</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/plus/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/plus/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/plus +plus [JVM] Content operator fun ByteString.plus(other: ByteString): ByteString \ +Concatenates the given ByteString to this one.</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/set/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/set/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/set +set [JVM] Content operator fun &lt;M : GeneratedMessageV3.ExtendableMessage&lt;M&gt;, B : GeneratedMessageV3.ExtendableBuilder&lt;M, B&gt;, T : Any&gt; B.set(extension: ExtensionLite&lt;M, T&gt;, value: T) +Sets the current value of the proto extension in this builder.</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string-utf8/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string-utf8/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/toByteStringUtf8 +toByteStringUtf8 [JVM] Content fun String.toByteStringUtf8(): ByteString +Encodes this String into a sequence of UTF-8 bytes and returns the result as a ByteString.</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/toByteString +toByteString [JVM] Content fun ByteArray.toByteString(): ByteString +Returns a copy of this ByteArray as an immutable ByteString. +[JVM] Content fun ByteBuffer.toByteString(): ByteString +Copies the remaining bytes from this ByteBuffer to a ByteString.</description></item><item><title/><link>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/unpack/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/unpack/</guid><description>//protobuf-kotlin/com.google.protobuf.kotlin/unpack +unpack [JVM] Content inline fun &lt;T : Message&gt; Any.unpack(): T +Returns the message of type T encoded in this com.google.protobuf.Any. +Throws | | &mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;- | &mdash; InvalidProtocolBufferException | if this com.google.protobuf.Any does not contain a T message.</description></item></channel></rss> \ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/is-a/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/is-a/index.html new file mode 100644 index 000000000..f1dbceb4e --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/is-a/index.html @@ -0,0 +1,17 @@ +<!doctype html><html itemscope itemtype=http://schema.org/WebPage lang=en class=no-js><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name=robots content="index, follow"><link rel="shortcut icon" href=/favicons/favicon.ico><link rel=apple-touch-icon href=/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=icon type=image/png href=/favicons/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=/favicons/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=/favicons/android-36x36.png sizes=36x36><link rel=icon type=image/png href=/favicons/android-48x48.png sizes=48x48><link rel=icon type=image/png href=/favicons/android-72x72.png sizes=72x72><link rel=icon type=image/png href=/favicons/android-96x96.png sizes=96x96><link rel=icon type=image/png href=/favicons/android-144x144.png sizes=144x144><link rel=icon type=image/png href=/favicons/android-192x192.png sizes=192x192><title>Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/isA

isA

[JVM]
Content
inline fun <T : +Message> +Any.isA(): +Boolean

Returns true if this +com.google.protobuf.Any +contains a message of type T.

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/plus/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/plus/index.html new file mode 100644 index 000000000..4045de86d --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/plus/index.html @@ -0,0 +1,18 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/plus

plus

[JVM]
Content
operator fun +ByteString.plus(other: +ByteString): +ByteString +\

Concatenates the given +ByteString +to this one.

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/set/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/set/index.html new file mode 100644 index 000000000..09b97fe3b --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/set/index.html @@ -0,0 +1,20 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/set

set

[JVM]
Content
operator fun <M : +GeneratedMessageV3.ExtendableMessage<M>, +B : +GeneratedMessageV3.ExtendableBuilder<M, +B>, T : +Any> +B.set(extension: +ExtensionLite<M, +T>, value: T)

Sets the current value of the proto extension in this builder.

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string-utf8/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string-utf8/index.html new file mode 100644 index 000000000..186fd5d17 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string-utf8/index.html @@ -0,0 +1,15 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/toByteStringUtf8

toByteStringUtf8

[JVM]
Content
fun +String.toByteStringUtf8(): +ByteString

Encodes this String into a sequence of UTF-8 bytes and returns the result as a +ByteString.

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string/index.html new file mode 100644 index 000000000..71ac1851a --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string/index.html @@ -0,0 +1,30 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/toByteString

toByteString

[JVM]
Content
fun +ByteArray.toByteString(): +ByteString

Returns a copy of this +ByteArray +as an immutable +ByteString.

[JVM]
Content
fun +ByteBuffer.toByteString(): +ByteString

Copies the remaining bytes from this +ByteBuffer +to a +ByteString.

\ No newline at end of file diff --git a/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/unpack/index.html b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/unpack/index.html new file mode 100644 index 000000000..34ce4e892 --- /dev/null +++ b/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/unpack/index.html @@ -0,0 +1,22 @@ +Protocol Buffers Documentation +

//protobuf-kotlin/com.google.protobuf.kotlin/unpack

unpack

[JVM]
Content
inline fun <T : +Message> +Any.unpack(): +T

Returns the message of type T encoded in this +com.google.protobuf.Any.

Throws

                                                                                                                            |     |
+

——————————————————————————————————————————- | — +InvalidProtocolBufferException |

if this com.google.protobuf.Any does not contain a T message.

\ No newline at end of file diff --git a/content/reference/kotlin/api-docs/protobuf-kotlin/package-list b/reference/kotlin/api-docs/protobuf-kotlin/package-list similarity index 100% rename from content/reference/kotlin/api-docs/protobuf-kotlin/package-list rename to reference/kotlin/api-docs/protobuf-kotlin/package-list diff --git a/reference/kotlin/index.html b/reference/kotlin/index.html new file mode 100644 index 000000000..9325e24cd --- /dev/null +++ b/reference/kotlin/index.html @@ -0,0 +1,8 @@ +Kotlin Reference | Protocol Buffers Documentation +

Kotlin Reference

Reference documentation for working with protocol buffer classes in Kotlin.

Kotlin Reference

This section contains reference documentation for working with protocol buffers in Kotlin.

Kotlin Generated Code Guide

Describes exactly what Kotlin code the protocol buffer compiler generates for any given protocol definition, in addition to the code generated for Java.

\ No newline at end of file diff --git a/reference/kotlin/index.xml b/reference/kotlin/index.xml new file mode 100644 index 000000000..a4a0697ea --- /dev/null +++ b/reference/kotlin/index.xml @@ -0,0 +1,2 @@ +Kotlin Reference on Protocol Buffers Documentationhttps://protobuf.dev/reference/kotlin/Recent content in Kotlin Reference on Protocol Buffers DocumentationHugoenKotlin Generated Code Guidehttps://protobuf.dev/reference/kotlin/kotlin-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/kotlin/kotlin-generated/Any differences between proto2, proto3, and editions generated code are highlighted—note that these differences are in the generated code as described in this document, not the base message classes/interfaces, which are the same in both versions. You should read the proto2 language guide, proto3 language guide, and/or the Editions guide before reading this document. +Compiler Invocation The protocol buffer compiler produces Kotlin code that builds on top of Java code. As a result, it must be invoked with two command-line flags, --java_out= and --kotlin_out=. \ No newline at end of file diff --git a/reference/kotlin/kotlin-generated/index.html b/reference/kotlin/kotlin-generated/index.html new file mode 100644 index 000000000..5ed2976a9 --- /dev/null +++ b/reference/kotlin/kotlin-generated/index.html @@ -0,0 +1,145 @@ +Kotlin Generated Code Guide | Protocol Buffers Documentation +

Kotlin Generated Code Guide

Describes exactly what Kotlin code the protocol buffer compiler generates for any given protocol definition, in addition to the code generated for Java.

Any differences between proto2, proto3, and editions +generated code are highlighted—note that these differences are in the +generated code as described in this document, not the base message +classes/interfaces, which are the same in both versions. You should read the +proto2 language guide, +proto3 language guide, +and/or the Editions guide +before reading this document.

Compiler Invocation

The protocol buffer compiler produces Kotlin code that builds on top of Java +code. As a result, it must be invoked with two command-line flags, --java_out= +and --kotlin_out=. The parameter to the --java_out= option is the directory +where you want the compiler to write your Java output, and the same for the +--kotlin_out=. For each .proto file input, the compiler creates a wrapper +.java file containing a Java class which represents the .proto file itself.

Regardless of whether or not your .proto file contains a line like the +following:

option java_multiple_files = true;
+

The compiler will create separate .kt files for each of the classes and +factory methods which it will generate for each top-level message declared in +the .proto file.

The Java package name for each file is the same as that used by the generated +Java code as described in the +Java generated code reference.

The output file is chosen by concatenating the parameter to --kotlin_out=, the +package name (with periods [.] replaced with slashes [/]), and the suffix +Kt.kt file name.

So, for example, let’s say you invoke the compiler as follows:

protoc --proto_path=src --java_out=build/gen/java --kotlin_out=build/gen/kotlin src/foo.proto
+

If foo.proto’s Java package is com.example and it contains a message named +Bar, then the protocol buffer compiler will generate the file +build/gen/kotlin/com/example/BarKt.kt. The protocol buffer compiler will +automatically create the build/gen/kotlin/com and +build/gen/kotlin/com/example directories if needed. However, it will not +create build/gen/kotlin, build/gen, or build; they must already exist. You +can specify multiple .proto files in a single invocation; all output files +will be generated at once.

Messages

Given a simple message declaration:

message FooBar {}
+

The protocol buffer compiler generates—in addition to the generated Java +code—an object called FooBarKt, as well as two top-level functions, +having the following structure:

object FooBarKt {
+  class Dsl private constructor { ... }
+}
+inline fun fooBar(block: FooBarKt.Dsl.() -> Unit): FooBar
+inline fun FooBar.copy(block: FooBarKt.Dsl.() -> Unit): FooBar
+

Nested Types

A message can be declared inside another message. For example:

message Foo {
+  message Bar { }
+}
+

In this case, the compiler nests the BarKt object and the bar factory method +inside FooKt, though the copy method remains top-level:

object FooKt {
+  class Dsl { ... }
+  object BarKt {
+    class Dsl private constructor { ... }
+  }
+  inline fun bar(block: FooKt.BarKt.Dsl.() -> Unit): Foo.Bar
+}
+inline fun foo(block: FooKt.Dsl.() -> Unit): Foo
+inline fun Foo.copy(block: FooKt.Dsl.() -> Unit): Foo
+inline fun Foo.Bar.copy(block: FooKt.BarKt.Dsl.() -> Unit): Foo.Bar
+

Fields

In addition to the methods described in the previous section, the protocol +buffer compiler generates mutable properties in the DSL for each field defined +within the message in the .proto file. (Kotlin already infers read-only +properties on the message object from the getters generated by Java.)

Note that properties always use camel-case naming, even if the field name in the +.proto file uses lower-case with underscores +(as it should). The +case-conversion works as follows:

  1. For each underscore in the name, the underscore is removed, and the +following letter is capitalized.
  2. If the name will have a prefix attached (for example, “clear”), the first +letter is capitalized. Otherwise, it is lower-cased.

Thus, the field foo_bar_baz becomes fooBarBaz.

In a few special cases in which a field name conflicts with reserved words in +Kotlin or methods already defined in the protobuf library, an extra underscore +is appended. For instance, the clearer for a field named in is clearIn_().

Singular Fields

For this field definition:

int32 foo = 1;
+

The compiler will generate the following accessors in the DSL:

  • fun hasFoo(): Boolean: Returns true if the field is set. This is not +generated for fields using implicit presence.
  • var foo: Int: The current value of the field. If the field is not set, +returns the default value.
  • fun clearFoo(): Clears the value of the field. After calling this, +hasFoo() will return false and getFoo() will return the default value.

For other simple field types, the corresponding Java type is chosen according to +the +scalar value types table. +For message and enum types, the value type is replaced with the message or enum +class. As the message type is still defined in Java, unsigned types in the +message are represented using the standard corresponding signed types in the +DSL, for compatibility with Java and older versions of Kotlin.

Embedded Message Fields

Note that there is no special handling of submessages. For example, if you have +a field

optional Foo my_foo = 1;
+

you must write

myFoo = foo {
+  ...
+}
+

In general, this is because the compiler does not know whether Foo has a +Kotlin DSL at all, or e.g. only has the Java APIs generated. This means that you +do not have to wait for messages you depend on to add Kotlin code generation.

Repeated Fields

For this field definition:

repeated string foo = 1;
+

The compiler will generate the following members in the DSL:

  • class FooProxy: DslProxy, an unconstructable type used only in generics
  • val fooList: DslList<String, FooProxy>, a read-only view of the list of +current elements in the repeated field
  • fun DslList<String, FooProxy>.add(value: String), an extension function +allowing elements to be added to the repeated field
  • operator fun DslList<String, FooProxy>.plusAssign(value: String), an alias +for add
  • fun DslList<String, FooProxy>.addAll(values: Iterable<String>), an +extension function allowing an Iterable of elements to be added to the +repeated field
  • operator fun DslList<String, FooProxy>.plusAssign(values: Iterable<String>), an alias for addAll
  • operator fun DslList<String, FooProxy>.set(index: Int, value: String), an +extension function setting the value of the element at the given zero-based +inde
  • fun DslList<String, FooProxy>.clear(), an extension function clearing the +contents of the repeated field

This unusual construction allows fooList to "behave like" a mutable list +within the scope of the DSL, supporting only the methods supported by the +underlying builder, while preventing mutability from "escaping" the DSL, which +could cause confusing side effects.

For other simple field types, the corresponding Java type is chosen according to +the +scalar value types table. +For message and enum types, the type is the message or enum class.

Oneof Fields

For this oneof field definition:

oneof oneof_name {
+    int32 foo = 1;
+    ...
+}
+

The compiler will generate the following accessor methods in the DSL:

  • val oneofNameCase: OneofNameCase: gets which, if any, of the oneof_name +fields are set; see the +Java code reference +for the return type
  • fun hasFoo(): Boolean: Returns true if the oneof case is FOO.
  • val foo: Int: Returns the current value of oneof_name if the oneof case +is FOO. Otherwise, returns the default value of this field.

For other simple field types, the corresponding Java type is chosen according to +the +scalar value types table. +For message and enum types, the value type is replaced with the message or enum +class.

Map Fields

For this map field definition:

map<int32, int32> weight = 1;
+

The compiler will generate the following members in the DSL class:

  • class WeightProxy private constructor(): DslProxy(), an unconstructable +type used only in generics
  • val weight: DslMap<Int, Int, WeightProxy>, a read-only view of the current +entries in the map field
  • fun DslMap<Int, Int, WeightProxy>.put(key: Int, value: Int): add the entry +to this map field
  • operator fun DslMap<Int, Int, WeightProxy>.put(key: Int, value: Int): +alias for put using operator syntax
  • fun DslMap<Int, Int, WeightProxy>.remove(key: Int): removes the entry +associated with key, if present
  • fun DslMap<Int, Int, WeightProxy>.putAll(map: Map<Int, Int>): adds all +entries from the specified map to this map field, overwriting prior values +for already present keys
  • fun DslMap<Int, Int, WeightProxy>.clear(): clears all entries from this +map field

Extensions

Given a proto2 or editions message with an extension range:

message Foo {
+  extensions 100 to 199;
+}
+

The protocol buffer compiler will add the following methods to FooKt.Dsl:

  • operator fun <T> get(extension: ExtensionLite<Foo, T>): T: gets the +current value of the extension field in the DSL
  • operator fun <T> get(extension: ExtensionLite<Foo, List<T>>): ExtensionList<T, Foo>: gets the current value of the repeated extension +field in the DSL as a read-only List
  • operator fun <T : Comparable<T>> set(extension: ExtensionLite<Foo, T>): +sets the current value of the extension field in the DSL (for Comparable +field types)
  • operator fun <T : MessageLite> set(extension: ExtensionLite<Foo, T>): sets +the current value of the extension field in the DSL (for message field +types)
  • operator fun set(extension: ExtensionLite<Foo, ByteString>): sets the +current value of the extension field in the DSL (for bytes fields)
  • operator fun contains(extension: ExtensionLite<Foo, *>): Boolean: returns +true if the extension field has a value
  • fun clear(extension: ExtensionLite<Foo, *>): clears the extension field
  • fun <E> ExtensionList<Foo, E>.add(value: E): adds a value to the repeated +extension field
  • operator fun <E> ExtensionList<Foo, E>.plusAssign(value: E): alias for +add using operator syntax
  • operator fun <E> ExtensionList<Foo, E>.addAll(values: Iterable<E>): adds +multiple values to the repeated extension field
  • operator fun <E> ExtensionList<Foo, E>.plusAssign(values: Iterable<E>): +alias for addAll using operator syntax
  • operator fun <E> ExtensionList<Foo, E>.set(index: Int, value: E): sets the +element of the repeated extension field at the specified index
  • inline fun ExtensionList<Foo, *>.clear(): clears the elements of the +repeated extension field

The generics here are complex, but the effect is that this[extension] = value +works for every extension type except repeated extensions, and repeated +extensions have "natural" list syntax that works similarly to +non-extension repeated fields.

Given an extension definition:

extend Foo {
+  int32 bar = 123;
+}
+

Java generates the “extension identifier” bar, which is used to “key” +extension operations above.

\ No newline at end of file diff --git a/reference/objective-c/index.html b/reference/objective-c/index.html new file mode 100644 index 000000000..d769520b3 --- /dev/null +++ b/reference/objective-c/index.html @@ -0,0 +1,8 @@ +Objective-C Reference | Protocol Buffers Documentation +

Objective-C Reference

Reference documentation for working with protocol buffer classes in Objective-C.

Objective-C Generated Code Guide

Describes exactly what Objective-C code the protocol buffer compiler generates for any given protocol definition.

\ No newline at end of file diff --git a/reference/objective-c/index.xml b/reference/objective-c/index.xml new file mode 100644 index 000000000..3826db0ef --- /dev/null +++ b/reference/objective-c/index.xml @@ -0,0 +1,2 @@ +Objective-C Reference on Protocol Buffers Documentationhttps://protobuf.dev/reference/objective-c/Recent content in Objective-C Reference on Protocol Buffers DocumentationHugoenObjective-C Generated Code Guidehttps://protobuf.dev/reference/objective-c/objective-c-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/objective-c/objective-c-generated/Any differences between proto2, proto3, and Editions generated code are highlighted. You should read the proto2 language guide and/or proto3 language guide and/or the Editions guide before reading this document. +Compiler invocation The protocol buffer compiler produces Objective-C output when invoked with the --objc_out= command-line flag. The parameter to the --objc_out= option is the directory where you want the compiler to write your Objective-C output. The compiler creates a header file and an implementation file for each . \ No newline at end of file diff --git a/reference/objective-c/objective-c-generated/index.html b/reference/objective-c/objective-c-generated/index.html new file mode 100644 index 000000000..def0ac17f --- /dev/null +++ b/reference/objective-c/objective-c-generated/index.html @@ -0,0 +1,843 @@ +Objective-C Generated Code Guide | Protocol Buffers Documentation +

Objective-C Generated Code Guide

Describes exactly what Objective-C code the protocol buffer compiler generates for any given protocol definition.

Any +differences between proto2, proto3, and Editions generated code are highlighted. +You should read the +proto2 language guide +and/or +proto3 language guide +and/or the Editions guide +before reading this document.

Compiler invocation

The protocol buffer compiler produces Objective-C output when invoked with the +--objc_out= command-line flag. The parameter to the --objc_out= option is +the directory where you want the compiler to write your Objective-C output. The +compiler creates a header file and an implementation file for each .proto file +input. The names of the output files are computed by taking the name of the +.proto file and making the following changes:

  • The file name is determined by converting the .proto file base name to +camel case. For example, foo_bar.proto will become FooBar.
  • The extension (.proto) is replaced with either pbobjc.h or pbobjc.m +for the header or implementation file, respectively.
  • The proto path (specified with the --proto_path= or -I command-line +flag) is replaced with the output path (specified with the --objc_out= +flag).

So, for example, if you invoke the compiler as follows:

protoc --proto_path=src --objc_out=build/gen src/foo.proto src/bar/baz.proto
+

The compiler will read the files src/foo.proto and src/bar/baz.proto and +produce four output files: build/gen/Foo.pbobjc.h, build/gen/Foo.pbobjc.m, +build/gen/bar/Baz.pbobjc.h, and build/gen/bar/Baz.pbobjc.m. The compiler +will automatically create the directory build/gen/bar if necessary, but it +will not create build or build/gen; they must already exist.

Packages

The Objective-C code generated by the protocol buffer compiler is completely +unaffected by the package name defined in the .proto file, as Objective-C has +no language-enforced namespacing. Instead, Objective-C class names are +distinguished using prefixes, which you can find out about in the next section.

Class prefix

Given the following +file option:

option objc_class_prefix = "CGOOP";
+

The specified string - in this case, CGOOP - is prefixed in front of all +Objective-C classes generated for this .proto file. Use prefixes that are 3 or +more characters as recommended by Apple. Note that all 2 letter prefixes are +reserved by Apple.

Camel case conversion

Idiomatic Objective-C uses camel case for all identifiers.

Messages will not have their names converted because the standard for proto +files is to name messages in camel case already. It is assumed that the user has +bypassed the convention for good reason, and the implementation will conform +with their intentions.

Methods generated from field names and oneofs, enum declarations, and +extension accessors will have their names camel cased. In general to convert +from a proto name to a camel cased Objective-C name:

  • The first letter converted to uppercase (except for fields, which always +start with a lowercase letter).
  • For each underscore in the name, the underscore is removed, and the +following letter is capitalized.

So, for example, the field foo_bar_baz becomes fooBarBaz. The field +FOO_bar becomes fooBar.

Messages

Given a simple message declaration:

message Foo {}
+

The protocol buffer compiler generates a class called Foo. If you specify an +objc_class_prefix file option, the value of this option is +prepended to the generated class name.

In the case of outer messages that have names matching any C/C++ or Objective-C +keywords:

message static {}
+

the generated interfaces are suffixed by _Class, as follows:

@interface static_Class {}
+

Note that as per the camel case conversion rules the name static is +not converted. In the case of an inner message that has a camel cased name +that is FieldNumber or OneOfCase, the generated interface will be the camel +cased name suffixed by _Class to make sure that the generated names do not +conflict with the FieldNumber enumerations or OneOfCase enumerations.

A message can also be declared inside another message.

message Foo {
+  message Bar {}
+}
+

This generates:

@interface Foo_Bar : GPBMessage
+@end
+

As you can see, the generated nested message name is the name of the generated +containing message name (Foo) appended with underscore (_) and the nested +message name (Bar).

Note: While we have tried to ensure that conflicts are kept to a minimum, +there are still potential cases where message names may conflict due to the +conversion between underscores and camel case. As an example:

message foo_bar {}
+message foo { message bar {} }
+

will both generate @interface foo_bar and will conflict. The most pragmatic +solution may be to rename the conflicting messages.

GPBMessage interface

GPBMessage is the superclass of all generated message classes. It is required +to support a superset of the following interface:

@interface GPBMessage : NSObject
+@end
+

The behaviors for this interface are as follows:

// Will do a deep copy.
+- (id)copy;
+// Will perform a deep equality comparison.
+- (BOOL)isEqual:(id)value;
+

Unknown fields

When a message is parsed, it may contain fields that are not known to the +parsing code. This can happen when a message is created with an +older version of a +.proto definition and is then parsed with code generated from a newer version +(or vice versa).

These fields are not discarded and are stored in the message’s unknownFields +property:

@property(nonatomic, copy, nullable) GPBUnknownFieldSet *unknownFields;
+

You can use the GPBUnknownFieldSet interface to fetch these fields by number +or loop over them as an array.

Fields

The following sections describe the code generated by the protocol buffer +compiler for message fields. They are divided by those with implicit and +explicit presence. You can learn more about this distinction in +Field Presence.

Singular Fields with Implicit Presence

For every singular field the compiler generates a property to store data and an +integer constant containing the field number. Message type fields also get a +has.. property that lets you check if the field is set in the encoded message. +So, for example, given the following message:

message Foo {
+  message Bar {
+    int32 int32_value = 1;
+  }
+  enum Qux {...}
+  int32 int32_value = 1;
+  string string_value = 2;
+  Bar message_value = 3;
+  Qux enum_value = 4;
+  bytes bytes_value = 5;
+}
+

The compiler will generate the following:

typedef GPB_ENUM(Foo_Bar_FieldNumber) {
+  // The generated field number name is the enclosing message names delimited by
+  // underscores followed by "FieldNumber", followed by the field name
+  // camel cased.
+  Foo_Bar_FieldNumber_Int32Value = 1,
+};
+
+@interface Foo_Bar : GPBMessage
+@property(nonatomic, readwrite) int32_t int32Value;
+@end
+
+typedef GPB_ENUM(Foo_FieldNumber) {
+  Foo_FieldNumber_Int32Value = 1,
+  Foo_FieldNumber_StringValue = 2,
+  Foo_FieldNumber_MessageValue = 3,
+  Foo_FieldNumber_EnumValue = 4,
+  Foo_FieldNumber_BytesValue = 5,
+};
+
+typedef GPB_ENUM(Foo_Qux) {
+  Foo_Qux_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
+  ...
+};
+
+@interface Foo : GPBMessage
+// Field names are camel cased.
+@property(nonatomic, readwrite) int32_t int32Value;
+@property(nonatomic, readwrite, copy, null_resettable) NSString *stringValue;
+@property(nonatomic, readwrite) BOOL hasMessageValue;
+@property(nonatomic, readwrite, strong, null_resettable) Foo_Bar *messageValue;
+@property(nonatomic, readwrite) Foo_Qux enumValue;
+@property(nonatomic, readwrite, copy, null_resettable) NSData *bytesValue;
+@end
+

Special naming cases

There are cases where the field name generation rules may result in name +conflicts and names will need to be "uniqued". Such conflicts are resolved by +appending _p to the end of the field (_p was selected because it’s pretty +unique, and stands for "property").

message Foo {
+  int32 foo_array = 1;      // Ends with Array
+  int32 bar_OneOfCase = 2;  // Ends with oneofcase
+  int32 id = 3;             // Is a C/C++/Objective-C keyword
+}
+

generates:

typedef GPB_ENUM(Foo_FieldNumber) {
+  // If a non-repeatable field name ends with "Array" it will be suffixed
+  // with "_p" to keep the name distinct from repeated types.
+  Foo_FieldNumber_FooArray_p = 1,
+  // If a field name ends with "OneOfCase" it will be suffixed with "_p" to
+  // keep the name distinct from OneOfCase properties.
+  Foo_FieldNumber_BarOneOfCase_p = 2,
+  // If a field name is a C/C++/ObjectiveC keyword it will be suffixed with
+  // "_p" to allow it to compile.
+  Foo_FieldNumber_Id_p = 3,
+};
+
+@interface Foo : GPBMessage
+@property(nonatomic, readwrite) int32_t fooArray_p;
+@property(nonatomic, readwrite) int32_t barOneOfCase_p;
+@property(nonatomic, readwrite) int32_t id_p;
+@end
+

Default values

The default value +for numeric types is 0.

The default value for strings is @"", and the default value for bytes is +[NSData data].

Assigning nil to a string field will assert in debug, and set the field to +@"" in release. Assigning nil to a bytes field will assert in debug and set +the field to [NSData data] in release. To test whether a bytes or string field +is set requires testing its length property and comparing it to 0.

The default "empty" value for a message is an instance of the default message. +To clear a message value it should be set to nil. Accessing a cleared message +will return an instance of the default message and the hasFoo method will +return false.

The default message returned for a field is a local instance. The reason behind +returning a default message instead of nil is that in the case of:

message Foo {
+  message Bar {
+     int32 b;
+  }
+  Bar a;
+}
+

The implementation will support:

Foo *foo = [[Foo alloc] init];
+foo.a.b = 2;
+

where a will be automatically created via the accessors if necessary. If +foo.a returned nil, the foo.a.b setter pattern would not work.

Singular Fields with Explicit Presence

For every singular field the compiler generates a property to store data, an +integer constant containing the field number, and a has.. property that lets +you check if the field is set in the encoded message. So, for example, given the +following message:

message Foo {
+  message Bar {
+    int32 int32_value = 1;
+  }
+  enum Qux {...}
+  optional int32 int32_value = 1;
+  optional string string_value = 2;
+  optional Bar message_value = 3;
+  optional Qux enum_value = 4;
+  optional bytes bytes_value = 5;
+}
+

The compiler will generate the following:

# Enum Foo_Qux
+
+typedef GPB_ENUM(Foo_Qux) {
+  Foo_Qux_Flupple = 0,
+};
+
+GPBEnumDescriptor *Foo_Qux_EnumDescriptor(void);
+
+BOOL Foo_Qux_IsValidValue(int32_t value);
+
+# Message Foo
+
+typedef GPB_ENUM(Foo_FieldNumber) {
+  Foo_FieldNumber_Int32Value = 2,
+  Foo_FieldNumber_MessageValue = 3,
+  Foo_FieldNumber_EnumValue = 4,
+  Foo_FieldNumber_BytesValue = 5,
+  Foo_FieldNumber_StringValue = 6,
+};
+
+@interface Foo : GPBMessage
+
+@property(nonatomic, readwrite) BOOL hasInt32Value;
+@property(nonatomic, readwrite) int32_t int32Value;
+
+@property(nonatomic, readwrite) BOOL hasStringValue;
+@property(nonatomic, readwrite, copy, null_resettable) NSString *stringValue;
+
+@property(nonatomic, readwrite) BOOL hasMessageValue;
+@property(nonatomic, readwrite, strong, null_resettable) Foo_Bar *messageValue;
+
+@property(nonatomic, readwrite) BOOL hasEnumValue;
+@property(nonatomic, readwrite) Foo_Qux enumValue;
+
+@property(nonatomic, readwrite) BOOL hasBytesValue;
+@property(nonatomic, readwrite, copy, null_resettable) NSData *bytesValue;
+
+@end
+
+# Message Foo_Bar
+
+typedef GPB_ENUM(Foo_Bar_FieldNumber) {
+  Foo_Bar_FieldNumber_Int32Value = 1,
+};
+
+@interface Foo_Bar : GPBMessage
+
+@property(nonatomic, readwrite) BOOL hasInt32Value;
+@property(nonatomic, readwrite) int32_t int32Value;
+
+@end
+

Special naming cases

There are cases where the field name generation rules may result in name +conflicts and names will need to be "uniqued". Such conflicts are resolved by +appending _p to the end of the field (_p was selected because it’s pretty +unique, and stands for "property").

message Foo {
+  optional int32 foo_array = 1;      // Ends with Array
+  optional int32 bar_OneOfCase = 2;  // Ends with oneofcase
+  optional int32 id = 3;             // Is a C/C++/Objective-C keyword
+}
+

generates:

typedef GPB_ENUM(Foo_FieldNumber) {
+  // If a non-repeatable field name ends with "Array" it will be suffixed
+  // with "_p" to keep the name distinct from repeated types.
+  Foo_FieldNumber_FooArray_p = 1,
+  // If a field name ends with "OneOfCase" it will be suffixed with "_p" to
+  // keep the name distinct from OneOfCase properties.
+  Foo_FieldNumber_BarOneOfCase_p = 2,
+  // If a field name is a C/C++/ObjectiveC keyword it will be suffixed with
+  // "_p" to allow it to compile.
+  Foo_FieldNumber_Id_p = 3,
+};
+
+@interface Foo : GPBMessage
+@property(nonatomic, readwrite) int32_t fooArray_p;
+@property(nonatomic, readwrite) int32_t barOneOfCase_p;
+@property(nonatomic, readwrite) int32_t id_p;
+@end
+

Default values (optional fields only)

The default value +for numeric types, if no explicit default was specified by the user, is 0.

The default value for strings is @"", and the default value for bytes is +[NSData data].

Assigning nil to a string field will assert in debug, and set the field to +@"" in release. Assigning nil to a bytes field will assert in debug and set +the field to [NSData data] in release. To test whether a bytes or string field +is set requires testing its length property and comparing it to 0.

The default "empty" value for a message is an instance of the default message. +To clear a message value it should be set to nil. Accessing a cleared message +will return an instance of the default message and the hasFoo method will +return false.

The default message returned for a field is a local instance. The reason behind +returning a default message instead of nil is that in the case of:

message Foo {
+  message Bar {
+     int32 b;
+  }
+  Bar a;
+}
+

The implementation will support:

Foo *foo = [[Foo alloc] init];
+foo.a.b = 2;
+

where a will be automatically created via the accessors if necessary. If +foo.a returned nil, the foo.a.b setter pattern would not work.

Repeated fields

Like singular fields (proto2 proto3), the protocol +buffer compiler generates one data property for each repeated field. This data +property is a GPB<VALUE>Array depending on the field type where <VALUE> can +be one of UInt32, Int32, UInt64, Int64, Bool, Float, Double, or +Enum. NSMutableArray will be used for string, bytes and message types. +Field names for repeated types have Array appended to them. The reason for +appending Array in the Objective-C interface is to make the code more +readable. Repeated fields in proto files tend to have singular names which do +not read well in standard Objective-C usage. Making the singular names plural +would be more idiomatic Objective-C, however pluralization rules are too complex +to support in the compiler.

message Foo {
+  message Bar {}
+  enum Qux {}
+  repeated int32 int32_value = 1;
+  repeated string string_value = 2;
+  repeated Bar message_value = 3;
+  repeated Qux enum_value = 4;
+}
+

generates:

typedef GPB_ENUM(Foo_FieldNumber) {
+  Foo_FieldNumber_Int32ValueArray = 1,
+  Foo_FieldNumber_StringValueArray = 2,
+  Foo_FieldNumber_MessageValueArray = 3,
+  Foo_FieldNumber_EnumValueArray = 4,
+};
+
+@interface Foo : GPBMessage
+// Field names for repeated types are the camel case name with
+// "Array" suffixed.
+@property(nonatomic, readwrite, strong, null_resettable)
+ GPBInt32Array *int32ValueArray;
+@property(nonatomic, readonly) NSUInteger int32ValueArray_Count;
+
+@property(nonatomic, readwrite, strong, null_resettable)
+ NSMutableArray *stringValueArray;
+@property(nonatomic, readonly) NSUInteger stringValueArray_Count;
+
+@property(nonatomic, readwrite, strong, null_resettable)
+ NSMutableArray *messageValueArray;
+@property(nonatomic, readonly) NSUInteger messageValueArray_Count;
+
+@property(nonatomic, readwrite, strong, null_resettable)
+ GPBEnumArray *enumValueArray;
+@property(nonatomic, readonly) NSUInteger enumValueArray_Count;
+@end
+

Note: The behavior of repeated fields can be configured in Editions with the +features.repeated_field_encoding feature.

For string, bytes and message fields, elements of the array are NSString*, +NSData* and pointers to subclasses of GPBMessage respectively.

Default values

The default value +for a repeated field is to be empty. In Objective-C generated code, this is an +empty GPB<VALUE>Array. If you access an empty repeated field, you’ll get back +an empty array that you can update like any other repeated field array.

Foo *myFoo = [[Foo alloc] init];
+[myFoo.stringValueArray addObject:@"A string"]
+

You can also use the provided <field>Array_Count property to check if the +array for a particular repeated field is empty without having to create the +array:

if (myFoo.messageValueArray_Count) {
+  // There is something in the array...
+}
+

GPB<VALUE>Array interface

GPB<VALUE>Arrays (aside from GPBEnumArray, which we’ll look at below) have +the following interface:

@interface GPBArray : NSObject
+@property (nonatomic, readonly) NSUInteger count;
++ (instancetype)array;
++ (instancetype)arrayWithValue:()value;
++ (instancetype)arrayWithValueArray:(GPBArray *)array;
++ (instancetype)arrayWithCapacity:(NSUInteger)count;
+
+// Initializes the array, copying the values.
+- (instancetype)initWithValueArray:(GPBArray *)array;
+- (instancetype)initWithValues:(const  [])values
+                         count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithCapacity:(NSUInteger)count;
+
+- ()valueAtIndex:(NSUInteger)index;
+
+- (void)enumerateValuesWithBlock:
+     (void (^)( value, NSUInteger idx, BOOL *stop))block;
+- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
+    usingBlock:(void (^)( value, NSUInteger idx, BOOL *stop))block;
+
+- (void)addValue:()value;
+- (void)addValues:(const  [])values count:(NSUInteger)count;
+- (void)addValuesFromArray:(GPBArray *)array;
+
+- (void)removeValueAtIndex:(NSUInteger)count;
+- (void)removeAll;
+
+- (void)exchangeValueAtIndex:(NSUInteger)idx1
+            withValueAtIndex:(NSUInteger)idx2;
+- (void)insertValue:()value atIndex:(NSUInteger)count;
+- (void)replaceValueAtIndex:(NSUInteger)index withValue:()value;
+
+
+@end
+

GPBEnumArray has a slightly different interface to handle the validation +function and to access raw values.

@interface GPBEnumArray : NSObject
+@property (nonatomic, readonly) NSUInteger count;
+@property (nonatomic, readonly) GPBEnumValidationFunc validationFunc;
+
++ (instancetype)array;
++ (instancetype)arrayWithValidationFunction:(nullable GPBEnumValidationFunc)func;
++ (instancetype)arrayWithValidationFunction:(nullable GPBEnumValidationFunc)func
+                                   rawValue:value;
++ (instancetype)arrayWithValueArray:(GPBEnumArray *)array;
++ (instancetype)arrayWithValidationFunction:(nullable GPBEnumValidationFunc)func
+                                   capacity:(NSUInteger)count;
+
+- (instancetype)initWithValidationFunction:
+  (nullable GPBEnumValidationFunc)func;
+
+// Initializes the array, copying the values.
+- (instancetype)initWithValueArray:(GPBEnumArray *)array;
+- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func
+    values:(const int32_t [])values
+    count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func
+                                  capacity:(NSUInteger)count;
+
+// These will return kGPBUnrecognizedEnumeratorValue if the value at index
+// is not a valid enumerator as defined by validationFunc. If the actual
+// value is desired, use the "raw" version of the method.
+- (int32_t)valueAtIndex:(NSUInteger)index;
+- (void)enumerateValuesWithBlock:
+    (void (^)(int32_t value, NSUInteger idx, BOOL *stop))block;
+- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
+    usingBlock:(void (^)(int32_t value, NSUInteger idx, BOOL *stop))block;
+
+// These methods bypass the validationFunc to provide access to values
+// that were not known at the time the binary was compiled.
+- (int32_t)rawValueAtIndex:(NSUInteger)index;
+
+- (void)enumerateRawValuesWithBlock:
+    (void (^)(int32_t value, NSUInteger idx, BOOL *stop))block;
+- (void)enumerateRawValuesWithOptions:(NSEnumerationOptions)opts
+    usingBlock:(void (^)(int32_t value, NSUInteger idx, BOOL *stop))block;
+
+// If value is not a valid enumerator as defined by validationFunc, these
+// methods will assert in debug, and will log in release and assign the value
+// to the default value. Use the rawValue methods below to assign
+// non enumerator values.
+- (void)addValue:(int32_t)value;
+- (void)addValues:(const int32_t [])values count:(NSUInteger)count;
+- (void)insertValue:(int32_t)value atIndex:(NSUInteger)count;
+- (void)replaceValueAtIndex:(NSUInteger)index withValue:(int32_t)value;
+
+// These methods bypass the validationFunc to provide setting of values that
+// were not known at the time the binary was compiled.
+- (void)addRawValue:(int32_t)rawValue;
+- (void)addRawValuesFromEnumArray:(GPBEnumArray *)array;
+- (void)addRawValues:(const int32_t [])values count:(NSUInteger)count;
+- (void)replaceValueAtIndex:(NSUInteger)index withRawValue:(int32_t)rawValue;
+- (void)insertRawValue:(int32_t)value atIndex:(NSUInteger)count;
+
+// No validation applies to these methods.
+- (void)removeValueAtIndex:(NSUInteger)count;
+- (void)removeAll;
+- (void)exchangeValueAtIndex:(NSUInteger)idx1
+            withValueAtIndex:(NSUInteger)idx2;
+
+@end
+

Oneof fields

Given a message with +oneof field +definitions:

message Order {
+  oneof OrderID {
+    string name = 1;
+    int32 address = 2;
+  };
+  int32 quantity = 3;
+};
+

The protocol buffer compiler generates:

typedef GPB_ENUM(Order_OrderID_OneOfCase) {
+  Order_OrderID_OneOfCase_GPBUnsetOneOfCase = 0,
+  Order_OrderID_OneOfCase_Name = 1,
+  Order_OrderID_OneOfCase_Address = 2,
+};
+
+typedef GPB_ENUM(Order_FieldNumber) {
+  Order_FieldNumber_Name = 1,
+  Order_FieldNumber_Address = 2,
+  Order_FieldNumber_Quantity = 3,
+};
+
+@interface Order : GPBMessage
+@property (nonatomic, readwrite) Order_OrderID_OneOfCase orderIDOneOfCase;
+@property (nonatomic, readwrite, copy, null_resettable) NSString *name;
+@property (nonatomic, readwrite) int32_t address;
+@property (nonatomic, readwrite) int32_t quantity;
+@end
+
+void Order_ClearOrderIDOneOfCase(Order *message);
+

Setting one of the oneof properties will clear all the other properties +associated with the oneof.

<ONE_OF_NAME>_OneOfCase_GPBUnsetOneOfCase will always be equivalent to 0 to +allow for easy testing to see if any field in the oneof is set.

Map Fields

For this message definition:

message Bar {...}
+message Foo {
+  map<int32, string> a_map = 1;
+  map<string, Bar> b_map = 2;
+};
+

The compiler generates the following:

typedef GPB_ENUM(Foo_FieldNumber) {
+  Foo_FieldNumber_AMap = 1,
+  Foo_FieldNumber_BMap = 2,
+};
+
+@interface Foo : GPBMessage
+// Map names are the camel case version of the field name.
+@property (nonatomic, readwrite, strong, null_resettable) GPBInt32ObjectDictionary *aMap;
+@property(nonatomic, readonly) NSUInteger aMap_Count;
+@property (nonatomic, readwrite, strong, null_resettable) NSMutableDictionary *bMap;
+@property(nonatomic, readonly) NSUInteger bMap_Count;
+@end
+

Cases where keys are strings and values are strings, bytes, or messages are +handled by NSMutableDictionary.

Other cases are:

GBP<KEY><VALUE>Dictionary
+

where:

  • <KEY> is Uint32, Int32, UInt64, Int64, Bool or String.
  • <VALUE> is UInt32, Int32, UInt64, Int64, Bool, Float, Double, Enum, or +Object. Object is used for values of type string bytes or message to +cut down on the number of classes and is in line with how Objective-C works +with NSMutableDictionary.

Default values

The default value +for a map field is empty. In Objective-C generated code, this is an empty +GBP<KEY><VALUE>Dictionary. If you access an empty map field, you’ll get back +an empty dictionary that you can update like any other map field.

You can also use the provided <mapField>_Count property to check if a +particular map is empty:

if (myFoo.myMap_Count) {
+  // There is something in the map...
+}
+

GBP<KEY><VALUE>Dictionary interface

The GBP<KEY><VALUE>Dictionary (apart from GBP<KEY>ObjectDictionary and +GBP<KEY>EnumDictionary) interface is as follows:

@interface GPB<KEY>Dictionary : NSObject
+@property (nonatomic, readonly) NSUInteger count;
+
++ (instancetype)dictionary;
++ (instancetype)dictionaryWithValue:(const )value
+                             forKey:(const <KEY>)key;
++ (instancetype)dictionaryWithValues:(const  [])values
+                             forKeys:(const <KEY> [])keys
+                               count:(NSUInteger)count;
++ (instancetype)dictionaryWithDictionary:(GPB<KEY>Dictionary *)dictionary;
++ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
+
+- (instancetype)initWithValues:(const  [])values
+                       forKeys:(const <KEY> [])keys
+                         count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithDictionary:(GPB<KEY>Dictionary *)dictionary;
+- (instancetype)initWithCapacity:(NSUInteger)numItems;
+
+- (BOOL)valueForKey:(<KEY>)key value:(VALUE *)value;
+
+- (void)enumerateKeysAndValuesUsingBlock:
+    (void (^)(<KEY> key,  value, BOOL *stop))block;
+
+- (void)removeValueForKey:(<KEY>)aKey;
+- (void)removeAll;
+- (void)setValue:()value forKey:(<KEY>)key;
+- (void)addEntriesFromDictionary:(GPB<KEY>Dictionary *)otherDictionary;
+@end
+

The GBP<KEY>ObjectDictionary interface is:

@interface GPB<KEY>ObjectDictionary : NSObject
+@property (nonatomic, readonly) NSUInteger count;
+
++ (instancetype)dictionary;
++ (instancetype)dictionaryWithObject:(id)object
+                             forKey:(const <KEY>)key;
++ (instancetype)
+  dictionaryWithObjects:(const id GPB_UNSAFE_UNRETAINED [])objects
+                forKeys:(const <KEY> [])keys
+                  count:(NSUInteger)count;
++ (instancetype)dictionaryWithDictionary:(GPB<KEY>ObjectDictionary *)dictionary;
++ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
+
+- (instancetype)initWithObjects:(const id GPB_UNSAFE_UNRETAINED [])objects
+                        forKeys:(const <KEY> [])keys
+                          count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithDictionary:(GPB<KEY>ObjectDictionary *)dictionary;
+- (instancetype)initWithCapacity:(NSUInteger)numItems;
+
+- (id)objectForKey:(uint32_t)key;
+
+- (void)enumerateKeysAndObjectsUsingBlock:
+    (void (^)(<KEY> key, id object, BOOL *stop))block;
+
+- (void)removeObjectForKey:(<KEY>)aKey;
+- (void)removeAll;
+- (void)setObject:(id)object forKey:(<KEY>)key;
+- (void)addEntriesFromDictionary:(GPB<KEY>ObjectDictionary *)otherDictionary;
+@end
+

GBP<KEY>EnumDictionary has a slightly different interface to handle the +validation function and to access raw values.

@interface GPB<KEY>EnumDictionary : NSObject
+
+@property(nonatomic, readonly) NSUInteger count;
+@property(nonatomic, readonly) GPBEnumValidationFunc validationFunc;
+
++ (instancetype)dictionary;
++ (instancetype)dictionaryWithValidationFunction:(nullable GPBEnumValidationFunc)func;
++ (instancetype)dictionaryWithValidationFunction:(nullable GPBEnumValidationFunc)func
+                                        rawValue:(int32_t)rawValue
+                                          forKey:(<KEY>_t)key;
++ (instancetype)dictionaryWithValidationFunction:(nullable GPBEnumValidationFunc)func
+                                       rawValues:(const int32_t [])values
+                                         forKeys:(const <KEY>_t [])keys
+                                           count:(NSUInteger)count;
++ (instancetype)dictionaryWithDictionary:(GPB<KEY>EnumDictionary *)dictionary;
++ (instancetype)dictionaryWithValidationFunction:(nullable GPBEnumValidationFunc)func
+                                        capacity:(NSUInteger)numItems;
+
+- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func;
+- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func
+                                 rawValues:(const int32_t [])values
+                                   forKeys:(const <KEY>_t [])keys
+                                     count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithDictionary:(GPB<KEY>EnumDictionary *)dictionary;
+- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func
+                                  capacity:(NSUInteger)numItems;
+
+// These will return kGPBUnrecognizedEnumeratorValue if the value for the key
+// is not a valid enumerator as defined by validationFunc. If the actual value is
+// desired, use "raw" version of the method.
+
+- (BOOL)valueForKey:(<KEY>_t)key value:(nullable int32_t *)value;
+
+- (void)enumerateKeysAndValuesUsingBlock:
+    (void (^)(<KEY>_t key, int32_t value, BOOL *stop))block;
+
+// These methods bypass the validationFunc to provide access to values that were not
+// known at the time the binary was compiled.
+
+- (BOOL)valueForKey:(<KEY>_t)key rawValue:(nullable int32_t *)rawValue;
+
+- (void)enumerateKeysAndRawValuesUsingBlock:
+    (void (^)(<KEY>_t key, int32_t rawValue, BOOL *stop))block;
+
+- (void)addRawEntriesFromDictionary:(GPB<KEY>EnumDictionary *)otherDictionary;
+
+// If value is not a valid enumerator as defined by validationFunc, these
+// methods will assert in debug, and will log in release and assign the value
+// to the default value. Use the rawValue methods below to assign non enumerator
+// values.
+
+- (void)setValue:(int32_t)value forKey:(<KEY>_t)key;
+
+// This method bypass the validationFunc to provide setting of values that were not
+// known at the time the binary was compiled.
+- (void)setRawValue:(int32_t)rawValue forKey:(<KEY>_t)key;
+
+// No validation applies to these methods.
+
+- (void)removeValueForKey:(<KEY>_t)aKey;
+- (void)removeAll;
+
+@end
+

Enumerations

Given an enum definition like:

enum Foo {
+  VALUE_A = 0;
+  VALUE_B = 1;
+  VALUE_C = 5;
+}
+

the generated code will be:

// The generated enum value name will be the enumeration name followed by
+// an underscore and then the enumerator name converted to camel case.
+// GPB_ENUM is a macro defined in the Objective-C Protocol Buffer headers
+// that enforces all enum values to be int32 and aids in Swift Enumeration
+// support.
+typedef GPB_ENUM(Foo) {
+  Foo_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, //proto3 only
+  Foo_ValueA = 0,
+  Foo_ValueB = 1;
+  Foo_ValueC = 5;
+};
+
+// Returns information about what values this enum type defines.
+GPBEnumDescriptor *Foo_EnumDescriptor();
+

Each enumeration has a validation function declared for it:

// Returns YES if the given numeric value matches one of Foo's
+// defined values (0, 1, 5).
+BOOL Foo_IsValidValue(int32_t value);
+

and an enumeration descriptor accessor function declared for it:

// GPBEnumDescriptor is defined in the runtime and contains information
+// about the enum definition, such as the enum name, enum value and enum value
+// validation function.
+typedef GPBEnumDescriptor *(*GPBEnumDescriptorAccessorFunc)();
+

The enum descriptor accessor functions are C functions, as opposed to methods on +the enumeration class, because they are rarely used by client software. This +will cut down on the amount of Objective-C runtime information generated, and +potentially allow the linker to deadstrip them.

In the case of outer enums that have names matching any C/C++ or Objective-C +keywords, such as:

enum method {}
+

the generated interfaces are suffixed with _Enum, as follows:

// The generated enumeration name is the keyword suffixed by _Enum.
+typedef GPB_ENUM(Method_Enum) {}
+

An enum can also be declared inside another message. For example:

message Foo {
+  enum Bar {
+    VALUE_A = 0;
+    VALUE_B = 1;
+    VALUE_C = 5;
+  }
+  Bar aBar = 1;
+  Bar aDifferentBar = 2;
+  repeated Bar aRepeatedBar = 3;
+}
+

generates:

typedef GPB_ENUM(Foo_Bar) {
+  Foo_Bar_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, //proto3 only
+  Foo_Bar_ValueA = 0;
+  Foo_Bar_ValueB = 1;
+  Foo_Bar_ValueC = 5;
+};
+
+GPBEnumDescriptor *Foo_Bar_EnumDescriptor();
+
+BOOL Foo_Bar_IsValidValue(int32_t value);
+
+@interface Foo : GPBMessage
+@property (nonatomic, readwrite) Foo_Bar aBar;
+@property (nonatomic, readwrite) Foo_Bar aDifferentBar;
+@property (nonatomic, readwrite, strong, null_resettable)
+ GPBEnumArray *aRepeatedBarArray;
+@end
+
+// proto3 only Every message that has an enum field will have an accessor function to get
+// the value of that enum as an integer. This allows clients to deal with
+// raw values if they need to.
+int32_t Foo_ABar_RawValue(Foo *message);
+void SetFoo_ABar_RawValue(Foo *message, int32_t value);
+int32_t Foo_ADifferentBar_RawValue(Foo *message);
+void SetFoo_ADifferentBar_RawValue(Foo *message, int32_t value);
+

All enumeration fields have the ability to access the value as a typed +enumerator (Foo_Bar in the example above), or, if using proto3, as a raw +int32_t value (using the accessor functions in the example above). This is to +support the case where the server returns values that the client may not +recognize due to the client and server being compiled with different versions of +the proto file.

Unrecognized enum values are treated differently depending on the language +version and the features.enum_type feature in Editions.

  • In open enums, kGPBUnrecognizedEnumeratorValue is returned for the typed +enumerator value if the enumerator value in the parsed message data is not +one that the code reading it was compiled to support. If the actual value is +desired, use the raw value accessors to get the value as an int32_t.
  • In closed enums, unrecognized enum values are treated as unknown fields.
  • Proto2 enums are closed, and proto3 enums are open. In Editions, the +behavior is configurable with the features.enum_type feature.

kGPBUnrecognizedEnumeratorValue is defined as 0xFBADBEEF, and it will be an +error if any enumerator in an enumeration has this value. Attempting to set any +enumeration field to this value is a runtime error. Similarly, attempting to set +any enumeration field to an enumerator not defined by its enumeration type using +the typed accessors is a runtime error. In both error cases, debug builds will +cause an assertion and release builds will log and set the field to its default +value (0).

The raw value accessors are defined as C functions instead of as Objective-C +methods because they are not used in most cases. Declaring them as C functions +cuts down on wasted Objective-C runtime information and allows the linker to +potentially dead strip them.

Swift Enumeration Support

Apple documents how they import Objective-C enumerations to Swift enumerations +in +Interacting with C APIs. +Protocol buffer-generated enumerations support Objective-C to Swift conversions.

// Proto
+enum Foo {
+  VALUE_A = 0;
+}
+

generates:

// Objective-C
+typedef GPB_ENUM(Foo) {
+  Foo_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
+  Foo_ValueA = 0,
+};
+

which in Swift code will allow:

// Swift
+let aValue = Foo.ValueA
+let anotherValue: Foo = .GPBUnrecognizedEnumeratorValue
+

Well-known types

If you use any of the message types provided with protocol buffers, they will in +general just use their proto definitions in generated Objective-C code, though +we supply some basic conversion methods in categories to make using them +simpler. Note that we do not have special APIs for all well-known types yet, +including Any (there +is currently no helper method to convert an Any’s message value into a message +of the appropriate type).

Time Stamps

@interface GPBTimeStamp (GPBWellKnownTypes)
+@property (nonatomic, readwrite, strong) NSDate *date;
+@property (nonatomic, readwrite) NSTimeInterval timeIntervalSince1970;
+- (instancetype)initWithDate:(NSDate *)date;
+- (instancetype)initWithTimeIntervalSince1970:
+    (NSTimeInterval)timeIntervalSince1970;
+@end
+

Duration

@interface GPBDuration (GPBWellKnownTypes)
+@property (nonatomic, readwrite) NSTimeInterval timeIntervalSince1970;
+- (instancetype)initWithTimeIntervalSince1970:
+    (NSTimeInterval)timeIntervalSince1970;
+@end
+

Extensions (proto2 and editions only)

You can control the generation of extensions by using the +extension_generation_mode option. There are three modes:

  • class_based: Generates Objective-C classes and methods for extensions +(Legacy).
  • c_function: Generates C functions for extensions (New).
  • migration: Generates both.

Class-based (Legacy)

Given a message with an +extension range:

message Foo {
+  extensions 100 to 199;
+}
+
+extend Foo {
+  int32 foo = 101;
+  repeated int32 repeated_foo = 102;
+}
+
+message Bar {
+  extend Foo {
+    int32 bar = 103;
+    repeated int32 repeated_bar = 104;
+  }
+}
+

The compiler generates the following:

# File Test2Root
+
+@interface Test2Root : GPBRootObject
+
+// The base class provides:
+//   + (GPBExtensionRegistry *)extensionRegistry;
+// which is an GPBExtensionRegistry that includes all the extensions defined by
+// this file and all files that it depends on.
+
+@end
+
+@interface Test2Root (DynamicMethods)
++ (GPBExtensionDescriptor *)foo;
++ (GPBExtensionDescriptor *)repeatedFoo;
+@end
+
+# Message Foo
+
+@interface Foo : GPBMessage
+
+@end
+
+# Message Bar
+
+@interface Bar : GPBMessage
+
+@end
+
+@interface Bar (DynamicMethods)
+
++ (GPBExtensionDescriptor *)bar;
++ (GPBExtensionDescriptor *)repeatedBar;
+@end
+

To get and set these extension fields, you use the following:

Foo *fooMsg = [[Foo alloc] init];
+
+// Set the single field extensions
+[fooMsg setExtension:[Test2Root foo] value:@5];
+NSAssert([fooMsg hasExtension:[Test2Root foo]]);
+NSAssert([[fooMsg getExtension:[Test2Root foo]] intValue] == 5);
+
+// Add two things to the repeated extension:
+[fooMsg addExtension:[Test2Root repeatedFoo] value:@1];
+[fooMsg addExtension:[Test2Root repeatedFoo] value:@2];
+NSAssert([fooMsg hasExtension:[Test2Root repeatedFoo]]);
+NSAssert([[fooMsg getExtension:[Test2Root repeatedFoo]] count] == 2);
+
+// Clearing
+[fooMsg clearExtension:[Test2Root foo]];
+[fooMsg clearExtension:[Test2Root repeatedFoo]];
+NSAssert(![fooMsg hasExtension:[Test2Root foo]]);
+NSAssert(![fooMsg hasExtension:[Test2Root repeatedFoo]]);
+

C-functions (New)

When using c_function mode, C functions are generated instead of Objective-C +classes. This reduces binary size and avoids name conflicts.

The naming convention for the generated functions involves the proto package and +the extension name. If an objc_class_prefix is defined, it is prepended.

  • File-scoped registry: <Prefix><Package>_<File>_Registry()
  • File-scoped extension: <Prefix><Package>_extension_<Field>()
  • Message-scoped extension: +<Prefix><Package>_<ScopeMessage>_extension_<Field>()

(Note: Package is the CamelCased proto package name. File is the file name. +ScopeMessage is the message containing the extension definition.)

Using the same example as above, but assuming package my.package; and file +test2.proto:

The compiler generates C functions declared in the header:

// Registry function for the file.
+GPBExtensionRegistry *MyPackage_Test2_Registry(void);
+
+// File-scoped extensions.
+GPBExtensionDescriptor *MyPackage_extension_Foo(void);
+GPBExtensionDescriptor *MyPackage_extension_RepeatedFoo(void);
+
+// Message-scoped extensions (scoped to Bar).
+GPBExtensionDescriptor *MyPackage_Bar_extension_Bar(void);
+GPBExtensionDescriptor *MyPackage_Bar_extension_RepeatedBar(void);
+

To get and set these extension fields:

Foo *fooMsg = [[Foo alloc] init];
+
+// Set the single field extensions
+[fooMsg setExtension:MyPackage_extension_Foo() value:@5];
+NSAssert([fooMsg hasExtension:MyPackage_extension_Foo()]);
+NSAssert([[fooMsg getExtension:MyPackage_extension_Foo()] intValue] == 5);
+
+// Add two things to the repeated extension:
+[fooMsg addExtension:MyPackage_extension_RepeatedFoo() value:@1];
+[fooMsg addExtension:MyPackage_extension_RepeatedFoo() value:@2];
+NSAssert([fooMsg hasExtension:MyPackage_extension_RepeatedFoo()]);
+NSAssert([[fooMsg getExtension:MyPackage_extension_RepeatedFoo()] count] == 2);
+
+// Clearing
+[fooMsg clearExtension:MyPackage_extension_Foo()];
+[fooMsg clearExtension:MyPackage_extension_RepeatedFoo()];
+NSAssert(![fooMsg hasExtension:MyPackage_extension_Foo()]);
+NSAssert(![fooMsg hasExtension:MyPackage_extension_RepeatedFoo()]);
+
\ No newline at end of file diff --git a/reference/other/index.html b/reference/other/index.html new file mode 100644 index 000000000..26baa4d87 --- /dev/null +++ b/reference/other/index.html @@ -0,0 +1,27 @@ +Other Languages | Protocol Buffers Documentation +

Other Languages

protoc, the Protocol Buffers Compiler, can be extended to support new languages via plugins.

While the current release includes compilers and APIs for C++, Java, Go, Ruby, +C#, and Python, the compiler code is designed so that it’s easy to add support +for other languages. There are several ongoing projects to add new language +implementations to Protocol Buffers, including C, Haskell, Perl, Rust, and more.

For a list of links to projects we know about, see the +third-party add-ons wiki page.

Compiler Plugins

protoc, the Protocol Buffers Compiler, can be extended to support new +languages via plugins. A plugin is just a program which reads a +CodeGeneratorRequest protocol buffer from standard input and then writes a +CodeGeneratorResponse protocol buffer to standard output. These message types +are defined in +plugin.proto. +We recommend that all third-party code generators be written as plugins, as this +allows all generators to provide a consistent interface and share a single +parser implementation.

Plugins can be written in any programming language, but Google owned plugins are +written in C++. If you are writing your own plugin you may find it easiest to +use C++ for the plugin to be able to follow those examples and reuse utilities.

Additionally, plugins are able to insert code into the files generated by other +code generators. See the comments about "insertion points" in plugin.proto +for more on this. This could be used, for example, to write a plugin which +generates RPC service code that is tailored for a particular RPC system. See the +documentation for the generated code in each language to find out what insertion +points they provide.

\ No newline at end of file diff --git a/reference/php/api-docs-link/index.html b/reference/php/api-docs-link/index.html new file mode 100644 index 000000000..84dbe4794 --- /dev/null +++ b/reference/php/api-docs-link/index.html @@ -0,0 +1,4 @@ +PHP API | Protocol Buffers Documentation +
\ No newline at end of file diff --git a/content/reference/php/api-docs/DOCTUM_VERSION b/reference/php/api-docs/DOCTUM_VERSION similarity index 100% rename from content/reference/php/api-docs/DOCTUM_VERSION rename to reference/php/api-docs/DOCTUM_VERSION diff --git a/content/reference/php/api-docs/Google.html b/reference/php/api-docs/Google.html similarity index 100% rename from content/reference/php/api-docs/Google.html rename to reference/php/api-docs/Google.html diff --git a/content/reference/php/api-docs/Google/Protobuf.html b/reference/php/api-docs/Google/Protobuf.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf.html rename to reference/php/api-docs/Google/Protobuf.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Any.html b/reference/php/api-docs/Google/Protobuf/Any.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Any.html rename to reference/php/api-docs/Google/Protobuf/Any.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Api.html b/reference/php/api-docs/Google/Protobuf/Api.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Api.html rename to reference/php/api-docs/Google/Protobuf/Api.html diff --git a/content/reference/php/api-docs/Google/Protobuf/BoolValue.html b/reference/php/api-docs/Google/Protobuf/BoolValue.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/BoolValue.html rename to reference/php/api-docs/Google/Protobuf/BoolValue.html diff --git a/content/reference/php/api-docs/Google/Protobuf/BytesValue.html b/reference/php/api-docs/Google/Protobuf/BytesValue.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/BytesValue.html rename to reference/php/api-docs/Google/Protobuf/BytesValue.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Descriptor.html b/reference/php/api-docs/Google/Protobuf/Descriptor.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Descriptor.html rename to reference/php/api-docs/Google/Protobuf/Descriptor.html diff --git a/content/reference/php/api-docs/Google/Protobuf/DescriptorPool.html b/reference/php/api-docs/Google/Protobuf/DescriptorPool.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/DescriptorPool.html rename to reference/php/api-docs/Google/Protobuf/DescriptorPool.html diff --git a/content/reference/php/api-docs/Google/Protobuf/DoubleValue.html b/reference/php/api-docs/Google/Protobuf/DoubleValue.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/DoubleValue.html rename to reference/php/api-docs/Google/Protobuf/DoubleValue.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Duration.html b/reference/php/api-docs/Google/Protobuf/Duration.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Duration.html rename to reference/php/api-docs/Google/Protobuf/Duration.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Enum.html b/reference/php/api-docs/Google/Protobuf/Enum.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Enum.html rename to reference/php/api-docs/Google/Protobuf/Enum.html diff --git a/content/reference/php/api-docs/Google/Protobuf/EnumDescriptor.html b/reference/php/api-docs/Google/Protobuf/EnumDescriptor.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/EnumDescriptor.html rename to reference/php/api-docs/Google/Protobuf/EnumDescriptor.html diff --git a/content/reference/php/api-docs/Google/Protobuf/EnumValue.html b/reference/php/api-docs/Google/Protobuf/EnumValue.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/EnumValue.html rename to reference/php/api-docs/Google/Protobuf/EnumValue.html diff --git a/content/reference/php/api-docs/Google/Protobuf/EnumValueDescriptor.html b/reference/php/api-docs/Google/Protobuf/EnumValueDescriptor.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/EnumValueDescriptor.html rename to reference/php/api-docs/Google/Protobuf/EnumValueDescriptor.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Field.html b/reference/php/api-docs/Google/Protobuf/Field.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Field.html rename to reference/php/api-docs/Google/Protobuf/Field.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Field/Cardinality.html b/reference/php/api-docs/Google/Protobuf/Field/Cardinality.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Field/Cardinality.html rename to reference/php/api-docs/Google/Protobuf/Field/Cardinality.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Field/Kind.html b/reference/php/api-docs/Google/Protobuf/Field/Kind.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Field/Kind.html rename to reference/php/api-docs/Google/Protobuf/Field/Kind.html diff --git a/content/reference/php/api-docs/Google/Protobuf/FieldDescriptor.html b/reference/php/api-docs/Google/Protobuf/FieldDescriptor.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/FieldDescriptor.html rename to reference/php/api-docs/Google/Protobuf/FieldDescriptor.html diff --git a/content/reference/php/api-docs/Google/Protobuf/FieldMask.html b/reference/php/api-docs/Google/Protobuf/FieldMask.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/FieldMask.html rename to reference/php/api-docs/Google/Protobuf/FieldMask.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Field_Cardinality.html b/reference/php/api-docs/Google/Protobuf/Field_Cardinality.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Field_Cardinality.html rename to reference/php/api-docs/Google/Protobuf/Field_Cardinality.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Field_Kind.html b/reference/php/api-docs/Google/Protobuf/Field_Kind.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Field_Kind.html rename to reference/php/api-docs/Google/Protobuf/Field_Kind.html diff --git a/content/reference/php/api-docs/Google/Protobuf/FloatValue.html b/reference/php/api-docs/Google/Protobuf/FloatValue.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/FloatValue.html rename to reference/php/api-docs/Google/Protobuf/FloatValue.html diff --git a/content/reference/php/api-docs/Google/Protobuf/GPBEmpty.html b/reference/php/api-docs/Google/Protobuf/GPBEmpty.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/GPBEmpty.html rename to reference/php/api-docs/Google/Protobuf/GPBEmpty.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Int32Value.html b/reference/php/api-docs/Google/Protobuf/Int32Value.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Int32Value.html rename to reference/php/api-docs/Google/Protobuf/Int32Value.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Int64Value.html b/reference/php/api-docs/Google/Protobuf/Int64Value.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Int64Value.html rename to reference/php/api-docs/Google/Protobuf/Int64Value.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal.html b/reference/php/api-docs/Google/Protobuf/Internal.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal.html rename to reference/php/api-docs/Google/Protobuf/Internal.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/AnyBase.html b/reference/php/api-docs/Google/Protobuf/Internal/AnyBase.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/AnyBase.html rename to reference/php/api-docs/Google/Protobuf/Internal/AnyBase.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/CodedInputStream.html b/reference/php/api-docs/Google/Protobuf/Internal/CodedInputStream.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/CodedInputStream.html rename to reference/php/api-docs/Google/Protobuf/Internal/CodedInputStream.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/CodedOutputStream.html b/reference/php/api-docs/Google/Protobuf/Internal/CodedOutputStream.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/CodedOutputStream.html rename to reference/php/api-docs/Google/Protobuf/Internal/CodedOutputStream.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/Descriptor.html b/reference/php/api-docs/Google/Protobuf/Internal/Descriptor.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/Descriptor.html rename to reference/php/api-docs/Google/Protobuf/Internal/Descriptor.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/DescriptorPool.html b/reference/php/api-docs/Google/Protobuf/Internal/DescriptorPool.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/DescriptorPool.html rename to reference/php/api-docs/Google/Protobuf/Internal/DescriptorPool.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto.html b/reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto.html rename to reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.html b/reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.html rename to reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto/ReservedRange.html b/reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto/ReservedRange.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto/ReservedRange.html rename to reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto/ReservedRange.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.html b/reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.html rename to reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto_ReservedRange.html b/reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto_ReservedRange.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto_ReservedRange.html rename to reference/php/api-docs/Google/Protobuf/Internal/DescriptorProto_ReservedRange.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/EnumBuilderContext.html b/reference/php/api-docs/Google/Protobuf/Internal/EnumBuilderContext.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/EnumBuilderContext.html rename to reference/php/api-docs/Google/Protobuf/Internal/EnumBuilderContext.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/EnumDescriptor.html b/reference/php/api-docs/Google/Protobuf/Internal/EnumDescriptor.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/EnumDescriptor.html rename to reference/php/api-docs/Google/Protobuf/Internal/EnumDescriptor.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/EnumDescriptorProto.html b/reference/php/api-docs/Google/Protobuf/Internal/EnumDescriptorProto.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/EnumDescriptorProto.html rename to reference/php/api-docs/Google/Protobuf/Internal/EnumDescriptorProto.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.html b/reference/php/api-docs/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.html rename to reference/php/api-docs/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.html b/reference/php/api-docs/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.html rename to reference/php/api-docs/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/EnumOptions.html b/reference/php/api-docs/Google/Protobuf/Internal/EnumOptions.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/EnumOptions.html rename to reference/php/api-docs/Google/Protobuf/Internal/EnumOptions.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/EnumValueDescriptorProto.html b/reference/php/api-docs/Google/Protobuf/Internal/EnumValueDescriptorProto.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/EnumValueDescriptorProto.html rename to reference/php/api-docs/Google/Protobuf/Internal/EnumValueDescriptorProto.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/EnumValueOptions.html b/reference/php/api-docs/Google/Protobuf/Internal/EnumValueOptions.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/EnumValueOptions.html rename to reference/php/api-docs/Google/Protobuf/Internal/EnumValueOptions.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/ExtensionRangeOptions.html b/reference/php/api-docs/Google/Protobuf/Internal/ExtensionRangeOptions.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/ExtensionRangeOptions.html rename to reference/php/api-docs/Google/Protobuf/Internal/ExtensionRangeOptions.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptor.html b/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptor.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptor.html rename to reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptor.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto.html b/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto.html rename to reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto/Label.html b/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto/Label.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto/Label.html rename to reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto/Label.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto/Type.html b/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto/Type.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto/Type.html rename to reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto/Type.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto_Label.html b/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto_Label.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto_Label.html rename to reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto_Label.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto_Type.html b/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto_Type.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto_Type.html rename to reference/php/api-docs/Google/Protobuf/Internal/FieldDescriptorProto_Type.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FieldOptions.html b/reference/php/api-docs/Google/Protobuf/Internal/FieldOptions.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FieldOptions.html rename to reference/php/api-docs/Google/Protobuf/Internal/FieldOptions.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FieldOptions/CType.html b/reference/php/api-docs/Google/Protobuf/Internal/FieldOptions/CType.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FieldOptions/CType.html rename to reference/php/api-docs/Google/Protobuf/Internal/FieldOptions/CType.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FieldOptions/JSType.html b/reference/php/api-docs/Google/Protobuf/Internal/FieldOptions/JSType.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FieldOptions/JSType.html rename to reference/php/api-docs/Google/Protobuf/Internal/FieldOptions/JSType.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FieldOptions_CType.html b/reference/php/api-docs/Google/Protobuf/Internal/FieldOptions_CType.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FieldOptions_CType.html rename to reference/php/api-docs/Google/Protobuf/Internal/FieldOptions_CType.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FieldOptions_JSType.html b/reference/php/api-docs/Google/Protobuf/Internal/FieldOptions_JSType.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FieldOptions_JSType.html rename to reference/php/api-docs/Google/Protobuf/Internal/FieldOptions_JSType.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FileDescriptor.html b/reference/php/api-docs/Google/Protobuf/Internal/FileDescriptor.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FileDescriptor.html rename to reference/php/api-docs/Google/Protobuf/Internal/FileDescriptor.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FileDescriptorProto.html b/reference/php/api-docs/Google/Protobuf/Internal/FileDescriptorProto.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FileDescriptorProto.html rename to reference/php/api-docs/Google/Protobuf/Internal/FileDescriptorProto.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FileDescriptorSet.html b/reference/php/api-docs/Google/Protobuf/Internal/FileDescriptorSet.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FileDescriptorSet.html rename to reference/php/api-docs/Google/Protobuf/Internal/FileDescriptorSet.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FileOptions.html b/reference/php/api-docs/Google/Protobuf/Internal/FileOptions.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FileOptions.html rename to reference/php/api-docs/Google/Protobuf/Internal/FileOptions.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FileOptions/OptimizeMode.html b/reference/php/api-docs/Google/Protobuf/Internal/FileOptions/OptimizeMode.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FileOptions/OptimizeMode.html rename to reference/php/api-docs/Google/Protobuf/Internal/FileOptions/OptimizeMode.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/FileOptions_OptimizeMode.html b/reference/php/api-docs/Google/Protobuf/Internal/FileOptions_OptimizeMode.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/FileOptions_OptimizeMode.html rename to reference/php/api-docs/Google/Protobuf/Internal/FileOptions_OptimizeMode.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/GPBDecodeException.html b/reference/php/api-docs/Google/Protobuf/Internal/GPBDecodeException.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/GPBDecodeException.html rename to reference/php/api-docs/Google/Protobuf/Internal/GPBDecodeException.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/GPBJsonWire.html b/reference/php/api-docs/Google/Protobuf/Internal/GPBJsonWire.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/GPBJsonWire.html rename to reference/php/api-docs/Google/Protobuf/Internal/GPBJsonWire.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/GPBLabel.html b/reference/php/api-docs/Google/Protobuf/Internal/GPBLabel.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/GPBLabel.html rename to reference/php/api-docs/Google/Protobuf/Internal/GPBLabel.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/GPBType.html b/reference/php/api-docs/Google/Protobuf/Internal/GPBType.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/GPBType.html rename to reference/php/api-docs/Google/Protobuf/Internal/GPBType.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/GPBUtil.html b/reference/php/api-docs/Google/Protobuf/Internal/GPBUtil.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/GPBUtil.html rename to reference/php/api-docs/Google/Protobuf/Internal/GPBUtil.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/GPBWire.html b/reference/php/api-docs/Google/Protobuf/Internal/GPBWire.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/GPBWire.html rename to reference/php/api-docs/Google/Protobuf/Internal/GPBWire.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/GPBWireType.html b/reference/php/api-docs/Google/Protobuf/Internal/GPBWireType.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/GPBWireType.html rename to reference/php/api-docs/Google/Protobuf/Internal/GPBWireType.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/GeneratedCodeInfo.html b/reference/php/api-docs/Google/Protobuf/Internal/GeneratedCodeInfo.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/GeneratedCodeInfo.html rename to reference/php/api-docs/Google/Protobuf/Internal/GeneratedCodeInfo.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.html b/reference/php/api-docs/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.html rename to reference/php/api-docs/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.html b/reference/php/api-docs/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.html rename to reference/php/api-docs/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/GetPublicDescriptorTrait.html b/reference/php/api-docs/Google/Protobuf/Internal/GetPublicDescriptorTrait.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/GetPublicDescriptorTrait.html rename to reference/php/api-docs/Google/Protobuf/Internal/GetPublicDescriptorTrait.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/HasPublicDescriptorTrait.html b/reference/php/api-docs/Google/Protobuf/Internal/HasPublicDescriptorTrait.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/HasPublicDescriptorTrait.html rename to reference/php/api-docs/Google/Protobuf/Internal/HasPublicDescriptorTrait.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/MapEntry.html b/reference/php/api-docs/Google/Protobuf/Internal/MapEntry.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/MapEntry.html rename to reference/php/api-docs/Google/Protobuf/Internal/MapEntry.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/MapField.html b/reference/php/api-docs/Google/Protobuf/Internal/MapField.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/MapField.html rename to reference/php/api-docs/Google/Protobuf/Internal/MapField.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/MapFieldIter.html b/reference/php/api-docs/Google/Protobuf/Internal/MapFieldIter.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/MapFieldIter.html rename to reference/php/api-docs/Google/Protobuf/Internal/MapFieldIter.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/Message.html b/reference/php/api-docs/Google/Protobuf/Internal/Message.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/Message.html rename to reference/php/api-docs/Google/Protobuf/Internal/Message.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/MessageBuilderContext.html b/reference/php/api-docs/Google/Protobuf/Internal/MessageBuilderContext.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/MessageBuilderContext.html rename to reference/php/api-docs/Google/Protobuf/Internal/MessageBuilderContext.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/MessageOptions.html b/reference/php/api-docs/Google/Protobuf/Internal/MessageOptions.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/MessageOptions.html rename to reference/php/api-docs/Google/Protobuf/Internal/MessageOptions.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/MethodDescriptorProto.html b/reference/php/api-docs/Google/Protobuf/Internal/MethodDescriptorProto.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/MethodDescriptorProto.html rename to reference/php/api-docs/Google/Protobuf/Internal/MethodDescriptorProto.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/MethodOptions.html b/reference/php/api-docs/Google/Protobuf/Internal/MethodOptions.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/MethodOptions.html rename to reference/php/api-docs/Google/Protobuf/Internal/MethodOptions.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.html b/reference/php/api-docs/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.html rename to reference/php/api-docs/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.html b/reference/php/api-docs/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.html rename to reference/php/api-docs/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/OneofDescriptor.html b/reference/php/api-docs/Google/Protobuf/Internal/OneofDescriptor.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/OneofDescriptor.html rename to reference/php/api-docs/Google/Protobuf/Internal/OneofDescriptor.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/OneofDescriptorProto.html b/reference/php/api-docs/Google/Protobuf/Internal/OneofDescriptorProto.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/OneofDescriptorProto.html rename to reference/php/api-docs/Google/Protobuf/Internal/OneofDescriptorProto.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/OneofField.html b/reference/php/api-docs/Google/Protobuf/Internal/OneofField.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/OneofField.html rename to reference/php/api-docs/Google/Protobuf/Internal/OneofField.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/OneofOptions.html b/reference/php/api-docs/Google/Protobuf/Internal/OneofOptions.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/OneofOptions.html rename to reference/php/api-docs/Google/Protobuf/Internal/OneofOptions.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/RawInputStream.html b/reference/php/api-docs/Google/Protobuf/Internal/RawInputStream.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/RawInputStream.html rename to reference/php/api-docs/Google/Protobuf/Internal/RawInputStream.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/RepeatedField.html b/reference/php/api-docs/Google/Protobuf/Internal/RepeatedField.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/RepeatedField.html rename to reference/php/api-docs/Google/Protobuf/Internal/RepeatedField.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/RepeatedFieldIter.html b/reference/php/api-docs/Google/Protobuf/Internal/RepeatedFieldIter.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/RepeatedFieldIter.html rename to reference/php/api-docs/Google/Protobuf/Internal/RepeatedFieldIter.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/ServiceDescriptorProto.html b/reference/php/api-docs/Google/Protobuf/Internal/ServiceDescriptorProto.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/ServiceDescriptorProto.html rename to reference/php/api-docs/Google/Protobuf/Internal/ServiceDescriptorProto.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/ServiceOptions.html b/reference/php/api-docs/Google/Protobuf/Internal/ServiceOptions.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/ServiceOptions.html rename to reference/php/api-docs/Google/Protobuf/Internal/ServiceOptions.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/SourceCodeInfo.html b/reference/php/api-docs/Google/Protobuf/Internal/SourceCodeInfo.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/SourceCodeInfo.html rename to reference/php/api-docs/Google/Protobuf/Internal/SourceCodeInfo.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/SourceCodeInfo/Location.html b/reference/php/api-docs/Google/Protobuf/Internal/SourceCodeInfo/Location.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/SourceCodeInfo/Location.html rename to reference/php/api-docs/Google/Protobuf/Internal/SourceCodeInfo/Location.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/SourceCodeInfo_Location.html b/reference/php/api-docs/Google/Protobuf/Internal/SourceCodeInfo_Location.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/SourceCodeInfo_Location.html rename to reference/php/api-docs/Google/Protobuf/Internal/SourceCodeInfo_Location.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/TimestampBase.html b/reference/php/api-docs/Google/Protobuf/Internal/TimestampBase.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/TimestampBase.html rename to reference/php/api-docs/Google/Protobuf/Internal/TimestampBase.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/UninterpretedOption.html b/reference/php/api-docs/Google/Protobuf/Internal/UninterpretedOption.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/UninterpretedOption.html rename to reference/php/api-docs/Google/Protobuf/Internal/UninterpretedOption.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/UninterpretedOption/NamePart.html b/reference/php/api-docs/Google/Protobuf/Internal/UninterpretedOption/NamePart.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/UninterpretedOption/NamePart.html rename to reference/php/api-docs/Google/Protobuf/Internal/UninterpretedOption/NamePart.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Internal/UninterpretedOption_NamePart.html b/reference/php/api-docs/Google/Protobuf/Internal/UninterpretedOption_NamePart.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Internal/UninterpretedOption_NamePart.html rename to reference/php/api-docs/Google/Protobuf/Internal/UninterpretedOption_NamePart.html diff --git a/content/reference/php/api-docs/Google/Protobuf/ListValue.html b/reference/php/api-docs/Google/Protobuf/ListValue.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/ListValue.html rename to reference/php/api-docs/Google/Protobuf/ListValue.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Method.html b/reference/php/api-docs/Google/Protobuf/Method.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Method.html rename to reference/php/api-docs/Google/Protobuf/Method.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Mixin.html b/reference/php/api-docs/Google/Protobuf/Mixin.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Mixin.html rename to reference/php/api-docs/Google/Protobuf/Mixin.html diff --git a/content/reference/php/api-docs/Google/Protobuf/NullValue.html b/reference/php/api-docs/Google/Protobuf/NullValue.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/NullValue.html rename to reference/php/api-docs/Google/Protobuf/NullValue.html diff --git a/content/reference/php/api-docs/Google/Protobuf/OneofDescriptor.html b/reference/php/api-docs/Google/Protobuf/OneofDescriptor.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/OneofDescriptor.html rename to reference/php/api-docs/Google/Protobuf/OneofDescriptor.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Option.html b/reference/php/api-docs/Google/Protobuf/Option.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Option.html rename to reference/php/api-docs/Google/Protobuf/Option.html diff --git a/content/reference/php/api-docs/Google/Protobuf/SourceContext.html b/reference/php/api-docs/Google/Protobuf/SourceContext.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/SourceContext.html rename to reference/php/api-docs/Google/Protobuf/SourceContext.html diff --git a/content/reference/php/api-docs/Google/Protobuf/StringValue.html b/reference/php/api-docs/Google/Protobuf/StringValue.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/StringValue.html rename to reference/php/api-docs/Google/Protobuf/StringValue.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Struct.html b/reference/php/api-docs/Google/Protobuf/Struct.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Struct.html rename to reference/php/api-docs/Google/Protobuf/Struct.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Syntax.html b/reference/php/api-docs/Google/Protobuf/Syntax.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Syntax.html rename to reference/php/api-docs/Google/Protobuf/Syntax.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Timestamp.html b/reference/php/api-docs/Google/Protobuf/Timestamp.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Timestamp.html rename to reference/php/api-docs/Google/Protobuf/Timestamp.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Type.html b/reference/php/api-docs/Google/Protobuf/Type.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Type.html rename to reference/php/api-docs/Google/Protobuf/Type.html diff --git a/content/reference/php/api-docs/Google/Protobuf/UInt32Value.html b/reference/php/api-docs/Google/Protobuf/UInt32Value.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/UInt32Value.html rename to reference/php/api-docs/Google/Protobuf/UInt32Value.html diff --git a/content/reference/php/api-docs/Google/Protobuf/UInt64Value.html b/reference/php/api-docs/Google/Protobuf/UInt64Value.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/UInt64Value.html rename to reference/php/api-docs/Google/Protobuf/UInt64Value.html diff --git a/content/reference/php/api-docs/Google/Protobuf/Value.html b/reference/php/api-docs/Google/Protobuf/Value.html similarity index 100% rename from content/reference/php/api-docs/Google/Protobuf/Value.html rename to reference/php/api-docs/Google/Protobuf/Value.html diff --git a/content/reference/php/api-docs/PROJECT_VERSION b/reference/php/api-docs/PROJECT_VERSION similarity index 100% rename from content/reference/php/api-docs/PROJECT_VERSION rename to reference/php/api-docs/PROJECT_VERSION diff --git a/content/reference/php/api-docs/classes.html b/reference/php/api-docs/classes.html similarity index 100% rename from content/reference/php/api-docs/classes.html rename to reference/php/api-docs/classes.html diff --git a/content/reference/php/api-docs/css/bootstrap-theme.min.css b/reference/php/api-docs/css/bootstrap-theme.min.css similarity index 100% rename from content/reference/php/api-docs/css/bootstrap-theme.min.css rename to reference/php/api-docs/css/bootstrap-theme.min.css diff --git a/content/reference/php/api-docs/css/bootstrap.min.css b/reference/php/api-docs/css/bootstrap.min.css similarity index 100% rename from content/reference/php/api-docs/css/bootstrap.min.css rename to reference/php/api-docs/css/bootstrap.min.css diff --git a/content/reference/php/api-docs/css/doctum.css b/reference/php/api-docs/css/doctum.css similarity index 100% rename from content/reference/php/api-docs/css/doctum.css rename to reference/php/api-docs/css/doctum.css diff --git a/content/reference/php/api-docs/doc-index.html b/reference/php/api-docs/doc-index.html similarity index 100% rename from content/reference/php/api-docs/doc-index.html rename to reference/php/api-docs/doc-index.html diff --git a/content/reference/php/api-docs/doctum-search.json b/reference/php/api-docs/doctum-search.json similarity index 100% rename from content/reference/php/api-docs/doctum-search.json rename to reference/php/api-docs/doctum-search.json diff --git a/content/reference/php/api-docs/doctum.js b/reference/php/api-docs/doctum.js similarity index 100% rename from content/reference/php/api-docs/doctum.js rename to reference/php/api-docs/doctum.js diff --git a/content/reference/php/api-docs/fonts/doctum-font.css b/reference/php/api-docs/fonts/doctum-font.css similarity index 100% rename from content/reference/php/api-docs/fonts/doctum-font.css rename to reference/php/api-docs/fonts/doctum-font.css diff --git a/content/reference/php/api-docs/fonts/doctum.eot b/reference/php/api-docs/fonts/doctum.eot similarity index 100% rename from content/reference/php/api-docs/fonts/doctum.eot rename to reference/php/api-docs/fonts/doctum.eot diff --git a/content/reference/php/api-docs/fonts/doctum.svg b/reference/php/api-docs/fonts/doctum.svg similarity index 100% rename from content/reference/php/api-docs/fonts/doctum.svg rename to reference/php/api-docs/fonts/doctum.svg diff --git a/content/reference/php/api-docs/fonts/doctum.ttf b/reference/php/api-docs/fonts/doctum.ttf similarity index 100% rename from content/reference/php/api-docs/fonts/doctum.ttf rename to reference/php/api-docs/fonts/doctum.ttf diff --git a/content/reference/php/api-docs/fonts/doctum.woff b/reference/php/api-docs/fonts/doctum.woff similarity index 100% rename from content/reference/php/api-docs/fonts/doctum.woff rename to reference/php/api-docs/fonts/doctum.woff diff --git a/content/reference/php/api-docs/fonts/doctum.woff2 b/reference/php/api-docs/fonts/doctum.woff2 similarity index 100% rename from content/reference/php/api-docs/fonts/doctum.woff2 rename to reference/php/api-docs/fonts/doctum.woff2 diff --git a/content/reference/php/api-docs/index.html b/reference/php/api-docs/index.html similarity index 100% rename from content/reference/php/api-docs/index.html rename to reference/php/api-docs/index.html diff --git a/content/reference/php/api-docs/interfaces.html b/reference/php/api-docs/interfaces.html similarity index 100% rename from content/reference/php/api-docs/interfaces.html rename to reference/php/api-docs/interfaces.html diff --git a/content/reference/php/api-docs/js/autocomplete.min.js b/reference/php/api-docs/js/autocomplete.min.js similarity index 100% rename from content/reference/php/api-docs/js/autocomplete.min.js rename to reference/php/api-docs/js/autocomplete.min.js diff --git a/content/reference/php/api-docs/js/bootstrap.min.js b/reference/php/api-docs/js/bootstrap.min.js similarity index 100% rename from content/reference/php/api-docs/js/bootstrap.min.js rename to reference/php/api-docs/js/bootstrap.min.js diff --git a/content/reference/php/api-docs/js/jquery-3.5.1.slim.min.js b/reference/php/api-docs/js/jquery-3.5.1.slim.min.js similarity index 100% rename from content/reference/php/api-docs/js/jquery-3.5.1.slim.min.js rename to reference/php/api-docs/js/jquery-3.5.1.slim.min.js diff --git a/content/reference/php/api-docs/namespaces.html b/reference/php/api-docs/namespaces.html similarity index 100% rename from content/reference/php/api-docs/namespaces.html rename to reference/php/api-docs/namespaces.html diff --git a/reference/php/api-docs/opensearch.xml b/reference/php/api-docs/opensearch.xml new file mode 100644 index 000000000..e69de29bb diff --git a/content/reference/php/api-docs/renderer.index b/reference/php/api-docs/renderer.index similarity index 100% rename from content/reference/php/api-docs/renderer.index rename to reference/php/api-docs/renderer.index diff --git a/content/reference/php/api-docs/search.html b/reference/php/api-docs/search.html similarity index 100% rename from content/reference/php/api-docs/search.html rename to reference/php/api-docs/search.html diff --git a/content/reference/php/api-docs/traits.html b/reference/php/api-docs/traits.html similarity index 100% rename from content/reference/php/api-docs/traits.html rename to reference/php/api-docs/traits.html diff --git a/reference/php/index.html b/reference/php/index.html new file mode 100644 index 000000000..275e1967b --- /dev/null +++ b/reference/php/index.html @@ -0,0 +1,8 @@ +PHP Reference | Protocol Buffers Documentation +

PHP Reference

Reference documentation for working with protocol buffer classes in PHP.

PHP Generated Code Guide

Describes the PHP code that the protocol buffer compiler generates for any given protocol definition.

PHP API

\ No newline at end of file diff --git a/reference/php/index.xml b/reference/php/index.xml new file mode 100644 index 000000000..8ba53c404 --- /dev/null +++ b/reference/php/index.xml @@ -0,0 +1,2 @@ +PHP Reference on Protocol Buffers Documentationhttps://protobuf.dev/reference/php/Recent content in PHP Reference on Protocol Buffers DocumentationHugoenPHP Generated Code Guidehttps://protobuf.dev/reference/php/php-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/php/php-generated/You should read the proto3 language guide or Editions language guide before reading this document. Note that the protocol buffer compiler currently only supports proto3 and editions code generation for PHP. +Compiler Invocation The protocol buffer compiler produces PHP output when invoked with the --php_out= command-line flag. The parameter to the --php_out= option is the directory where you want the compiler to write your PHP output. In order to conform to PSR-4, the compiler creates a sub-directory corresponding to the package defined in the proto file.PHP APIhttps://protobuf.dev/reference/php/api-docs-link/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/php/api-docs-link/ \ No newline at end of file diff --git a/reference/php/php-generated/index.html b/reference/php/php-generated/index.html new file mode 100644 index 000000000..cf3dec568 --- /dev/null +++ b/reference/php/php-generated/index.html @@ -0,0 +1,166 @@ +PHP Generated Code Guide | Protocol Buffers Documentation +

PHP Generated Code Guide

Describes the PHP code that the protocol buffer compiler generates for any given protocol definition.

You should read the +proto3 language guide or +Editions language guide +before reading this document. Note that the protocol buffer compiler currently +only supports proto3 and editions code generation for PHP.

Compiler Invocation

The protocol buffer compiler produces PHP output when invoked with the +--php_out= command-line flag. The parameter to the --php_out= option is the +directory where you want the compiler to write your PHP output. In order to +conform to PSR-4, the compiler creates a sub-directory corresponding to the +package defined in the proto file. In addition, for each message in the proto +file input the compiler creates a separate file in the package’s subdirectory. +The names of the output files of messages are composed of three parts:

  • Base directory: The proto path (specified with the --proto_path= or -I +command-line flag) is replaced with the output path (specified with the +--php_out= flag).
  • Sub-directory: . in the package name are replaced by the operating system +directory separator. Each package name component is capitalized.
  • File: The message name is appended by .php.

So, for example, let’s say you invoke the compiler as follows:

protoc --proto_path=src --php_out=build/gen src/example.proto
+

And src/example.proto is defined as:

edition = "2023";
+package foo.bar;
+message MyMessage {}
+

The compiler will read the files src/foo.proto and produce the output file: +build/gen/Foo/Bar/MyMessage.php. The compiler will automatically create the +directory build/gen/Foo/Bar if necessary, but it will not create build or +build/gen; they must already exist.

Packages

The package name defined in the .proto file is used by default to generate a +module structure for the generated PHP classes. Given a file like:

package foo.bar;
+
+message MyMessage {}
+

The protocol compiler generates an output class with the name +Foo\Bar\MyMessage.

Namespace Options

The compiler supports additional options to define the PHP and metadata +namespace. When defined, these are used to generate the module structure and the +namespace. Given options like:

package foo.bar;
+option php_namespace = "baz\\qux";
+option php_metadata_namespace = "Foo";
+message MyMessage {}
+

The protocol compiler generates an output class with the name +baz\qux\MyMessage. The class will have the namespace namespace baz\qux.

The protocol compiler generates a metadata class with the name Foo\Metadata. +The class will have the namespace namespace Foo.

The options generated are case-sensitive. By default, the package is converted +to Pascal case.

Messages

Given a simple message declaration:

message Foo {
+  int32 int32_value = 1;
+  string string_value = 2;
+  repeated int32 repeated_int32_value = 3;
+  map<int32, int32> map_int32_int32_value = 4;
+}
+

The protocol buffer compiler generates a PHP class called Foo. This class +inherits from a common base class, Google\Protobuf\Internal\Message, which +provides methods for encoding and decoding your message types, as shown in the +following example:

$from = new Foo();
+$from->setInt32Value(1);
+$from->setStringValue('a');
+$from->getRepeatedInt32Value()[] = 1;
+$from->getMapInt32Int32Value()[1] = 1;
+$data = $from->serializeToString();
+$to = new Foo();
+try {
+  $to->mergeFromString($data);
+} catch (Exception $e) {
+  // Handle parsing error from invalid data.
+  ...
+}
+

You should not create your own Foo subclasses. Generated classes are not +designed for subclassing and may lead to "fragile base class" problems.

Nested messages result in a PHP class of the same name prefixed by their +containing message and separated by underscores, as PHP doesn’t support nested +classes. So, for example, if you have this in your .proto:

message TestMessage {
+  message NestedMessage {
+    int32 a = 1;
+  }
+}
+

The compiler will generate the following class:

// PHP doesn’t support nested classes.
+class TestMessage_NestedMessage {
+  public function __construct($data = NULL) {...}
+  public function getA() {...}
+  public function setA($var) {...}
+}
+

If the message class name is reserved (for example, Empty), the prefix PB is +prepended to the class name:

class PBEmpty {...}
+

We have also provided the file level option php_class_prefix. If this is +specified, it is prepended to all generated message classes.

Fields

For each field in a message type, the protocol buffer compiler generates a set +of accessor methods to set and get the field. The accessor methods are named +using snake_case field names converted to PascalCase. So, given a field +field_name, the accessor methods will be getFieldName and setFieldName.

// optional MyEnum optional_enum
+$m->getOptionalEnum();
+$m->setOptionalEnum(MyEnum->FOO);
+$m->hasOptionalEnum();
+$m->clearOptionalEnum();
+
+// MyEnum implicit_enum
+$m->getImplicitEnum();
+$m->setImplicitEnum(MyEnum->FOO);
+

Whenever you set a field, the value is type-checked against the declared type of +that field. If the value is of the wrong type (or out of range), an exception +will be raised. By default type conversions (for example, when assigning a value +to a field or adding an element to a repeated field) are permitted to and from +integer, float, and numeric strings. Conversions that are not permitted include +all conversions to/from arrays or objects. Float to integer overflow conversions +are undefined.

You can see the corresponding PHP type for each scalar protocol buffers type in +the +scalar value types table.

has... and clear...

For fields with explicit presence, the compiler generates a has...() method. +This method returns true if the field is set.

The compiler also generates a clear...() method. This method unsets the field. +After calling this method, has...() will return false.

For fields with implicit presence, the compiler does not generate has...() or +clear...() methods. For these fields, you can check for presence by comparing +the field value with the default value.

Singular Message Fields

For a field with a message type, the compiler generates the same accessor +methods as for scalar types.

A field with a message type defaults to null, and is not automatically created +when the field is accessed. Thus you need to explicitly create sub messages, as +in the following:

$m = new MyMessage();
+$m->setZ(new SubMessage());
+$m->getZ()->setFoo(42);
+
+$m2 = new MyMessage();
+$m2->getZ()->setFoo(42);  // FAILS with an exception
+

You can assign any instance to a message field, even if the instance is also +held elsewhere (for example, as a field value on another message).

Repeated Fields

The protocol buffer compiler generates a special RepeatedField for each +repeated field. So, for example, given the following field:

repeated int32 foo = 1;
+

The generated code lets you do this:

$m->getFoo()[] =1;
+$m->setFoo($array);
+

Map Fields

The protocol buffer compiler generates a MapField for each map field. So given +this field:

map<int32, int32> weight = 1;
+

You can do the following with the generated code:

$m->getWeight()[1] = 1;
+

Enumerations

PHP doesn’t have native enums, so instead the protocol buffer compiler generates +a PHP class for each enum type in your .proto file, just like for +messages, with constants defined for each value. So, given this +enum:

enum TestEnum {
+  Default = 0;
+  A = 1;
+}
+

The compiler generates the following class:

class TestEnum {
+  const DEFAULT = 0;
+  const A = 1;
+}
+

Also as with messages, a nested enum will result in a PHP class of the same name +prefixed by its containing message(s) and separated with underscores, as PHP +does not support nested classes.

class TestMessage_NestedEnum {...}
+

If an enum class or value name is reserved (for example, Empty), the prefix +PB is prepended to the class or value name:

class PBEmpty {
+  const PBECHO = 0;
+}
+

We have also provided the file level option php_class_prefix. If this is +specified, it is prepended to all generated enum classes.

Oneof

For a oneof, the +protocol buffer compiler generates a has and clear method for each field in +the oneof, as well as a special accessor method that lets you find out which +oneof field (if any) is set. So, given this message:

message TestMessage {
+  oneof test_oneof {
+    int32 oneof_int32 = 1;
+    int64 oneof_int64 = 2;
+  }
+}
+

The compiler generates the following fields and special method:

class TestMessage {
+  private oneof_int32;
+  private oneof_int64;
+  public function getOneofInt32();
+  public function setOneofInt32($var);
+  public function getOneofInt64();
+  public function setOneofInt64($var);
+  public function getTestOneof();  // Return field name
+}
+

The accessor method’s name is based on the oneof’s name, and returns a string +representing the field in the oneof that is currently set. If the oneof is not +set, the method returns an empty string.

When you set a field in a oneof, it automatically clears all other fields in the +oneof. If you want to set multiple fields in a oneof, you must do so in separate +statements.

$m = new TestMessage();
+$m->setOneofInt32(42); // $m->hasOneofInt32() is true
+$m->setOneofInt64(123); // $m->hasOneofInt32() is now false
+
\ No newline at end of file diff --git a/reference/protobuf/edition-2023-spec/index.html b/reference/protobuf/edition-2023-spec/index.html new file mode 100644 index 000000000..f3d5d33e0 --- /dev/null +++ b/reference/protobuf/edition-2023-spec/index.html @@ -0,0 +1,197 @@ +Protocol Buffers Edition 2023 Language Specification | Protocol Buffers Documentation +

Protocol Buffers Edition 2023 Language Specification

Language specification reference for edition 2023 of the Protocol Buffers language.

The syntax is specified using +Extended Backus-Naur Form (EBNF):

|   alternation
+()  grouping
+[]  option (zero or one time)
+{}  repetition (any number of times)
+

Lexical Elements

Letters and Digits

letter = "A" ... "Z" | "a" ... "z"
+capitalLetter =  "A" ... "Z"
+decimalDigit = "0" ... "9"
+octalDigit   = "0" ... "7"
+hexDigit     = "0" ... "9" | "A" ... "F" | "a" ... "f"
+

Identifiers

ident = letter { letter | decimalDigit | "_" }
+fullIdent = ident { "." ident }
+messageName = ident
+enumName = ident
+fieldName = ident
+oneofName = ident
+mapName = ident
+serviceName = ident
+rpcName = ident
+streamName = ident
+messageType = [ "." ] { ident "." } messageName
+enumType = [ "." ] { ident "." } enumName
+groupName = capitalLetter { letter | decimalDigit | "_" }
+

Integer Literals

intLit     = decimalLit | octalLit | hexLit
+decimalLit = [-] ( "1" ... "9" ) { decimalDigit }
+octalLit   = [-] "0" { octalDigit }
+hexLit     = [-] "0" ( "x" | "X" ) hexDigit { hexDigit }
+

Floating-point Literals

floatLit = [-] ( decimals "." [ decimals ] [ exponent ] | decimals exponent | "."decimals [ exponent ] ) | "inf" | "nan"
+decimals  = [-] decimalDigit { decimalDigit }
+exponent  = ( "e" | "E" ) [ "+" | "-" ] decimals
+

Boolean

boolLit = "true" | "false"
+

String Literals

strLit = strLitSingle { strLitSingle }
+strLitSingle = ( "'" { charValue } "'" ) | ( '"' { charValue } '"' )
+charValue = hexEscape | octEscape | charEscape | unicodeEscape | unicodeLongEscape | /[^\0\n\\]/
+hexEscape = '\' ( "x" | "X" ) hexDigit [ hexDigit ]
+octEscape = '\' octalDigit [ octalDigit [ octalDigit ] ]
+charEscape = '\' ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | '\' | "'" | '"' )
+unicodeEscape = '\' "u" hexDigit hexDigit hexDigit hexDigit
+unicodeLongEscape = '\' "U" ( "000" hexDigit hexDigit hexDigit hexDigit hexDigit |
+                              "0010" hexDigit hexDigit hexDigit hexDigit
+

EmptyStatement

emptyStatement = ";"
+

Constant

constant = fullIdent | ( [ "-" | "+" ] intLit ) | ( [ "-" | "+" ] floatLit ) |
+                strLit | boolLit | MessageValue
+

MessageValue is defined in the +Text Format Language Specification.

Edition

The edition statement replaces the legacy syntax keyword, and is used to +define the edition that this file is using.

edition = "edition" "=" [ ( "'" decimalLit "'" ) | ( '"' decimalLit '"' ) ] ";"
+

Import Statement

The import statement is used to import another .proto’s definitions.

import = "import" [ "weak" | "public" ] strLit ";"
+

Example:

import public "other.proto";
+

Package

The package specifier can be used to prevent name clashes between protocol +message types.

package = "package" fullIdent ";"
+

Example:

package foo.bar;
+

Option

Options can be used in proto files, messages, enums and services. An option can +be a protobuf defined option or a custom option. For more information, see +Options in the +language guide. Options are also be used to control +Feature Settings.

option = "option" optionName  "=" constant ";"
+optionName = ( ident | "(" ["."] fullIdent ")" )
+

For examples:

option java_package = "com.example.foo";
+option features.enum_type = CLOSED;
+

Fields

Fields are the basic elements of a protocol buffer message. Fields can be normal +fields, group fields, oneof fields, or map fields. A field has a label, type and +field number.

label = [ "repeated" ]
+type = "double" | "float" | "int32" | "int64" | "uint32" | "uint64"
+      | "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64"
+      | "bool" | "string" | "bytes" | messageType | enumType
+fieldNumber = intLit;
+

Normal field

Each field has a label, type, name, and field number. It may have field options.

field = [label] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
+fieldOptions = fieldOption { ","  fieldOption }
+fieldOption = optionName "=" constant
+

Examples:

foo.bar nested_message = 2;
+repeated int32 samples = 4 [packed=true];
+

Oneof and oneof field

A oneof consists of oneof fields and a oneof name. Oneof fields do not have +labels.

oneof = "oneof" oneofName "{" { option | oneofField } "}"
+oneofField = type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
+

Example:

oneof foo {
+    string name = 4;
+    SubMessage sub_message = 9;
+}
+

Map field

A map field has a key type, value type, name, and field number. The key type can +be any integral or string type. Note, the key type may not be an enum.

mapField = "map" "<" keyType "," type ">" mapName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
+keyType = "int32" | "int64" | "uint32" | "uint64" | "sint32" | "sint64" |
+          "fixed32" | "fixed64" | "sfixed32" | "sfixed64" | "bool" | "string"
+

Example:

map<string, Project> projects = 3;
+

Extensions and Reserved

Extensions and reserved are message elements that declare a range of field +numbers or field names.

Extensions

Extensions declare that a range of field numbers in a message are available for +third-party extensions. Other people can declare new fields for your message +type with those numeric tags in their own .proto files without having to edit +the original file.

extensions = "extensions" ranges ";"
+ranges = range { "," range }
+range =  intLit [ "to" ( intLit | "max" ) ]
+

Examples:

extensions 100 to 199;
+extensions 4, 20 to max;
+

Reserved

Reserved declares a range of field numbers or names in a message or enum that +can’t be used.

reserved = "reserved" ( ranges | reservedIdent ) ";"
+fieldNames = fieldName { "," fieldName }
+

Examples:

reserved 2, 15, 9 to 11;
+reserved foo, bar;
+

Top Level definitions

Enum definition

The enum definition consists of a name and an enum body. The enum body can have +options, enum fields, and reserved statements.

enum = "enum" enumName enumBody
+enumBody = "{" { option | enumField | emptyStatement | reserved } "}"
+enumField = fieldName "=" [ "-" ] intLit [ "[" enumValueOption { ","  enumValueOption } "]" ]";"
+enumValueOption = optionName "=" constant
+

Example:

enum EnumAllowingAlias {
+  option allow_alias = true;
+  EAA_UNSPECIFIED = 0;
+  EAA_STARTED = 1;
+  EAA_RUNNING = 2 [(custom_option) = "hello world"];
+}
+

Message definition

A message consists of a message name and a message body. The message body can +have fields, nested enum definitions, nested message definitions, extend +statements, extensions, groups, options, oneofs, map fields, and reserved +statements. A message cannot contain two fields with the same name in the same +message schema.

message = "message" messageName messageBody
+messageBody = "{" { field | enum | message | extend | extensions | group |
+option | oneof | mapField | reserved | emptyStatement } "}"
+

Example:

message Outer {
+  option (my_option).a = true;
+  message Inner {   // Level 2
+    required int64 ival = 1;
+  }
+  map<int32, string> my_map = 2;
+  extensions 20 to 30;
+}
+

None of the entities declared inside a message may have conflicting names. All +of the following are prohibited:

message MyMessage {
+  string foo = 1;
+  message foo {}
+}
+
+message MyMessage {
+  string foo = 1;
+  oneof foo {
+    string bar = 2;
+  }
+}
+
+message MyMessage {
+  string foo = 1;
+  extend Extendable {
+    string foo = 2;
+  }
+}
+
+message MyMessage {
+  string foo = 1;
+  enum E {
+    foo = 0;
+  }
+}
+

Extend

If a message in the same or imported .proto file has reserved a range for +extensions, the message can be extended.

extend = "extend" messageType "{" {field | group} "}"
+

Example:

extend Foo {
+  int32 bar = 126;
+}
+

Service definition

service = "service" serviceName "{" { option | rpc | emptyStatement } "}"
+rpc = "rpc" rpcName "(" [ "stream" ] messageType ")" "returns" "(" [ "stream" ]
+messageType ")" (( "{" { option | emptyStatement } "}" ) | ";" )
+

Example:

service SearchService {
+  rpc Search (SearchRequest) returns (SearchResponse);
+}
+

Proto file

proto = [syntax] { import | package | option | topLevelDef | emptyStatement }
+topLevelDef = message | enum | extend | service
+

An example .proto file:

edition = "2023";
+import public "other.proto";
+option java_package = "com.example.foo";
+enum EnumAllowingAlias {
+  option allow_alias = true;
+  EAA_UNSPECIFIED = 0;
+  EAA_STARTED = 1;
+  EAA_RUNNING = 1;
+  EAA_FINISHED = 2 [(custom_option) = "hello world"];
+}
+message Outer {
+  option (my_option).a = true;
+  message Inner {   // Level 2
+    int64 ival = 1 [features.field_presence = LEGACY_REQUIRED];
+  }
+  repeated Inner inner_message = 2;
+  EnumAllowingAlias enum_field = 3;
+  map<int32, string> my_map = 4;
+  extensions 20 to 30;
+  reserved reserved_field;
+}
+message Foo {
+  message GroupMessage {
+    bool a = 1;
+  }
+  GroupMessage groupmessage = [features.message_encoding = DELIMITED];
+}
+
\ No newline at end of file diff --git a/reference/protobuf/edition-2024-spec/index.html b/reference/protobuf/edition-2024-spec/index.html new file mode 100644 index 000000000..1b026d018 --- /dev/null +++ b/reference/protobuf/edition-2024-spec/index.html @@ -0,0 +1,200 @@ +Protocol Buffers Edition 2024 Language Specification | Protocol Buffers Documentation +

Protocol Buffers Edition 2024 Language Specification

Language specification reference for edition 2024 of the Protocol Buffers language.

The syntax is specified using +Extended Backus-Naur Form (EBNF):

|   alternation
+()  grouping
+[]  option (zero or one time)
+{}  repetition (any number of times)
+

Lexical Elements

Letters and Digits

letter = "A" ... "Z" | "a" ... "z"
+capitalLetter =  "A" ... "Z"
+decimalDigit = "0" ... "9"
+octalDigit   = "0" ... "7"
+hexDigit     = "0" ... "9" | "A" ... "F" | "a" ... "f"
+

Identifiers

ident = letter { letter | decimalDigit | "_" }
+fullIdent = ident { "." ident }
+messageName = ident
+enumName = ident
+fieldName = ident
+oneofName = ident
+mapName = ident
+serviceName = ident
+rpcName = ident
+streamName = ident
+messageType = [ "." ] { ident "." } messageName
+enumType = [ "." ] { ident "." } enumName
+groupName = capitalLetter { letter | decimalDigit | "_" }
+

Integer Literals

intLit     = decimalLit | octalLit | hexLit
+decimalLit = [-] ( "1" ... "9" ) { decimalDigit }
+octalLit   = [-] "0" { octalDigit }
+hexLit     = [-] "0" ( "x" | "X" ) hexDigit { hexDigit }
+

Floating-point Literals

floatLit = [-] ( decimals "." [ decimals ] [ exponent ] | decimals exponent | "."decimals [ exponent ] ) | "inf" | "nan"
+decimals  = [-] decimalDigit { decimalDigit }
+exponent  = ( "e" | "E" ) [ "+" | "-" ] decimals
+

Boolean

boolLit = "true" | "false"
+

String Literals

strLit = strLitSingle { strLitSingle }
+strLitSingle = ( "'" { charValue } "'" ) | ( '"' { charValue } '"' )
+charValue = hexEscape | octEscape | charEscape | unicodeEscape | unicodeLongEscape | /[^\0\n\\]/
+hexEscape = '\' ( "x" | "X" ) hexDigit [ hexDigit ]
+octEscape = '\' octalDigit [ octalDigit [ octalDigit ] ]
+charEscape = '\' ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | '\' | "'" | '"' )
+unicodeEscape = '\' "u" hexDigit hexDigit hexDigit hexDigit
+unicodeLongEscape = '\' "U" ( "000" hexDigit hexDigit hexDigit hexDigit hexDigit |
+                              "0010" hexDigit hexDigit hexDigit hexDigit
+

EmptyStatement

emptyStatement = ";"
+

Constant

constant = fullIdent | ( [ "-" | "+" ] intLit ) | ( [ "-" | "+" ] floatLit ) |
+                strLit | boolLit | MessageValue
+

MessageValue is defined in the +Text Format Language Specification.

Edition

The edition statement replaces the legacy syntax keyword, and is used to +define the edition that this file is using.

edition = "edition" "=" [ ( "'" decimalLit "'" ) | ( '"' decimalLit '"' ) ] ";"
+

Import Statement

The import statement is used to import another .proto’s definitions.

import = "import" [ "public" | "option" ] strLit ";"
+

Example:

import public "other.proto";
+import option "custom_option.proto";
+

Package

The package specifier can be used to prevent name clashes between protocol +message types.

package = "package" fullIdent ";"
+

Example:

package foo.bar;
+

Option

Options can be used in proto files, messages, enums and services. An option can +be a protobuf defined option or a custom option. For more information, see +Options in the +language guide. Options are also be used to control +Feature Settings.

option = "option" optionName  "=" constant ";"
+optionName = ( ident | "(" ["."] fullIdent ")" )
+

For examples:

option java_package = "com.example.foo";
+option features.enum_type = CLOSED;
+

Fields

Fields are the basic elements of a protocol buffer message. Fields can be normal +fields, group fields, oneof fields, or map fields. A field has a label, type and +field number.

label = [ "repeated" ]
+type = "double" | "float" | "int32" | "int64" | "uint32" | "uint64"
+      | "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64"
+      | "bool" | "string" | "bytes" | messageType | enumType
+fieldNumber = intLit;
+

Normal field

Each field has a label, type, name, and field number. It may have field options.

field = [label] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
+fieldOptions = fieldOption { ","  fieldOption }
+fieldOption = optionName "=" constant
+

Examples:

foo.bar nested_message = 2;
+repeated int32 samples = 4 [packed=true];
+

Oneof and oneof field

A oneof consists of oneof fields and a oneof name. Oneof fields do not have +labels.

oneof = "oneof" oneofName "{" { option | oneofField } "}"
+oneofField = type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
+

Example:

oneof foo {
+    string name = 4;
+    SubMessage sub_message = 9;
+}
+

Map field

A map field has a key type, value type, name, and field number. The key type can +be any integral or string type. Note, the key type may not be an enum.

mapField = "map" "<" keyType "," type ">" mapName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
+keyType = "int32" | "int64" | "uint32" | "uint64" | "sint32" | "sint64" |
+          "fixed32" | "fixed64" | "sfixed32" | "sfixed64" | "bool" | "string"
+

Example:

map<string, Project> projects = 3;
+

Extensions and Reserved

Extensions and reserved are message elements that declare a range of field +numbers or field names.

Extensions

Extensions declare that a range of field numbers in a message are available for +third-party extensions. Other people can declare new fields for your message +type with those numeric tags in their own .proto files without having to edit +the original file.

extensions = "extensions" ranges ";"
+ranges = range { "," range }
+range =  intLit [ "to" ( intLit | "max" ) ]
+

Examples:

extensions 100 to 199;
+extensions 4, 20 to max;
+

Reserved

Reserved declares a range of field numbers or names in a message or enum that +can’t be used.

reserved = "reserved" ( ranges | reservedIdent ) ";"
+fieldNames = fieldName { "," fieldName }
+

Examples:

reserved 2, 15, 9 to 11;
+reserved foo, bar;
+

Top Level definitions

Symbol Visibility

Some message and enum definitions can be annotated to override their default +symbol visibility.

This is controlled by features.default_symbol_visibility and symbol visibility is further documented in export / local Keywords

symbolVisibility = "export" | "local"
+

Enum definition

The enum definition consists of a name and an enum body. The enum body can have options, enum fields, and reserved statements.

enum = [ symbolVisibility ] "enum" enumName enumBody
+enumBody = "{" { option | enumField | emptyStatement | reserved } "}"
+enumField = fieldName "=" [ "-" ] intLit [ "[" enumValueOption { ","  enumValueOption } "]" ]";"
+enumValueOption = optionName "=" constant
+

Example:

enum EnumAllowingAlias {
+  option allow_alias = true;
+  EAA_UNSPECIFIED = 0;
+  EAA_STARTED = 1;
+  EAA_RUNNING = 2 [(custom_option) = "hello world"];
+}
+

Message definition

A message consists of a message name and a message body. The message body can +have fields, nested enum definitions, nested message definitions, extend +statements, extensions, groups, options, oneofs, map fields, and reserved +statements. A message cannot contain two fields with the same name in the same +message schema.

message = [ symbolVisibility ] "message" messageName messageBody
+messageBody = "{" { field | enum | message | extend | extensions | group |
+option | oneof | mapField | reserved | emptyStatement } "}"
+

Example:

message Outer {
+  option (my_option).a = true;
+  message Inner {   // Level 2
+    required int64 ival = 1;
+  }
+  map<int32, string> my_map = 2;
+  extensions 20 to 30;
+}
+

None of the entities declared inside a message may have conflicting names. All +of the following are prohibited:

message MyMessage {
+  string foo = 1;
+  message foo {}
+}
+
+message MyMessage {
+  string foo = 1;
+  oneof foo {
+    string bar = 2;
+  }
+}
+
+message MyMessage {
+  string foo = 1;
+  extend Extendable {
+    string foo = 2;
+  }
+}
+
+message MyMessage {
+  string foo = 1;
+  enum E {
+    foo = 0;
+  }
+}
+

Extend

If a message in the same or imported .proto file has reserved a range for +extensions, the message can be extended.

extend = "extend" messageType "{" {field | group} "}"
+

Example:

extend Foo {
+  int32 bar = 126;
+}
+

Service definition

service = "service" serviceName "{" { option | rpc | emptyStatement } "}"
+rpc = "rpc" rpcName "(" [ "stream" ] messageType ")" "returns" "(" [ "stream" ]
+messageType ")" (( "{" { option | emptyStatement } "}" ) | ";" )
+

Example:

service SearchService {
+  rpc Search (SearchRequest) returns (SearchResponse);
+}
+

Proto file

proto = [syntax] { import | package | option | topLevelDef | emptyStatement }
+topLevelDef = message | enum | extend | service
+

An example .proto file:

edition = "2024";
+import public "other.proto";
+import option "custom_option.proto";
+option java_package = "com.example.foo";
+enum EnumAllowingAlias {
+  option allow_alias = true;
+  EAA_UNSPECIFIED = 0;
+  EAA_STARTED = 1;
+  EAA_RUNNING = 1;
+  EAA_FINISHED = 2 [(custom_option) = "hello world"];
+}
+message Outer {
+  option (my_option).a = true;
+  message Inner {   // Level 2
+    int64 ival = 1 [features.field_presence = LEGACY_REQUIRED];
+  }
+  repeated Inner inner_message = 2;
+  EnumAllowingAlias enum_field = 3;
+  map<int32, string> my_map = 4;
+  extensions 20 to 30;
+  reserved reserved_field;
+}
+message Foo {
+  message GroupMessage {
+    bool a = 1;
+  }
+  GroupMessage groupmessage = [features.message_encoding = DELIMITED];
+}
+
\ No newline at end of file diff --git a/reference/protobuf/google.protobuf/index.html b/reference/protobuf/google.protobuf/index.html new file mode 100644 index 000000000..94c3b6f30 --- /dev/null +++ b/reference/protobuf/google.protobuf/index.html @@ -0,0 +1,277 @@ +Protocol Buffers Well-Known Types | Protocol Buffers Documentation +

Protocol Buffers Well-Known Types

API documentation for the google.protobuf package.

Index

Well-Known Types that end in “Value” are wrapper messages for other types, +such as BoolValue and EnumValue. These are now obsolete. The only reasons to +use wrappers today would be:

  • Wire compatibility with messages that already use them.
  • If you want to put a scalar value into an Any message.

In most cases, there are better options:

  • For new messages, it’s better to use regular explicit-presence fields +(optional in proto2/proto3, regular field in edition >= 2023).
  • Extensions are generally a better option than Any fields.

Any

Any contains an arbitrary serialized message along with a URL that describes +the type of the serialized message.

JSON

The JSON representation of an Any value uses the regular representation of the +deserialized, embedded message, with an additional field @type which contains +the type URL. Example:

package google.profile;
+message Person {
+  string first_name = 1;
+  string last_name = 2;
+}
+
{
+  "@type": "type.googleapis.com/google.profile.Person",
+  "firstName": <string>,
+  "lastName": <string>
+}
+

If the embedded message type is well-known and has a custom JSON representation, +that representation will be embedded adding a field value which holds the +custom JSON in addition to the @type field. Example (for message +google.protobuf.Duration):

{
+  "@type": "type.googleapis.com/google.protobuf.Duration",
+  "value": "1.212s"
+}
+
Field nameTypeDescription
type_urlstring

A URL/resource name whose content describes the type of the serialized message.

For URLs which use the schema http, https, or no schema, the following restrictions and interpretations apply:

  • If no schema is provided, https is assumed.
  • The last segment of the URL's path must represent the fully qualified name of the type (as in path/google.protobuf.Duration).
  • An HTTP GET on the URL must yield a google.protobuf.Type value in binary format, or produce an error.
  • Applications are allowed to cache lookup results based on the URL, or have them precompiled into a binary to avoid any lookup. Therefore, binary compatibility needs to be preserved on changes to types. (Use versioned type names to manage breaking changes.)

Schemas other than http, https (or the empty schema) might be used with implementation specific semantics.

valuebytesMust be valid serialized data of the above specified type.

Api

Api is a light-weight descriptor for a protocol buffer service.

Field nameTypeDescription
namestringThe fully qualified name of this api, including package name followed by +the api's simple name.
methodsMethodThe methods of this api, in unspecified order.
optionsOptionAny metadata attached to the API.
versionstring

A version string for this api. If specified, must have the form +major-version.minor-version, as in 1.10. If +the minor version is omitted, it defaults to zero. If the entire +version field is empty, the major version is derived from the package +name, as outlined below. If the field is not empty, the version in the +package name will be verified to be consistent with what is provided +here.

The versioning schema uses +semantic versioning where the major +version number indicates a breaking change and the minor version an +additive, non-breaking change. Both version numbers are signals to +users what to expect from different versions, and should be carefully +chosen based on the product plan.

The major version is also reflected in the package name of the API, +which must end in v<major-version>, as in +google.feature.v1. For major versions 0 and 1, the suffix +can be omitted. Zero major versions must only be used for +experimental, none-GA apis.

source_contextSourceContextSource context for the protocol buffer service represented by this +message.
mixinsMixinIncluded APIs. See +Mixin.
syntaxSyntaxThe source syntax of the service.

BoolValue

Wrapper message for bool.

The JSON representation for BoolValue is JSON true and false.

Field nameTypeDescription
valueboolThe bool value.

BytesValue

Wrapper message for bytes.

The JSON representation for BytesValue is JSON string.

Field nameTypeDescription
valuebytesThe bytes value.

DoubleValue

Wrapper message for double.

The JSON representation for DoubleValue is JSON number.

Field nameTypeDescription
valuedoubleThe double value.

Duration

A Duration represents a signed, fixed-length span of time represented as a count +of seconds and fractions of seconds at nanosecond resolution. It is independent +of any calendar and concepts like "day" or "month". It is related to +Timestamp in that the difference between two Timestamp values is a Duration and +it can be added or subtracted from a Timestamp. Range is approximately +-10,000 +years.

Example 1: Compute Duration from two Timestamps in pseudo code.

Timestamp start = ...;
+Timestamp end = ...;
+Duration duration = ...;
+
+duration.seconds = end.seconds - start.seconds;
+duration.nanos = end.nanos - start.nanos;
+
+if (duration.seconds < 0 && duration.nanos > 0) {
+  duration.seconds += 1;
+  duration.nanos -= 1000000000;
+} else if (duration.seconds > 0 && duration.nanos < 0) {
+  duration.seconds -= 1;
+  duration.nanos += 1000000000;
+}
+

Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.

Timestamp start = ...;
+Duration duration = ...;
+Timestamp end = ...;
+
+end.seconds = start.seconds + duration.seconds;
+end.nanos = start.nanos + duration.nanos;
+
+if (end.nanos < 0) {
+  end.seconds -= 1;
+  end.nanos += 1000000000;
+} else if (end.nanos >= 1000000000) {
+  end.seconds += 1;
+  end.nanos -= 1000000000;
+}
+

The JSON representation for Duration is a String that ends in s to +indicate seconds and is preceded by the number of seconds, with nanoseconds +expressed as fractional seconds.

Field nameTypeDescription
secondsint64Signed seconds of the span of time. Must be from -315,576,000,000 to ++315,576,000,000 inclusive.
nanosint32Signed fractions of a second at nanosecond resolution of the span of +time. Durations less than one second are represented with a 0 +seconds field and a positive or negative +nanos field. For durations of one second or more, a +non-zero value for the nanos field must be of the same sign +as the seconds field. Must be from -999,999,999 to ++999,999,999 inclusive.

Empty

A generic empty message that you can re-use to avoid defining duplicated empty +messages in your APIs. A typical example is to use it as the request or the +response type of an API method. For instance:

service Foo {
+  rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
+}
+

The JSON representation for Empty is empty JSON object {}.

Enum

Enum type definition

Field nameTypeDescription
namestringEnum type name.
enumvalueEnumValueEnum value definitions.
optionsOptionProtocol buffer options.
source_contextSourceContextThe source context.
syntaxSyntaxThe source syntax.
editionstringThe source edition if syntax is SYNTAX_EDITIONS.

EnumValue

Enum value definition.

Field nameTypeDescription
namestringEnum value name.
numberint32Enum value number.
optionsOptionProtocol buffer options.

Field

A single field of a message type.

Field nameTypeDescription
kindKindThe field type.
cardinalityCardinalityThe field cardinality.
numberint32The field number.
namestringThe field name.
type_urlstringThe field type URL, without the scheme, for message or enumeration +types. Example: +"type.googleapis.com/google.protobuf.Timestamp".
oneof_indexint32The index of the field type in Type.oneofs, for message or +enumeration types. The first type has index 1; zero means the type is +not in the list.
packedboolWhether to use alternative packed wire representation.
optionsOptionThe protocol buffer options.
json_namestringThe field JSON name.
default_valuestringThe string value of the default value of this field. Proto2 syntax only.

Cardinality

Whether a field is optional, required, or repeated.

Enum valueDescription
CARDINALITY_UNKNOWNFor fields with unknown cardinality.
CARDINALITY_OPTIONALFor optional fields.
CARDINALITY_REQUIREDFor required fields. Proto2 syntax only.
CARDINALITY_REPEATEDFor repeated fields.

Kind

Basic field types.

Enum valueDescription
TYPE_UNKNOWNField type unknown.
TYPE_DOUBLEField type double.
TYPE_FLOATField type float.
TYPE_INT64Field type int64.
TYPE_UINT64Field type uint64.
TYPE_INT32Field type int32.
TYPE_FIXED64Field type fixed64.
TYPE_FIXED32Field type fixed32.
TYPE_BOOLField type bool.
TYPE_STRINGField type string.
TYPE_GROUPField type group. Proto2 syntax only, and deprecated.
TYPE_MESSAGEField type message.
TYPE_BYTESField type bytes.
TYPE_UINT32Field type uint32.
TYPE_ENUMField type enum.
TYPE_SFIXED32Field type sfixed32.
TYPE_SFIXED64Field type sfixed64.
TYPE_SINT32Field type sint32.
TYPE_SINT64Field type sint64.

FieldMask

FieldMask represents a set of symbolic field paths, for example:

paths: "f.a"
+paths: "f.b.d"
+

Here f represents a field in some root message, a and b fields in the +message found in f, and d a field found in the message in f.b.

Field masks are used to specify a subset of fields that should be returned by a +get operation (a projection), or modified by an update operation. Field masks +also have a custom JSON encoding (see below).

Field Masks in Projections

When a FieldMask specifies a projection, the API will filter the response +message (or sub-message) to contain only those fields specified in the mask. For +example, consider this "pre-masking" response message:

f {
+  a : 22
+  b {
+    d : 1
+    x : 2
+  }
+  y : 13
+}
+z: 8
+

After applying the mask in the previous example, the API response will not +contain specific values for fields x, y, or z (their value will be set to the +default, and omitted in proto text output):

f {
+  a : 22
+  b {
+    d : 1
+  }
+}
+

A repeated field is not allowed except at the last position of a field mask.

If a FieldMask object is not present in a get operation, the operation applies +to all fields (as if a FieldMask of all fields had been specified).

Note that a field mask does not necessarily apply to the top-level response +message. In case of a REST get operation, the field mask applies directly to the +response, but in case of a REST list operation, the mask instead applies to each +individual message in the returned resource list. In case of a REST custom +method, other definitions may be used. Where the mask applies will be clearly +documented together with its declaration in the API. In any case, the effect on +the returned resource/resources is required behavior for APIs.

Field Masks in Update Operations

A field mask in update operations specifies which fields of the targeted +resource are going to be updated. The API is required to only change the values +of the fields as specified in the mask and leave the others untouched. If a +resource is passed in to describe the updated values, the API ignores the values +of all fields not covered by the mask.

In order to reset a field’s value to the default, the field must be in the mask +and set to the default value in the provided resource. Hence, in order to reset +all fields of a resource, provide a default instance of the resource and set all +fields in the mask, or do not provide a mask as described below.

If a field mask is not present on update, the operation applies to all fields +(as if a field mask of all fields has been specified). Note that in the presence +of schema evolution, this may mean that fields the client does not know and has +therefore not filled into the request will be reset to their default. If this is +unwanted behavior, a specific service may require a client to always specify a +field mask, producing an error if not.

As with get operations, the location of the resource which describes the updated +values in the request message depends on the operation kind. In any case, the +effect of the field mask is required to be honored by the API.

Considerations for HTTP REST

The HTTP kind of an update operation which uses a field mask must be set to +PATCH instead of PUT in order to satisfy HTTP semantics (PUT must only be used +for full updates).

JSON Encoding of Field Masks

In JSON, a field mask is encoded as a single string where paths are separated by +a comma. Fields name in each path are converted to/from lower-camel naming +conventions.

As an example, consider the following message declarations:

message Profile {
+  User user = 1;
+  Photo photo = 2;
+}
+message User {
+  string display_name = 1;
+  string address = 2;
+}
+

In proto a field mask for Profile may look as such:

mask {
+  paths: "user.display_name"
+  paths: "photo"
+}
+

In JSON, the same mask is represented as below:

{
+  mask: "user.displayName,photo"
+}
+
Field nameTypeDescription
pathsstringThe set of field mask paths.

FloatValue

Wrapper message for float.

The JSON representation for FloatValue is JSON number.

Field nameTypeDescription
valuefloatThe float value.

Int32Value

Wrapper message for int32.

The JSON representation for Int32Value is JSON number.

Field nameTypeDescription
valueint32The int32 value.

Int64Value

Wrapper message for int64.

The JSON representation for Int64Value is JSON string.

Field nameTypeDescription
valueint64The int64 value.

ListValue

ListValue is a wrapper around a repeated field of values.

The JSON representation for ListValue is JSON array.

Field nameTypeDescription
valuesValueRepeated field of dynamically typed values.

Method

Method represents a method of an api.

Field nameTypeDescription
namestringThe simple name of this method.
request_type_urlstringA URL of the input message type.
request_streamingboolIf true, the request is streamed.
response_type_urlstringThe URL of the output message type.
response_streamingboolIf true, the response is streamed.
optionsOptionAny metadata attached to the method.
syntaxSyntaxThe source syntax of this method.

Mixin

Declares an API to be included in this API. The including API must redeclare all +the methods from the included API, but documentation and options are inherited +as follows:

  • If after comment and whitespace stripping, the documentation string of the +redeclared method is empty, it will be inherited from the original method.

  • Each annotation belonging to the service config (http, visibility) which is +not set in the redeclared method will be inherited.

  • If an http annotation is inherited, the path pattern will be modified as +follows. Any version prefix will be replaced by the version of the including +API plus the root path if specified.

Example of a simple mixin:

package google.acl.v1;
+service AccessControl {
+  // Get the underlying ACL object.
+  rpc GetAcl(GetAclRequest) returns (Acl) {
+    option (google.api.http).get = "/v1/{resource=**}:getAcl";
+  }
+}
+
+package google.storage.v2;
+service Storage {
+  //       rpc GetAcl(GetAclRequest) returns (Acl);
+
+  // Get a data record.
+  rpc GetData(GetDataRequest) returns (Data) {
+    option (google.api.http).get = "/v2/{resource=**}";
+  }
+}
+

Example of a mixin configuration:

apis:
+- name: google.storage.v2.Storage
+  mixins:
+  - name: google.acl.v1.AccessControl
+

The mixin construct implies that all methods in AccessControl are also +declared with same name and request/response types in Storage. A documentation +generator or annotation processor will see the effective Storage.GetAcl method +after inheriting documentation and annotations as follows:

service Storage {
+  // Get the underlying ACL object.
+  rpc GetAcl(GetAclRequest) returns (Acl) {
+    option (google.api.http).get = "/v2/{resource=**}:getAcl";
+  }
+  ...
+}
+

Note how the version in the path pattern changed from v1 to v2.

If the root field in the mixin is specified, it should be a relative path +under which inherited HTTP paths are placed. Example:

apis:
+- name: google.storage.v2.Storage
+  mixins:
+  - name: google.acl.v1.AccessControl
+    root: acls
+

This implies the following inherited HTTP annotation:

service Storage {
+  // Get the underlying ACL object.
+  rpc GetAcl(GetAclRequest) returns (Acl) {
+    option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
+  }
+  ...
+}
+
Field nameTypeDescription
namestringThe fully qualified name of the API which is included.
rootstringIf non-empty specifies a path under which inherited HTTP paths are +rooted.

NullValue

NullValue is a singleton enumeration to represent the null value for the +Value type union.

The JSON representation for NullValue is JSON null.

Enum valueDescription
NULL_VALUENull value.

Option

A protocol buffer option, which can be attached to a message, field, +enumeration, etc.

Field nameTypeDescription
namestringThe option's name. For example, "java_package".
valueAnyThe option's value. For example, +"com.google.protobuf".

SourceContext

SourceContext represents information about the source of a protobuf element, +like the file in which it is defined.

Field nameTypeDescription
file_namestringThe path-qualified name of the .proto file that contained the associated +protobuf element. For example: +"google/protobuf/source.proto".

StringValue

Wrapper message for string.

The JSON representation for StringValue is JSON string.

Field nameTypeDescription
valuestringThe string value.

Struct

Struct represents a structured data value, consisting of fields which map to +dynamically typed values. In some languages, Struct might be supported by a +native representation. For example, in scripting languages like JS a struct is +represented as an object. The details of that representation are described +together with the proto support for the language.

The JSON representation for Struct is JSON object.

Field nameTypeDescription
fieldsmap<string, Value>Map of dynamically typed values.

Syntax

The syntax in which a protocol buffer element is defined.

Enum valueDescription
SYNTAX_PROTO2Syntax proto2.
SYNTAX_PROTO3Syntax proto3.
SYNTAX_EDITIONSSyntax uses the edition construct.

Timestamp

A Timestamp represents a point in time independent of any time zone or calendar, +represented as seconds and fractions of seconds at nanosecond resolution in UTC +Epoch time. It is encoded using the Proleptic Gregorian Calendar which extends +the Gregorian calendar backwards to year one. It is encoded assuming all minutes +are 60 seconds long, i.e. leap seconds are “smeared” so that no leap second +table is needed for interpretation. Range is from 0001-01-01T00:00:00Z to +9999-12-31T23:59:59.999999999Z. By restricting to that range, we ensure that we +can convert to and from RFC 3339 date strings. See +https://www.ietf.org/rfc/rfc3339.txt.

The Timestamp type is encoded as a string in the RFC 3339 format: +“{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z”, where {year} is +always expressed using four digits while {month}, {day}, {hour}, {min}, +and {sec} are zero-padded to two digits each. The fractional seconds, which +can go up to 9 digits (that is, up to 1 nanosecond resolution), are optional. +The “Z” suffix indicates the timezone (“UTC”); the timezone is required. A +proto3 JSON serializer should always use UTC (as indicated by “Z”) when printing +the Timestamp type and a proto3 JSON parser should be able to accept both UTC +and other timezones (as indicated by an offset).

Example 1: Compute Timestamp from POSIX time().

Timestamp timestamp;
+timestamp.set_seconds(time(NULL));
+timestamp.set_nanos(0);
+

Example 2: Compute Timestamp from POSIX gettimeofday().

struct timeval tv;
+gettimeofday(&tv, NULL);
+
+Timestamp timestamp;
+timestamp.set_seconds(tv.tv_sec);
+timestamp.set_nanos(tv.tv_usec * 1000);
+

Example 3: Compute Timestamp from Win32 GetSystemTimeAsFileTime().

FILETIME ft;
+GetSystemTimeAsFileTime(&ft);
+UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
+
+// A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
+// is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
+Timestamp timestamp;
+timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
+timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
+

Example 4: Compute Timestamp from Java System.currentTimeMillis().

long millis = System.currentTimeMillis();
+
+Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
+    .setNanos((int) ((millis % 1000) * 1000000)).build();
+

Example 5: Compute Timestamp from current time in Python.

now = time.time()
+seconds = int(now)
+nanos = int((now - seconds) * 10**9)
+timestamp = Timestamp(seconds=seconds, nanos=nanos)
+
Field nameTypeDescription
secondsint64Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. +Must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive.
nanosint32Non-negative fractions of a second at nanosecond resolution. Negative +second values with fractions must still have non-negative nanos values +that count forward in time. Must be from 0 to 999,999,999 inclusive.

Type

A protocol buffer message type.

Field nameTypeDescription
namestringThe fully qualified message name.
fieldsFieldThe list of fields.
oneofsstringThe list of types appearing in oneof definitions in this +type.
optionsOptionThe protocol buffer options.
source_contextSourceContextThe source context.
syntaxSyntaxThe source syntax.

UInt32Value

Wrapper message for uint32.

The JSON representation for UInt32Value is JSON number.

Field nameTypeDescription
valueuint32The uint32 value.

UInt64Value

Wrapper message for uint64.

The JSON representation for UInt64Value is JSON string.

Field nameTypeDescription
valueuint64The uint64 value.

Value

Value represents a dynamically typed value which can be either null, a number, +a string, a boolean, a recursive struct value, or a list of values. A producer +of value is expected to set one of that variants, absence of any variant +indicates an error.

The JSON representation for Value is JSON value.

Field nameTypeDescription
Union field, only one of the following:
null_valueNullValueRepresents a null value.
number_valuedoubleRepresents a double value. Note that attempting to serialize NaN or +Infinity results in error. (We can't serialize these as string "NaN" or +"Infinity" values like we do for regular fields, because they would +parse as string_value, not number_value).
string_valuestringRepresents a string value.
bool_valueboolRepresents a boolean value.
struct_valueStructRepresents a structured value.
list_valueListValueRepresents a repeated Value.
\ No newline at end of file diff --git a/reference/protobuf/index.html b/reference/protobuf/index.html new file mode 100644 index 000000000..27be457b4 --- /dev/null +++ b/reference/protobuf/index.html @@ -0,0 +1,8 @@ +Protocol Buffers Reference | Protocol Buffers Documentation +

Protocol Buffers Reference

Language-agnostic information about how to use protocol buffers.

Protocol Buffers Edition 2023 Language Specification

Language specification reference for edition 2023 of the Protocol Buffers language.

Protocol Buffers Language Specification (Proto2 Syntax)

Language specification reference for the proto2 syntax and its relationship to Protobuf Editions.

Protocol Buffers Edition 2024 Language Specification

Language specification reference for edition 2024 of the Protocol Buffers language.

Protocol Buffers Language Specification (Proto3)

Language specification reference for the Protocol Buffers language (Proto3).

Text Format Language Specification

The protocol buffer Text Format Language specifies a syntax for representation of protobuf data in text form, which is often useful for configurations or tests.

Protocol Buffer MIME Types

Standard MIME types for Protobuf Serializations.

Protocol Buffers Well-Known Types

API documentation for the google.protobuf package.

\ No newline at end of file diff --git a/reference/protobuf/index.xml b/reference/protobuf/index.xml new file mode 100644 index 000000000..02c91e518 --- /dev/null +++ b/reference/protobuf/index.xml @@ -0,0 +1,9 @@ +Protocol Buffers Reference on Protocol Buffers Documentationhttps://protobuf.dev/reference/protobuf/Recent content in Protocol Buffers Reference on Protocol Buffers DocumentationHugoenProtocol Buffers Edition 2023 Language Specificationhttps://protobuf.dev/reference/protobuf/edition-2023-spec/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/protobuf/edition-2023-spec/The syntax is specified using Extended Backus-Naur Form (EBNF): +| alternation () grouping [] option (zero or one time) {} repetition (any number of times) Lexical Elements Letters and Digits letter = &#34;A&#34; ... &#34;Z&#34; | &#34;a&#34; ... &#34;z&#34; capitalLetter = &#34;A&#34; ... &#34;Z&#34; decimalDigit = &#34;0&#34; ... &#34;9&#34; octalDigit = &#34;0&#34; ... &#34;7&#34; hexDigit = &#34;0&#34; ... &#34;9&#34; | &#34;A&#34; ... &#34;F&#34; | &#34;a&#34; ... &#34;f&#34; Identifiers ident = letter { letter | decimalDigit | &#34;_&#34; } fullIdent = ident { &#34;.Protocol Buffers Language Specification (Proto2 Syntax)https://protobuf.dev/reference/protobuf/proto2-spec/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/protobuf/proto2-spec/The syntax is specified using Extended Backus-Naur Form (EBNF): +| alternation () grouping [] option (zero or one time) {} repetition (any number of times) For more information about using proto2, see the language guide. +Lexical Elements Letters and Digits letter = &#34;A&#34; ... &#34;Z&#34; | &#34;a&#34; ... &#34;z&#34; capitalLetter = &#34;A&#34; ... &#34;Z&#34; decimalDigit = &#34;0&#34; ... &#34;9&#34; octalDigit = &#34;0&#34; ... &#34;7&#34; hexDigit = &#34;0&#34; ... &#34;9&#34; | &#34;A&#34; .Protocol Buffers Edition 2024 Language Specificationhttps://protobuf.dev/reference/protobuf/edition-2024-spec/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/protobuf/edition-2024-spec/The syntax is specified using Extended Backus-Naur Form (EBNF): +| alternation () grouping [] option (zero or one time) {} repetition (any number of times) Lexical Elements Letters and Digits letter = &#34;A&#34; ... &#34;Z&#34; | &#34;a&#34; ... &#34;z&#34; capitalLetter = &#34;A&#34; ... &#34;Z&#34; decimalDigit = &#34;0&#34; ... &#34;9&#34; octalDigit = &#34;0&#34; ... &#34;7&#34; hexDigit = &#34;0&#34; ... &#34;9&#34; | &#34;A&#34; ... &#34;F&#34; | &#34;a&#34; ... &#34;f&#34; Identifiers ident = letter { letter | decimalDigit | &#34;_&#34; } fullIdent = ident { &#34;.Protocol Buffers Language Specification (Proto3)https://protobuf.dev/reference/protobuf/proto3-spec/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/protobuf/proto3-spec/The syntax is specified using Extended Backus-Naur Form (EBNF): +| alternation () grouping [] option (zero or one time) {} repetition (any number of times) For more information about using proto3, see the language guide. +Lexical Elements Letters and Digits letter = &#34;A&#34; ... &#34;Z&#34; | &#34;a&#34; ... &#34;z&#34; decimalDigit = &#34;0&#34; ... &#34;9&#34; octalDigit = &#34;0&#34; ... &#34;7&#34; hexDigit = &#34;0&#34; ... &#34;9&#34; | &#34;A&#34; ... &#34;F&#34; | &#34;a&#34; .Text Format Language Specificationhttps://protobuf.dev/reference/protobuf/textformat-spec/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/protobuf/textformat-spec/This format is distinct from the format of text within a .proto schema, for example. This document contains reference documentation using the syntax specified in ISO/IEC 14977 EBNF. +Note This is a draft spec originally reverse-engineered from the C++ text format implementation It has evolved and may change further based on discussion and review. While an effort has been made to keep text formats consistent across supported languages, incompatibilities are likely to exist.Protocol Buffer MIME Typeshttps://protobuf.dev/reference/protobuf/mime-types/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/protobuf/mime-types/All Protobuf documents should have the MIME type application and the subtype protobuf, with the suffix +json for JSON encodings according to the standard, followed by the following parameters: +encoding should be set only to binary, or json, denoting those respective formats. With subtype protobuf+json, encoding has the default json and cannot be set to binary. With subtype protobuf (without +json), encoding has the default binary and cannot be set to json.Protocol Buffers Well-Known Typeshttps://protobuf.dev/reference/protobuf/google.protobuf/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/protobuf/google.protobuf/Index Any (message) Api (message) BoolValue (message) BytesValue (message) DoubleValue (message) Duration (message) Empty (message) Enum (message) EnumValue (message) Field (message) Field.Cardinality (enum) Field.Kind (enum) FieldMask (message) FloatValue (message) Int32Value (message) Int64Value (message) ListValue (message) Method (message) Mixin (message) NullValue (enum) Option (message) SourceContext (message) StringValue (message) Struct (message) Syntax (enum) Timestamp (message) Type (message) UInt32Value (message) UInt64Value (message) Value (message) Well-Known Types that end in &ldquo;Value&rdquo; are wrapper messages for other types, such as BoolValue and EnumValue. \ No newline at end of file diff --git a/reference/protobuf/mime-types/index.html b/reference/protobuf/mime-types/index.html new file mode 100644 index 000000000..548e4badb --- /dev/null +++ b/reference/protobuf/mime-types/index.html @@ -0,0 +1,29 @@ +Protocol Buffer MIME Types | Protocol Buffers Documentation +

Protocol Buffer MIME Types

Standard MIME types for Protobuf Serializations.

All Protobuf documents should have the MIME type application and the subtype +protobuf, with the suffix +json for +JSON +encodings according to +the standard, +followed by the following parameters:

  • encoding should be set only to binary, +or json, denoting those respective +formats.
    • With subtype protobuf+json, encoding has the default json and +cannot be set to binary. With subtype protobuf (without +json), +encoding has the default binary and cannot be set to +json.
    • Use +json for JSON even in HTTP responses that use parser +breakers as a CORB mitigation.
  • Set charset to utf-8 for all JSONor Text Format encodings, and never set +it for binary encodings.
    • If charset is unspecified it is assumed to be UTF-8. It is preferable +to always specify a charset as that may prevent certain attack vectors +when protos are used in HTTP responses.
  • Protobuf reserves the version parameter for potential future versioning of +our wire formats. Do not set it until a wire format is versioned.

So the standard MIME types for common protobuf encodings are:

  • application/protobuf for serialized binary protos.
  • application/protobuf+json; charset=utf-8 for JSON format protos.

Services that read Protobuf should also handle application/json, which may be +used to encode JSON format protos.

Parsers must fail if MIME parameters (encoding, charset, or version) have +unknown or illegal values.

When binary protos are transacted over HTTP, Protobuf strongly recommends +Base64-encoding them and setting X-Content-Type-Options: nosniff to prevent +XSS, as it is possible for a Protobuf to parse as active content.

It is acceptable to pass additional parameters to these MIME types if desired, +such as a type URL which indicates the content schema; but the MIME type +parameters must not include encoding options.

\ No newline at end of file diff --git a/reference/protobuf/proto2-spec/index.html b/reference/protobuf/proto2-spec/index.html new file mode 100644 index 000000000..734360175 --- /dev/null +++ b/reference/protobuf/proto2-spec/index.html @@ -0,0 +1,209 @@ +Protocol Buffers Language Specification (Proto2 Syntax) | Protocol Buffers Documentation +

Protocol Buffers Language Specification (Proto2 Syntax)

Language specification reference for the proto2 syntax and its relationship to Protobuf Editions.

The syntax is specified using +Extended Backus-Naur Form (EBNF):

|   alternation
+()  grouping
+[]  option (zero or one time)
+{}  repetition (any number of times)
+

For more information about using proto2, see the +language guide.

Lexical Elements

Letters and Digits

letter = "A" ... "Z" | "a" ... "z"
+capitalLetter =  "A" ... "Z"
+decimalDigit = "0" ... "9"
+octalDigit   = "0" ... "7"
+hexDigit     = "0" ... "9" | "A" ... "F" | "a" ... "f"
+

Identifiers

ident = letter { letter | decimalDigit | "_" }
+fullIdent = ident { "." ident }
+messageName = ident
+enumName = ident
+fieldName = ident
+oneofName = ident
+mapName = ident
+serviceName = ident
+rpcName = ident
+streamName = ident
+messageType = [ "." ] { ident "." } messageName
+enumType = [ "." ] { ident "." } enumName
+groupName = capitalLetter { letter | decimalDigit | "_" }
+

Integer Literals

intLit     = decimalLit | octalLit | hexLit
+decimalLit = [-] ( "1" ... "9" ) { decimalDigit }
+octalLit   = [-] "0" { octalDigit }
+hexLit     = [-] "0" ( "x" | "X" ) hexDigit { hexDigit }
+

Floating-point Literals

floatLit = [-] ( decimals "." [ decimals ] [ exponent ] | decimals exponent | "."decimals [ exponent ] ) | "inf" | "nan"
+decimals  = [-] decimalDigit { decimalDigit }
+exponent  = ( "e" | "E" ) [ "+" | "-" ] decimals
+

Boolean

boolLit = "true" | "false"
+

String Literals

strLit = strLitSingle { strLitSingle }
+strLitSingle = ( "'" { charValue } "'" ) | ( '"' { charValue } '"' )
+charValue = hexEscape | octEscape | charEscape | unicodeEscape | unicodeLongEscape | /[^\0\n\\]/
+hexEscape = '\' ( "x" | "X" ) hexDigit [ hexDigit ]
+octEscape = '\' octalDigit [ octalDigit [ octalDigit ] ]
+charEscape = '\' ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | '\' | "'" | '"' )
+unicodeEscape = '\' "u" hexDigit hexDigit hexDigit hexDigit
+unicodeLongEscape = '\' "U" ( "000" hexDigit hexDigit hexDigit hexDigit hexDigit |
+                              "0010" hexDigit hexDigit hexDigit hexDigit
+

EmptyStatement

emptyStatement = ";"
+

Constant

constant = fullIdent | ( [ "-" | "+" ] intLit ) | ( [ "-" | "+" ] floatLit ) |
+                strLit | boolLit | MessageValue
+

MessageValue is defined in the +Text Format Language Specification.

Syntax

The syntax statement is used to define the protobuf version. If syntax is +omitted, the protocol compiler will use proto2. For the sake of clarity, it’s +recommended to always explicitly include a syntax statement in your .proto +files.

syntax = "syntax" "=" ("'" "proto2" "'" | '"' "proto2" '"') ";"
+

Import Statement

The import statement is used to import another .proto’s definitions.

import = "import" [ "weak" | "public" ] strLit ";"
+

Example:

import public "other.proto";
+

Package

The package specifier can be used to prevent name clashes between protocol +message types.

package = "package" fullIdent ";"
+

Example:

package foo.bar;
+

Option

Options can be used in proto files, messages, enums and services. An option can +be a protobuf defined option or a custom option. For more information, see +Options in the +language guide.

option = "option" optionName  "=" constant ";"
+optionName = ( ident | bracedFullIdent ) { "." ( ident | bracedFullIdent ) }
+bracedFullIdent = "(" ["."] fullIdent ")"
+

For examples:

option java_package = "com.example.foo";
+

Fields

Fields are the basic elements of a protocol buffer message. Fields can be normal +fields, group fields, oneof fields, or map fields. A field has a type, name, and +field number. In proto2, fields also have a label (required, optional, or +repeated).

label = "required" | "optional" | "repeated"
+type = "double" | "float" | "int32" | "int64" | "uint32" | "uint64"
+      | "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64"
+      | "bool" | "string" | "bytes" | messageType | enumType
+fieldNumber = intLit;
+

Normal field

Each field has a type, name and field number. It may have field options. Note +that labels are optional only for oneof fields.

field = [ label ] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
+fieldOptions = fieldOption { ","  fieldOption }
+fieldOption = optionName "=" constant
+

Examples:

optional foo.bar nested_message = 2;
+repeated int32 samples = 4 [packed=true];
+

Group field

Note that this feature is deprecated and should not be used when creating new +message types. Use nested message types instead.

Groups are one way to nest information in message definitions. The group name +must begin with capital letter.

group = label "group" groupName "=" fieldNumber messageBody
+

Example:

repeated group Result = 1 {
+    required string url = 1;
+    optional string title = 2;
+    repeated string snippets = 3;
+}
+

Oneof and oneof field

A oneof consists of oneof fields and a oneof name. Oneof fields do not have +labels.

oneof = "oneof" oneofName "{" { option | oneofField } "}"
+oneofField = type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
+

Example:

oneof foo {
+    string name = 4;
+    SubMessage sub_message = 9;
+}
+

Map field

A map field has a key type, value type, name, and field number. The key type can +be any integral or string type. Note, the key type may not be an enum.

mapField = "map" "<" keyType "," type ">" mapName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
+keyType = "int32" | "int64" | "uint32" | "uint64" | "sint32" | "sint64" |
+          "fixed32" | "fixed64" | "sfixed32" | "sfixed64" | "bool" | "string"
+

Example:

map<string, Project> projects = 3;
+

Extensions and Reserved

Extensions and reserved are message elements that declare a range of field +numbers or field names.

Extensions

Extensions declare that a range of field numbers in a message are available for +third-party extensions. Other people can declare new fields for your message +type with those numeric tags in their own .proto files without having to edit +the original file.

extensions = "extensions" ranges ";"
+ranges = range { "," range }
+range =  intLit [ "to" ( intLit | "max" ) ]
+

Examples:

extensions 100 to 199;
+extensions 4, 20 to max;
+

For more on this topic, see +Extension Declarations.

Reserved

Reserved declares a range of field numbers or field names in a message that can +not be used.

reserved = "reserved" ( ranges | strFieldNames ) ";"
+strFieldNames = strFieldName { "," strFieldName }
+strFieldName = "'" fieldName "'" | '"' fieldName '"'
+

Examples:

reserved 2, 15, 9 to 11;
+reserved "foo", "bar";
+

Top Level definitions

Enum definition

The enum definition consists of a name and an enum body. The enum body can have +options, enum fields, and reserved statements.

enum = "enum" enumName enumBody
+enumBody = "{" { option | enumField | emptyStatement | reserved } "}"
+enumField = ident "=" [ "-" ] intLit [ "[" enumValueOption { ","  enumValueOption } "]" ]";"
+enumValueOption = optionName "=" constant
+

Example:

enum EnumAllowingAlias {
+  option allow_alias = true;
+  EAA_UNSPECIFIED = 0;
+  EAA_STARTED = 1;
+  EAA_RUNNING = 2 [(custom_option) = "hello world"];
+}
+

Message definition

A message consists of a message name and a message body. The message body can +have fields, nested enum definitions, nested message definitions, extend +statements, extensions, groups, options, oneofs, map fields, and reserved +statements. A message cannot contain two fields with the same name in the same +message schema.

message = "message" messageName messageBody
+messageBody = "{" { field | enum | message | extend | extensions | group |
+option | oneof | mapField | reserved | emptyStatement } "}"
+

Example:

message Outer {
+  option (my_option).a = true;
+  message Inner {   // Level 2
+    required int64 ival = 1;
+  }
+  map<int32, string> my_map = 2;
+  extensions 20 to 30;
+}
+

None of the entities declared inside a message may have conflicting names. All +of the following are prohibited:

message MyMessage {
+  optional string foo = 1;
+  message foo {}
+}
+
+message MyMessage {
+  optional string foo = 1;
+  oneof foo {
+    string bar = 2;
+  }
+}
+
+message MyMessage {
+  optional string foo = 1;
+  extend Extendable {
+    optional string foo = 2;
+  }
+}
+
+message MyMessage {
+  optional string foo = 1;
+  enum E {
+    foo = 0;
+  }
+}
+

Extend

If a message in the same or imported .proto file has reserved a range for +extensions, the message can be extended.

extend = "extend" messageType "{" {field | group} "}"
+

Example:

extend Foo {
+  optional int32 bar = 126;
+}
+

Service definition

service = "service" serviceName "{" { option | rpc | emptyStatement } "}"
+rpc = "rpc" rpcName "(" [ "stream" ] messageType ")" "returns" "(" [ "stream" ]
+messageType ")" (( "{" { option | emptyStatement } "}" ) | ";" )
+

Example:

service SearchService {
+  rpc Search (SearchRequest) returns (SearchResponse);
+}
+

Proto file

proto = [syntax] { import | package | option | topLevelDef | emptyStatement }
+topLevelDef = message | enum | extend | service
+

An example .proto file:

syntax = "proto2";
+import public "other.proto";
+option java_package = "com.example.foo";
+enum EnumAllowingAlias {
+  option allow_alias = true;
+  EAA_UNSPECIFIED = 0;
+  EAA_STARTED = 1;
+  EAA_RUNNING = 1;
+  EAA_FINISHED = 2 [(custom_option) = "hello world"];
+}
+message Outer {
+  option (my_option).a = true;
+  message Inner {   // Level 2
+    required int64 ival = 1;
+  }
+  repeated Inner inner_message = 2;
+  optional EnumAllowingAlias enum_field = 3;
+  map<int32, string> my_map = 4;
+  extensions 20 to 30;
+}
+message Foo {
+  optional group GroupMessage = 1 {
+    optional bool a = 1;
+  }
+}
+
\ No newline at end of file diff --git a/reference/protobuf/proto3-spec/index.html b/reference/protobuf/proto3-spec/index.html new file mode 100644 index 000000000..99f0051d0 --- /dev/null +++ b/reference/protobuf/proto3-spec/index.html @@ -0,0 +1,164 @@ +Protocol Buffers Language Specification (Proto3) | Protocol Buffers Documentation +

Protocol Buffers Language Specification (Proto3)

Language specification reference for the Protocol Buffers language (Proto3).

The syntax is specified using +Extended Backus-Naur Form (EBNF):

|   alternation
+()  grouping
+[]  option (zero or one time)
+{}  repetition (any number of times)
+

For more information about using proto3, see the +language guide.

Lexical Elements

Letters and Digits

letter = "A" ... "Z" | "a" ... "z"
+decimalDigit = "0" ... "9"
+octalDigit   = "0" ... "7"
+hexDigit     = "0" ... "9" | "A" ... "F" | "a" ... "f"
+

Identifiers

ident = letter { letter | decimalDigit | "_" }
+fullIdent = ident { "." ident }
+messageName = ident
+enumName = ident
+fieldName = ident
+oneofName = ident
+mapName = ident
+serviceName = ident
+rpcName = ident
+messageType = [ "." ] { ident "." } messageName
+enumType = [ "." ] { ident "." } enumName
+

Integer Literals

intLit     = decimalLit | octalLit | hexLit
+decimalLit = [-] ( "1" ... "9" ) { decimalDigit }
+octalLit   = [-] "0" { octalDigit }
+hexLit     = [-] "0" ( "x" | "X" ) hexDigit { hexDigit }
+

Floating-point Literals

floatLit = [-] ( decimals "." [ decimals ] [ exponent ] | decimals exponent | "."decimals [ exponent ] ) | "inf" | "nan"
+decimals  = [-] decimalDigit { decimalDigit }
+exponent  = ( "e" | "E" ) [ "+" | "-" ] decimals
+

Boolean

boolLit = "true" | "false"
+

String Literals

strLit = strLitSingle { strLitSingle }
+strLitSingle = ( "'" { charValue } "'" ) |  ( '"' { charValue } '"' )
+charValue = hexEscape | octEscape | charEscape | unicodeEscape | unicodeLongEscape | /[^\0\n\\]/
+hexEscape = '\' ( "x" | "X" ) hexDigit [ hexDigit ]
+octEscape = '\' octalDigit [ octalDigit [ octalDigit ] ]
+charEscape = '\' ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | '\' | "'" | '"' )
+unicodeEscape = '\' "u" hexDigit hexDigit hexDigit hexDigit
+unicodeLongEscape = '\' "U" ( "000" hexDigit hexDigit hexDigit hexDigit hexDigit |
+                              "0010" hexDigit hexDigit hexDigit hexDigit
+

EmptyStatement

emptyStatement = ";"
+

Constant

constant = fullIdent | ( [ "-" | "+" ] intLit ) | ( [ "-" | "+" ] floatLit ) |
+                strLit | boolLit | MessageValue
+

MessageValue is defined in the +Text Format Language Specification.

Syntax

The syntax statement is used to define the protobuf version.

syntax = "syntax" "=" ("'" "proto3" "'" | '"' "proto3" '"') ";"
+

Example:

syntax = "proto3";
+

Import Statement

The import statement is used to import another .proto’s definitions.

import = "import" [ "weak" | "public" ] strLit ";"
+

Example:

import public "other.proto";
+

Package

The package specifier can be used to prevent name clashes between protocol +message types.

package = "package" fullIdent ";"
+

Example:

package foo.bar;
+

Option

Options can be used in proto files, messages, enums and services. An option can +be a protobuf defined option or a custom option. For more information, see +Options in the +language guide.

option = "option" optionName  "=" constant ";"
+optionName = ( ident | bracedFullIdent ) { "." ( ident | bracedFullIdent ) }
+bracedFullIdent = "(" ["."] fullIdent ")"
+optionNamePart = { ident | "(" ["."] fullIdent ")" }
+

Example:

option java_package = "com.example.foo";
+

Fields

Fields are the basic elements of a protocol buffer message. Fields can be normal +fields, oneof fields, or map fields. A field has a type and field number.

type = "double" | "float" | "int32" | "int64" | "uint32" | "uint64"
+      | "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64"
+      | "bool" | "string" | "bytes" | messageType | enumType
+fieldNumber = intLit;
+

Normal Field

Each field has type, name and field number. It may have field options.

field = [ "repeated" | "optional" ] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
+fieldOptions = fieldOption { ","  fieldOption }
+fieldOption = optionName "=" constant
+

Examples:

foo.Bar nested_message = 2;
+repeated int32 samples = 4 [packed=true];
+

Oneof and Oneof Field

A oneof consists of oneof fields and a oneof name.

oneof = "oneof" oneofName "{" { option | oneofField } "}"
+oneofField = type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
+

Example:

oneof foo {
+    string name = 4;
+    SubMessage sub_message = 9;
+}
+

Map Field

A map field has a key type, value type, name, and field number. The key type can +be any integral or string type.

mapField = "map" "<" keyType "," type ">" mapName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
+keyType = "int32" | "int64" | "uint32" | "uint64" | "sint32" | "sint64" |
+          "fixed32" | "fixed64" | "sfixed32" | "sfixed64" | "bool" | "string"
+

Example:

map<string, Project> projects = 3;
+

Reserved

Reserved statements declare a range of field numbers or field names that cannot +be used in this message.

reserved = "reserved" ( ranges | strFieldNames ) ";"
+ranges = range { "," range }
+range =  intLit [ "to" ( intLit | "max" ) ]
+strFieldNames = strFieldName { "," strFieldName }
+strFieldName = "'" fieldName "'" | '"' fieldName '"'
+

Examples:

reserved 2, 15, 9 to 11;
+reserved "foo", "bar";
+

Top Level Definitions

Enum Definition

The enum definition consists of a name and an enum body. The enum body can have +options, enum fields, and reserved statements.

enum = "enum" enumName enumBody
+enumBody = "{" { option | enumField | emptyStatement | reserved } "}"
+enumField = ident "=" [ "-" ] intLit [ "[" enumValueOption { ","  enumValueOption } "]" ]";"
+enumValueOption = optionName "=" constant
+

Example:

enum EnumAllowingAlias {
+  option allow_alias = true;
+  EAA_UNSPECIFIED = 0;
+  EAA_STARTED = 1;
+  EAA_RUNNING = 2 [(custom_option) = "hello world"];
+}
+

Message Definition

A message consists of a message name and a message body. The message body can +have fields, nested enum definitions, nested message definitions, options, +oneofs, map fields, and reserved statements. A message cannot contain two fields +with the same name in the same message schema.

message = "message" messageName messageBody
+messageBody = "{" { field | enum | message | option | oneof | mapField |
+reserved | emptyStatement } "}"
+

Example:

message Outer {
+  option (my_option).a = true;
+  message Inner {   // Level 2
+    int64 ival = 1;
+  }
+  map<int32, string> my_map = 2;
+}
+

None of the entities declared inside a message may have conflicting names. All +of the following are prohibited:

message MyMessage {
+  optional string foo = 1;
+  message foo {}
+}
+
+message MyMessage {
+  optional string foo = 1;
+  oneof foo {
+    string bar = 2;
+  }
+}
+
+message MyMessage {
+  optional string foo = 1;
+  enum E {
+    foo = 0;
+  }
+}
+

Service Definition

service = "service" serviceName "{" { option | rpc | emptyStatement } "}"
+rpc = "rpc" rpcName "(" [ "stream" ] messageType ")" "returns" "(" [ "stream" ]
+messageType ")" (( "{" {option | emptyStatement } "}" ) | ";")
+

Example:

service SearchService {
+  rpc Search (SearchRequest) returns (SearchResponse);
+}
+

Proto File

proto = [syntax] { import | package | option | topLevelDef | emptyStatement }
+topLevelDef = message | enum | service
+

An example .proto file:

syntax = "proto3";
+import public "other.proto";
+option java_package = "com.example.foo";
+enum EnumAllowingAlias {
+  option allow_alias = true;
+  EAA_UNSPECIFIED = 0;
+  EAA_STARTED = 1;
+  EAA_RUNNING = 1;
+  EAA_FINISHED = 2 [(custom_option) = "hello world"];
+}
+message Outer {
+  option (my_option).a = true;
+  message Inner {   // Level 2
+    int64 ival = 1;
+  }
+  repeated Inner inner_message = 2;
+  EnumAllowingAlias enum_field = 3;
+  map<int32, string> my_map = 4;
+}
+
\ No newline at end of file diff --git a/reference/protobuf/textformat-spec/index.html b/reference/protobuf/textformat-spec/index.html new file mode 100644 index 000000000..48b4e321c --- /dev/null +++ b/reference/protobuf/textformat-spec/index.html @@ -0,0 +1,412 @@ +Text Format Language Specification | Protocol Buffers Documentation +

Text Format Language Specification

The protocol buffer Text Format Language specifies a syntax for representation of protobuf data in text form, which is often useful for configurations or tests.

This format is distinct from the format of text +within a .proto schema, for example. This document contains reference +documentation using the syntax specified in +ISO/IEC 14977 EBNF.

Example

convolution_benchmark {
+  label: "NHWC_128x20x20x56x160"
+  input {
+    dimension: [128, 56, 20, 20]
+    data_type: DATA_HALF
+    format: TENSOR_NHWC
+  }
+}
+

Parsing Overview

The language elements in this spec are split into lexical and syntactic +categories. Lexical elements must match the input text exactly as described, but +syntactic elements may be separated by optional WHITESPACE and COMMENT +tokens.

For example, a signed floating point value comprises two syntactic elements: the +sign (-) and the FLOAT literal. Optional whitespace and comments may exist +between the sign and the number, but not within the number. Example:

value: -2.0   # Valid: no additional whitespace.
+value: - 2.0  # Valid: whitespace between '-' and '2.0'.
+value: -
+  # comment
+  2.0         # Valid: whitespace and comments between '-' and '2.0'.
+value: 2 . 0  # Invalid: the floating point period is part of the lexical
+              # element, so no additional whitespace is allowed.
+

There is one edge case that requires special attention: a number token (FLOAT, +DEC_INT, OCT_INT, or HEX_INT) may not be immediately followed by an +IDENT token. Example:

foo: 10 bar: 20           # Valid: whitespace separates '10' and 'bar'
+foo: 10,bar: 20           # Valid: ',' separates '10' and 'bar'
+foo: 10[com.foo.ext]: 20  # Valid: '10' is followed immediately by '[', which is
+                          # not an identifier.
+foo: 10bar: 20            # Invalid: no space between '10' and identifier 'bar'.
+

Lexical Elements

The lexical elements described below fall into two categories: uppercase primary +elements and lowercase fragments. Only primary elements are included in the +output stream of tokens used during syntactic analysis; fragments exist only to +simplify construction of primary elements.

When parsing input text, the longest matching primary element wins. Example:

value: 10   # '10' is parsed as a DEC_INT token.
+value: 10f  # '10f' is parsed as a FLOAT token, despite containing '10' which
+            # would also match DEC_INT. In this case, FLOAT matches a longer
+            # subsequence of the input.
+

Characters

char    = ? Any non-NUL unicode character ? ;
+newline = ? ASCII #10 (line feed) ? ;
+
+letter = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M"
+       | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
+       | "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m"
+       | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
+       | "_" ;
+
+oct = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" ;
+dec = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
+hex = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
+    | "A" | "B" | "C" | "D" | "E" | "F"
+    | "a" | "b" | "c" | "d" | "e" | "f" ;
+

A limited set of URL characters following +RFC 3986: Uniform Resource Identifier (URI):

url_unreserved  = letter | dec | "-" | "." | "~" | "_"
+url_sub_delim   = "!" | "$" | "&" | "(" | ")"
+                | "*" | "+" | "," | ";" | "="
+url_pct_encoded = "%" hex hex
+url_char        = url_unreserved | url_sub_delim | url_pct_encoded
+

Whitespace and Comments

COMMENT    = "#", { char - newline }, [ newline ] ;
+WHITESPACE = " "
+           | newline
+           | ? ASCII #9  (horizontal tab) ?
+           | ? ASCII #11 (vertical tab) ?
+           | ? ASCII #12 (form feed) ?
+           | ? ASCII #13 (carriage return) ? ;
+

Identifiers

IDENT = letter, { letter | dec } ;
+

Numeric Literals

dec_lit   = "0"
+          | ( dec - "0" ), { dec } ;
+float_lit = ".", dec, { dec }, [ exp ]
+          | dec_lit, ".", { dec }, [ exp ]
+          | dec_lit, exp ;
+exp       = ( "E" | "e" ), [ "+" | "-" ], dec, { dec } ;
+
+DEC_INT   = dec_lit
+OCT_INT   = "0", oct, { oct } ;
+HEX_INT   = "0", ( "X" | "x" ), hex, { hex } ;
+FLOAT     = float_lit, [ "F" | "f" ]
+          | dec_lit,   ( "F" | "f" ) ;
+

Decimal integers can be cast as floating-point values by using the F and f +suffixes. Example:

foo: 10    # This is an integer value.
+foo: 10f   # This is a floating-point value.
+foo: 1.0f  # Also optional for floating-point literals.
+

String Literals

STRING = single_string | double_string ;
+single_string = "'", { escape | char - "'" - newline - "\" }, "'" ;
+double_string = '"', { escape | char - '"' - newline - "\" }, '"' ;
+
+escape = "\a"                        (* ASCII #7  (bell)                 *)
+       | "\b"                        (* ASCII #8  (backspace)            *)
+       | "\f"                        (* ASCII #12 (form feed)            *)
+       | "\n"                        (* ASCII #10 (line feed)            *)
+       | "\r"                        (* ASCII #13 (carriage return)      *)
+       | "\t"                        (* ASCII #9  (horizontal tab)       *)
+       | "\v"                        (* ASCII #11 (vertical tab)         *)
+       | "\?"                        (* ASCII #63 (question mark)        *)
+       | "\\"                        (* ASCII #92 (backslash)            *)
+       | "\'"                        (* ASCII #39 (apostrophe)           *)
+       | '\"'                        (* ASCII #34 (quote)                *)
+       | "\", oct, [ oct, [ oct ] ]  (* octal escaped byte value         *)
+       | "\x", hex, [ hex ]          (* hexadecimal escaped byte value   *)
+       | "\u", hex, hex, hex, hex    (* Unicode code point up to 0xffff  *)
+       | "\U000",
+         hex, hex, hex, hex, hex     (* Unicode code point up to 0xfffff *)
+       | "\U0010",
+         hex, hex, hex, hex ;        (* Unicode code point between 0x100000 and 0x10ffff *)
+

Octal escape sequences consume up to three octal digits. Additional digits are +passed through without escaping. For example, when unescaping the input \1234, +the parser consumes three octal digits (123) to unescape the byte value 0x53 +(ASCII ‘S’, 83 in decimal) and the subsequent ‘4’ passes through as the byte +value 0x34 (ASCII ‘4’). To ensure correct parsing, express octal escape +sequences with 3 octal digits, using leading zeros as needed, such as: \000, +\001, \063, \377. Fewer than three digits are consumed when a non-numeric +character follows the numeric characters, such as \5Hello.

Hexadecimal escape sequences consume up to two hexadecimal digits. For example, +when unescaping \x213, the parser consumes only the first two digits (21) to +unescape the byte value 0x21 (ASCII ‘!’). To ensure correct parsing, express +hexadecimal escape sequences with 2 hexadecimal digits, using leading zeros as +needed, such as: \x00, \x01, \xFF. Fewer than two digits are consumed when +a non-hexadecimal character follows the numeric character, such as \xFHello or +\x3world.

Use byte-wise escaping only for fields with type bytes. While it is possible +to use byte-wise escaping in fields with type string, those escape sequences +are required to form valid UTF-8 sequences. Using byte-wise escaping to express +UTF-8 sequences is error-prone. Prefer unicode escape sequences for unprintable +characters and line-breaking characters in literals for string-type fields.

Longer strings can be broken into several quoted strings on successive lines. +For example:

  quote:
+      "When we got into office, the thing that surprised me most was to find "
+      "that things were just as bad as we'd been saying they were.\n\n"
+      "  -- John F. Kennedy"
+

Unicode code points are interpreted per +Unicode 13 Table A-1 Extended BNF +and are encoded as UTF-8.

Syntax Elements

Message

A message is a collection of fields. A text format file is a single Message.

Message = { Field } ;
+

Literals

Field literal values can be numbers, strings, or identifiers such as true or +enum values.

String             = STRING, { STRING } ;
+Float              = [ "-" ], FLOAT ;
+Identifier         = IDENT ;
+SignedIdentifier   = "-", IDENT ;   (* For example, "-inf" *)
+DecSignedInteger   = "-", DEC_INT ;
+OctSignedInteger   = "-", OCT_INT ;
+HexSignedInteger   = "-", HEX_INT ;
+DecUnsignedInteger = DEC_INT ;
+OctUnsignedInteger = OCT_INT ;
+HexUnsignedInteger = HEX_INT ;
+

A single string value can comprise multiple quoted parts separated by optional +whitespace. Example:

a_string: "first part" 'second part'
+          "third part"
+no_whitespace: "first""second"'third''fourth'
+

Field Names

Fields that are part of the containing message use simple Identifiers as +names. +Extension and +Any field names are +wrapped in square brackets and fully-qualified. Any field names are URI suffix +references, meaning that they are prefixed with a qualifying authority and an +optional path, such as type.googleapis.com/.

FieldName     = ExtensionName | AnyName | IDENT ;
+ExtensionName = "[", TypeName, "]" ;
+AnyName       = "[", UrlPrefix, "/", TypeName, "]" ;
+TypeName      = IDENT, { ".", IDENT } ;
+UrlPrefix     = url_char, { url_char | "/" } ;
+

Text format serializers should not write any whitespace characters or comments +between the brackets of an ExtensionName or AnyName. Parsers should skip any +whitespace characters and comments between the brackets of an ExtensionName or +AnyName. This includes whitespace and comments which split the name into +multiple segments.

Regular fields and extension fields can have scalar or message values. Any +fields are always messages. Example:

reg_scalar: 10
+reg_message { foo: "bar" }
+
+[com.foo.ext.scalar]​: 10
+[com.foo.ext.message] { foo: "bar" }
+
+any_value {
+  [type.googleapis.com/com.foo.any] { foo: "bar" }
+}
+

Unknown Fields

Text format parsers cannot support unknown fields represented as raw field +numbers in place of field names because three of the six wire types are +represented in the same way in textformat. Some text-format serializer +implementations encode unknown fields with a format that uses a field number and +a numeric representation of the value, but this is inherently lossy because the +wire-type information is ignored. For comparison, wire-format is non-lossy +because it includes the wire-type in each field tag as (field_number << 3) | wire_type. For more information on encoding, see the +Encoding topic.

Without information about the field type from the message schema, the value +cannot be correctly encoded into a wire-format proto message.

Fields

Field values can be literals (strings, numbers, or identifiers), or nested +messages.

Field        = ScalarField | MessageField ;
+MessageField = FieldName, [ ":" ], ( MessageValue | MessageList ) [ ";" | "," ];
+ScalarField  = FieldName, ":",     ( ScalarValue  | ScalarList  ) [ ";" | "," ];
+MessageList  = "[", [ MessageValue, { ",", MessageValue } ], "]" ;
+ScalarList   = "[", [ ScalarValue,  { ",", ScalarValue  } ], "]" ;
+MessageValue = "{", Message, "}" | "<", Message, ">" ;
+ScalarValue  = String
+             | Float
+             | Identifier
+             | SignedIdentifier
+             | DecSignedInteger
+             | OctSignedInteger
+             | HexSignedInteger
+             | DecUnsignedInteger
+             | OctUnsignedInteger
+             | HexUnsignedInteger ;
+

The : delimiter between the field name and value is required for scalar fields +but optional for message fields (including lists). Example:

scalar: 10          # Valid
+scalar  10          # Invalid
+scalars: [1, 2, 3]  # Valid
+scalars  [1, 2, 3]  # Invalid
+message: {}         # Valid
+message  {}         # Valid
+messages: [{}, {}]  # Valid
+messages  [{}, {}]  # Valid
+

Values of message fields can be surrounded by curly brackets +or angle brackets:

message: { foo: "bar" }
+message: < foo: "bar" >
+

Fields marked repeated can have multiple values specified by repeating the +field, using the special [] list syntax, or some combination of both. The +order of values is maintained. Example:

repeated_field: 1
+repeated_field: 2
+repeated_field: [3, 4, 5]
+repeated_field: 6
+repeated_field: [7, 8, 9]
+

is equivalent to:

repeated_field: [1, 2, 3, 4, 5, 6, 7, 8, 9]
+

Non-repeated fields cannot use the list syntax. For example, [0] is not +valid for optional or required fields. Fields marked optional can be +omitted or specified once. Fields marked required must be specified exactly +once. required is a legacy feature of proto2 and is not available in proto3. +Backward compatibility is available for messages in Editions using +features.field_presence = LEGACY_REQUIRED.

Fields not specified in the associated .proto message are not allowed unless +the field name is present in the message’s reserved field list. reserved +fields, if present in any form (scalar, list, message), are simply ignored by +text format.

Value Types

When a field’s associated .proto value type is known, the following value +descriptions and constraints apply. For the purposes of this section, we declare +the following container elements:

signedInteger   = DecSignedInteger | OctSignedInteger | HexSignedInteger ;
+unsignedInteger = DecUnsignedInteger | OctUnsignedInteger | HexUnsignedInteger ;
+integer         = signedInteger | unsignedInteger ;
+
.proto TypeValues
float, doubleA Float, DecSignedInteger, or +DecUnsignedInteger element, or an Identifier +or SignedIdentifier element whose IDENT +portion is equal to "inf", "infinity", or +"nan" (case-insensitive). Overflows are treated as infinity or +-infinity. Octal and hexadecimal values are not valid.

Note: "nan" should be interpreted as Quiet NaN

int32, sint32, sfixed32Any of the integer elements in the range +-0x80000000 to 0x7FFFFFFF.
int64, sint64, sfixed64Any of the integer elements in the range +-0x8000000000000000 to 0x7FFFFFFFFFFFFFFF.
uint32, fixed32Any of the unsignedInteger elements in the range +0 to 0xFFFFFFFF. Note that signed values +(-0) are not valid.
uint64, fixed64Any of the unsignedInteger elements in the range +0 to 0xFFFFFFFFFFFFFFFF. Note that signed +values (-0) are not valid.
stringA String element containing valid UTF-8 data. Any escape +sequences must form valid UTF-8 byte sequences when unescaped.
bytesA String element, possibly including invalid UTF-8 escape +sequences.
boolAn Identifier element or any of the +unsignedInteger elements matching one of the following +values.
True values: "True", "true", +"t", 1
False values: "False", "false", +"f", 0
Any unsigned integer representation of 0 or 1 +is permitted: 00, 0x0, 01, +0x1, etc.
enum valuesAn Identifier element containing an enum value name, or any +of the integer elements in the range +-0x80000000 to 0x7FFFFFFF containing an enum +value number. It is not valid to specify a name that is not a +member of the field's enum type definition. Depending on +the particular protobuf runtime implementation, it may or may not be +valid to specify a number that is not a member of the field's +enum type definition. Text format processors not tied to a +particular runtime implementation (such as IDE support) may choose to +issue a warning when a provided number value is not a valid member. Note +that certain names that are valid keywords in other contexts, such as +"true" or "infinity", are also valid enum value names.
message valuesA MessageValue element.

Extension Fields

Extension fields are specified using their qualified names. Example:

local_field: 10
+[com.example.ext_field]​: 20
+

Extension fields are generally defined in other .proto files. The text format +language does not provide a mechanism for specifying the locations of files that +define extension fields; instead, the parser must have prior knowledge of their +locations.

Any Fields

Text format supports an expanded form of the +google.protobuf.Any +well-known type using a special syntax resembling extension fields. Example:

local_field: 10
+
+# An Any value using regular fields.
+any_value {
+  type_url: "type.googleapis.com/com.example.SomeType"
+  value: "\x0a\x05hello"  # serialized bytes of com.example.SomeType
+}
+
+# The same value using Any expansion
+any_value {
+  [type.googleapis.com/com.example.SomeType] {
+    field1: "hello"
+  }
+}
+

In this example, any_value is a field of type google.protobuf.Any, and it +stores a serialized com.example.SomeType message containing field1: hello.

group Fields

In text format, a group field uses a normal MessageValue element as its +value, but is specified using the capitalized group name rather than the +implicit lower-cased field name. Example:

// proto2
+message MessageWithGroup {
+  optional group MyGroup = 1 {
+    optional int32 my_value = 1;
+  }
+}
+

With the above .proto definition, the following text format is a valid +MessageWithGroup:

MyGroup {
+  my_value: 1
+}
+

Similar to Message fields, the : delimiter between the group name and value is +optional.

This functionality is included in Editions for backward-compatibility. Normally +DELIMITED fields will serialize like normal messages. The following shows the +behavior with Editions:

edition = "2024";
+
+message Parent {
+  message GroupLike {
+    int32 foo = 1;
+  }
+  GroupLike grouplike = 1 [features.message_encoding = DELIMITED];
+}
+

The content of that .proto file will be serialized like a proto2 group:

GroupLike {
+  foo: 2;
+}
+

map Fields

Text format does not provide a custom syntax for specifying map field entries. +When a map field is defined in a .proto file, an implicit Entry message is +defined containing key and value fields. Map fields are always repeated, +accepting multiple key/value entries. Example:

// Editions
+edition = "2024";
+
+message MessageWithMap {
+  map<string, int32> my_map = 1;
+}
+

With the above .proto definition, the following text format is a valid +MessageWithMap:

my_map { key: "entry1" value: 1 }
+my_map { key: "entry2" value: 2 }
+
+# You can also use the list syntax
+my_map: [
+  { key: "entry3" value: 3 },
+  { key: "entry4" value: 4 }
+]
+

Both the key and value fields are optional and default to the zero value of +their respective types if unspecified. If a key is duplicated, only the +last-specified value will be retained in a parsed map.

The order of maps is not maintained in textprotos.

oneof Fields

While there is no special syntax related to oneof fields in text format, only +one oneof member may be specified at a time. Specifying multiple members +concurrently is not valid. Example:

// Editions
+edition = "2024";
+
+message OneofExample {
+  message MessageWithOneof {
+    string not_part_of_oneof = 1;
+    oneof Example {
+      string first_oneof_field = 2;
+      string second_oneof_field = 3;
+    }
+  }
+  repeated MessageWithOneof message = 1;
+}
+

The above .proto definition results in the following text format behavior:

# Valid: only one field from the Example oneof is set.
+message {
+  not_part_of_oneof: "always valid"
+  first_oneof_field: "valid by itself"
+}
+
+# Valid: the other oneof field is set.
+message {
+  not_part_of_oneof: "always valid"
+  second_oneof_field: "valid by itself"
+}
+
+# Invalid: multiple fields from the Example oneof are set.
+message {
+  not_part_of_oneof: "always valid"
+  first_oneof_field: "not valid"
+  second_oneof_field: "not valid"
+}
+

Text Format Files

A text format file uses the .txtpb filename suffix and contains a single +Message. Text format files are UTF-8 encoded. An example textproto file is +provided below.

# This is an example of Protocol Buffer's text format.
+# Unlike .proto files, only shell-style line comments are supported.
+
+name: "John Smith"
+
+pet {
+  kind: DOG
+  name: "Fluffy"
+  tail_wagginess: 0.65f
+}
+
+pet <
+  kind: LIZARD
+  name: "Lizzy"
+  legs: 4
+>
+
+string_value_with_escape: "valid \n escape"
+repeated_values: [ "one", "two", "three" ]
+

The header comments proto-file and proto-message inform developer tools of +the schema, so they may provide various features.

# proto-file: some/proto/my_file.proto
+# proto-message: MyMessage
+

Working with the Format Programmatically

Due to how individual Protocol Buffer implementations emit +neither a consistent nor canonical text format, +tools or libraries that modify TextProto files or emit TextProto output must +explicitly use +https://github.com/protocolbuffers/txtpbfmt +to format their output.

\ No newline at end of file diff --git a/reference/python/api-docs-link/index.html b/reference/python/api-docs-link/index.html new file mode 100644 index 000000000..6583331bf --- /dev/null +++ b/reference/python/api-docs-link/index.html @@ -0,0 +1,4 @@ +Python API | Protocol Buffers Documentation +
\ No newline at end of file diff --git a/reference/python/index.html b/reference/python/index.html new file mode 100644 index 000000000..7247edbc7 --- /dev/null +++ b/reference/python/index.html @@ -0,0 +1,8 @@ +Python Reference | Protocol Buffers Documentation +

Python Reference

Reference documentation for working with protocol buffer classes in Python.

Python Generated Code Guide

Describes exactly what Python definitions the protocol buffer compiler generates for any given protocol definition.

Python Comparison

Describes how Python compares objects.

Python API

\ No newline at end of file diff --git a/reference/python/index.xml b/reference/python/index.xml new file mode 100644 index 000000000..a5ebfb611 --- /dev/null +++ b/reference/python/index.xml @@ -0,0 +1,3 @@ +Python Reference on Protocol Buffers Documentationhttps://protobuf.dev/reference/python/Recent content in Python Reference on Protocol Buffers DocumentationHugoenPython Generated Code Guidehttps://protobuf.dev/reference/python/python-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/python/python-generated/Any differences between proto2, proto3, and Editions generated code are highlighted - note that these differences are in the generated code as described in this document, not the base message classes/interfaces, which are the same across all versions. You should read the proto2 language guide, proto3 language guide, and/or Editions guide before reading this document. +The Python Protocol Buffers implementation is a little different from C++ and Java. In Python, the compiler only outputs code to build descriptors for the generated classes, and a Python metaclass does the real work.Python Comparisonhttps://protobuf.dev/reference/python/python-comparison/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/python/python-comparison/Because of how proto data is serialized, you cannot rely on the wire representation of a proto message instance to determine if its content is the same as another instance. A subset of the ways that a wire-format proto message instance can vary include the following: +The protobuf schema changes in certain ways. A map field stores its values in a different order. The binary is built with different flags (such as opt vs.Python APIhttps://protobuf.dev/reference/python/api-docs-link/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/python/api-docs-link/ \ No newline at end of file diff --git a/reference/python/python-comparison/index.html b/reference/python/python-comparison/index.html new file mode 100644 index 000000000..83b4adfde --- /dev/null +++ b/reference/python/python-comparison/index.html @@ -0,0 +1,44 @@ +Python Comparison | Protocol Buffers Documentation +

Python Comparison

Describes how Python compares objects.

Because of how proto data is serialized, you cannot rely on the wire +representation of a proto message instance to determine if its content is the +same as another instance. A subset of the ways that a wire-format proto message +instance can vary include the following:

  • The protobuf schema changes in certain ways.
  • A map field stores its values in a different order.
  • The binary is built with different flags (such as opt vs. debug).
  • The protobuf library is updated.

Because of these ways that serialized data can vary, determining equality +involves other methods.

Comparison Methods

You can compare protocol buffer messages for equality using the standard Python +== operator. Comparing two objects using the == operator compares with +message.ListFields(). When testing, you can use self.assertEqual(msg1, msg2).

Two messages are considered equal if they have the same type and all of their +corresponding fields are equal. The inequality operator != is the exact +inverse of ==.

Message equality is recursive: for two messages to be equal, any nested messages +must also be equal.

Field Equality and Presence

The equality check for fields is value-based. For fields with +explicit presence, the presence of a field is also taken +into account.

A field that is explicitly set to its default value is not considered equal +to a field that is unset.

For example, consider the following message which has an explicit presence +field:

edition = "2023";
+message MyMessage {
+  int32 value = 1; // 'explicit' presence by default in Editions
+}
+

If you create two instances, one where value is unset and one where value is +explicitly set to 0, they will not be equal:

msg1 = MyMessage()
+msg2 = MyMessage()
+msg2.value = 0
+
+assert not msg1.HasField("value")
+assert msg2.HasField("value")
+assert msg1 != msg2
+

This same principle applies to sub-message fields: an unset sub-message is not +equal to a sub-message that is present but empty (a default instance of the +sub-message class).

For fields with implicit presence, since presence cannot +be tracked, the field is always compared by its value against the corresponding +field in the other message.

This behavior, where presence is part of the equality check, is different from +how some other languages or protobuf libraries might handle equality, where +unset fields and fields set to their default value are sometimes treated as +equivalent (often for wire-format compatibility). In Python, == performs a +stricter check.

Other Field Types

  • Repeated fields are equal if they have the same number of elements and +each corresponding element is equal. The order of elements matters.
  • Map fields are equal if they have the same set of key-value pairs. The +order of pairs does not matter.
  • Floating-point fields (float and double) are compared by value. Be +aware of the usual caveats with floating-point comparisons.
\ No newline at end of file diff --git a/reference/python/python-generated/index.html b/reference/python/python-generated/index.html new file mode 100644 index 000000000..6fdf699c5 --- /dev/null +++ b/reference/python/python-generated/index.html @@ -0,0 +1,588 @@ +Python Generated Code Guide | Protocol Buffers Documentation +

Python Generated Code Guide

Describes exactly what Python definitions the protocol buffer compiler generates for any given protocol definition.

Any +differences between proto2, proto3, and Editions generated code are +highlighted - note that these differences are in the generated code as described +in this document, not the base message classes/interfaces, which are the same +across all versions. You should read the +proto2 language guide, +proto3 language guide, +and/or Editions guide +before reading this document.

The Python Protocol Buffers implementation is a little different from C++ and +Java. In Python, the compiler only outputs code to build descriptors for the +generated classes, and a +Python metaclass +does the real work. This document describes what you get after the metaclass +has been applied.

Compiler Invocation

The protocol buffer compiler produces Python output when invoked with the +--python_out= command-line flag. The parameter to the --python_out= option +is the directory where you want the compiler to write your Python output. The +compiler creates a .py file for each .proto file input. The names of the +output files are computed by taking the name of the .proto file and making two +changes:

  • The extension (.proto) is replaced with _pb2.py.
  • The proto path (specified with the --proto_path= or -I command-line +flag) is replaced with the output path (specified with the --python_out= +flag).

So, for example, let’s say you invoke the compiler as follows:

protoc --proto_path=src --python_out=build/gen src/foo.proto src/bar/baz.proto
+

The compiler will read the files src/foo.proto and src/bar/baz.proto and +produce two output files: build/gen/foo_pb2.py and build/gen/bar/baz_pb2.py. +The compiler will automatically create the directory build/gen/bar if +necessary, but it will not create build or build/gen; they must already +exist.

Protoc can generate Python stubs (.pyi) using the --pyi_out parameter.

Note that if the .proto file or its path contains any characters which cannot +be used in Python module names (for example, hyphens), they will be replaced +with underscores. So, the file foo-bar.proto becomes the Python file +foo_bar_pb2.py.

Packages

The Python code generated by the protocol buffer compiler is completely +unaffected by the package name defined in the .proto file. Instead, Python +packages are identified by directory structure.

Messages

Given a simple message declaration:

message Foo {}
+

The protocol buffer compiler generates a class called Foo, which subclasses +google.protobuf.Message. +The class is a concrete class; no abstract methods are left unimplemented. +Unlike C++ and Java, Python generated code is unaffected by the optimize_for +option in the .proto file; in effect, all Python code is optimized for code +size.

If the message’s name is a Python keyword, then its class will only be +accessible via getattr(), as described in the +Names that conflict with Python keywords section.

You should not create your own Foo subclasses. Generated classes are not +designed for subclassing and may lead to "fragile base class" problems. +Besides, implementation inheritance is bad design.

Python message classes have no particular public members other than those +defined by the Message interface and those generated for nested fields, +messages, and enum types (described below). Message provides methods you can +use to check, manipulate, read, or write the entire message, including parsing +from and serializing to binary strings. In addition to these methods, the Foo +class defines the following static methods:

  • FromString(s): Returns a new message instance deserialized from the given +string.

Note that you can also use the +text_format +module to work with protocol messages in text format: for example, the Merge() +method lets you merge an ASCII representation of a message into an existing +message.

Nested Types

A message can be declared inside another message. For example:

message Foo {
+  message Bar {}
+}
+

In this case, the Bar class is declared as a static member of Foo, so you +can refer to it as Foo.Bar.

Well-known Types

Protocol buffers provides a number of +well-known types +that you can use in your .proto files along with your own message types. Some +WKT messages have special methods in addition to the usual protocol buffer +message methods, as they subclass both +google.protobuf.Message +and a WKT class.

Any

For Any messages, you can call Pack() to pack a specified message into the +current Any message, or Unpack() to unpack the current Any message into a +specified message. For example:

any_message.Pack(message)
+any_message.Unpack(message)
+

Unpack() also checks the descriptor of the passed-in message object against +the stored one and returns False if they don’t match and does not attempt any +unpacking; True otherwise.

You can also call the Is() method to check if the Any message represents the +given protocol buffer type. For example:

assert any_message.Is(message.DESCRIPTOR)
+

Use the TypeName() method to retrieve the protobuf type name of an inner +message.

Timestamp

Timestamp messages can be converted to/from RFC 3339 date string format (JSON +string) using the ToJsonString()/FromJsonString() methods. For example:

timestamp_message.FromJsonString("1970-01-01T00:00:00Z")
+assert timestamp_message.ToJsonString() == "1970-01-01T00:00:00Z"
+

You can also call GetCurrentTime() to fill the Timestamp message with current +time:

timestamp_message.GetCurrentTime()
+

To convert between other time units since epoch, you can call ToNanoseconds(), FromNanoseconds(), ToMicroseconds(), FromMicroseconds(), ToMilliseconds(), FromMilliseconds(), ToSeconds(), or FromSeconds(). The generated code also +has ToDatetime() and FromDatetime() methods to convert between Python +datetime objects and Timestamps. For example:

timestamp_message.FromMicroseconds(-1)
+assert timestamp_message.ToMicroseconds() == -1
+dt = datetime(2016, 1, 1)
+timestamp_message.FromDatetime(dt)
+self.assertEqual(dt, timestamp_message.ToDatetime())
+

Duration

Duration messages have the same methods as Timestamp to convert between JSON +string and other time units. To convert between timedelta and Duration, you can +call ToTimedelta() or FromTimedelta. For example:

duration_message.FromNanoseconds(1999999999)
+td = duration_message.ToTimedelta()
+assert td.seconds == 1
+assert td.microseconds == 999999
+

FieldMask

FieldMask messages can be converted to/from JSON string using the +ToJsonString()/FromJsonString() methods. In addition, a FieldMask message +has the following methods:

  • IsValidForDescriptor(message_descriptor): Checks whether the FieldMask is +valid for Message Descriptor.
  • AllFieldsFromDescriptor(message_descriptor): Gets all direct fields of +Message Descriptor to FieldMask.
  • CanonicalFormFromMask(mask): Converts a FieldMask to the canonical form.
  • Union(mask1, mask2): Merges two FieldMasks into this FieldMask.
  • Intersect(mask1, mask2): Intersects two FieldMasks into this FieldMask.
  • MergeMessage(source, destination, replace_message_field=False, replace_repeated_field=False): Merges fields specified in FieldMask from +source to destination.

Struct

Struct messages let you get and set the items directly. For example:

struct_message["key1"] = 5
+struct_message["key2"] = "abc"
+struct_message["key3"] = True
+

To get or create a list/struct, you can call +get_or_create_list()/get_or_create_struct(). For example:

struct.get_or_create_struct("key4")["subkey"] = 11.0
+struct.get_or_create_list("key5")
+

ListValue

A ListValue message acts like a Python sequence that lets you do the following:

list_value = struct_message.get_or_create_list("key")
+list_value.extend([6, "seven", True, None])
+list_value.append(False)
+assert len(list_value) == 5
+assert list_value[0] == 6
+assert list_value[1] == "seven"
+assert list_value[2] == True
+assert list_value[3] == None
+assert list_Value[4] == False
+

To add a ListValue/Struct, call add_list()/add_struct(). For example:

list_value.add_struct()["key"] = 1
+list_value.add_list().extend([1, "two", True])
+

Fields

For each field in a message type, the corresponding class has a property with +the same name as the field. How you can manipulate the property depends on its +type.

As well as a property, the compiler generates an integer constant for each field +containing its field number. The constant name is the field name converted to +upper-case followed by _FIELD_NUMBER. For example, given the field int32 foo_bar = 5;, the compiler will generate the constant FOO_BAR_FIELD_NUMBER = 5.

If the field’s name is a Python keyword, then its property will only be +accessible via getattr() and setattr(), as described in the +Names that conflict with Python keywords section.

Protocol buffers defines two modes of field presence: explicit and implicit. +Each of these is described in the following sections.

Singular Fields with Explicit Presence

Singular fields with explicit presence are always able to differentiate +between the field being unset and the field being set to its default value.

If you have a singular field foo of any non-message type, you can manipulate +the field foo as if it were a regular field. For example, if foo’s type is +int32, you can say:

message.foo = 123
+print(message.foo)
+

Note that setting foo to a value of the wrong type will raise a TypeError.

If foo is read when it is not set, its value is the default value for that +field. To check if foo is set, or to clear the value of foo, you must call +the HasField() or ClearField() methods of the +Message +interface. For example:

assert not message.HasField("foo")
+message.foo = 123
+assert message.HasField("foo")
+message.ClearField("foo")
+assert not message.HasField("foo")
+

In Editions, fields have explicit presence by default. The following is an +example of an explicit field in an Editions .proto file:

edition = "2023";
+message MyMessage {
+  int32 foo = 1;
+}
+

Singular Fields with Implicit Presence

Singular fields with implicit presence do not have a HasField() method. An +implicit field is always “set” and reading the field will always return a +value. Reading an implicit field that has not been assigned a value will +return the default value for that type.

If you have a singular field foo of any non-message type, you can manipulate +the field foo as if it were a regular field. For example, if foo’s type is +int32, you can say:

message.foo = 123
+print(message.foo)
+

Note that setting foo to a value of the wrong type will raise a TypeError.

If foo is read when it is not set, its value is the default value for that +field. To clear the value of foo and reset it to the default value for its +type, you call the ClearField() method of the +Message +interface. For example:

message.foo = 123
+message.ClearField("foo")
+

Singular Message Fields

Message types work slightly differently. You cannot assign a value to an +embedded message field. Instead, assigning a value to any field within the child +message implies setting the message field in the parent. Submessages always have +explicit presence, so you can also use the +parent message’s HasField() method to check if a message type field value has +been set.

So, for example, let’s say you have the following .proto definition:

edition = "2023";
+message Foo {
+  Bar bar = 1;
+}
+message Bar {
+  int32 i = 1;
+}
+

You cannot do the following:

foo = Foo()
+foo.bar = Bar()  # WRONG!
+

Instead, to set bar, you simply assign a value directly to a field within +bar, and - presto! - foo has a bar field:

foo = Foo()
+assert not foo.HasField("bar")
+foo.bar.i = 1
+assert foo.HasField("bar")
+assert foo.bar.i == 1
+foo.ClearField("bar")
+assert not foo.HasField("bar")
+assert foo.bar.i == 0  # Default value
+

Similarly, you can set bar using the +Message +interface’s CopyFrom() method. This copies all the values from another message +of the same type as bar.

foo.bar.CopyFrom(baz)
+

Note that simply reading a field inside bar does not set the field:

foo = Foo()
+assert not foo.HasField("bar")
+print(foo.bar.i)  # Print i's default value
+assert not foo.HasField("bar")
+

If you need the "has" bit on a message that does not have any fields you can +or want to set, you may use the SetInParent() method.

foo = Foo()
+assert not foo.HasField("bar")
+foo.bar.SetInParent()  # Set Foo.bar to a default Bar message
+assert foo.HasField("bar")
+

Repeated Fields

There are three types of repeated fields: scalar, enum, and message. Map fields +and oneof fields cannot be repeated.

Repeated Scalar and Enum Fields

Repeated fields are represented as an object that acts like a Python sequence. +As with embedded messages, you cannot assign the field directly, but you can +manipulate it. For example, given this message definition:

message Foo {
+  repeated int32 nums = 1;
+}
+

You can do the following:

foo = Foo()
+foo.nums.append(15)        # Appends one value
+foo.nums.extend([32, 47])  # Appends an entire list
+
+assert len(foo.nums) == 3
+assert foo.nums[0] == 15
+assert foo.nums[1] == 32
+assert foo.nums == [15, 32, 47]
+
+foo.nums[:] = [33, 48]     # Assigns an entire list
+assert foo.nums == [33, 48]
+
+foo.nums[1] = 56    # Reassigns a value
+assert foo.nums[1] == 56
+for i in foo.nums:  # Loops and print
+  print(i)
+del foo.nums[:]     # Clears list (works just like in a Python list)
+

The ClearField() method of the +Message +interface works in addition to using Python del.

When using the index to retrieve a value, you can use negative numbers, such as +using -1 to retrieve the last element in the list. If your index goes out of +bounds, you’ll get an IndexError: list index out of range.

Repeated Message Fields

Repeated message fields work similar to repeated scalar fields. However, the +corresponding Python object also has an add() method that creates a new +message object, appends it to the list, and returns it for the caller to fill +in. Also, the object’s append() method makes a copy of the given message +and appends that copy to the list. This is done so that messages are always +owned by the parent message to avoid circular references and other confusion +that can happen when a mutable data structure has multiple owners. Similarly, +the object’s extend() method appends an entire list of messages, but makes a +copy of every message in the list.

For example, given this message definition:

edition = "2023";
+message Foo {
+  repeated Bar bars = 1;
+}
+message Bar {
+  int32 i = 1;
+  int32 j = 2;
+}
+

You can do the following:

foo = Foo()
+bar = foo.bars.add()        # Adds a Bar then modify
+bar.i = 15
+foo.bars.add().i = 32       # Adds and modify at the same time
+new_bar = Bar()
+new_bar.i = 40
+another_bar = Bar()
+another_bar.i = 57
+foo.bars.append(new_bar)        # Uses append() to copy
+foo.bars.extend([another_bar])  # Uses extend() to copy
+
+assert len(foo.bars) == 4
+assert foo.bars[0].i == 15
+assert foo.bars[1].i == 32
+assert foo.bars[2].i == 40
+assert foo.bars[2] == new_bar      # The appended message is equal,
+assert foo.bars[2] is not new_bar  # but it is a copy!
+assert foo.bars[3].i == 57
+assert foo.bars[3] == another_bar      # The extended message is equal,
+assert foo.bars[3] is not another_bar  # but it is a copy!
+
+foo.bars[1].i = 56    # Modifies a single element
+assert foo.bars[1].i == 56
+for bar in foo.bars:  # Loops and print
+  print(bar.i)
+del foo.bars[:]       # Clears list
+
+# add() also forwards keyword arguments to the concrete class.
+# For example, you can do:
+
+foo.bars.add(i=12, j=13)
+
+# Initializers forward keyword arguments to a concrete class too.
+# For example:
+
+foo = Foo(             # Creates Foo
+  bars=[               # with its field bars set to a list
+    Bar(i=15, j=17),   # where each list member is also initialized during creation.
+    Bar(i=32),
+    Bar(i=47, j=77),
+  ]
+)
+
+assert len(foo.bars) == 3
+assert foo.bars[0].i == 15
+assert foo.bars[0].j == 17
+assert foo.bars[1].i == 32
+assert foo.bars[2].i == 47
+assert foo.bars[2].j == 77
+

Unlike repeated scalar fields, repeated message fields don’t support item +assignment (i.e. +__setitem__). +For example:

foo = Foo()
+foo.bars.add(i=3)
+# WRONG!
+foo.bars[0] = Bar(i=15)  # Raises an exception
+# WRONG!
+foo.bars[:] = [Bar(i=15), Bar(i=17)]  # Also raises an exception
+# WRONG!
+# AttributeError: Cannot delete field attribute
+del foo.bars
+# RIGHT
+del foo.bars[:]
+foo.bars.extend([Bar(i=15), Bar(i=17)])
+

Groups (proto2)

Note that groups are deprecated and should not be used when creating new +message types – use nested message types (proto2, proto3) or +delimited fields +(editions) instead.

A group combines a nested message type and a field into a single declaration, +and uses a different +wire format for the +message. The generated message has the same name as the group. The generated +field’s name is the lowercased name of the group.

For example, except for wire format, the following two message definitions are +equivalent:

// Version 1: Using groups
+message SearchResponse {
+  repeated group SearchResult = 1 {
+    optional string url = 1;
+  }
+}
+// Version 2: Not using groups
+message SearchResponse {
+  message SearchResult {
+    optional string url = 1;
+  }
+  repeated SearchResult searchresult = 1;
+}
+

A group is either required, optional, or repeated. A required or optional +group is manipulated using the same API as a regular singular message field. A +repeated group is manipulated using the same API as a regular repeated message +field.

For example, given the above SearchResponse definition, you can do the +following:

resp = SearchResponse()
+resp.searchresult.add(url="https://blog.google")
+assert resp.searchresult[0].url == "https://blog.google"
+assert resp.searchresult[0] == SearchResponse.SearchResult(url="https://blog.google")
+

Map Fields

Given this message definition:

message MyMessage {
+  map<int32, int32> mapfield = 1;
+}
+

The generated Python API for the map field is just like a Python dict:

# Assign value to map
+m.mapfield[5] = 10
+
+# Read value from map
+m.mapfield[5]
+
+# Iterate over map keys
+for key in m.mapfield:
+  print(key)
+  print(m.mapfield[key])
+
+# Test whether key is in map:
+if 5 in m.mapfield:
+  print(Found!”)
+
+# Delete key from map.
+del m.mapfield[key]
+

As with embedded message fields, messages cannot be +directly assigned into a map value. Instead, to add a message as a map value you +reference an undefined key, which constructs and returns a new +submessage:

m.message_map[key].submessage_field = 10
+

You can find out more about undefined keys in the next section.

Referencing undefined keys

The semantics of Protocol Buffer maps behave slightly differently to Python +dicts when it comes to undefined keys. In a regular Python dict, referencing +an undefined key raises a KeyError exception:

>>> x = {}
+>>> x[5]
+Traceback (most recent call last):
+  File "<stdin>", line 1, in <module>
+KeyError: 5
+

However, in Protocol Buffers maps, referencing an undefined key creates the key +in the map with a zero/false/empty value. This behavior is more like the Python +standard library defaultdict.

>>> dict(m.mapfield)
+{}
+>>> m.mapfield[5]
+0
+>>> dict(m.mapfield)
+{5: 0}
+

This behavior is especially convenient for maps with message type values, +because you can directly update the fields of the returned message.

>>> m.message_map[5].foo = 3
+

Note that even if you don’t assign any values to message fields, the submessage +is still created in the map:

>>> m.message_map[10]
+<test_pb2.M2 object at 0x7fb022af28c0>
+>>> dict(m.message_map)
+{10: <test_pb2.M2 object at 0x7fb022af28c0>}
+

This is different from regular embedded message fields, +where the message itself is only created once you assign a value to one of its +fields.

As it may not be immediately obvious to anyone reading your code that +m.message_map[10] alone, for example, may create a submessage, we also provide +a get_or_create() method that does the same thing but whose name makes the +possible message creation more explicit:

# Equivalent to:
+#   m.message_map[10]
+# but more explicit that the statement might be creating a new
+# empty message in the map.
+m.message_map.get_or_create(10)
+

Memory management

Note that clearing a field (via ClearField, Clear, del (for lists) or +ClearExtension) doesn’t necessarily reclaim memory. It just resets the object +to look as if things are unset, but the subobjects may continue to exist. For +example, clearing a repeated field sets its size to 0, but does not relinquish +its capacity (analogous to calling .clear() on a std::vector in C++).

There are various ways in which to ensure the memory is freed up. One method is +to make a copy of the proto after clearing the fields, as the unused memory is +not copied over:

# Assuming 'my_proto' has a memory-intensive field 'big_field'
+# Clears the field. Memory might still be reserved.
+my_proto.ClearField('big_field')
+
+# Copy to a new instance. This allocates only necessary memory.
+compact_proto = my_proto_pb2.MyProto()
+compact_proto.CopyFrom(my_proto)
+
+# Once all references to the initial proto are gone, it is garbage collected.
+my_proto = compact_proto
+

Enumerations

In Python, enums are just integers. A set of integral constants are defined +corresponding to the enum’s defined values. For example, given:

message Foo {
+  enum SomeEnum {
+    VALUE_A = 0;
+    VALUE_B = 5;
+    VALUE_C = 1234;
+  }
+  SomeEnum bar = 1;
+}
+

The constants VALUE_A, VALUE_B, and VALUE_C are defined with values 0, 5, +and 1234, respectively. You can access SomeEnum if desired. If an enum is +defined in the outer scope, the values are module constants; if it is defined +within a message (like above), they become static members of that message class.

For example, you can access the values in the three following ways for the +following enum in a proto:

enum SomeEnum {
+  VALUE_A = 0;
+  VALUE_B = 5;
+  VALUE_C = 1234;
+}
+
value_a = myproto_pb2.SomeEnum.VALUE_A
+# or
+myproto_pb2.VALUE_A
+# or
+myproto_pb2.SomeEnum.Value('VALUE_A')
+

An enum field works just like a scalar field.

foo = Foo()
+foo.bar = Foo.VALUE_A
+assert foo.bar == 0
+assert foo.bar == Foo.VALUE_A
+

If the enum’s name (or an enum value) is a Python keyword, then its object (or +the enum value’s property) will only be accessible via getattr(), as described +in the Names that conflict with Python keywords section.

With proto2, enums are closed, and with proto3, enums are open. In Editions, the +enum_type feature determines the behavior of an enum.

  • OPEN enums can have any int32 value, even if it is not specified in the +enum definition. This is the default in Editions.
  • CLOSED enums cannot contain a numeric value other than those defined for +the enum type. If you assign a value that is not in the enum, the generated +code will throw an exception. This is equivalent to the behavior of enums in +proto2.

Enums have a number of utility methods for getting field names from values and +vice versa, lists of fields, and so on - these are defined in +enum_type_wrapper.EnumTypeWrapper +(the base class for generated enum classes). So, for example, if you have the +following standalone enum in myproto.proto:

enum SomeEnum {
+  VALUE_A = 0;
+  VALUE_B = 5;
+  VALUE_C = 1234;
+}
+

…you can do this:

self.assertEqual('VALUE_A', myproto_pb2.SomeEnum.Name(myproto_pb2.VALUE_A))
+self.assertEqual(5, myproto_pb2.SomeEnum.Value('VALUE_B'))
+

For an enum declared within a protocol message, such as Foo above, the syntax is +similar:

self.assertEqual('VALUE_A', myproto_pb2.Foo.SomeEnum.Name(myproto_pb2.Foo.VALUE_A))
+self.assertEqual(5, myproto_pb2.Foo.SomeEnum.Value('VALUE_B'))
+

If multiple enum constants have the same value (aliases), the first constant +defined is returned.

enum SomeEnum {
+  option allow_alias = true;
+  VALUE_A = 0;
+  VALUE_B = 5;
+  VALUE_C = 1234;
+  VALUE_B_ALIAS = 5;
+}
+

In the above example, myproto_pb2.SomeEnum.Name(5) returns "VALUE_B".

Oneof

Given a message with a oneof:

message Foo {
+  oneof test_oneof {
+     string name = 1;
+     int32 serial_number = 2;
+  }
+}
+

The Python class corresponding to Foo will have properties called name and +serial_number just like regular fields. However, unlike regular +fields, at most one of the fields in a oneof can be set at a time, which is +ensured by the runtime. For example:

message = Foo()
+message.name = "Bender"
+assert message.HasField("name")
+message.serial_number = 2716057
+assert message.HasField("serial_number")
+assert not message.HasField("name")
+

The message class also has a WhichOneof method that lets you find out which +field (if any) in the oneof has been set. This method returns the name of the +field that is set, or None if nothing has been set:

assert message.WhichOneof("test_oneof") is None
+message.name = "Bender"
+assert message.WhichOneof("test_oneof") == "name"
+

HasField and ClearField also accept oneof names in addition to field names:

assert not message.HasField("test_oneof")
+message.name = "Bender"
+assert message.HasField("test_oneof")
+message.serial_number = 2716057
+assert message.HasField("test_oneof")
+message.ClearField("test_oneof")
+assert not message.HasField("test_oneof")
+assert not message.HasField("serial_number")
+

Note that calling ClearField on a oneof just clears the currently set field.

Names that conflict with Python keywords

If the name of a message, field, enum, or enum value is a +Python keyword, +then the name of its corresponding class or property will be the same, but +you’ll only be able to access it using Python’s +getattr() and +setattr() built-in +functions, and not via Python’s normal attribute reference syntax (i.e. the dot +operator).

For example, if you have the following .proto definition:

message Baz {
+  optional int32 from = 1
+  repeated int32 in = 2;
+}
+

You would access those fields like this:

baz = Baz()
+setattr(baz, "from", 99)
+assert getattr(baz, "from") == 99
+getattr(baz, "in").append(42)
+assert getattr(baz, "in") == [42]
+

By contrast, trying to use obj.attr syntax to access these fields results in +Python raising syntax errors when parsing your code:

# WRONG!
+baz.in  # SyntaxError: invalid syntax
+baz.from  # SyntaxError: invalid syntax
+

Extensions

Given a proto2 or editions message with an extension range:

edition = "2023";
+message Foo {
+  extensions 100 to 199;
+}
+

The Python class corresponding to Foo will have a member called Extensions, +which is a dictionary mapping extension identifiers to their current values.

Given an extension definition:

extend Foo {
+  int32 bar = 123;
+}
+

The protocol buffer compiler generates an "extension identifier" called bar. +The identifier acts as a key to the Extensions dictionary. The result of +looking up a value in this dictionary is exactly the same as if you accessed a +normal field of the same type. So, given the above example, you could do:

foo = Foo()
+foo.Extensions[proto_file_pb2.bar] = 2
+assert foo.Extensions[proto_file_pb2.bar] == 2
+

Note that you need to specify the extension identifier constant, not just a +string name: this is because it’s possible for multiple extensions with the same +name to be specified in different scopes.

Analogous to normal fields, Extensions[...] returns a message object for +singular messages and a sequence for repeated fields.

The +Message +interface’s HasField() and ClearField() methods do not work with extensions; +you must use HasExtension() and ClearExtension() instead. To use the +HasExtension() and ClearExtension() methods, pass in the field_descriptor +for the extension you are checking for the existence of.

Services

If the .proto file contains the following line:

option py_generic_services = true;
+

Then the protocol buffer compiler will generate code based on the service +definitions found in the file as described in this section. However, the +generated code may be undesirable as it is not tied to any particular RPC +system, and thus requires more levels of indirection that code tailored to one +system. If you do NOT want this code to be generated, add this line to the file:

option py_generic_services = false;
+

If neither of the above lines are given, the option defaults to false, as +generic services are deprecated. (Note that prior to 2.4.0, the option defaults +to true)

RPC systems based on .proto-language service definitions should provide +plugins +to generate code appropriate for the system. These plugins are likely to require +that abstract services are disabled, so that they can generate their own classes +of the same names.

The remainder of this section describes what the protocol buffer compiler +generates when abstract services are enabled.

Interface

Given a service definition:

service Foo {
+  rpc Bar(FooRequest) returns(FooResponse);
+}
+

The protocol buffer compiler will generate a class Foo to represent this +service. Foo will have a method for each method defined in the service +definition. In this case, the method Bar is defined as:

def Bar(self, rpc_controller, request, done)
+

The parameters are equivalent to the parameters of +Service.CallMethod(), +except that the method_descriptor argument is implied.

These generated methods are intended to be overridden by subclasses. The default +implementations simply call +controller.SetFailed() +with an error message indicating that the method is unimplemented, then invoke +the done callback. When implementing your own service, you must subclass this +generated service and implement its methods as appropriate.

Foo subclasses the Service interface. The protocol buffer compiler +automatically generates implementations of the methods of Service as follows:

  • GetDescriptor: Returns the service’s +ServiceDescriptor.
  • CallMethod: Determines which method is being called based on the provided +method descriptor and calls it directly.
  • GetRequestClass and GetResponseClass: Returns the class of the request +or response of the correct type for the given method.

Stub

The protocol buffer compiler also generates a "stub" implementation of every +service interface, which is used by clients wishing to send requests to servers +implementing the service. For the Foo service (above), the stub implementation +Foo_Stub will be defined.

Foo_Stub is a subclass of Foo. Its constructor takes an +RpcChannel +as a parameter. The stub then implements each of the service’s methods by +calling the channel’s CallMethod() method.

The Protocol Buffer library does not include an RPC implementation. However, it +includes all of the tools you need to hook up a generated service class to any +arbitrary RPC implementation of your choice. You need only provide +implementations of RpcChannel and +RpcController.

Plugin Insertion Points

Code generator plugins +which want to extend the output of the Python code generator may insert code of +the following types using the given insertion point names.

  • imports: Import statements.
  • module_scope: Top-level declarations.

Sharing Messages Between Python and C++

Prior to the 4.21.0 version of the Protobuf Python API, Python apps could share +messages with C++ using a native extension. Starting in the 4.21.0 API version, +sharing messages between Python and C++ is not supported by the default install. +To enable this capability when working with the 4.x and later versions of the +Protobuf Python API, define the environment variable, +PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp, and ensure that the Python/C++ +extension is installed.

\ No newline at end of file diff --git a/reference/ruby/index.html b/reference/ruby/index.html new file mode 100644 index 000000000..766c9972c --- /dev/null +++ b/reference/ruby/index.html @@ -0,0 +1,8 @@ +Ruby Reference | Protocol Buffers Documentation +

Ruby Reference

Reference documentation for working with protocol buffer classes in Ruby.

Ruby Generated Code Guide

Describes the API of message objects that the protocol buffer compiler generates for any given protocol definition.

\ No newline at end of file diff --git a/reference/ruby/index.xml b/reference/ruby/index.xml new file mode 100644 index 000000000..115823059 --- /dev/null +++ b/reference/ruby/index.xml @@ -0,0 +1,2 @@ +Ruby Reference on Protocol Buffers Documentationhttps://protobuf.dev/reference/ruby/Recent content in Ruby Reference on Protocol Buffers DocumentationHugoenRuby Generated Code Guidehttps://protobuf.dev/reference/ruby/ruby-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/ruby/ruby-generated/You should read the language guides for proto2, proto3, or editions before reading this document. +Compiler Invocation The protocol buffer compiler produces Ruby output when invoked with the --ruby_out= command-line flag. The parameter to the --ruby_out= option is the directory where you want the compiler to write your Ruby output. The compiler creates a .rb file for each .proto file input. The names of the output files are computed by taking the name of the . \ No newline at end of file diff --git a/reference/ruby/ruby-generated/index.html b/reference/ruby/ruby-generated/index.html new file mode 100644 index 000000000..4008863ff --- /dev/null +++ b/reference/ruby/ruby-generated/index.html @@ -0,0 +1,255 @@ +Ruby Generated Code Guide | Protocol Buffers Documentation +

Ruby Generated Code Guide

Describes the API of message objects that the protocol buffer compiler generates for any given protocol definition.

You should +read the language guides for +proto2, +proto3, or +editions before reading +this document.

Compiler Invocation

The protocol buffer compiler produces Ruby output when invoked with the +--ruby_out= command-line flag. The parameter to the --ruby_out= option is +the directory where you want the compiler to write your Ruby output. The +compiler creates a .rb file for each .proto file input. The names of the +output files are computed by taking the name of the .proto file and making two +changes:

  • The extension (.proto) is replaced with _pb.rb.
  • The proto path (specified with the --proto_path= or -I command-line +flag) is replaced with the output path (specified with the --ruby_out= +flag).

So, for example, let’s say you invoke the compiler as follows:

protoc --proto_path=src --ruby_out=build/gen src/foo.proto src/bar/baz.proto
+

The compiler will read the files src/foo.proto and src/bar/baz.proto and +produce two output files: build/gen/foo_pb.rb and build/gen/bar/baz_pb.rb. +The compiler will automatically create the directory build/gen/bar if +necessary, but it will not create build or build/gen; they must already +exist.

Packages

The package name defined in the .proto file is used to generate a module +structure for the generated messages. Given a file like:

package foo_bar.baz;
+
+message MyMessage {}
+

The protocol compiler generates an output message with the name +FooBar::Baz::MyMessage.

However, if the .proto file contains the ruby_package option, like this:

option ruby_package = "Foo::Bar";
+

then the generated output will give precedence to the ruby_package option +instead and generate Foo::Bar::MyMessage.

Messages

Given a simple message declaration:

message Foo {}
+

The protocol buffer compiler generates a class called Foo. The generated class +derives from the Ruby Object class (protos have no common base class). Unlike +C++ and Java, Ruby generated code is unaffected by the optimize_for option in +the .proto file; in effect, all Ruby code is optimized for code size.

You should not create your own Foo subclasses. Generated classes are not +designed for subclassing and may lead to "fragile base class" problems.

Ruby message classes define accessors for each field, and also provide the +following standard methods:

  • Message#dup, Message#clone: Performs a shallow copy of this message and +returns the new copy.
  • Message#==: Performs a deep equality comparison between two messages.
  • Message#hash: Computes a shallow hash of the message’s value.
  • Message#to_hash, Message#to_h: Converts the object to a ruby Hash +object. Only the top-level message is converted.
  • Message#inspect: Returns a human-readable string representing this +message.
  • Message#[], Message#[]=: Gets or sets a field by string name. In the +future this will probably also be used to get/set extensions.

The message classes also define the following methods as static. (In general we +prefer static methods, since regular methods can conflict with field names you +defined in your .proto file.)

  • Message.decode(str): Decodes a binary protobuf for this message and +returns it in a new instance.
  • Message.encode(proto): Serializes a message object of this class to a +binary string.
  • Message.decode_json(str): Decodes a JSON text string for this message and +returns it in a new instance.
  • Message.encode_json(proto): Serializes a message object of this class to a +JSON text string.
  • Message.descriptor: Returns the Google::Protobuf::Descriptor object for +this message.

When you create a message, you can conveniently initialize fields in the +constructor. Here is an example of constructing and using a message:

message = MyMessage.new(int_field: 1,
+                        string_field: "String",
+                        repeated_int_field: [1, 2, 3, 4],
+                        submessage_field: MyMessage::SubMessage.new(foo: 42))
+serialized = MyMessage.encode(message)
+
+message2 = MyMessage.decode(serialized)
+raise unless message2.int_field == 1
+

Nested Types

A message can be declared inside another message. For example:

message Foo {
+  message Bar { }
+}
+

In this case, the Bar class is declared as a class inside of Foo, so you can +refer to it as Foo::Bar.

Fields

For each field in a message type, there are accessor methods to set and get the +field. So given a field foo you can write:

message.foo = get_value()
+print message.foo
+

Whenever you set a field, the value is type-checked against the declared type of +that field. If the value is of the wrong type (or out of range), an exception +will be raised.

Singular Fields

For singular primitive fields (numbers, strings, and boolean), the value you +assign to the field should be of the correct type and must be in the appropriate +range:

  • Number types: the value should be a Fixnum, Bignum, or Float. The +value you assign must be exactly representable in the target type. So +assigning 1.0 to an int32 field is ok, but assigning 1.2 is not.
  • Boolean fields: the value must be true or false. No other values +will implicitly convert to true/false.
  • Bytes fields: the assigned value must be a String object. The protobuf +library will duplicate the string, convert it to ASCII-8BIT encoding, and +freeze it.
  • String fields: the assigned value must be a String object. The +protobuf library will duplicate the string, convert it to UTF-8 encoding, +and freeze it.

No automatic #to_s, #to_i, etc. calls will happen to perform automatic +conversion. You should convert values yourself first, if necessary.

Checking Presence

Explicit field presence is determined by the field_presence feature (in +editions), the optional keyword (in proto2/proto3), and the field type +(message and oneof fields always have explicit presence). When a field has +presence, you can check whether the field is set on a message by calling a +generated has_...? method. Setting any value—even the default +value—marks the field as present. Fields can be cleared by calling a +different generated clear_... method.

For example, for a message MyMessage with an int32 field foo:

message MyMessage {
+  int32 foo = 1;
+}
+

The presence of foo can be checked as follows:

m = MyMessage.new
+raise if m.has_foo?
+m.foo = 0
+raise unless m.has_foo?
+m.clear_foo
+raise if m.has_foo?
+

Singular Message Fields

Submessage fields always have presence, regardless of whether they’re marked as +optional. Unset submessage fields return nil, so you can always tell if the +message was explicitly set or not. To clear a submessage field, set its value +explicitly to nil.

if message.submessage_field.nil?
+  puts "Submessage field is unset."
+else
+  message.submessage_field = nil
+  puts "Cleared submessage field."
+end
+

In addition to comparing and assigning nil, generated messages have has_... +and clear_... methods, which behave the same as for basic types:

if !message.has_submessage_field?
+  puts "Submessage field is unset."
+else
+  message.clear_submessage_field
+  raise if message.has_submessage_field?
+  puts "Cleared submessage field."
+end
+

When you assign a submessage, it must be a generated message object of the +correct type.

It is possible to create message cycles when you assign submessages. For +example:

// foo.proto
+message RecursiveMessage {
+  RecursiveMessage submessage = 1;
+}
+
+# test.rb
+require 'foo'
+
+message = RecursiveMessage.new
+message.submessage = message
+

If you try to serialize this, the library will detect the cycle and fail to +serialize.

Repeated Fields

Repeated fields are represented using a custom class +Google::Protobuf::RepeatedField. This class acts like a Ruby Array and mixes +in Enumerable. Unlike a regular Ruby array, RepeatedField is constructed +with a specific type and expects all of the array members to have the correct +type. The types and ranges are checked just like message fields.

int_repeatedfield = Google::Protobuf::RepeatedField.new(:int32, [1, 2, 3])
+
+raise unless !int_repeatedfield.empty?
+
+# Raises TypeError.
+int_repeatedfield[2] = "not an int32"
+
+# Raises RangeError
+int_repeatedfield[2] = 2**33
+
+message.int32_repeated_field = int_repeatedfield
+
+# This isn't allowed; the regular Ruby array doesn't enforce types like we need.
+message.int32_repeated_field = [1, 2, 3, 4]
+
+# This is fine, since the elements are copied into the type-safe array.
+message.int32_repeated_field += [1, 2, 3, 4]
+
+# The elements can be cleared without reassigning.
+int_repeatedfield.clear
+raise unless int_repeatedfield.empty?
+

For repeated fields that contain messages, the constructor for +Google::Protobuf::RepeatedField supports a variant with three arguments: +:message, the class of the submessage, and the values to set:

first_message = MySubMessage.new(foo: 42)
+second_message = MySubMessage.new(foo: 79)
+
+repeated_field = Google::Protobuf::RepeatedField.new(
+    :message,
+    MySubMessage,
+    [first_message, second_message]
+)
+message.sub_message_repeated_field = repeated_field
+

The RepeatedField type supports all of the same methods as a regular Ruby +Array. You can convert it to a regular Ruby Array with repeated_field.to_a.

Unlike singular fields, has_...? methods are never generated for repeated +fields.

Map Fields

Map fields are represented using a special class that acts like a Ruby Hash +(Google::Protobuf::Map). Unlike a regular Ruby hash, Map is constructed with +a specific type for the key and value and expects all of the map’s keys and +values to have the correct type. The types and ranges are checked just like +message fields and RepeatedField elements.

int_string_map = Google::Protobuf::Map.new(:int32, :string)
+
+# Returns nil; items is not in the map.
+print int_string_map[5]
+
+# Raises TypeError, value should be a string
+int_string_map[11] = 200
+
+# Ok.
+int_string_map[123] = "abc"
+
+message.int32_string_map_field = int_string_map
+

Enumerations

Since Ruby does not have native enums, we create a module for each enum with +constants to define the values. Given the .proto file:

message Foo {
+  enum SomeEnum {
+    VALUE_A = 0;
+    VALUE_B = 5;
+    VALUE_C = 1234;
+  }
+  SomeEnum bar = 1;
+}
+

You can refer to enum values like so:

print Foo::SomeEnum::VALUE_A  # => 0
+message.bar = Foo::SomeEnum::VALUE_A
+

You may assign either a number or a symbol to an enum field. When reading the +value back, it will be a symbol if the enum value is known, or a number if it is +not.

With OPEN enums, which proto3 uses, any integer value can be assigned to the +enum, even if that value is not defined in the enum.

message.bar = 0
+puts message.bar.inspect  # => :VALUE_A
+message.bar = :VALUE_B
+puts message.bar.inspect  # => :VALUE_B
+message.bar = 999
+puts message.bar.inspect  # => 999
+
+# Raises: RangeError: Unknown symbol value for enum field.
+message.bar = :UNDEFINED_VALUE
+
+# Switching on an enum value is convenient.
+case message.bar
+when :VALUE_A
+  # ...
+when :VALUE_B
+  # ...
+when :VALUE_C
+  # ...
+else
+  # ...
+end
+

An enum module also defines the following utility methods:

  • Foo::SomeEnum.lookup(number): Looks up the given number and returns its +name, or nil if none was found. If more than one name has this number, +returns the first that was defined.
  • Foo::SomeEnum.resolve(symbol): Returns the number for this enum name, or +nil if none was found.
  • Foo::SomeEnum.descriptor: Returns the descriptor for this enum.

Oneof

Given a message with a oneof:

message Foo {
+  oneof test_oneof {
+     string name = 1;
+     int32 serial_number = 2;
+  }
+}
+

The Ruby class corresponding to Foo will have members called name and +serial_number with accessor methods just like regular fields. +However, unlike regular fields, at most one of the fields in a oneof can be set +at a time, so setting one field will clear the others.

message = Foo.new
+
+# Fields have their defaults.
+raise unless message.name == ""
+raise unless message.serial_number == 0
+raise unless message.test_oneof == nil
+
+message.name = "Bender"
+raise unless message.name == "Bender"
+raise unless message.serial_number == 0
+raise unless message.test_oneof == :name
+
+# Setting serial_number clears name.
+message.serial_number = 2716057
+raise unless message.name == ""
+raise unless message.test_oneof == :serial_number
+
+# Setting serial_number to nil clears the oneof.
+message.serial_number = nil
+raise unless message.test_oneof == nil
+

For proto2 messages, oneof members have individual has_...? methods as well:

message = Foo.new
+
+raise unless !message.has_test_oneof?
+raise unless !message.has_name?
+raise unless !message.has_serial_number?
+raise unless !message.has_test_oneof?
+
+message.name = "Bender"
+raise unless message.has_test_oneof?
+raise unless message.has_name?
+raise unless !message.has_serial_number?
+raise unless !message.has_test_oneof?
+
\ No newline at end of file diff --git a/reference/rust/building-rust-protos/index.html b/reference/rust/building-rust-protos/index.html new file mode 100644 index 000000000..5d62f9892 --- /dev/null +++ b/reference/rust/building-rust-protos/index.html @@ -0,0 +1,49 @@ +Building Rust Protos | Protocol Buffers Documentation +

Building Rust Protos

Describes how to build Rust protos using Cargo or Bazel.

Cargo

See the +protobuf-example crate +for an example of how to set up your build.

Bazel

The process of building a Rust library for a Protobuf definition is similar to +other programming languages:

  1. Use the language-agnostic proto_library rule:

    proto_library(
    +    name = "person_proto",
    +    srcs = ["person.proto"],
    +)
    +
  2. Create a Rust library:

    load("//third_party/protobuf/rust:defs.bzl", "rust_proto_library")
    +
    +proto_library(
    +    name = "person_proto",
    +    srcs = ["person.proto"],
    +)
    +
    +rust_proto_library(
    +    name = "person_rust_proto",
    +    deps = [":person_proto"],
    +)
    +
  3. Use the library by including it in a Rust binary:

    load("//devtools/rust/build_defs:rules.bzl", "rust_binary")
    +load("//third_party/protobuf/rust:defs.bzl", "rust_proto_library")
    +
    +proto_library(
    +    name = "person_proto",
    +    srcs = ["person.proto"],
    +)
    +
    +rust_proto_library(
    +    name = "person_rust_proto",
    +    deps = [":person_proto"],
    +)
    +
    +rust_binary(
    +    name = "greet",
    +    srcs = ["greet.rs"],
    +    deps = [
    +        ":person_rust_proto",
    +    ],
    +)
    +
\ No newline at end of file diff --git a/reference/rust/index.html b/reference/rust/index.html new file mode 100644 index 000000000..98015149f --- /dev/null +++ b/reference/rust/index.html @@ -0,0 +1,8 @@ +Rust Reference | Protocol Buffers Documentation +

Rust Reference

Reference documentation for working with protocol buffer classes in Rust.

Rust Generated Code Guide

Describes the API of message objects that the protocol buffer compiler generates for any given protocol definition.

Redaction in Rust

Describes redaction in Rust.

Building Rust Protos

Describes how to build Rust protos using Cargo or Bazel.

Rust Proto Design Decisions

Explains some of the design choices that the Rust Proto implementation makes.

\ No newline at end of file diff --git a/reference/rust/index.xml b/reference/rust/index.xml new file mode 100644 index 000000000..b9ec0db00 --- /dev/null +++ b/reference/rust/index.xml @@ -0,0 +1,10 @@ +Rust Reference on Protocol Buffers Documentationhttps://protobuf.dev/reference/rust/Recent content in Rust Reference on Protocol Buffers DocumentationHugoenRust Generated Code Guidehttps://protobuf.dev/reference/rust/rust-generated/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/rust/rust-generated/This page describes exactly what Rust code the protocol buffer compiler generates for any given protocol definition. +This document covers how the protocol buffer compiler generates Rust code for proto2, proto3, and protobuf editions. Any differences between proto2, proto3, and editions generated code are highlighted. You should read the proto2 language guide, proto3 language guide, or editions guide before reading this document. +Protobuf Rust Protobuf Rust is an implementation of protocol buffers designed to be able to sit on top of other existing protocol buffer implementations that we refer to as &lsquo;kernels&rsquo;.Redaction in Rusthttps://protobuf.dev/reference/rust/rust-redaction/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/rust/rust-redaction/Use the standard fmt::Debug (&quot;{:?}&quot; in format strings) on Protobuf messages for human-readable strings for logging, error messages, exceptions, and similar use cases. The output of this debug info is not intended to be machine-readable (unlike TextFormat and JSON which are not be used for debug output). +Using fmt::Debug enables redaction of some sensitive fields. +Note that under upb kernel this redaction is not yet implemented, but is expected to be added.Building Rust Protoshttps://protobuf.dev/reference/rust/building-rust-protos/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/rust/building-rust-protos/Cargo See the protobuf-example crate for an example of how to set up your build. +Bazel The process of building a Rust library for a Protobuf definition is similar to other programming languages: +Use the language-agnostic proto_library rule: +proto_library( name = &#34;person_proto&#34;, srcs = [&#34;person.proto&#34;], ) Create a Rust library: +load(&#34;//third_party/protobuf/rust:defs.bzl&#34;, &#34;rust_proto_library&#34;) proto_library( name = &#34;person_proto&#34;, srcs = [&#34;person.proto&#34;], ) rust_proto_library( name = &#34;person_rust_proto&#34;, deps = [&#34;:person_proto&#34;], ) Use the library by including it in a Rust binary:Rust Proto Design Decisionshttps://protobuf.dev/reference/rust/rust-design-decisions/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/reference/rust/rust-design-decisions/As with any library, Rust Protobuf is designed considering the needs of both Google&rsquo;s first-party usage of Rust as well that of external users. Choosing a path in that design space means that some choices made will not be optimal for some users in some cases, even if it is the right choice for the implementation overall. +This page covers some of the larger design decisions that the Rust Protobuf implementation makes and the considerations which led to those decisions. \ No newline at end of file diff --git a/reference/rust/rust-design-decisions/index.html b/reference/rust/rust-design-decisions/index.html new file mode 100644 index 000000000..afa0fa919 --- /dev/null +++ b/reference/rust/rust-design-decisions/index.html @@ -0,0 +1,117 @@ +Rust Proto Design Decisions | Protocol Buffers Documentation +

Rust Proto Design Decisions

Explains some of the design choices that the Rust Proto implementation makes.

As with any library, Rust Protobuf is designed considering the needs of both +Google’s first-party usage of Rust as well that of external users. Choosing a +path in that design space means that some choices made will not be optimal for +some users in some cases, even if it is the right choice for the implementation +overall.

This page covers some of the larger design decisions that the Rust Protobuf +implementation makes and the considerations which led to those decisions.

Designed to Be ‘Backed’ by Other Protobuf Implementations, Including C++ Protobuf

Protobuf Rust is not a pure Rust implementation of protobuf, but a safe Rust API +implemented on top of existing protobuf implementations, or as we call these +implementations: kernels.

The biggest factor that goes into this decision was to enable zero-cost of +adding Rust to a preexisting binary which already uses non-Rust Protobuf. By +enabling the implementation to be ABI-compatible with the C++ Protobuf generated +code, it is possible to share Protobuf messages across the language boundary +(FFI) as plain pointers, avoiding the need to serialize in one language, pass +the byte array across the boundary, and deserialize in the other language. This +also reduces binary size for these use cases by avoiding having redundant schema +information embedded in the binary for the same messages for each language.

Google sees Rust as an opportunity to incrementally get memory safety to key +portions of preexisting brownfield C++ servers; the cost of serialization at the +language boundaries would prevent adoption of Rust to replace C++ in many of +these important and performance-sensitive cases. If we pursued a greenfield Rust +Protobuf implementation that did not have this support, it would end up blocking +Rust adoption and require that these important cases stay on C++ instead.

Protobuf Rust currently supports three kernels:

  • C++ kernel - the generated code is backed by C++ Protocol Buffers (the +“full” implementation, typically used for servers). This kernel offers +in-memory interoperability with C++ code that uses the C++ runtime. This is +the default for servers within Google.
  • C++ Lite kernel - the generated code is backed by C++ Lite Protocol Buffers +(typically used for mobile). This kernel offers in-memory interoperability +with C++ code that uses the C++ Lite runtime. This is the default for +for mobile apps within Google.
  • upb kernel - the generated code is backed by +upb, +a highly performant and small-binary-size Protobuf library written in C. upb +is designed to be used as an implementation detail by Protobuf runtimes in +other languages. This is the default in open source builds where we expect +static linking with code already using C++ Protobuf to be more rare.

Rust Protobuf is designed to support multiple alternate implementations +(including multiple different memory layouts) while exposing exactly the same +API, allowing for the same application code to be recompiled targeting being +backed by a different implementation. This design constraint significantly +influences our public API decisions, including the types used on getters +(discussed later in this document).

No Pure Rust Kernel

Given that we designed the API to be implementable by multiple backing +implementations, a natural question is why the only supported kernels are +written in the memory unsafe languages of C and C++ today.

While Rust being a memory-safe language can significantly reduce exposure to +critical security issues, no language is immune to security issues. The Protobuf +implementations that we support as kernels have been scrutinized and fuzzed to +the extent that Google is comfortable using those implementations to perform +unsandboxed parsing of untrusted inputs in our own servers and apps.

A greenfield binary parser written in Rust at this time would be understood to +be much more likely to contain critical vulnerabilities than our preexisting C++ +Protobuf or upb parsers, which have been extensively fuzzed, tested, and +reviewed.

There are legitimate arguments for supporting a pure Rust kernel implementation +long-term, including the ability for developers to avoid needing to have Clang +available to compile C code at build time.

We expect that Google will support a pure Rust implementation with the same +exposed API at some later date, but we have no concrete roadmap for it at this +time. A second official Rust Protobuf implementation that has a ‘better’ API by +avoiding the constraints that come from being backed by C++ Proto and upb is not +planned, as we wouldn’t want to fragment Google’s own Protobuf usage.

View/Mut Proxy Types

The Rust Proto API is designed with opaque “Proxy” types. For a .proto file +that defines message SomeMsg {}, we generate the Rust types SomeMsg, +SomeMsgView<'_> and SomeMsgMut<'_>. The simple rule of thumb is that we +expect the View and Mut types to stand in for &SomeMsg and &mut SomeMsg in +all usages by default, while still getting all of the borrow checking/Send/etc. +behavior that you would expect from those types.

Another Lens to Understand These Types

To better understand the nuances of these types, it may be useful to think of +these types as follows:

struct SomeMsg(Box<cpp::SomeMsg>);
+struct SomeMsgView<'a>(&'a cpp::SomeMsg);
+struct SomeMsgMut<'a>(&'a mut cpp::SomeMsg);
+

Under this lens you can see that:

  • Given a &SomeMsg it is possible to get a SomeMsgView (similar to how +given a &Box<T> you can get a &T)
  • Given a SomeMsgView it in not possible to get a &SomeMsg (similar to +how given a &T you couldn’t get a &Box<T>).

Just like with the &Box example, this means that on function arguments, it is +generally better to default to use SomeMsgView<'a> rather than a &'a SomeMsg, as it will allow a superset of callers to use the function.

Why

There are two main reasons for this design: to unlock possible optimization +benefits, and as an inherent outcome of the kernel design.

Optimization Opportunity Benefit

Protobuf being such a core and widespread technology makes it unusually both +prone to all possible observable behaviors being depended on by someone, as well +as relatively small optimizations having unusually major net impact at scale. We +have found that more opaqueness of types gives unusually high amount of +leverage: they permit us to be more deliberate about exactly what behaviors are +exposed, and give us more room to optimize the implementation.

A SomeMsgMut<'_> provides those opportunities where a &mut SomeMsg would +not: namely that we can construct them lazily and with an implementation detail +which is not the same as the owned message representation. It also inherently +allows us to control certain behaviors that we couldn’t otherwise limit or +control: for example, any &mut can be used with std::mem::swap(), which is a +behavior that would place strong limits on what invariants you are able to +maintain between a parent and child struct if &mut SomeChild is given to +callers.

Inherent to Kernel Design

The other reason for the proxy types is more of an inherent limitation to our +kernel design; when you have a &T there must be a real Rust T type in memory +somewhere.

Our C++ kernel design allows you to parse a message which contains nested +messages, and create only a small Rust stack-allocated object to representing +the root message, with all other memory being stored on the C++ Heap. When you +later access a child message, there will be no already-allocated Rust object +which corresponds to that child, and so there’s no Rust instance to borrow at +that moment.

By using proxy types, we’re able to on-demand create the Rust proxy types that +semantically acting as borrows, without there being any eagerly allocated Rust +memory for those instances ahead of time.

Non-Std Types

Simple Types Which May Have a Directly Corresponding Std Type

In some cases the Rust Protobuf API may choose to create our own types where a +corresponding std type exists with the same name, where the current +implementation may even simply wrap the std type, for example +protobuf::UTF8Error.

Using these types rather than std types gives us more flexibility in optimizing +the implementation in the future. While our current implementation uses the Rust +std UTF-8 validation today, by creating our own protobuf::Utf8Error type it +enables us to change the implementation to use the highly optimized C++ +implementation of UTF-8 validation that we use from C++ Protobuf which is faster +than Rust’s std UTF-8 validation.

ProtoString

Rust’s str and std::string::String types maintain a strict invariant that +they only contain valid UTF-8, but C++’s std::string type does not enforce any +such guarantee. string typed Protobuf fields are intended to only ever contain +valid UTF-8, and C++ Protobuf does use a correct and highly optimized UTF8 +validator. However, C++ Protobuf’s API surface is not set up to strictly enforce +as a runtime invariant that its string fields always contain valid UTF-8, +instead, in some cases it allows setting of non-UTF8 data into a string field +and validation will only occur at a later time when serialization is happening.

To enable integrating Rust into preexisting codebases that use C++ Protobuf +while allowing for zero-cost boundary crossings with no risk of undefined +behavior in Rust, we unfortunately have to avoid the str/String types for +string field getters. Instead, the types ProtoStr and ProtoString are +used, which are equivalent types, except that they may contain invalid UTF-8 in +rare situations. Those types let the application code choose if they wish to +perform the validation on-demand to observe the fields as a Result<&str>, or +operate on the raw bytes to avoid any runtime validation. All of the setter +paths are still designed to allow you to pass &str or String types.

We are aware that vocabulary types like str are very important to idiomatic +usage, and intend to keep an eye on if this decision is the right one as usage +details of Rust evolves.

\ No newline at end of file diff --git a/reference/rust/rust-generated/index.html b/reference/rust/rust-generated/index.html new file mode 100644 index 000000000..aa9b051b9 --- /dev/null +++ b/reference/rust/rust-generated/index.html @@ -0,0 +1,362 @@ +Rust Generated Code Guide | Protocol Buffers Documentation +

Rust Generated Code Guide

Describes the API of message objects that the protocol buffer compiler generates for any given protocol definition.

This page describes exactly what Rust code the protocol buffer compiler +generates for any given protocol definition.

This document covers how the protocol buffer compiler generates Rust code for +proto2, proto3, and protobuf editions. Any differences between proto2, proto3, +and editions generated code are highlighted. You should read the +proto2 language guide, +proto3 language guide, or +editions guide before +reading this document.

Protobuf Rust

Protobuf Rust is an implementation of protocol buffers designed to be able to +sit on top of other existing protocol buffer implementations that we refer to as +‘kernels’.

The decision to support multiple non-Rust kernels has significantly influenced +our public API, including the choice to use custom types like ProtoStr over +Rust std types like str. See +Rust Proto Design Decisions +for more on this topic.

Packages

Unlike in most other languages, the package declarations in the .proto files +are not used in Rust codegen.

When rust_proto_library is used, the library will correspond to one crate. The +name of the target is used as the crate name. Choose your library name +correspondingly.

When using Cargo, we recommend you include! the generated.rs entry point in +a mod of an appropriate name, as in our +Example Crate.

Messages

Given the message declaration:

message Foo {}
+

The compiler generates a struct named Foo. The Foo struct defines the +following associated functions and methods:

Associated Functions

  • fn new() -> Self: Creates a new instance of Foo.

Traits

For a number of reasons, including gencode size, name collision problems, and +gencode stability, most common functionality on messages is implemented on +traits instead of as inherent implementations.

Most users should import our prelude, which only includes traits and our +proto! macro and no other types (use protobuf::prelude::*). If you would +rather avoid preludes, you can always import the specific traits as needed (see +the

documentation here +for the names and definitions of the traits if you want to import them +directly).

  • fn parse(data: &[u8]) -> Result<Self, ParseError>: Parses a new instance +of a message.
  • fn parse_dont_enforce_required(data: &[u8]) -> Result<Self, ParseError>: +Same as parse but does not fail on missing proto2 required fields.
  • fn clear(&mut self): Clears message.
  • fn clear_and_parse(&mut self, data: &[u8]) -> Result<(), ParseError>: +Clearing and parsing into an existing instance.
  • fn clear_and_parse_dont_enforce_required(&mut self, data: &[u8]) -> Result<(), ParseError>: Same as parse but does not fail on missing proto2 +required fields.
  • fn serialize(&self) -> Result<Vec<u8>, SerializeError>: Serializes the +message to Protobuf wire format. Serialization can fail but rarely will. +Failure reasons include if the representation exceeds the maximum encoded +message size (must be less than 2 GiB), and required fields (proto2) that +are unset.
  • fn take_from(&mut self, other): Moves other into self, discarding any +previous state that self contained.
  • fn copy_from(&mut self, other): Copies other into self, discarding any +previous state that self contained. other is unmodified.
  • fn merge_from(&mut self, other): Merges other into self.
  • fn as_view(&self) -> FooView<'_>: Returns an immutable handle (view) to +Foo. This is further covered in the section on proxy types.
  • fn as_mut(&mut self) -> FooMut<'_>: Returns a mutable handle (mut) to +Foo. This is further covered in the section on proxy types.

Foo additionally implements the following std traits:

  • std::fmt::Debug
  • std::default::Default
  • std::clone::Clone
  • std::marker::Send
  • std::marker::Sync

Fluently Create New Instances

The API design of setters follows our established Protobuf idioms, but the +verbosity when constructing new instances is a mild pain point in certain other +languages. To mitigate this, we offer a proto! macro, which can be used to +more-succinctly/fluently create new instances.

For example, instead of writing this:

let mut msg = SomeMsg::new();
+msg.set_x(1);
+msg.set_y("hello");
+msg.some_submessage_mut().set_z(42);
+

This macro can be used to write it as follows:

let msg = proto!(SomeMsg {
+  x: 1,
+  y: "hello",
+  some_submsg: SomeSubmsg {
+    z: 42
+  }
+});
+

Message Proxy Types

For a number of technical reasons, we have chosen to avoid using native Rust +references (&T and &mut T) in certain cases. Instead, we need to express +these concepts using types - Views and Muts. These situations are shared and +mutable references to:

  • Messages
  • Repeated fields
  • Map fields

For example, the compiler emits structs FooView<'a> and FooMut<'msg> +alongside Foo. These types are used in place of &Foo and &mut Foo, and +they behave the same as native Rust references in terms of borrow checker +behavior. Just like native borrows, Views are Copy and the borrow checker will +enforce that you can either have any number of Views or at most one Mut live at +a given time.

For the purposes of this documentation, we focus on describing all methods +emitted for the owned message type (Foo). A subset of these functions with +&self receiver will also be included on the FooView<'msg>. A subset of these +functions with either &self or &mut self will also be included on the +FooMut<'msg>.

To create an owned message type from a View / Mut type call to_owned(), which +creates a deep copy.

See the corresponding section in our +design decisions +documentation for more discussion about why this choice was made.

Nested Types

Given the message declaration:

message Foo {
+  message Bar {
+      enum Baz { ... }
+  }
+}
+

In addition to the struct named Foo, a module named foo is created to +contain the struct for Bar. And similarly a nested module named bar to +contain the deeply nested enum Baz:

pub struct Foo {}
+
+pub mod foo {
+   pub struct Bar {}
+   pub mod bar {
+      pub struct Baz { ... }
+   }
+}
+

Fields

In addition to the methods described in the previous section, the protocol +buffer compiler generates a set of accessor methods for each field defined +within the message in the .proto file.

Following Rust style, the methods are in lower-case/snake-case, such as +has_foo() and clear_foo(). Note that the capitalization of the field name +portion of the accessor maintains the style from the original .proto file, which +in turn should be lower-case/snake-case per the +.proto file style guide.

Fields with Explicit Presence

Explicit presence means that a field distinguishes between the default value and +no value set. In proto2, optional fields have explicit presence. In proto3, +only message fields and oneof or optional fields have explicit presence. +Presence is set using the +features.field_presence +option in editions.

Numeric Fields

For this field definition:

int32 foo = 1;
+

The compiler generates the following accessor methods:

  • fn has_foo(&self) -> bool: Returns true if the field is set.
  • fn foo(&self) -> i32: Returns the current value of the field. If the field +is not set, it returns the default value.
  • fn foo_opt(&self) -> protobuf::Optional<i32>: Returns an optional with the +variant Set(value) if the field is set or Unset(default value) if it’s +unset. See +Optional rustdoc
  • fn set_foo(&mut self, val: i32): Sets the value of the field. After +calling this, has_foo() will return true and foo() will return +value.
  • fn clear_foo(&mut self): Clears the value of the field. After calling +this, has_foo() will return false and foo() will return the default +value.

For other numeric field types (including bool), int32 is replaced with the +corresponding Rust type according to the +scalar value types table.

String and Bytes Fields

For these field definitions:

string foo = 1;
+bytes foo = 1;
+

The compiler generates the following accessor methods:

  • fn has_foo(&self) -> bool: Returns true if the field is set.
  • fn foo(&self) -> &protobuf::ProtoStr: Returns the current value of the +field. If the field is not set, it returns the default value. See +ProtoStr rustdoc.
  • fn foo_opt(&self) -> protobuf::Optional<&ProtoStr>: Returns an optional +with the variant Set(value) if the field is set or Unset(default value) +if it’s unset.
  • fn set_foo(&mut self, val: impl IntoProxied<ProtoString>): Sets the value +of the field. &str, String, &ProtoStr and ProtoString all +implelement IntoProxied and can be passed to this method.
  • fn clear_foo(&mut self): Clears the value of the field. After calling +this, has_foo() will return false and foo() will return the default +value.

For fields of type bytes the compiler will generate the ProtoBytes type +instead.

Enum Fields

Given this enum definition in any proto syntax version:

enum Bar {
+  BAR_UNSPECIFIED = 0;
+  BAR_VALUE = 1;
+  BAR_OTHER_VALUE = 2;
+}
+

The compiler generates a struct where each variant is an associated constant:

#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+#[repr(transparent)]
+pub struct Bar(i32);
+
+impl Bar {
+  pub const Unspecified: Bar = Bar(0);
+  pub const Value: Bar = Bar(1);
+  pub const OtherValue: Bar = Bar(2);
+}
+

For this field definition:

Bar foo = 1;
+

The compiler generates the following accessor methods:

  • fn has_foo(&self) -> bool: Returns true if the field is set.
  • fn foo(&self) -> Bar: Returns the current value of the field. If the field +is not set, it returns the default value.
  • fn foo_opt(&self) -> Optional<Bar>: Returns an optional with the variant +Set(value) if the field is set or Unset(default value) if it’s unset.
  • fn set_foo(&mut self, val: Bar): Sets the value of the field. After +calling this, has_foo() will return true and foo() will return +value.
  • fn clear_foo(&mut self): Clears the value of the field. After calling +this, has_foo() will return false and foo() will return the default +value.

Embedded Message Fields

Given the message type Bar from any proto syntax version:

message Bar {}
+

For any of these field definitions:


+message MyMessage {
+  Bar foo = 1;
+}
+

The compiler will generate the following accessor methods:

  • fn foo(&self) -> BarView<'_>: Returns a view of the current value of the +field. If the field is not set it returns an empty message.
  • fn foo_mut(&mut self) -> BarMut<'_>: Returns a mutable handle to the +current value of the field. Sets the field if it is not set. After calling +this method, has_foo() returns true.
  • fn foo_opt(&self) -> protobuf::Optional<BarView>: If the field is set, +returns the variant Set with its value. Else returns the variant Unset +with the default value.
  • fn set_foo(&mut self, value: impl protobuf::IntoProxied<Bar>): Sets the +field to value. After calling this method, has_foo() returns true.
  • fn has_foo(&self) -> bool: Returns true if the field is set.
  • fn clear_foo(&mut self): Clears the field. After calling this method +has_foo() returns false.

Fields with Implicit Presence (proto3 and Editions)

Implicit presence means that a field does not distinguish between the default +value and no value set. In proto3, fields have implicit presence by default. In +editions, you can declare a field with implicit presence by setting the +field_presence feature to IMPLICIT.

Numeric Fields

For these field definitions:

// proto3
+int32 foo = 1;
+
+// editions
+message MyMessage {
+  int32 foo = 1 [features.field_presence = IMPLICIT];
+}
+

The compiler generates the following accessor methods:

  • fn foo(&self) -> i32: Returns the current value of the field. If the field +is not set, it returns 0.
  • fn set_foo(&mut self, val: i32): Sets the value of the field.

For other numeric field types (including bool), int32 is replaced with the +corresponding Rust type according to the +scalar value types table.

String and Bytes Fields

For these field definitions:

// proto3
+string foo = 1;
+bytes foo = 1;
+
+// editions
+string foo = 1 [features.field_presence = IMPLICIT];
+bytes bar = 2 [features.field_presence = IMPLICIT];
+

The compiler will generate the following accessor methods:

  • fn foo(&self) -> &ProtoStr: Returns the current value of the field. If the +field is not set, returns the empty string/empty bytes. See +ProtoStr rustdoc.
  • fn set_foo(&mut self, value: IntoProxied<ProtoString>): Sets the field to +value.

For fields of type bytes the compiler will generate the ProtoBytes type +instead.

Singular String and Bytes Fields with Cord Support

[ctype = CORD] enables bytes and strings to be stored as an +absl::Cord +in C++ Protobufs. absl::Cord currently does not have an equivalent type in +Rust . Protobuf Rust uses an enum to represent a cord +field:

enum ProtoStringCow<'a> {
+  Owned(ProtoString),
+  Borrowed(&'a ProtoStr)
+}
+

In the common case, for small strings, an absl::Cord stores its data as a +contiguous string. In this case cord accessors return +ProtoStringCow::Borrowed. If the underlying absl::Cord is non-contiguous, +the accessor copies the data from the cord into an owned ProtoString and +returns ProtoStringCow::Owned. The ProtoStringCow implements +Deref<Target=ProtoStr>.

For any of these field definitions:

optional string foo = 1 [ctype = CORD];
+string foo = 1 [ctype = CORD];
+optional bytes foo = 1 [ctype = CORD];
+bytes foo = 1 [ctype = CORD];
+

The compiler generates the following accessor methods:

  • fn my_field(&self) -> ProtoStringCow<'_>: Returns the current value of the +field. If the field is not set, returns the empty string/empty bytes.
  • fn set_my_field(&mut self, value: IntoProxied<ProtoString>): Sets the +field to value. After calling this function foo() returns value and +has_foo() returns true.
  • fn has_foo(&self) -> bool: Returns true if the field is set.
  • fn clear_foo(&mut self): Clears the value of the field. After calling +this, has_foo() returns false and foo() returns the default value. +Cords have not been implemented yet.

For fields of type bytes the compiler generates the ProtoBytesCow type +instead.

The compiler generates the following accessor methods:

  • fn foo(&self) -> &ProtoStr: Returns the current value of the field. If the +field is not set, returns the empty string/empty bytes.
  • fn set_foo(&mut self, value: impl IntoProxied<ProtoString>): Sets the +field to value.

Enum Fields

Given the enum type:

enum Bar {
+  BAR_UNSPECIFIED = 0;
+  BAR_VALUE = 1;
+  BAR_OTHER_VALUE = 2;
+}
+

The compiler generates a struct where each variant is an associated constant:

#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+#[repr(transparent)]
+pub struct Bar(i32);
+
+impl Bar {
+  pub const Unspecified: Bar = Bar(0);
+  pub const Value: Bar = Bar(1);
+  pub const OtherValue: Bar = Bar(2);
+}
+

For these field definitions:

// proto3
+Bar foo = 1;
+
+// editions
+message MyMessage {
+ Bar foo = 1 [features.field_presence = IMPLICIT];
+}
+

The compiler will generate the following accessor methods:

  • fn foo(&self) -> Bar: Returns the current value of the field. If the field +is not set, it returns the default value.
  • fn set_foo(&mut self, value: Bar): Sets the value of the field. After +calling this, has_foo() will return true and foo() will return +value.

Repeated Fields

For any repeated field definition the compiler will generate the same three +accessor methods that deviate only in the field type.

In editions, you can control the wire format encoding of repeated primitive +fields using the +repeated_field_encoding +feature.

// proto2
+repeated int32 foo = 1; // EXPANDED by default
+
+// proto3
+repeated int32 foo = 1; // PACKED by default
+
+// editions
+repeated int32 foo = 1 [features.repeated_field_encoding = PACKED];
+repeated int32 bar = 2 [features.repeated_field_encoding = EXPANDED];
+

Given any of the above field definitions, the compiler generates the following +accessor methods:

  • fn foo(&self) -> RepeatedView<'_, i32>: Returns a view of the underlying +repeated field. See +RepeatedView rustdoc.
  • fn foo_mut(&mut self) -> RepeatedMut<'_, i32>: Returns a mutable handle to +the underlying repeated field. See +RepeatedMut rustdoc.
  • fn set_foo(&mut self, src: impl IntoProxied<Repeated<i32>>): Sets the +underlying repeated field to a new repeated field provided in src. Accepts +a RepeatedView, RepeatedMut or Repeated. See +Repeated rustdoc.

For different field types only the respective generic types of the +RepeatedView, RepeatedMut and Repeated types will change. For example, +given a field of type string the foo() accessor would return a +RepeatedView<'_, ProtoString>.

Map Fields

For this map field definition:

map<int32, int32> weight = 1;
+

The compiler will generate the following 3 accessor methods:

  • fn weight(&self) -> protobuf::MapView<'_, i32, i32>: Returns an immutable +view of the underlying map. See +MapView rustdoc.
  • fn weight_mut(&mut self) -> protobuf::MapMut<'_, i32, i32>: Returns a +mutable handle to the underlying map. See +MapMut rustdoc.
  • fn set_weight(&mut self, src: protobuf::IntoProxied<Map<i32, i32>>): Sets +the underlying map to src. Accepts a MapView, MapMut or Map. See +Map rustdoc.

For different field types only the respective generic types of the MapView, +MapMut and Map types will change. For example, given a field of type +string the foo() accessor would return a MapView<'_, int32, ProtoString>.

Any

Any is not special-cased by Rust Protobuf at this time; it will behave as though +it was a simple message with this definition:

message Any {
+  string type_url = 1;
+  bytes value = 2;
+}
+

Oneof

Given a oneof definition like this:

oneof example_name {
+    int32 foo_int = 4;
+    string foo_string = 9;
+    ...
+}
+

The compiler will generate accessors (getters, setters, hazzers) for every field +as if the same field was declared as an optional field outside of the oneof. +So you can work with oneof fields like regular fields, but setting one will +clear the other fields in the oneof block. In addition, the following types are +emitted for the oneof block:

  #[non_exhaustive]
+  #[derive(Debug, Clone, Copy)]
+
+  pub enum ExampleNameOneof<'msg> {
+    FooInt(i32) = 4,
+    FooString(&'msg protobuf::ProtoStr) = 9,
+    not_set(std::marker::PhantomData<&'msg ()>) = 0
+  }
+
  #[derive(Debug, Copy, Clone, PartialEq, Eq)]
+
+  pub enum ExampleNameCase {
+    FooInt = 4,
+    FooString = 9,
+    not_set = 0
+  }
+

Additionally, it will generate the two accessors:

  • 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 +indicating which field is set. Returns not_set if no field is set.

Enumerations

Given an enum definition like:

enum FooBar {
+  FOO_BAR_UNKNOWN = 0;
+  FOO_BAR_A = 1;
+  FOO_B = 5;
+  VALUE_C = 1234;
+}
+

The compiler will generate:

  #[derive(Clone, Copy, PartialEq, Eq, Hash)]
+  #[repr(transparent)]
+  pub struct FooBar(i32);
+
+  impl FooBar {
+    pub const Unknown: FooBar = FooBar(0);
+    pub const A: FooBar = FooBar(1);
+    pub const FooB: FooBar = FooBar(5);
+    pub const ValueC: FooBar = FooBar(1234);
+  }
+

Note that for values with a prefix that matches the enum, the prefix will be +stripped; this is done to improve ergonomics. Enum values are commonly prefixed +with the enum name to avoid name collisions between sibling enums (which follow +the semantics of C++ enums where the values are not scoped by their containing +enum). Since the generated Rust consts are scoped within the impl, the +additional prefix, which is beneficial to add in .proto files, would be +redundant in Rust.

Extensions

Protobuf Rust supports extensions for proto2 messages. Extensions are accessed +via generated ExtensionId constants.

Given a message with extensions defined:

package xyz;
+message Foo {
+  extensions 100 to 199;
+}
+
+extend Foo {
+  optional int32 i32_ext = 100;
+  repeated int32 repeated_i32_ext = 101;
+}
+

The compiler generates constants of type proto::ExtensionId named I32_EXT +and REPEATED_I32_EXT, which you can use to read and write the extensions on +the Foo type.

Accessing Extensions

The ExtensionId type provides methods to interact with extensions on a +message. These methods work with owned messages, views, and muts.

  • fn has(&self, msg: impl AsView<Target = M>) -> bool: Returns true if the +extension is set on the message. (Not available for repeated extensions, by +design).
  • fn get(&self, msg: impl AsView<Target = M>) -> View<'_, E>: Returns the +value of the extension. If not set, returns the default value. For repeated +fields, returns a RepeatedView.
  • fn set(&self, msg: impl AsMut<Target = M>, value: impl IntoProxied<E>): +Sets the value of the extension.
  • fn clear(&self, msg: impl AsMut<Target = M>): Clears the extension from +the message.
  • fn get_mut(&self, msg: impl AsMut<Target = M>) -> Mut<'_, E>: Returns a +mutable handle to the extension. For messages and repeated fields, this will +create the field if it doesn’t exist.

Example Usage

use protobuf::prelude::*;
+
+let mut foo = xyz::Foo::new();
+
+// Check and set scalar extension
+assert!(!xyz::INT32_EXT.has(&foo));
+xyz::INT32_EXT.set(&mut foo, 42);
+assert!(xyz::INT32_EXT.has(&foo));
+assert_eq!(xyz::INT32_EXT.get(&foo), 42);
+
+// Clear scalar extension
+xyz::INT32_EXT.clear(&mut foo);
+assert!(!xyz::INT32_EXT.has(&foo));
+
+// Working with repeated extensions
+{
+    let mut rep_mut = xyz::REPEATED_INT32_EXT.get_mut(&mut foo);
+    rep_mut.push(1);
+    rep_mut.push(2);
+}
+assert_eq!(xyz::REPEATED_INT32_EXT.get(&foo).len(), 2);
+assert_eq!(xyz::REPEATED_INT32_EXT.get(&foo).get(0), Some(1));
+

Arena Allocation

A Rust API for arena allocated messages has not yet been implemented.

Internally, Protobuf Rust on upb kernel uses arenas, but on C++ kernels it +doesn’t. However, references (both const and mutable) to messages that were +arena allocated in C++ can be safely passed to Rust to be accessed or mutated.

Services

A Rust API for services has not yet been implemented.

\ No newline at end of file diff --git a/reference/rust/rust-redaction/index.html b/reference/rust/rust-redaction/index.html new file mode 100644 index 000000000..d314d85e1 --- /dev/null +++ b/reference/rust/rust-redaction/index.html @@ -0,0 +1,13 @@ +Redaction in Rust | Protocol Buffers Documentation +

Redaction in Rust

Describes redaction in Rust.

Use the standard fmt::Debug ("{:?}" in format strings) on Protobuf messages +for human-readable strings for logging, error messages, exceptions, and similar +use cases. The output of this debug info is not intended to be machine-readable +(unlike TextFormat and JSON which are +not be used for debug output).

Using fmt::Debug enables redaction of some sensitive fields.

Note that under upb kernel this redaction is not yet implemented, but is +expected to be added.

\ No newline at end of file diff --git a/scss/main.min.4f1376b1ff36b4e1500eb32a3dc4db0108d6e7f4e3a5c5edcfa32e8114b87427.css b/scss/main.min.4f1376b1ff36b4e1500eb32a3dc4db0108d6e7f4e3a5c5edcfa32e8114b87427.css new file mode 100644 index 000000000..4e271e40e --- /dev/null +++ b/scss/main.min.4f1376b1ff36b4e1500eb32a3dc4db0108d6e7f4e3a5c5edcfa32e8114b87427.css @@ -0,0 +1,9 @@ +@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,700,700i&display=swap";:root,[data-bs-theme=light]{--td-pre-bg:var(--bs-tertiary-bg)}/*!* Bootstrap v5.3.3 (https://getbootstrap.com/) +* Copyright 2011-2024 The Bootstrap Authors +* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)*/:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#30638e;--bs-secondary:#ffa630;--bs-success:#3772ff;--bs-info:#c0e0de;--bs-warning:#ed6a5a;--bs-danger:#ed6a5a;--bs-light:#d3f3ee;--bs-dark:#403f4c;--bs-primary-rgb:48, 99, 142;--bs-secondary-rgb:255, 166, 48;--bs-success-rgb:55, 114, 255;--bs-info-rgb:192, 224, 222;--bs-warning-rgb:237, 106, 90;--bs-danger-rgb:237, 106, 90;--bs-light-rgb:211, 243, 238;--bs-dark-rgb:64, 63, 76;--bs-primary-text-emphasis:#132839;--bs-secondary-text-emphasis:#664213;--bs-success-text-emphasis:#162e66;--bs-info-text-emphasis:#4d5a59;--bs-warning-text-emphasis:#5f2a24;--bs-danger-text-emphasis:#5f2a24;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#d6e0e8;--bs-secondary-bg-subtle:#ffedd6;--bs-success-bg-subtle:#d7e3ff;--bs-info-bg-subtle:#f2f9f8;--bs-warning-bg-subtle:#fbe1de;--bs-danger-bg-subtle:#fbe1de;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#acc1d2;--bs-secondary-border-subtle:#ffdbac;--bs-success-border-subtle:#afc7ff;--bs-info-border-subtle:#e6f3f2;--bs-warning-border-subtle:#f8c3bd;--bs-danger-border-subtle:#f8c3bd;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255, 255, 255;--bs-black-rgb:0, 0, 0;--bs-font-sans-serif:"Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--bs-font-monospace:SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:"Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33, 37, 41;--bs-body-bg:#fff;--bs-body-bg-rgb:255, 255, 255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0, 0, 0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33, 37, 41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233, 236, 239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33, 37, 41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248, 249, 250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13, 110, 253;--bs-link-decoration:underline;--bs-link-hover-color:#094db1;--bs-link-hover-color-rgb:9, 77, 177;--bs-code-color:#99641d;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(48, 99, 142, 0.25);--bs-form-valid-color:#3772ff;--bs-form-valid-border-color:#3772ff;--bs-form-invalid-color:#ed6a5a;--bs-form-invalid-border-color:#ed6a5a}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#dee2e6;--bs-body-color-rgb:222, 226, 230;--bs-body-bg:#212529;--bs-body-bg-rgb:33, 37, 41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255, 255, 255;--bs-secondary-color:rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb:222, 226, 230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52, 58, 64;--bs-tertiary-color:rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb:222, 226, 230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43, 48, 53;--bs-primary-text-emphasis:#83a1bb;--bs-secondary-text-emphasis:#ffca83;--bs-success-text-emphasis:#87aaff;--bs-info-text-emphasis:#d9eceb;--bs-warning-text-emphasis:#f4a69c;--bs-danger-text-emphasis:#f4a69c;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#0a141c;--bs-secondary-bg-subtle:#33210a;--bs-success-bg-subtle:#0b1733;--bs-info-bg-subtle:#262d2c;--bs-warning-bg-subtle:#2f1512;--bs-danger-bg-subtle:#2f1512;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#1d3b55;--bs-secondary-border-subtle:#99641d;--bs-success-border-subtle:#214499;--bs-info-border-subtle:#738685;--bs-warning-border-subtle:#8e4036;--bs-danger-border-subtle:#8e4036;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inherit;--bs-link-color:#83a1bb;--bs-link-hover-color:#a8bdcf;--bs-link-color-rgb:131, 161, 187;--bs-link-hover-color-rgb:168, 189, 207;--bs-code-color:#c2a277;--bs-highlight-color:#dee2e6;--bs-highlight-bg:#664d03;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15);--bs-form-valid-color:#75b798;--bs-form-valid-border-color:#75b798;--bs-form-invalid-color:#ea868f;--bs-form-invalid-border-color:#ea868f}*,*::before,*::after{box-sizing:border-box}@media(prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width)solid;opacity:.25}h6,.h6,h5,.h5,h4,.h4,h3,.h3,.td-footer__links-item,h2,.h2,h1,.h1{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color)}h1,.h1{font-size:calc(1.375rem + 1.5vw)}@media(min-width:1200px){h1,.h1{font-size:2.5rem}}h2,.h2{font-size:calc(1.325rem + .9vw)}@media(min-width:1200px){h2,.h2{font-size:2rem}}h3,.h3,.td-footer__links-item{font-size:calc(1.275rem + .3vw)}@media(min-width:1200px){h3,.h3,.td-footer__links-item{font-size:1.5rem}}h4,.h4{font-size:calc(1.26rem + .12vw)}@media(min-width:1200px){h4,.h4{font-size:1.35rem}}h5,.h5{font-size:1.15rem}h6,.h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small,.small,.td-footer__center,.td-cover-block>.byline{font-size:.875em}mark,.mark{padding:.1875em;color:var(--bs-highlight-color);background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}thead,tbody,tfoot,tr,td,th{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button:not(:disabled),[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media(min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled,.td-blog-posts-list{padding-left:0;list-style:none}.list-inline,.td-footer__links-list{padding-left:0;list-style:none}.list-inline-item,.td-footer__links-item{display:inline-block}.list-inline-item:not(:last-child),.td-footer__links-item:not(:last-child){margin-right:1rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid,.td-content img{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:var(--bs-body-bg);border:var(--bs-border-width)solid var(--bs-border-color);border-radius:var(--bs-border-radius);box-shadow:var(--bs-box-shadow-sm);max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:var(--bs-secondary-color)}.container,.container-fluid,.container-xxl,.container-xl,.container-lg,.container-md,.container-sm{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media(min-width:576px){.container-sm,.container{max-width:540px}}@media(min-width:768px){.container-md,.container-sm,.container{max-width:720px}}@media(min-width:992px){.container-lg,.container-md,.container-sm,.container{max-width:960px}}@media(min-width:1200px){.container-xl,.container-lg,.container-md,.container-sm,.container{max-width:1140px}}@media(min-width:1400px){.container-xxl,.container-xl,.container-lg,.container-md,.container-sm,.container{max-width:1320px}}:root{--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0}.row-cols-auto>*{flex:none;width:auto}.row-cols-1>*{flex:none;width:100%}.row-cols-2>*{flex:none;width:50%}.row-cols-3>*{flex:none;width:33.33333333%}.row-cols-4>*{flex:none;width:25%}.row-cols-5>*{flex:none;width:20%}.row-cols-6>*{flex:none;width:16.66666667%}.col-auto{flex:none;width:auto}.col-1{flex:none;width:8.33333333%}.col-2{flex:none;width:16.66666667%}.col-3{flex:none;width:25%}.col-4{flex:none;width:33.33333333%}.col-5{flex:none;width:41.66666667%}.col-6{flex:none;width:50%}.col-7{flex:none;width:58.33333333%}.col-8{flex:none;width:66.66666667%}.col-9{flex:none;width:75%}.col-10{flex:none;width:83.33333333%}.col-11{flex:none;width:91.66666667%}.col-12{flex:none;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media(min-width:576px){.col-sm{flex:1 0}.row-cols-sm-auto>*{flex:none;width:auto}.row-cols-sm-1>*{flex:none;width:100%}.row-cols-sm-2>*{flex:none;width:50%}.row-cols-sm-3>*{flex:none;width:33.33333333%}.row-cols-sm-4>*{flex:none;width:25%}.row-cols-sm-5>*{flex:none;width:20%}.row-cols-sm-6>*{flex:none;width:16.66666667%}.col-sm-auto{flex:none;width:auto}.col-sm-1{flex:none;width:8.33333333%}.col-sm-2{flex:none;width:16.66666667%}.col-sm-3{flex:none;width:25%}.col-sm-4{flex:none;width:33.33333333%}.col-sm-5{flex:none;width:41.66666667%}.col-sm-6{flex:none;width:50%}.col-sm-7{flex:none;width:58.33333333%}.col-sm-8{flex:none;width:66.66666667%}.col-sm-9{flex:none;width:75%}.col-sm-10{flex:none;width:83.33333333%}.col-sm-11{flex:none;width:91.66666667%}.col-sm-12{flex:none;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media(min-width:768px){.col-md{flex:1 0}.row-cols-md-auto>*{flex:none;width:auto}.row-cols-md-1>*{flex:none;width:100%}.row-cols-md-2>*{flex:none;width:50%}.row-cols-md-3>*{flex:none;width:33.33333333%}.row-cols-md-4>*{flex:none;width:25%}.row-cols-md-5>*{flex:none;width:20%}.row-cols-md-6>*{flex:none;width:16.66666667%}.col-md-auto{flex:none;width:auto}.col-md-1{flex:none;width:8.33333333%}.col-md-2{flex:none;width:16.66666667%}.col-md-3{flex:none;width:25%}.col-md-4{flex:none;width:33.33333333%}.col-md-5{flex:none;width:41.66666667%}.col-md-6{flex:none;width:50%}.col-md-7{flex:none;width:58.33333333%}.col-md-8{flex:none;width:66.66666667%}.col-md-9{flex:none;width:75%}.col-md-10{flex:none;width:83.33333333%}.col-md-11{flex:none;width:91.66666667%}.col-md-12{flex:none;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media(min-width:992px){.col-lg{flex:1 0}.row-cols-lg-auto>*{flex:none;width:auto}.row-cols-lg-1>*{flex:none;width:100%}.row-cols-lg-2>*{flex:none;width:50%}.row-cols-lg-3>*{flex:none;width:33.33333333%}.row-cols-lg-4>*{flex:none;width:25%}.row-cols-lg-5>*{flex:none;width:20%}.row-cols-lg-6>*{flex:none;width:16.66666667%}.col-lg-auto{flex:none;width:auto}.col-lg-1{flex:none;width:8.33333333%}.col-lg-2{flex:none;width:16.66666667%}.col-lg-3{flex:none;width:25%}.col-lg-4{flex:none;width:33.33333333%}.col-lg-5{flex:none;width:41.66666667%}.col-lg-6{flex:none;width:50%}.col-lg-7{flex:none;width:58.33333333%}.col-lg-8{flex:none;width:66.66666667%}.col-lg-9{flex:none;width:75%}.col-lg-10{flex:none;width:83.33333333%}.col-lg-11{flex:none;width:91.66666667%}.col-lg-12{flex:none;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media(min-width:1200px){.col-xl{flex:1 0}.row-cols-xl-auto>*{flex:none;width:auto}.row-cols-xl-1>*{flex:none;width:100%}.row-cols-xl-2>*{flex:none;width:50%}.row-cols-xl-3>*{flex:none;width:33.33333333%}.row-cols-xl-4>*{flex:none;width:25%}.row-cols-xl-5>*{flex:none;width:20%}.row-cols-xl-6>*{flex:none;width:16.66666667%}.col-xl-auto{flex:none;width:auto}.col-xl-1{flex:none;width:8.33333333%}.col-xl-2{flex:none;width:16.66666667%}.col-xl-3{flex:none;width:25%}.col-xl-4{flex:none;width:33.33333333%}.col-xl-5{flex:none;width:41.66666667%}.col-xl-6{flex:none;width:50%}.col-xl-7{flex:none;width:58.33333333%}.col-xl-8{flex:none;width:66.66666667%}.col-xl-9{flex:none;width:75%}.col-xl-10{flex:none;width:83.33333333%}.col-xl-11{flex:none;width:91.66666667%}.col-xl-12{flex:none;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media(min-width:1400px){.col-xxl{flex:1 0}.row-cols-xxl-auto>*{flex:none;width:auto}.row-cols-xxl-1>*{flex:none;width:100%}.row-cols-xxl-2>*{flex:none;width:50%}.row-cols-xxl-3>*{flex:none;width:33.33333333%}.row-cols-xxl-4>*{flex:none;width:25%}.row-cols-xxl-5>*{flex:none;width:20%}.row-cols-xxl-6>*{flex:none;width:16.66666667%}.col-xxl-auto{flex:none;width:auto}.col-xxl-1{flex:none;width:8.33333333%}.col-xxl-2{flex:none;width:16.66666667%}.col-xxl-3{flex:none;width:25%}.col-xxl-4{flex:none;width:33.33333333%}.col-xxl-5{flex:none;width:41.66666667%}.col-xxl-6{flex:none;width:50%}.col-xxl-7{flex:none;width:58.33333333%}.col-xxl-8{flex:none;width:66.66666667%}.col-xxl-9{flex:none;width:75%}.col-xxl-10{flex:none;width:83.33333333%}.col-xxl-11{flex:none;width:91.66666667%}.col-xxl-12{flex:none;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table,.td-table:not(.td-initial),.td-content table:not(.td-initial),.td-box table:not(.td-initial){--bs-table-color-type:initial;--bs-table-bg-type:initial;--bs-table-color-state:initial;--bs-table-bg-state:initial;--bs-table-color:var(--bs-emphasis-color);--bs-table-bg:var(--bs-body-bg);--bs-table-border-color:var(--bs-border-color);--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-emphasis-color);--bs-table-striped-bg:rgba(var(--bs-emphasis-color-rgb), 0.05);--bs-table-active-color:var(--bs-emphasis-color);--bs-table-active-bg:rgba(var(--bs-emphasis-color-rgb), 0.1);--bs-table-hover-color:var(--bs-emphasis-color);--bs-table-hover-bg:rgba(var(--bs-emphasis-color-rgb), 0.075);width:100%;margin-bottom:1rem;vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*,.td-table:not(.td-initial)>:not(caption)>*>*,.td-content table:not(.td-initial)>:not(caption)>*>*,.td-box table:not(.td-initial)>:not(caption)>*>*{padding:.5rem;color:var(--bs-table-color-state,var(--bs-table-color-type,var(--bs-table-color)));background-color:var(--bs-table-bg);border-bottom-width:var(--bs-border-width);box-shadow:inset 0 0 0 9999px var(--bs-table-bg-state,var(--bs-table-bg-type,var(--bs-table-accent-bg)))}.table>tbody,.td-table:not(.td-initial)>tbody,.td-content table:not(.td-initial)>tbody,.td-box table:not(.td-initial)>tbody{vertical-align:inherit}.table>thead,.td-table:not(.td-initial)>thead,.td-content table:not(.td-initial)>thead,.td-box table:not(.td-initial)>thead{vertical-align:bottom}.table-group-divider{border-top:calc(var(--bs-border-width) * 2)solid}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem}.table-bordered>:not(caption)>*{border-width:var(--bs-border-width)0}.table-bordered>:not(caption)>*>*{border-width:0 var(--bs-border-width)}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*,.td-table:not(.td-initial)>tbody>tr:nth-of-type(odd)>*,.td-content table:not(.td-initial)>tbody>tr:nth-of-type(odd)>*,.td-box table:not(.td-initial)>tbody>tr:nth-of-type(odd)>*{--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-striped-columns>:not(caption)>tr>:nth-child(even){--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-active{--bs-table-color-state:var(--bs-table-active-color);--bs-table-bg-state:var(--bs-table-active-bg)}.table-hover>tbody>tr:hover>*{--bs-table-color-state:var(--bs-table-hover-color);--bs-table-bg-state:var(--bs-table-hover-bg)}.table-primary{--bs-table-color:#000;--bs-table-bg:#d6e0e8;--bs-table-border-color:#abb3ba;--bs-table-striped-bg:#cbd5dc;--bs-table-striped-color:#000;--bs-table-active-bg:#c1cad1;--bs-table-active-color:#000;--bs-table-hover-bg:#c6cfd7;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#000;--bs-table-bg:#ffedd6;--bs-table-border-color:#ccbeab;--bs-table-striped-bg:#f2e1cb;--bs-table-striped-color:#000;--bs-table-active-bg:#e6d5c1;--bs-table-active-color:#000;--bs-table-hover-bg:#ecdbc6;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#000;--bs-table-bg:#d7e3ff;--bs-table-border-color:#acb6cc;--bs-table-striped-bg:#ccd8f2;--bs-table-striped-color:#000;--bs-table-active-bg:#c2cce6;--bs-table-active-color:#000;--bs-table-hover-bg:#c7d2ec;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#000;--bs-table-bg:#f2f9f8;--bs-table-border-color:#c2c7c6;--bs-table-striped-bg:#e6edec;--bs-table-striped-color:#000;--bs-table-active-bg:#dae0df;--bs-table-active-color:#000;--bs-table-hover-bg:#e0e6e5;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#000;--bs-table-bg:#fbe1de;--bs-table-border-color:#c9b4b2;--bs-table-striped-bg:#eed6d3;--bs-table-striped-color:#000;--bs-table-active-bg:#e2cbc8;--bs-table-active-color:#000;--bs-table-hover-bg:#e8d0cd;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#000;--bs-table-bg:#fbe1de;--bs-table-border-color:#c9b4b2;--bs-table-striped-bg:#eed6d3;--bs-table-striped-color:#000;--bs-table-active-bg:#e2cbc8;--bs-table-active-color:#000;--bs-table-hover-bg:#e8d0cd;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#000;--bs-table-bg:#d3f3ee;--bs-table-border-color:#a9c2be;--bs-table-striped-bg:#c8e7e2;--bs-table-striped-color:#000;--bs-table-active-bg:#bedbd6;--bs-table-active-color:#000;--bs-table-hover-bg:#c3e1dc;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#403f4c;--bs-table-border-color:#666570;--bs-table-striped-bg:#4a4955;--bs-table-striped-color:#fff;--bs-table-active-bg:#53525e;--bs-table-active-color:#fff;--bs-table-hover-bg:#4e4d59;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive,.td-table:not(.td-initial),.td-content table:not(.td-initial),.td-box table:not(.td-initial){overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + var(--bs-border-width));padding-bottom:calc(.375rem + var(--bs-border-width));margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + var(--bs-border-width));padding-bottom:calc(.5rem + var(--bs-border-width));font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + var(--bs-border-width));padding-bottom:calc(.25rem + var(--bs-border-width));font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--bs-secondary-color)}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-clip:padding-box;border:var(--bs-border-width)solid var(--bs-border-color);border-radius:var(--bs-border-radius);box-shadow:var(--bs-box-shadow-inset);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--bs-body-color);background-color:var(--bs-body-bg);border-color:#98b1c7;outline:0;box-shadow:var(--bs-box-shadow-inset),0 0 0 .25rem rgba(48,99,142,.25)}.form-control::-webkit-date-and-time-value{min-width:85px;height:1.5em;margin:0}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::-moz-placeholder{color:var(--bs-secondary-color);opacity:1}.form-control::placeholder{color:var(--bs-secondary-color);opacity:1}.form-control:disabled{background-color:var(--bs-secondary-bg);opacity:1}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);background-image:var(--bs-gradient);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:var(--bs-secondary-bg)}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:var(--bs-body-color);background-color:transparent;border:solid transparent;border-width:var(--bs-border-width)0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2));padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2))}textarea.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}textarea.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-control-color{width:3rem;height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2));padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color::-webkit-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon,none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width)solid var(--bs-border-color);border-radius:var(--bs-border-radius);box-shadow:var(--bs-box-shadow-inset);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#98b1c7;outline:0;box-shadow:var(--bs-box-shadow-inset),0 0 0 .25rem rgba(48,99,142,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:var(--bs-secondary-bg)}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--bs-body-color)}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}[data-bs-theme=dark] .form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23dee2e6' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e")}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{--bs-form-check-bg:var(--bs-body-bg);flex-shrink:0;width:1em;height:1em;margin-top:.25em;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:50%;background-size:contain;border:var(--bs-border-width)solid var(--bs-border-color);-webkit-print-color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#98b1c7;outline:0;box-shadow:0 0 0 .25rem rgba(48,99,142,.25)}.form-check-input:checked{background-color:#30638e;border-color:#30638e}.form-check-input:checked[type=checkbox]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e"), var(--bs-gradient)}.form-check-input:checked[type=radio]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e"), var(--bs-gradient)}.form-check-input[type=checkbox]:indeterminate{background-color:#30638e;border-color:#30638e;--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e"), var(--bs-gradient)}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input[disabled]~.form-check-label,.form-check-input:disabled~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");width:2em;margin-left:-2.5em;background-image:var(--bs-form-switch-bg);background-position:0;border-radius:2em;transition:background-position .15s ease-in-out}@media(prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2398b1c7'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:100%;--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e"), var(--bs-gradient)}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check[disabled]+.btn,div.drawio .btn-check[disabled]+button,.td-blog .btn-check[disabled]+.td-rss-button,.btn-check:disabled+.btn,div.drawio .btn-check:disabled+button,.td-blog .btn-check:disabled+.td-rss-button{pointer-events:none;filter:none;opacity:.65}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e")}.form-range{width:100%;height:1.5rem;padding:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(48,99,142,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(48,99,142,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;-webkit-appearance:none;appearance:none;background-color:#30638e;background-image:var(--bs-gradient);border:0;border-radius:1rem;box-shadow:0 .1rem .25rem rgba(0,0,0,.1);-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#c1d0dd;background-image:var(--bs-gradient)}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem;box-shadow:var(--bs-box-shadow-inset)}.form-range::-moz-range-thumb{width:1rem;height:1rem;-moz-appearance:none;appearance:none;background-color:#30638e;background-image:var(--bs-gradient);border:0;border-radius:1rem;box-shadow:0 .1rem .25rem rgba(0,0,0,.1);-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#c1d0dd;background-image:var(--bs-gradient)}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem;box-shadow:var(--bs-box-shadow-inset)}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:var(--bs-secondary-color)}.form-range:disabled::-moz-range-thumb{background-color:var(--bs-secondary-color)}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + calc(var(--bs-border-width) * 2));min-height:calc(3.5rem + calc(var(--bs-border-width) * 2));line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;z-index:2;height:100%;padding:1rem .75rem;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:var(--bs-border-width)solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media(prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control::-moz-placeholder,.form-floating>.form-control-plaintext::-moz-placeholder{color:transparent}.form-floating>.form-control::placeholder,.form-floating>.form-control-plaintext::placeholder{color:transparent}.form-floating>.form-control:not(:-moz-placeholder),.form-floating>.form-control-plaintext:not(:-moz-placeholder){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown),.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill,.form-floating>.form-control-plaintext:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder)~label{color:rgba(var(--bs-body-color-rgb),.65);transform:scale(.85)translateY(-.5rem)translateX(.15rem)}.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-control-plaintext~label,.form-floating>.form-select~label{color:rgba(var(--bs-body-color-rgb),.65);transform:scale(.85)translateY(-.5rem)translateX(.15rem)}.form-floating>.form-control:not(:-moz-placeholder)~label::after{position:absolute;inset:1rem .375rem;z-index:-1;height:1.5em;content:"";background-color:var(--bs-body-bg);border-radius:var(--bs-border-radius)}.form-floating>.form-control:focus~label::after,.form-floating>.form-control:not(:placeholder-shown)~label::after,.form-floating>.form-control-plaintext~label::after,.form-floating>.form-select~label::after{position:absolute;inset:1rem .375rem;z-index:-1;height:1.5em;content:"";background-color:var(--bs-body-bg);border-radius:var(--bs-border-radius)}.form-floating>.form-control:-webkit-autofill~label{color:rgba(var(--bs-body-color-rgb),.65);transform:scale(.85)translateY(-.5rem)translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:var(--bs-border-width)0}.form-floating>:disabled~label,.form-floating>.form-control:disabled~label{color:#6c757d}.form-floating>:disabled~label::after,.form-floating>.form-control:disabled~label::after{background-color:var(--bs-secondary-bg)}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select,.input-group>.form-floating{position:relative;flex:auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus,.input-group>.form-floating:focus-within{z-index:5}.input-group .btn,.input-group div.drawio button,div.drawio .input-group button,.input-group .td-blog .td-rss-button,.td-blog .input-group .td-rss-button{position:relative;z-index:2}.input-group .btn:focus,.input-group div.drawio button:focus,div.drawio .input-group button:focus,.input-group .td-blog .td-rss-button:focus,.td-blog .input-group .td-rss-button:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);text-align:center;white-space:nowrap;background-color:var(--bs-tertiary-bg);border:var(--bs-border-width)solid var(--bs-border-color);border-radius:var(--bs-border-radius)}.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text,.input-group-lg>.btn,div.drawio .input-group-lg>button,.td-blog .input-group-lg>.td-rss-button{padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text,.input-group-sm>.btn,div.drawio .input-group-sm>button,.td-blog .input-group-sm>.td-rss-button{padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select{border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:calc(var(--bs-border-width) * -1);border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-valid-color)}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-success);border-radius:var(--bs-border-radius)}.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip,.is-valid~.valid-feedback,.is-valid~.valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:var(--bs-form-valid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%233772ff' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem)center;background-size:calc(.75em + .375rem)calc(.75em + .375rem)}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:var(--bs-box-shadow-inset),0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem)right calc(.375em + .1875rem)}.was-validated .form-select:valid,.form-select.is-valid{border-color:var(--bs-form-valid-border-color)}.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"],.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%233772ff' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem)calc(.75em + .375rem)}.was-validated .form-select:valid:focus,.form-select.is-valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:var(--bs-box-shadow-inset),0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated .form-control-color:valid,.form-control-color.is-valid{width:calc(3rem + calc(1.5em + .75rem))}.was-validated .form-check-input:valid,.form-check-input.is-valid{border-color:var(--bs-form-valid-border-color)}.was-validated .form-check-input:valid:checked,.form-check-input.is-valid:checked{background-color:var(--bs-form-valid-color)}.was-validated .form-check-input:valid:focus,.form-check-input.is-valid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated .form-check-input:valid~.form-check-label,.form-check-input.is-valid~.form-check-label{color:var(--bs-form-valid-color)}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.was-validated .input-group>.form-control:not(:focus):valid,.input-group>.form-control:not(:focus).is-valid,.was-validated .input-group>.form-select:not(:focus):valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.input-group>.form-floating:not(:focus-within).is-valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-invalid-color)}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-danger);border-radius:var(--bs-border-radius)}.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip,.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:var(--bs-form-invalid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ed6a5a'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ed6a5a' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem)center;background-size:calc(.75em + .375rem)calc(.75em + .375rem)}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:var(--bs-box-shadow-inset),0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem)right calc(.375em + .1875rem)}.was-validated .form-select:invalid,.form-select.is-invalid{border-color:var(--bs-form-invalid-border-color)}.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"],.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ed6a5a'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ed6a5a' stroke='none'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem)calc(.75em + .375rem)}.was-validated .form-select:invalid:focus,.form-select.is-invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:var(--bs-box-shadow-inset),0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.was-validated .form-control-color:invalid,.form-control-color.is-invalid{width:calc(3rem + calc(1.5em + .75rem))}.was-validated .form-check-input:invalid,.form-check-input.is-invalid{border-color:var(--bs-form-invalid-border-color)}.was-validated .form-check-input:invalid:checked,.form-check-input.is-invalid:checked{background-color:var(--bs-form-invalid-color)}.was-validated .form-check-input:invalid:focus,.form-check-input.is-invalid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.was-validated .form-check-input:invalid~.form-check-label,.form-check-input.is-invalid~.form-check-label{color:var(--bs-form-invalid-color)}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.was-validated .input-group>.form-control:not(:focus):invalid,.input-group>.form-control:not(:focus).is-invalid,.was-validated .input-group>.form-select:not(:focus):invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.input-group>.form-floating:not(:focus-within).is-invalid{z-index:4}.btn,div.drawio button,.td-blog .td-rss-button{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:var(--bs-body-color);--bs-btn-bg:transparent;--bs-btn-border-width:var(--bs-border-width);--bs-btn-border-color:transparent;--bs-btn-border-radius:var(--bs-border-radius);--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y)var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width)solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);background-image:var(--bs-gradient);box-shadow:var(--bs-btn-box-shadow);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.btn,div.drawio button,.td-blog .td-rss-button{transition:none}}.btn:hover,div.drawio button:hover,.td-blog .td-rss-button:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover,div.drawio .btn-check+button:hover,.td-blog .btn-check+.td-rss-button:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible,div.drawio button:focus-visible,.td-blog .td-rss-button:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);background-image:var(--bs-gradient);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-box-shadow),var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn,div.drawio .btn-check:focus-visible+button,.td-blog .btn-check:focus-visible+.td-rss-button{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-box-shadow),var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,div.drawio .btn-check:checked+button,.td-blog .btn-check:checked+.td-rss-button,:not(.btn-check)+.btn:active,div.drawio :not(.btn-check)+button:active,.td-blog :not(.btn-check)+.td-rss-button:active,.btn:first-child:active,div.drawio button:first-child:active,.td-blog .td-rss-button:first-child:active,.btn.active,div.drawio button.active,.td-blog .active.td-rss-button,.btn.show,div.drawio button.show,.td-blog .show.td-rss-button{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);background-image:none;border-color:var(--bs-btn-active-border-color);box-shadow:var(--bs-btn-active-shadow)}.btn-check:checked+.btn:focus-visible,div.drawio .btn-check:checked+button:focus-visible,.td-blog .btn-check:checked+.td-rss-button:focus-visible,:not(.btn-check)+.btn:active:focus-visible,div.drawio :not(.btn-check)+button:active:focus-visible,.td-blog :not(.btn-check)+.td-rss-button:active:focus-visible,.btn:first-child:active:focus-visible,div.drawio button:first-child:active:focus-visible,.td-blog .td-rss-button:first-child:active:focus-visible,.btn.active:focus-visible,div.drawio button.active:focus-visible,.td-blog .active.td-rss-button:focus-visible,.btn.show:focus-visible,div.drawio button.show:focus-visible,.td-blog .show.td-rss-button:focus-visible{box-shadow:var(--bs-btn-active-shadow),var(--bs-btn-focus-box-shadow)}.btn-check:checked:focus-visible+.btn,div.drawio .btn-check:checked:focus-visible+button,.td-blog .btn-check:checked:focus-visible+.td-rss-button{box-shadow:var(--bs-btn-active-shadow),var(--bs-btn-focus-box-shadow)}.btn:disabled,div.drawio button:disabled,.td-blog .td-rss-button:disabled,.btn.disabled,div.drawio button.disabled,.td-blog .disabled.td-rss-button,fieldset:disabled .btn,fieldset:disabled div.drawio button,div.drawio fieldset:disabled button,fieldset:disabled .td-blog .td-rss-button,.td-blog fieldset:disabled .td-rss-button{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);background-image:none;border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity);box-shadow:none}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#30638e;--bs-btn-border-color:#30638e;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#295479;--bs-btn-hover-border-color:#264f72;--bs-btn-focus-shadow-rgb:79, 122, 159;--bs-btn-active-color:#fff;--bs-btn-active-bg:#264f72;--bs-btn-active-border-color:#244a6b;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#30638e;--bs-btn-disabled-border-color:#30638e}.btn-secondary{--bs-btn-color:#000;--bs-btn-bg:#ffa630;--bs-btn-border-color:#ffa630;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffb34f;--bs-btn-hover-border-color:#ffaf45;--bs-btn-focus-shadow-rgb:217, 141, 41;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffb859;--bs-btn-active-border-color:#ffaf45;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffa630;--bs-btn-disabled-border-color:#ffa630}.btn-success{--bs-btn-color:#000;--bs-btn-bg:#3772ff;--bs-btn-border-color:#3772ff;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#5587ff;--bs-btn-hover-border-color:#4b80ff;--bs-btn-focus-shadow-rgb:47, 97, 217;--bs-btn-active-color:#000;--bs-btn-active-bg:#5f8eff;--bs-btn-active-border-color:#4b80ff;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#3772ff;--bs-btn-disabled-border-color:#3772ff}.btn-info,.td-blog .td-rss-button{--bs-btn-color:#000;--bs-btn-bg:#c0e0de;--bs-btn-border-color:#c0e0de;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#c9e5e3;--bs-btn-hover-border-color:#c6e3e1;--bs-btn-focus-shadow-rgb:163, 190, 189;--bs-btn-active-color:#000;--bs-btn-active-bg:#cde6e5;--bs-btn-active-border-color:#c6e3e1;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#c0e0de;--bs-btn-disabled-border-color:#c0e0de}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ed6a5a;--bs-btn-border-color:#ed6a5a;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f08073;--bs-btn-hover-border-color:#ef796b;--bs-btn-focus-shadow-rgb:201, 90, 77;--bs-btn-active-color:#000;--bs-btn-active-bg:#f1887b;--bs-btn-active-border-color:#ef796b;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ed6a5a;--bs-btn-disabled-border-color:#ed6a5a}.btn-danger{--bs-btn-color:#000;--bs-btn-bg:#ed6a5a;--bs-btn-border-color:#ed6a5a;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f08073;--bs-btn-hover-border-color:#ef796b;--bs-btn-focus-shadow-rgb:201, 90, 77;--bs-btn-active-color:#000;--bs-btn-active-bg:#f1887b;--bs-btn-active-border-color:#ef796b;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ed6a5a;--bs-btn-disabled-border-color:#ed6a5a}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#d3f3ee;--bs-btn-border-color:#d3f3ee;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#b3cfca;--bs-btn-hover-border-color:#a9c2be;--bs-btn-focus-shadow-rgb:179, 207, 202;--bs-btn-active-color:#000;--bs-btn-active-bg:#a9c2be;--bs-btn-active-border-color:#9eb6b3;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#d3f3ee;--bs-btn-disabled-border-color:#d3f3ee}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#403f4c;--bs-btn-border-color:#403f4c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5d5c67;--bs-btn-hover-border-color:#53525e;--bs-btn-focus-shadow-rgb:93, 92, 103;--bs-btn-active-color:#fff;--bs-btn-active-bg:#666570;--bs-btn-active-border-color:#53525e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#403f4c;--bs-btn-disabled-border-color:#403f4c}.btn-outline-primary,div.drawio button{--bs-btn-color:#30638e;--bs-btn-border-color:#30638e;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#30638e;--bs-btn-hover-border-color:#30638e;--bs-btn-focus-shadow-rgb:48, 99, 142;--bs-btn-active-color:#fff;--bs-btn-active-bg:#30638e;--bs-btn-active-border-color:#30638e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#30638e;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#30638e;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#ffa630;--bs-btn-border-color:#ffa630;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffa630;--bs-btn-hover-border-color:#ffa630;--bs-btn-focus-shadow-rgb:255, 166, 48;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffa630;--bs-btn-active-border-color:#ffa630;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffa630;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffa630;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#3772ff;--bs-btn-border-color:#3772ff;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#3772ff;--bs-btn-hover-border-color:#3772ff;--bs-btn-focus-shadow-rgb:55, 114, 255;--bs-btn-active-color:#000;--bs-btn-active-bg:#3772ff;--bs-btn-active-border-color:#3772ff;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#3772ff;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#3772ff;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#c0e0de;--bs-btn-border-color:#c0e0de;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#c0e0de;--bs-btn-hover-border-color:#c0e0de;--bs-btn-focus-shadow-rgb:192, 224, 222;--bs-btn-active-color:#000;--bs-btn-active-bg:#c0e0de;--bs-btn-active-border-color:#c0e0de;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#c0e0de;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#c0e0de;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ed6a5a;--bs-btn-border-color:#ed6a5a;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ed6a5a;--bs-btn-hover-border-color:#ed6a5a;--bs-btn-focus-shadow-rgb:237, 106, 90;--bs-btn-active-color:#000;--bs-btn-active-bg:#ed6a5a;--bs-btn-active-border-color:#ed6a5a;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ed6a5a;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ed6a5a;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#ed6a5a;--bs-btn-border-color:#ed6a5a;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ed6a5a;--bs-btn-hover-border-color:#ed6a5a;--bs-btn-focus-shadow-rgb:237, 106, 90;--bs-btn-active-color:#000;--bs-btn-active-bg:#ed6a5a;--bs-btn-active-border-color:#ed6a5a;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ed6a5a;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ed6a5a;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#d3f3ee;--bs-btn-border-color:#d3f3ee;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3f3ee;--bs-btn-hover-border-color:#d3f3ee;--bs-btn-focus-shadow-rgb:211, 243, 238;--bs-btn-active-color:#000;--bs-btn-active-bg:#d3f3ee;--bs-btn-active-border-color:#d3f3ee;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#d3f3ee;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#d3f3ee;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#403f4c;--bs-btn-border-color:#403f4c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#403f4c;--bs-btn-hover-border-color:#403f4c;--bs-btn-focus-shadow-rgb:64, 63, 76;--bs-btn-active-color:#fff;--bs-btn-active-bg:#403f4c;--bs-btn-active-border-color:#403f4c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#403f4c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#403f4c;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:0 0 0 #000;--bs-btn-focus-shadow-rgb:49, 132, 253;text-decoration:underline;background-image:none}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-lg,.td-blog .td-rss-button,.btn-group-lg>.btn,div.drawio .btn-group-lg>button{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:var(--bs-border-radius-lg)}.btn-sm,.btn-group-sm>.btn,div.drawio .btn-group-sm>button,.td-blog .btn-group-sm>.td-rss-button{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:var(--bs-border-radius-sm)}.fade{transition:opacity .15s linear}@media(prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media(prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media(prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropup,.dropend,.dropdown,.dropstart,.dropup-center,.dropdown-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:var(--bs-body-color);--bs-dropdown-bg:var(--bs-body-bg);--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-border-radius:var(--bs-border-radius);--bs-dropdown-border-width:var(--bs-border-width);--bs-dropdown-inner-border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:var(--bs-box-shadow);--bs-dropdown-link-color:var(--bs-body-color);--bs-dropdown-link-hover-color:var(--bs-body-color);--bs-dropdown-link-hover-bg:var(--bs-tertiary-bg);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#30638e;--bs-dropdown-link-disabled-color:var(--bs-tertiary-color);--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#6c757d;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y)var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width)solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius);box-shadow:var(--bs-dropdown-box-shadow)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media(min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media(min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media(min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media(min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media(min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y)0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y)var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0;border-radius:var(--bs-dropdown-item-border-radius,0)}.dropdown-item:hover,.dropdown-item:focus{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg);background-image:var(--bs-gradient)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg);background-image:var(--bs-gradient)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent;background-image:none}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y)var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y)var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#343a40;--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#30638e;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,div.drawio .btn-group>button,.td-blog .btn-group>.td-rss-button,.btn-group-vertical>.btn,div.drawio .btn-group-vertical>button,.td-blog .btn-group-vertical>.td-rss-button{position:relative;flex:auto}.btn-group>.btn-check:checked+.btn,div.drawio .btn-group>.btn-check:checked+button,.td-blog .btn-group>.btn-check:checked+.td-rss-button,.btn-group>.btn-check:focus+.btn,div.drawio .btn-group>.btn-check:focus+button,.td-blog .btn-group>.btn-check:focus+.td-rss-button,.btn-group>.btn:hover,div.drawio .btn-group>button:hover,.td-blog .btn-group>.td-rss-button:hover,.btn-group>.btn:focus,div.drawio .btn-group>button:focus,.td-blog .btn-group>.td-rss-button:focus,.btn-group>.btn:active,div.drawio .btn-group>button:active,.td-blog .btn-group>.td-rss-button:active,.btn-group>.btn.active,div.drawio .btn-group>button.active,.td-blog .btn-group>.active.td-rss-button,.btn-group-vertical>.btn-check:checked+.btn,div.drawio .btn-group-vertical>.btn-check:checked+button,.td-blog .btn-group-vertical>.btn-check:checked+.td-rss-button,.btn-group-vertical>.btn-check:focus+.btn,div.drawio .btn-group-vertical>.btn-check:focus+button,.td-blog .btn-group-vertical>.btn-check:focus+.td-rss-button,.btn-group-vertical>.btn:hover,div.drawio .btn-group-vertical>button:hover,.td-blog .btn-group-vertical>.td-rss-button:hover,.btn-group-vertical>.btn:focus,div.drawio .btn-group-vertical>button:focus,.td-blog .btn-group-vertical>.td-rss-button:focus,.btn-group-vertical>.btn:active,div.drawio .btn-group-vertical>button:active,.td-blog .btn-group-vertical>.td-rss-button:active,.btn-group-vertical>.btn.active,div.drawio .btn-group-vertical>button.active,.td-blog .btn-group-vertical>.active.td-rss-button{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:var(--bs-border-radius)}.btn-group>:not(.btn-check:first-child)+.btn,div.drawio .btn-group>:not(.btn-check:first-child)+button,.td-blog .btn-group>:not(.btn-check:first-child)+.td-rss-button,.btn-group>.btn-group:not(:first-child){margin-left:calc(var(--bs-border-width) * -1)}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),div.drawio .btn-group>button:not(:last-child):not(.dropdown-toggle),.td-blog .btn-group>.td-rss-button:not(:last-child):not(.dropdown-toggle),.btn-group>.btn.dropdown-toggle-split:first-child,div.drawio .btn-group>button.dropdown-toggle-split:first-child,.td-blog .btn-group>.dropdown-toggle-split.td-rss-button:first-child,.btn-group>.btn-group:not(:last-child)>.btn,div.drawio .btn-group>.btn-group:not(:last-child)>button,.td-blog .btn-group>.btn-group:not(:last-child)>.td-rss-button{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:nth-child(n+3),div.drawio .btn-group>button:nth-child(n+3),.td-blog .btn-group>.td-rss-button:nth-child(n+3),.btn-group>:not(.btn-check)+.btn,div.drawio .btn-group>:not(.btn-check)+button,.td-blog .btn-group>:not(.btn-check)+.td-rss-button,.btn-group>.btn-group:not(:first-child)>.btn,div.drawio .btn-group>.btn-group:not(:first-child)>button,.td-blog .btn-group>.btn-group:not(:first-child)>.td-rss-button{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split,div.drawio .btn-group-sm>button+.dropdown-toggle-split,.td-blog .btn-group-sm>.td-rss-button+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-lg+.dropdown-toggle-split,.td-blog .td-rss-button+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split,div.drawio .btn-group-lg>button+.dropdown-toggle-split,.td-blog .btn-group-lg>.td-rss-button+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group.show .dropdown-toggle{box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.show .dropdown-toggle.btn-link{box-shadow:none}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,div.drawio .btn-group-vertical>button,.td-blog .btn-group-vertical>.td-rss-button,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),div.drawio .btn-group-vertical>button:not(:first-child),.td-blog .btn-group-vertical>.td-rss-button:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:calc(var(--bs-border-width) * -1)}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),div.drawio .btn-group-vertical>button:not(:last-child):not(.dropdown-toggle),.td-blog .btn-group-vertical>.td-rss-button:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn,div.drawio .btn-group-vertical>.btn-group:not(:last-child)>button,.td-blog .btn-group-vertical>.btn-group:not(:last-child)>.td-rss-button{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn~.btn,div.drawio .btn-group-vertical>button~.btn,div.drawio .btn-group-vertical>.btn~button,div.drawio .btn-group-vertical>button~button,.td-blog .btn-group-vertical>.td-rss-button~.btn,.td-blog div.drawio .btn-group-vertical>.td-rss-button~button,div.drawio .td-blog .btn-group-vertical>.td-rss-button~button,.td-blog .btn-group-vertical>.btn~.td-rss-button,.td-blog div.drawio .btn-group-vertical>button~.td-rss-button,div.drawio .td-blog .btn-group-vertical>button~.td-rss-button,.td-blog .btn-group-vertical>.td-rss-button~.td-rss-button,.btn-group-vertical>.btn-group:not(:first-child)>.btn,div.drawio .btn-group-vertical>.btn-group:not(:first-child)>button,.td-blog .btn-group-vertical>.btn-group:not(:first-child)>.td-rss-button{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y)var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;background:0 0;border:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media(prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:var(--bs-nav-link-hover-color)}.nav-link:focus-visible{outline:0;box-shadow:0 0 0 .25rem rgba(48,99,142,.25)}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:var(--bs-border-width);--bs-nav-tabs-border-color:var(--bs-border-color);--bs-nav-tabs-border-radius:var(--bs-border-radius);--bs-nav-tabs-link-hover-border-color:var(--bs-secondary-bg) var(--bs-secondary-bg) var(--bs-border-color);--bs-nav-tabs-link-active-color:var(--bs-emphasis-color);--bs-nav-tabs-link-active-bg:var(--bs-body-bg);--bs-nav-tabs-link-active-border-color:var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg);border-bottom:var(--bs-nav-tabs-border-width)solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));border:var(--bs-nav-tabs-border-width)solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:var(--bs-border-radius);--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#30638e}.nav-pills .nav-link{border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg);background-image:var(--bs-gradient)}.nav-underline{--bs-nav-underline-gap:1rem;--bs-nav-underline-border-width:0.125rem;--bs-nav-underline-link-active-color:var(--bs-emphasis-color);gap:var(--bs-nav-underline-gap)}.nav-underline .nav-link{padding-right:0;padding-left:0;border-bottom:var(--bs-nav-underline-border-width)solid transparent}.nav-underline .nav-link:hover,.nav-underline .nav-link:focus{border-bottom-color:initial}.nav-underline .nav-link.active,.nav-underline .show>.nav-link{font-weight:700;color:var(--bs-nav-underline-link-active-color);border-bottom-color:initial}.nav-fill>.nav-link,.nav-fill .nav-item{flex:auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar,.td-navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:0.5rem;--bs-navbar-color:rgba(var(--bs-emphasis-color-rgb), 0.65);--bs-navbar-hover-color:rgba(var(--bs-emphasis-color-rgb), 0.8);--bs-navbar-disabled-color:rgba(var(--bs-emphasis-color-rgb), 0.3);--bs-navbar-active-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-hover-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2833, 37, 41, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(var(--bs-emphasis-color-rgb), 0.15);--bs-navbar-toggler-border-radius:var(--bs-border-radius);--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y)var(--bs-navbar-padding-x);background-image:var(--bs-gradient)}.navbar>.container,.td-navbar>.container,.navbar>.container-fluid,.td-navbar>.container-fluid,.navbar>.container-sm,.td-navbar>.container-sm,.navbar>.container-md,.td-navbar>.container-md,.navbar>.container-lg,.td-navbar>.container-lg,.navbar>.container-xl,.td-navbar>.container-xl,.navbar>.container-xxl,.td-navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:hover,.navbar-brand:focus{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:hover,.navbar-text a:focus{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y)var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width)solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media(prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:50%;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media(min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;box-shadow:none;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media(min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;box-shadow:none;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media(min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;box-shadow:none;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media(min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;box-shadow:none;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media(min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;box-shadow:none;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand,.td-navbar{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav,.td-navbar .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu,.td-navbar .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link,.td-navbar .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll,.td-navbar .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse,.td-navbar .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler,.td-navbar .navbar-toggler{display:none}.navbar-expand .offcanvas,.td-navbar .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;box-shadow:none;transition:none}.navbar-expand .offcanvas .offcanvas-header,.td-navbar .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body,.td-navbar .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark,.navbar[data-bs-theme=dark],[data-bs-theme=dark].td-navbar{--bs-navbar-color:rgba(255, 255, 255, 0.55);--bs-navbar-hover-color:rgba(255, 255, 255, 0.75);--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}[data-bs-theme=dark] .navbar-toggler-icon{--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width:var(--bs-border-width);--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:rgba(var(--bs-body-color-rgb), 0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:var(--bs-body-bg);--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);color:var(--bs-body-color);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width)solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius);box-shadow:var(--bs-card-box-shadow)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:auto;padding:var(--bs-card-spacer-y)var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0;color:var(--bs-card-subtitle-color)}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y)var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width)solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius)var(--bs-card-inner-border-radius)0 0}.card-footer{padding:var(--bs-card-cap-padding-y)var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width)solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius)var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-top,.card-img-bottom{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media(min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-img-top,.card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-img-bottom,.card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-img-top,.card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-img-bottom,.card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:var(--bs-body-bg);--bs-accordion-transition:color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:var(--bs-border-width);--bs-accordion-border-radius:var(--bs-border-radius);--bs-accordion-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23212529' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M2 5L8 11L14 5'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23132839' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M2 5L8 11L14 5'/%3e%3c/svg%3e");--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(48, 99, 142, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:var(--bs-primary-text-emphasis);--bs-accordion-active-bg:var(--bs-primary-bg-subtle)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y)var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media(prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width))0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media(prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width)solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type>.accordion-header .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type>.accordion-header .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type>.accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y)var(--bs-accordion-body-padding-x)}.accordion-flush>.accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush>.accordion-item:first-child{border-top:0}.accordion-flush>.accordion-item:last-child{border-bottom:0}.accordion-flush>.accordion-item>.accordion-header .accordion-button,.accordion-flush>.accordion-item>.accordion-header .accordion-button.collapsed{border-radius:0}.accordion-flush>.accordion-item>.accordion-collapse{border-radius:0}[data-bs-theme=dark] .accordion-button::after{--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%2383a1bb'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%2383a1bb'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.breadcrumb{--bs-breadcrumb-padding-x:0;--bs-breadcrumb-padding-y:0;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color:var(--bs-secondary-color);--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y)var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider,"/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:#6c757d;--bs-pagination-bg:var(--bs-body-bg);--bs-pagination-border-width:var(--bs-border-width);--bs-pagination-border-color:var(--bs-border-color);--bs-pagination-border-radius:var(--bs-border-radius);--bs-pagination-hover-color:var(--bs-link-hover-color);--bs-pagination-hover-bg:var(--bs-tertiary-bg);--bs-pagination-hover-border-color:var(--bs-border-color);--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:var(--bs-secondary-bg);--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(48, 99, 142, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#30638e;--bs-pagination-active-border-color:#30638e;--bs-pagination-disabled-color:#dee2e6;--bs-pagination-disabled-bg:var(--bs-secondary-bg);--bs-pagination-disabled-border-color:var(--bs-border-color);display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y)var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width)solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.page-link.active,.active>.page-link{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);background-image:var(--bs-gradient);border-color:var(--bs-pagination-active-border-color)}.page-link.disabled,.disabled>.page-link{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(var(--bs-border-width) * -1)}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:var(--bs-border-radius-lg)}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:var(--bs-border-radius-sm)}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:var(--bs-border-radius);display:inline-block;padding:var(--bs-badge-padding-y)var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius);background-image:var(--bs-gradient)}.badge:empty{display:none}.btn .badge,div.drawio button .badge,.td-blog .td-rss-button .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:var(--bs-border-width) solid var(--bs-alert-border-color);--bs-alert-border-radius:var(--bs-border-radius);--bs-alert-link-color:inherit;position:relative;padding:var(--bs-alert-padding-y)var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary,.pageinfo-primary{--bs-alert-color:var(--bs-primary-text-emphasis);--bs-alert-bg:var(--bs-primary-bg-subtle);--bs-alert-border-color:var(--bs-primary-border-subtle);--bs-alert-link-color:var(--bs-primary-text-emphasis)}.alert-secondary,.pageinfo-secondary{--bs-alert-color:var(--bs-secondary-text-emphasis);--bs-alert-bg:var(--bs-secondary-bg-subtle);--bs-alert-border-color:var(--bs-secondary-border-subtle);--bs-alert-link-color:var(--bs-secondary-text-emphasis)}.alert-success,.pageinfo-success{--bs-alert-color:var(--bs-success-text-emphasis);--bs-alert-bg:var(--bs-success-bg-subtle);--bs-alert-border-color:var(--bs-success-border-subtle);--bs-alert-link-color:var(--bs-success-text-emphasis)}.alert-info,.pageinfo-info{--bs-alert-color:var(--bs-info-text-emphasis);--bs-alert-bg:var(--bs-info-bg-subtle);--bs-alert-border-color:var(--bs-info-border-subtle);--bs-alert-link-color:var(--bs-info-text-emphasis)}.alert-warning,.pageinfo-warning{--bs-alert-color:var(--bs-warning-text-emphasis);--bs-alert-bg:var(--bs-warning-bg-subtle);--bs-alert-border-color:var(--bs-warning-border-subtle);--bs-alert-link-color:var(--bs-warning-text-emphasis)}.alert-danger,.pageinfo-danger{--bs-alert-color:var(--bs-danger-text-emphasis);--bs-alert-bg:var(--bs-danger-bg-subtle);--bs-alert-border-color:var(--bs-danger-border-subtle);--bs-alert-link-color:var(--bs-danger-text-emphasis)}.alert-light,.pageinfo-light{--bs-alert-color:var(--bs-light-text-emphasis);--bs-alert-bg:var(--bs-light-bg-subtle);--bs-alert-border-color:var(--bs-light-border-subtle);--bs-alert-link-color:var(--bs-light-text-emphasis)}.alert-dark,.pageinfo-dark{--bs-alert-color:var(--bs-dark-text-emphasis);--bs-alert-bg:var(--bs-dark-bg-subtle);--bs-alert-border-color:var(--bs-dark-border-subtle);--bs-alert-link-color:var(--bs-dark-text-emphasis)}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress,.progress-stacked{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:var(--bs-secondary-bg);--bs-progress-border-radius:var(--bs-border-radius);--bs-progress-box-shadow:var(--bs-box-shadow-inset);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#30638e;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius);box-shadow:var(--bs-progress-box-shadow)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media(prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height)var(--bs-progress-height)}.progress-stacked>.progress{overflow:visible}.progress-stacked>.progress>.progress-bar{width:100%}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media(prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color:var(--bs-body-color);--bs-list-group-bg:var(--bs-body-bg);--bs-list-group-border-color:var(--bs-border-color);--bs-list-group-border-width:var(--bs-border-width);--bs-list-group-border-radius:var(--bs-border-radius);--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:var(--bs-secondary-color);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-tertiary-bg);--bs-list-group-action-active-color:var(--bs-body-color);--bs-list-group-action-active-bg:var(--bs-secondary-bg);--bs-list-group-disabled-color:var(--bs-secondary-color);--bs-list-group-disabled-bg:var(--bs-body-bg);--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#30638e;--bs-list-group-active-border-color:#30638e;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section,".")". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y)var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width)solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media(min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media(min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media(min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media(min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media(min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{--bs-list-group-color:var(--bs-primary-text-emphasis);--bs-list-group-bg:var(--bs-primary-bg-subtle);--bs-list-group-border-color:var(--bs-primary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-primary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-primary-border-subtle);--bs-list-group-active-color:var(--bs-primary-bg-subtle);--bs-list-group-active-bg:var(--bs-primary-text-emphasis);--bs-list-group-active-border-color:var(--bs-primary-text-emphasis)}.list-group-item-secondary{--bs-list-group-color:var(--bs-secondary-text-emphasis);--bs-list-group-bg:var(--bs-secondary-bg-subtle);--bs-list-group-border-color:var(--bs-secondary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-secondary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-secondary-border-subtle);--bs-list-group-active-color:var(--bs-secondary-bg-subtle);--bs-list-group-active-bg:var(--bs-secondary-text-emphasis);--bs-list-group-active-border-color:var(--bs-secondary-text-emphasis)}.list-group-item-success{--bs-list-group-color:var(--bs-success-text-emphasis);--bs-list-group-bg:var(--bs-success-bg-subtle);--bs-list-group-border-color:var(--bs-success-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-success-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-success-border-subtle);--bs-list-group-active-color:var(--bs-success-bg-subtle);--bs-list-group-active-bg:var(--bs-success-text-emphasis);--bs-list-group-active-border-color:var(--bs-success-text-emphasis)}.list-group-item-info{--bs-list-group-color:var(--bs-info-text-emphasis);--bs-list-group-bg:var(--bs-info-bg-subtle);--bs-list-group-border-color:var(--bs-info-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-info-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-info-border-subtle);--bs-list-group-active-color:var(--bs-info-bg-subtle);--bs-list-group-active-bg:var(--bs-info-text-emphasis);--bs-list-group-active-border-color:var(--bs-info-text-emphasis)}.list-group-item-warning{--bs-list-group-color:var(--bs-warning-text-emphasis);--bs-list-group-bg:var(--bs-warning-bg-subtle);--bs-list-group-border-color:var(--bs-warning-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-warning-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-warning-border-subtle);--bs-list-group-active-color:var(--bs-warning-bg-subtle);--bs-list-group-active-bg:var(--bs-warning-text-emphasis);--bs-list-group-active-border-color:var(--bs-warning-text-emphasis)}.list-group-item-danger{--bs-list-group-color:var(--bs-danger-text-emphasis);--bs-list-group-bg:var(--bs-danger-bg-subtle);--bs-list-group-border-color:var(--bs-danger-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-danger-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-danger-border-subtle);--bs-list-group-active-color:var(--bs-danger-bg-subtle);--bs-list-group-active-bg:var(--bs-danger-text-emphasis);--bs-list-group-active-border-color:var(--bs-danger-text-emphasis)}.list-group-item-light{--bs-list-group-color:var(--bs-light-text-emphasis);--bs-list-group-bg:var(--bs-light-bg-subtle);--bs-list-group-border-color:var(--bs-light-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-light-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-light-border-subtle);--bs-list-group-active-color:var(--bs-light-bg-subtle);--bs-list-group-active-bg:var(--bs-light-text-emphasis);--bs-list-group-active-border-color:var(--bs-light-text-emphasis)}.list-group-item-dark{--bs-list-group-color:var(--bs-dark-text-emphasis);--bs-list-group-bg:var(--bs-dark-bg-subtle);--bs-list-group-border-color:var(--bs-dark-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-dark-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-dark-border-subtle);--bs-list-group-active-color:var(--bs-dark-bg-subtle);--bs-list-group-active-bg:var(--bs-dark-text-emphasis);--bs-list-group-active-border-color:var(--bs-dark-text-emphasis)}.btn-close{--bs-btn-close-color:#000;--bs-btn-close-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e");--bs-btn-close-opacity:0.5;--bs-btn-close-hover-opacity:0.75;--bs-btn-close-focus-shadow:0 0 0 0.25rem rgba(48, 99, 142, 0.25);--bs-btn-close-focus-opacity:1;--bs-btn-close-disabled-opacity:0.25;--bs-btn-close-white-filter:invert(1) grayscale(100%) brightness(200%);box-sizing:content-box;width:1em;height:1em;padding:.25em;color:var(--bs-btn-close-color);background:var(--bs-btn-close-bg)50%/1em no-repeat;border:0;border-radius:.375rem;opacity:var(--bs-btn-close-opacity)}.btn-close:hover{color:var(--bs-btn-close-color);text-decoration:none;opacity:var(--bs-btn-close-hover-opacity)}.btn-close:focus{outline:0;box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity)}.btn-close:disabled,.btn-close.disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:var(--bs-btn-close-disabled-opacity)}.btn-close-white{filter:var(--bs-btn-close-white-filter)}[data-bs-theme=dark] .btn-close{filter:var(--bs-btn-close-white-filter)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-border-width:var(--bs-border-width);--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:var(--bs-border-radius);--bs-toast-box-shadow:var(--bs-box-shadow);--bs-toast-header-color:var(--bs-secondary-color);--bs-toast-header-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-header-border-color:var(--bs-border-color-translucent);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width)solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex:1090;position:absolute;z-index:var(--bs-toast-zindex);width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y)var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width)solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:var(--bs-body-bg);--bs-modal-border-color:var(--bs-border-color-translucent);--bs-modal-border-width:var(--bs-border-width);--bs-modal-border-radius:var(--bs-border-radius-lg);--bs-modal-box-shadow:var(--bs-box-shadow-sm);--bs-modal-inner-border-radius:calc(var(--bs-border-radius-lg) - (var(--bs-border-width)));--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:var(--bs-border-color);--bs-modal-header-border-width:var(--bs-border-width);--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:var(--bs-border-color);--bs-modal-footer-border-width:var(--bs-border-width);position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media(prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width)solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);box-shadow:var(--bs-modal-box-shadow);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width)solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5);margin:calc(-.5 * var(--bs-modal-header-padding-y))calc(-.5 * var(--bs-modal-header-padding-x))calc(-.5 * var(--bs-modal-header-padding-y))auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width)solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media(min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:var(--bs-box-shadow)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media(min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media(min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header,.modal-fullscreen .modal-footer{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media(max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header,.modal-fullscreen-sm-down .modal-footer{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media(max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header,.modal-fullscreen-md-down .modal-footer{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media(max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header,.modal-fullscreen-lg-down .modal-footer{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media(max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header,.modal-fullscreen-xl-down .modal-footer{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media(max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header,.modal-fullscreen-xxl-down .modal-footer{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:var(--bs-body-bg);--bs-tooltip-bg:var(--bs-emphasis-color);--bs-tooltip-border-radius:var(--bs-border-radius);--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;margin:var(--bs-tooltip-margin);font-family:open sans,-apple-system,BlinkMacSystemFont,segoe ui,Roboto,helvetica neue,Arial,sans-serif,apple color emoji,segoe ui emoji,segoe ui symbol;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-top .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow{bottom:calc(-1 * var(--bs-tooltip-arrow-height))}.bs-tooltip-top .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height)calc(var(--bs-tooltip-arrow-width) * .5)0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-end .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow{left:calc(-1 * var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-end .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5)var(--bs-tooltip-arrow-height)calc(var(--bs-tooltip-arrow-width) * .5)0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-bottom .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow{top:calc(-1 * var(--bs-tooltip-arrow-height))}.bs-tooltip-bottom .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5)var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-start .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow{right:calc(-1 * var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-start .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5)0 calc(var(--bs-tooltip-arrow-width) * .5)var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y)var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:var(--bs-body-bg);--bs-popover-border-width:var(--bs-border-width);--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:var(--bs-border-radius-lg);--bs-popover-inner-border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width));--bs-popover-box-shadow:var(--bs-box-shadow);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color:inherit;--bs-popover-header-bg:var(--bs-secondary-bg);--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:var(--bs-body-color);--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:open sans,-apple-system,BlinkMacSystemFont,segoe ui,Roboto,helvetica neue,Arial,sans-serif,apple color emoji,segoe ui emoji,segoe ui symbol;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width)solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius);box-shadow:var(--bs-popover-box-shadow)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::before,.popover .popover-arrow::after{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-top>.popover-arrow,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after{border-width:var(--bs-popover-arrow-height)calc(var(--bs-popover-arrow-width) * .5)0}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-end>.popover-arrow,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after{border-width:calc(var(--bs-popover-arrow-width) * .5)var(--bs-popover-arrow-height)calc(var(--bs-popover-arrow-width) * .5)0}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-bottom>.popover-arrow,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after{border-width:0 calc(var(--bs-popover-arrow-width) * .5)var(--bs-popover-arrow-height)}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-bottom .popover-header::before,.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width)solid var(--bs-popover-header-bg)}.bs-popover-start>.popover-arrow,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after{border-width:calc(var(--bs-popover-arrow-width) * .5)0 calc(var(--bs-popover-arrow-width) * .5)var(--bs-popover-arrow-height)}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y)var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width)solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y)var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;transition:transform .6s ease-in-out}@media(prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item.active,.carousel-item-next,.carousel-item-prev{display:block}.carousel-item-next:not(.carousel-item-start),.active.carousel-item-end{transform:translateX(100%)}.carousel-item-prev:not(.carousel-item-end),.active.carousel-item-start{transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item.active,.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end{z-index:1;opacity:1}.carousel-fade .active.carousel-item-start,.carousel-fade .active.carousel-item-end{z-index:0;opacity:0;transition:opacity 0s .6s}@media(prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-start,.carousel-fade .active.carousel-item-end{transition:none}}.carousel-control-prev,.carousel-control-next{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media(prefers-reduced-motion:reduce){.carousel-control-prev,.carousel-control-next{transition:none}}.carousel-control-prev:hover,.carousel-control-prev:focus,.carousel-control-next:hover,.carousel-control-next:focus{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0;background-image:linear-gradient(90deg,rgba(0,0,0,.25),rgba(0,0,0,.1%))}.carousel-control-next{right:0;background-image:linear-gradient(270deg,rgba(0,0,0,.25),rgba(0,0,0,.1%))}.carousel-control-prev-icon,.carousel-control-next-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:initial;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media(prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-prev-icon,.carousel-dark .carousel-control-next-icon{filter:invert(1)grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}[data-bs-theme=dark] .carousel .carousel-control-prev-icon,[data-bs-theme=dark] .carousel .carousel-control-next-icon,[data-bs-theme=dark].carousel .carousel-control-prev-icon,[data-bs-theme=dark].carousel .carousel-control-next-icon{filter:invert(1)grayscale(100)}[data-bs-theme=dark] .carousel .carousel-indicators [data-bs-target],[data-bs-theme=dark].carousel .carousel-indicators [data-bs-target]{background-color:#000}[data-bs-theme=dark] .carousel .carousel-caption,[data-bs-theme=dark].carousel .carousel-caption{color:#000}.spinner-grow,.spinner-border{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed)linear infinite var(--bs-spinner-animation-name)}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width)solid;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media(prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-xxl,.offcanvas-xl,.offcanvas-lg,.offcanvas-md,.offcanvas-sm{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color:var(--bs-body-color);--bs-offcanvas-bg:var(--bs-body-bg);--bs-offcanvas-border-width:var(--bs-border-width);--bs-offcanvas-border-color:var(--bs-border-color-translucent);--bs-offcanvas-box-shadow:var(--bs-box-shadow-sm);--bs-offcanvas-transition:transform 0.3s ease-in-out;--bs-offcanvas-title-line-height:1.5}@media(max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;box-shadow:var(--bs-offcanvas-box-shadow);transition:var(--bs-offcanvas-transition)}}@media(max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media(max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-sm.showing,.offcanvas-sm.show:not(.hiding){transform:none}.offcanvas-sm.showing,.offcanvas-sm.hiding,.offcanvas-sm.show{visibility:visible}}@media(min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media(max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;box-shadow:var(--bs-offcanvas-box-shadow);transition:var(--bs-offcanvas-transition)}}@media(max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media(max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-md.showing,.offcanvas-md.show:not(.hiding){transform:none}.offcanvas-md.showing,.offcanvas-md.hiding,.offcanvas-md.show{visibility:visible}}@media(min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media(max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;box-shadow:var(--bs-offcanvas-box-shadow);transition:var(--bs-offcanvas-transition)}}@media(max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media(max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-lg.showing,.offcanvas-lg.show:not(.hiding){transform:none}.offcanvas-lg.showing,.offcanvas-lg.hiding,.offcanvas-lg.show{visibility:visible}}@media(min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media(max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;box-shadow:var(--bs-offcanvas-box-shadow);transition:var(--bs-offcanvas-transition)}}@media(max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media(max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xl.showing,.offcanvas-xl.show:not(.hiding){transform:none}.offcanvas-xl.showing,.offcanvas-xl.hiding,.offcanvas-xl.show{visibility:visible}}@media(min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media(max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;box-shadow:var(--bs-offcanvas-box-shadow);transition:var(--bs-offcanvas-transition)}}@media(max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media(max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xxl.showing,.offcanvas-xxl.show:not(.hiding){transform:none}.offcanvas-xxl.showing,.offcanvas-xxl.hiding,.offcanvas-xxl.show{visibility:visible}}@media(min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;box-shadow:var(--bs-offcanvas-box-shadow);transition:var(--bs-offcanvas-transition)}@media(prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width)solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.showing,.offcanvas.show:not(.hiding){transform:none}.offcanvas.showing,.offcanvas.hiding,.offcanvas.show{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;padding:var(--bs-offcanvas-padding-y)var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5);margin:calc(-.5 * var(--bs-offcanvas-padding-y))calc(-.5 * var(--bs-offcanvas-padding-x))calc(-.5 * var(--bs-offcanvas-padding-y))auto}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y)var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before,div.drawio button.placeholder::before,.td-blog .placeholder.td-rss-button::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(var(--bs-primary-rgb),var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#000!important;background-color:RGBA(var(--bs-secondary-rgb),var(--bs-bg-opacity,1))!important}.text-bg-success{color:#000!important;background-color:RGBA(var(--bs-success-rgb),var(--bs-bg-opacity,1))!important}.text-bg-info{color:#000!important;background-color:RGBA(var(--bs-info-rgb),var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#000!important;background-color:RGBA(var(--bs-warning-rgb),var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#000!important;background-color:RGBA(var(--bs-danger-rgb),var(--bs-bg-opacity,1))!important}.text-bg-light{color:#000!important;background-color:RGBA(var(--bs-light-rgb),var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(var(--bs-dark-rgb),var(--bs-bg-opacity,1))!important}.link-primary{color:RGBA(var(--bs-primary-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important}.link-primary:hover,.link-primary:focus{color:RGBA(34,69,99,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(34,69,99,var(--bs-link-underline-opacity,1))!important}.link-secondary{color:RGBA(var(--bs-secondary-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important}.link-secondary:hover,.link-secondary:focus{color:RGBA(255,193,110,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(255,193,110,var(--bs-link-underline-opacity,1))!important}.link-success{color:RGBA(var(--bs-success-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important}.link-success:hover,.link-success:focus{color:RGBA(115,156,255,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(115,156,255,var(--bs-link-underline-opacity,1))!important}.link-info{color:RGBA(var(--bs-info-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important}.link-info:hover,.link-info:focus{color:RGBA(211,233,232,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(211,233,232,var(--bs-link-underline-opacity,1))!important}.link-warning{color:RGBA(var(--bs-warning-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important}.link-warning:hover,.link-warning:focus{color:RGBA(242,151,140,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(242,151,140,var(--bs-link-underline-opacity,1))!important}.link-danger{color:RGBA(var(--bs-danger-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important}.link-danger:hover,.link-danger:focus{color:RGBA(242,151,140,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(242,151,140,var(--bs-link-underline-opacity,1))!important}.link-light{color:RGBA(var(--bs-light-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important}.link-light:hover,.link-light:focus{color:RGBA(224,247,243,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(224,247,243,var(--bs-link-underline-opacity,1))!important}.link-dark{color:RGBA(var(--bs-dark-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important}.link-dark:hover,.link-dark:focus{color:RGBA(45,44,53,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(45,44,53,var(--bs-link-underline-opacity,1))!important}.link-body-emphasis{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-body-emphasis:hover,.link-body-emphasis:focus{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,.75))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,.75))!important}.focus-ring:focus{outline:0;box-shadow:var(--bs-focus-ring-x,0)var(--bs-focus-ring-y,0)var(--bs-focus-ring-blur,0)var(--bs-focus-ring-width)var(--bs-focus-ring-color)}.icon-link{display:inline-flex;gap:.375rem;align-items:center;text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,.5));text-underline-offset:.25em;backface-visibility:hidden}.icon-link>.bi{flex-shrink:0;width:1em;height:1em;fill:currentcolor;transition:.2s ease-in-out transform}@media(prefers-reduced-motion:reduce){.icon-link>.bi{transition:none}}.icon-link-hover:hover>.bi,.icon-link-hover:focus-visible>.bi{transform:var(--bs-icon-link-transform,translate3d(.25em,0,0))}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:calc(3 / 4 * 100%)}.ratio-16x9{--bs-aspect-ratio:calc(9 / 16 * 100%)}.ratio-21x9{--bs-aspect-ratio:calc(9 / 21 * 100%)}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}.sticky-bottom{position:sticky;bottom:0;z-index:1020}@media(min-width:576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:sticky;bottom:0;z-index:1020}}@media(min-width:768px){.sticky-md-top{position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:sticky;bottom:0;z-index:1020}}@media(min-width:992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:sticky;bottom:0;z-index:1020}}@media(min-width:1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:sticky;bottom:0;z-index:1020}}@media(min-width:1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.visually-hidden:not(caption),.visually-hidden-focusable:not(:focus):not(:focus-within):not(caption){position:absolute!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:var(--bs-border-width);min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.object-fit-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-none{-o-object-fit:none!important;object-fit:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.overflow-x-auto{overflow-x:auto!important}.overflow-x-hidden{overflow-x:hidden!important}.overflow-x-visible{overflow-x:visible!important}.overflow-x-scroll{overflow-x:scroll!important}.overflow-y-auto{overflow-y:auto!important}.overflow-y-hidden{overflow-y:hidden!important}.overflow-y-visible{overflow-y:visible!important}.overflow-y-scroll{overflow-y:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-inline-grid{display:inline-grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:var(--bs-box-shadow)!important}.shadow-sm{box-shadow:var(--bs-box-shadow-sm)!important}.shadow-lg{box-shadow:var(--bs-box-shadow-lg)!important}.shadow-none{box-shadow:none!important}.focus-ring-primary{--bs-focus-ring-color:rgba(var(--bs-primary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-secondary{--bs-focus-ring-color:rgba(var(--bs-secondary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-success{--bs-focus-ring-color:rgba(var(--bs-success-rgb), var(--bs-focus-ring-opacity))}.focus-ring-info{--bs-focus-ring-color:rgba(var(--bs-info-rgb), var(--bs-focus-ring-opacity))}.focus-ring-warning{--bs-focus-ring-color:rgba(var(--bs-warning-rgb), var(--bs-focus-ring-opacity))}.focus-ring-danger{--bs-focus-ring-color:rgba(var(--bs-danger-rgb), var(--bs-focus-ring-opacity))}.focus-ring-light{--bs-focus-ring-color:rgba(var(--bs-light-rgb), var(--bs-focus-ring-opacity))}.focus-ring-dark{--bs-focus-ring-color:rgba(var(--bs-dark-rgb), var(--bs-focus-ring-opacity))}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width)var(--bs-border-style)var(--bs-border-color)!important}.border-0{border:0!important}.border-top,.td-page-meta__lastmod{border-top:var(--bs-border-width)var(--bs-border-style)var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width)var(--bs-border-style)var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width)var(--bs-border-style)var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width)var(--bs-border-style)var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-black{--bs-border-opacity:1;border-color:rgba(var(--bs-black-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-primary-subtle{border-color:var(--bs-primary-border-subtle)!important}.border-secondary-subtle{border-color:var(--bs-secondary-border-subtle)!important}.border-success-subtle{border-color:var(--bs-success-border-subtle)!important}.border-info-subtle{border-color:var(--bs-info-border-subtle)!important}.border-warning-subtle{border-color:var(--bs-warning-border-subtle)!important}.border-danger-subtle{border-color:var(--bs-danger-border-subtle)!important}.border-light-subtle{border-color:var(--bs-light-border-subtle)!important}.border-dark-subtle{border-color:var(--bs-dark-border-subtle)!important}.border-1{border-width:1px!important}.border-2{border-width:2px!important}.border-3{border-width:3px!important}.border-4{border-width:4px!important}.border-5{border-width:5px!important}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.row-gap-0{row-gap:0!important}.row-gap-1{row-gap:.25rem!important}.row-gap-2{row-gap:.5rem!important}.row-gap-3{row-gap:1rem!important}.row-gap-4{row-gap:1.5rem!important}.row-gap-5{row-gap:3rem!important}.column-gap-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-1{-moz-column-gap:.25rem!important;column-gap:.25rem!important}.column-gap-2{-moz-column-gap:.5rem!important;column-gap:.5rem!important}.column-gap-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.275rem + .3vw)!important}.fs-4{font-size:calc(1.26rem + .12vw)!important}.fs-5{font-size:1.15rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-lighter{font-weight:lighter!important}.fw-light{font-weight:300!important}.fw-normal{font-weight:400!important}.fw-medium{font-weight:500!important}.fw-semibold{font-weight:600!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-body-secondary,.td-page-meta__lastmod{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-body-tertiary{--bs-text-opacity:1;color:var(--bs-tertiary-color)!important}.text-body-emphasis{--bs-text-opacity:1;color:var(--bs-emphasis-color)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.text-primary-emphasis{color:var(--bs-primary-text-emphasis)!important}.text-secondary-emphasis{color:var(--bs-secondary-text-emphasis)!important}.text-success-emphasis{color:var(--bs-success-text-emphasis)!important}.text-info-emphasis{color:var(--bs-info-text-emphasis)!important}.text-warning-emphasis{color:var(--bs-warning-text-emphasis)!important}.text-danger-emphasis{color:var(--bs-danger-text-emphasis)!important}.text-light-emphasis{color:var(--bs-light-text-emphasis)!important}.text-dark-emphasis{color:var(--bs-dark-text-emphasis)!important}.link-opacity-10{--bs-link-opacity:0.1}.link-opacity-10-hover:hover{--bs-link-opacity:0.1}.link-opacity-25{--bs-link-opacity:0.25}.link-opacity-25-hover:hover{--bs-link-opacity:0.25}.link-opacity-50{--bs-link-opacity:0.5}.link-opacity-50-hover:hover{--bs-link-opacity:0.5}.link-opacity-75{--bs-link-opacity:0.75}.link-opacity-75-hover:hover{--bs-link-opacity:0.75}.link-opacity-100{--bs-link-opacity:1}.link-opacity-100-hover:hover{--bs-link-opacity:1}.link-offset-1{text-underline-offset:.125em!important}.link-offset-1-hover:hover{text-underline-offset:.125em!important}.link-offset-2{text-underline-offset:.25em!important}.link-offset-2-hover:hover{text-underline-offset:.25em!important}.link-offset-3{text-underline-offset:.375em!important}.link-offset-3-hover:hover{text-underline-offset:.375em!important}.link-underline-primary{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-secondary{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-success{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important}.link-underline-info{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important}.link-underline-warning{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important}.link-underline-danger{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important}.link-underline-light{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important}.link-underline-dark{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important}.link-underline{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-underline-opacity-0{--bs-link-underline-opacity:0}.link-underline-opacity-0-hover:hover{--bs-link-underline-opacity:0}.link-underline-opacity-10{--bs-link-underline-opacity:0.1}.link-underline-opacity-10-hover:hover{--bs-link-underline-opacity:0.1}.link-underline-opacity-25{--bs-link-underline-opacity:0.25}.link-underline-opacity-25-hover:hover{--bs-link-underline-opacity:0.25}.link-underline-opacity-50{--bs-link-underline-opacity:0.5}.link-underline-opacity-50-hover:hover{--bs-link-underline-opacity:0.5}.link-underline-opacity-75{--bs-link-underline-opacity:0.75}.link-underline-opacity-75-hover:hover{--bs-link-underline-opacity:0.75}.link-underline-opacity-100{--bs-link-underline-opacity:1}.link-underline-opacity-100-hover:hover{--bs-link-underline-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-body-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-bg-rgb),var(--bs-bg-opacity))!important}.bg-body-tertiary{--bs-bg-opacity:1;background-color:rgba(var(--bs-tertiary-bg-rgb),var(--bs-bg-opacity))!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-primary-subtle{background-color:var(--bs-primary-bg-subtle)!important}.bg-secondary-subtle{background-color:var(--bs-secondary-bg-subtle)!important}.bg-success-subtle{background-color:var(--bs-success-bg-subtle)!important}.bg-info-subtle{background-color:var(--bs-info-bg-subtle)!important}.bg-warning-subtle{background-color:var(--bs-warning-bg-subtle)!important}.bg-danger-subtle{background-color:var(--bs-danger-bg-subtle)!important}.bg-light-subtle{background-color:var(--bs-light-bg-subtle)!important}.bg-dark-subtle{background-color:var(--bs-dark-bg-subtle)!important}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-xxl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-0{border-top-left-radius:0!important;border-top-right-radius:0!important}.rounded-top-1{border-top-left-radius:var(--bs-border-radius-sm)!important;border-top-right-radius:var(--bs-border-radius-sm)!important}.rounded-top-2{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-3{border-top-left-radius:var(--bs-border-radius-lg)!important;border-top-right-radius:var(--bs-border-radius-lg)!important}.rounded-top-4{border-top-left-radius:var(--bs-border-radius-xl)!important;border-top-right-radius:var(--bs-border-radius-xl)!important}.rounded-top-5{border-top-left-radius:var(--bs-border-radius-xxl)!important;border-top-right-radius:var(--bs-border-radius-xxl)!important}.rounded-top-circle{border-top-left-radius:50%!important;border-top-right-radius:50%!important}.rounded-top-pill{border-top-left-radius:var(--bs-border-radius-pill)!important;border-top-right-radius:var(--bs-border-radius-pill)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-0{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.rounded-end-1{border-top-right-radius:var(--bs-border-radius-sm)!important;border-bottom-right-radius:var(--bs-border-radius-sm)!important}.rounded-end-2{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-3{border-top-right-radius:var(--bs-border-radius-lg)!important;border-bottom-right-radius:var(--bs-border-radius-lg)!important}.rounded-end-4{border-top-right-radius:var(--bs-border-radius-xl)!important;border-bottom-right-radius:var(--bs-border-radius-xl)!important}.rounded-end-5{border-top-right-radius:var(--bs-border-radius-xxl)!important;border-bottom-right-radius:var(--bs-border-radius-xxl)!important}.rounded-end-circle{border-top-right-radius:50%!important;border-bottom-right-radius:50%!important}.rounded-end-pill{border-top-right-radius:var(--bs-border-radius-pill)!important;border-bottom-right-radius:var(--bs-border-radius-pill)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-0{border-bottom-right-radius:0!important;border-bottom-left-radius:0!important}.rounded-bottom-1{border-bottom-right-radius:var(--bs-border-radius-sm)!important;border-bottom-left-radius:var(--bs-border-radius-sm)!important}.rounded-bottom-2{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-3{border-bottom-right-radius:var(--bs-border-radius-lg)!important;border-bottom-left-radius:var(--bs-border-radius-lg)!important}.rounded-bottom-4{border-bottom-right-radius:var(--bs-border-radius-xl)!important;border-bottom-left-radius:var(--bs-border-radius-xl)!important}.rounded-bottom-5{border-bottom-right-radius:var(--bs-border-radius-xxl)!important;border-bottom-left-radius:var(--bs-border-radius-xxl)!important}.rounded-bottom-circle{border-bottom-right-radius:50%!important;border-bottom-left-radius:50%!important}.rounded-bottom-pill{border-bottom-right-radius:var(--bs-border-radius-pill)!important;border-bottom-left-radius:var(--bs-border-radius-pill)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-0{border-bottom-left-radius:0!important;border-top-left-radius:0!important}.rounded-start-1{border-bottom-left-radius:var(--bs-border-radius-sm)!important;border-top-left-radius:var(--bs-border-radius-sm)!important}.rounded-start-2{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-3{border-bottom-left-radius:var(--bs-border-radius-lg)!important;border-top-left-radius:var(--bs-border-radius-lg)!important}.rounded-start-4{border-bottom-left-radius:var(--bs-border-radius-xl)!important;border-top-left-radius:var(--bs-border-radius-xl)!important}.rounded-start-5{border-bottom-left-radius:var(--bs-border-radius-xxl)!important;border-top-left-radius:var(--bs-border-radius-xxl)!important}.rounded-start-circle{border-bottom-left-radius:50%!important;border-top-left-radius:50%!important}.rounded-start-pill{border-bottom-left-radius:var(--bs-border-radius-pill)!important;border-top-left-radius:var(--bs-border-radius-pill)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.z-n1{z-index:-1!important}.z-0{z-index:0!important}.z-1{z-index:1!important}.z-2{z-index:2!important}.z-3{z-index:3!important}@media(min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.object-fit-sm-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-sm-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-sm-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-sm-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-sm-none{-o-object-fit:none!important;object-fit:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-inline-grid{display:inline-grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.row-gap-sm-0{row-gap:0!important}.row-gap-sm-1{row-gap:.25rem!important}.row-gap-sm-2{row-gap:.5rem!important}.row-gap-sm-3{row-gap:1rem!important}.row-gap-sm-4{row-gap:1.5rem!important}.row-gap-sm-5{row-gap:3rem!important}.column-gap-sm-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-sm-1{-moz-column-gap:.25rem!important;column-gap:.25rem!important}.column-gap-sm-2{-moz-column-gap:.5rem!important;column-gap:.5rem!important}.column-gap-sm-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-sm-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-sm-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media(min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.object-fit-md-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-md-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-md-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-md-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-md-none{-o-object-fit:none!important;object-fit:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-inline-grid{display:inline-grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.row-gap-md-0{row-gap:0!important}.row-gap-md-1{row-gap:.25rem!important}.row-gap-md-2{row-gap:.5rem!important}.row-gap-md-3{row-gap:1rem!important}.row-gap-md-4{row-gap:1.5rem!important}.row-gap-md-5{row-gap:3rem!important}.column-gap-md-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-md-1{-moz-column-gap:.25rem!important;column-gap:.25rem!important}.column-gap-md-2{-moz-column-gap:.5rem!important;column-gap:.5rem!important}.column-gap-md-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-md-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-md-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media(min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.object-fit-lg-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-lg-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-lg-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-lg-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-lg-none{-o-object-fit:none!important;object-fit:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block,.td-blog .td-rss-button{display:block!important}.d-lg-grid{display:grid!important}.d-lg-inline-grid{display:inline-grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.row-gap-lg-0{row-gap:0!important}.row-gap-lg-1{row-gap:.25rem!important}.row-gap-lg-2{row-gap:.5rem!important}.row-gap-lg-3{row-gap:1rem!important}.row-gap-lg-4{row-gap:1.5rem!important}.row-gap-lg-5{row-gap:3rem!important}.column-gap-lg-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-lg-1{-moz-column-gap:.25rem!important;column-gap:.25rem!important}.column-gap-lg-2{-moz-column-gap:.5rem!important;column-gap:.5rem!important}.column-gap-lg-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-lg-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-lg-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media(min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.object-fit-xl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xl-none{-o-object-fit:none!important;object-fit:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-inline-grid{display:inline-grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.row-gap-xl-0{row-gap:0!important}.row-gap-xl-1{row-gap:.25rem!important}.row-gap-xl-2{row-gap:.5rem!important}.row-gap-xl-3{row-gap:1rem!important}.row-gap-xl-4{row-gap:1.5rem!important}.row-gap-xl-5{row-gap:3rem!important}.column-gap-xl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xl-1{-moz-column-gap:.25rem!important;column-gap:.25rem!important}.column-gap-xl-2{-moz-column-gap:.5rem!important;column-gap:.5rem!important}.column-gap-xl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media(min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.object-fit-xxl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xxl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xxl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xxl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xxl-none{-o-object-fit:none!important;object-fit:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-inline-grid{display:inline-grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.row-gap-xxl-0{row-gap:0!important}.row-gap-xxl-1{row-gap:.25rem!important}.row-gap-xxl-2{row-gap:.5rem!important}.row-gap-xxl-3{row-gap:1rem!important}.row-gap-xxl-4{row-gap:1.5rem!important}.row-gap-xxl-5{row-gap:3rem!important}.column-gap-xxl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xxl-1{-moz-column-gap:.25rem!important;column-gap:.25rem!important}.column-gap-xxl-2{-moz-column-gap:.5rem!important;column-gap:.5rem!important}.column-gap-xxl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xxl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xxl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media(min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.5rem!important}.fs-4{font-size:1.35rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-inline-grid{display:inline-grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}}/*!* Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com +* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) +* Copyright 2024 Fonticons, Inc.*/.fa,.td-search__icon:before{font-family:var(--fa-style-family,"Font Awesome 6 Free");font-weight:var(--fa-style,900)}.fa-solid,.fa-regular,.fa-brands,.fas,.td-offline-search-results__close-button:after,.far,.fab,.fa-sharp-solid,.fa-classic,.fa,.td-search__icon:before{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:var(--fa-display,inline-block);font-style:normal;font-variant:normal;line-height:1;text-rendering:auto}.fas,.td-offline-search-results__close-button:after,.fa-classic,.fa-solid,.far,.fa-regular{font-family:'font awesome 6 free'}.fab,.fa-brands{font-family:'font awesome 6 brands'}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.08333333em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.07142857em;vertical-align:.05357143em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.04166667em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:var(--fa-li-margin,2.5em);padding-left:0}.fa-ul>li{position:relative}.fa-li{left:calc(-1 * var(--fa-li-width,2em));position:absolute;text-align:center;width:var(--fa-li-width,2em);line-height:inherit}.fa-border{border-color:var(--fa-border-color,#eee);border-radius:var(--fa-border-radius,.1em);border-style:var(--fa-border-style,solid);border-width:var(--fa-border-width,.08em);padding:var(--fa-border-padding,.2em .25em .15em)}.fa-pull-left{float:left;margin-right:var(--fa-pull-margin,.3em)}.fa-pull-right{float:right;margin-left:var(--fa-pull-margin,.3em)}.fa-beat{animation-name:fa-beat;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-bounce{animation-name:fa-bounce;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1))}.fa-fade{animation-name:fa-fade;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-beat-fade{animation-name:fa-beat-fade;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-flip{animation-name:fa-flip;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-shake{animation-name:fa-shake;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin{animation-name:fa-spin;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,2s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin-reverse{--fa-animation-direction:reverse}.fa-pulse,.fa-spin-pulse{animation-name:fa-spin;animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,steps(8))}@media(prefers-reduced-motion:reduce){.fa-beat,.fa-bounce,.fa-fade,.fa-beat-fade,.fa-flip,.fa-pulse,.fa-shake,.fa-spin,.fa-spin-pulse{animation-delay:-1ms;animation-duration:1ms;animation-iteration-count:1;transition-delay:0s;transition-duration:0s}}@keyframes fa-beat{0%,90%{transform:scale(1)}45%{transform:scale(var(--fa-beat-scale,1.25))}}@keyframes fa-bounce{0%{transform:scale(1,1)translateY(0)}10%{transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9))translateY(0)}30%{transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1))translateY(var(--fa-bounce-height,-.5em))}50%{transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95))translateY(0)}57%{transform:scale(1,1)translateY(var(--fa-bounce-rebound,-.125em))}64%{transform:scale(1,1)translateY(0)}100%{transform:scale(1,1)translateY(0)}}@keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@keyframes fa-beat-fade{0%,100%{opacity:var(--fa-beat-fade-opacity,.4);transform:scale(1)}50%{opacity:1;transform:scale(var(--fa-beat-fade-scale,1.125))}}@keyframes fa-flip{50%{transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@keyframes fa-shake{0%{transform:rotate(-15deg)}4%{transform:rotate(15deg)}8%,24%{transform:rotate(-18deg)}12%,28%{transform:rotate(18deg)}16%{transform:rotate(-22deg)}20%{transform:rotate(22deg)}32%{transform:rotate(-12deg)}36%{transform:rotate(12deg)}40%,100%{transform:rotate(0)}}@keyframes fa-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.fa-rotate-90{transform:rotate(90deg)}.fa-rotate-180{transform:rotate(180deg)}.fa-rotate-270{transform:rotate(270deg)}.fa-flip-horizontal{transform:scale(-1,1)}.fa-flip-vertical{transform:scale(1,-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1,-1)}.fa-rotate-by{transform:rotate(var(--fa-rotate-angle,0))}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%;z-index:var(--fa-stack-z-index,auto)}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:var(--fa-inverse,#fff)}.fa-0::before{content:"\30"}.fa-1::before{content:"\31"}.fa-2::before{content:"\32"}.fa-3::before{content:"\33"}.fa-4::before{content:"\34"}.fa-5::before{content:"\35"}.fa-6::before{content:"\36"}.fa-7::before{content:"\37"}.fa-8::before{content:"\38"}.fa-9::before{content:"\39"}.fa-fill-drip::before{content:"\f576"}.fa-arrows-to-circle::before{content:"\e4bd"}.fa-circle-chevron-right::before{content:"\f138"}.fa-chevron-circle-right::before{content:"\f138"}.fa-at::before{content:"\40"}.fa-trash-can::before{content:"\f2ed"}.fa-trash-alt::before{content:"\f2ed"}.fa-text-height::before{content:"\f034"}.fa-user-xmark::before{content:"\f235"}.fa-user-times::before{content:"\f235"}.fa-stethoscope::before{content:"\f0f1"}.fa-message::before{content:"\f27a"}.fa-comment-alt::before{content:"\f27a"}.fa-info::before{content:"\f129"}.fa-down-left-and-up-right-to-center::before{content:"\f422"}.fa-compress-alt::before{content:"\f422"}.fa-explosion::before{content:"\e4e9"}.fa-file-lines::before{content:"\f15c"}.fa-file-alt::before{content:"\f15c"}.fa-file-text::before{content:"\f15c"}.fa-wave-square::before{content:"\f83e"}.fa-ring::before{content:"\f70b"}.fa-building-un::before{content:"\e4d9"}.fa-dice-three::before{content:"\f527"}.fa-calendar-days::before{content:"\f073"}.fa-calendar-alt::before{content:"\f073"}.fa-anchor-circle-check::before{content:"\e4aa"}.fa-building-circle-arrow-right::before{content:"\e4d1"}.fa-volleyball::before{content:"\f45f"}.fa-volleyball-ball::before{content:"\f45f"}.fa-arrows-up-to-line::before{content:"\e4c2"}.fa-sort-down::before{content:"\f0dd"}.fa-sort-desc::before{content:"\f0dd"}.fa-circle-minus::before{content:"\f056"}.fa-minus-circle::before{content:"\f056"}.fa-door-open::before{content:"\f52b"}.fa-right-from-bracket::before{content:"\f2f5"}.fa-sign-out-alt::before{content:"\f2f5"}.fa-atom::before{content:"\f5d2"}.fa-soap::before{content:"\e06e"}.fa-icons::before{content:"\f86d"}.fa-heart-music-camera-bolt::before{content:"\f86d"}.fa-microphone-lines-slash::before{content:"\f539"}.fa-microphone-alt-slash::before{content:"\f539"}.fa-bridge-circle-check::before{content:"\e4c9"}.fa-pump-medical::before{content:"\e06a"}.fa-fingerprint::before{content:"\f577"}.fa-hand-point-right::before{content:"\f0a4"}.fa-magnifying-glass-location::before{content:"\f689"}.fa-search-location::before{content:"\f689"}.fa-forward-step::before{content:"\f051"}.fa-step-forward::before{content:"\f051"}.fa-face-smile-beam::before{content:"\f5b8"}.fa-smile-beam::before{content:"\f5b8"}.fa-flag-checkered::before{content:"\f11e"}.fa-football::before{content:"\f44e"}.fa-football-ball::before{content:"\f44e"}.fa-school-circle-exclamation::before{content:"\e56c"}.fa-crop::before{content:"\f125"}.fa-angles-down::before{content:"\f103"}.fa-angle-double-down::before{content:"\f103"}.fa-users-rectangle::before{content:"\e594"}.fa-people-roof::before{content:"\e537"}.fa-people-line::before{content:"\e534"}.fa-beer-mug-empty::before{content:"\f0fc"}.fa-beer::before{content:"\f0fc"}.fa-diagram-predecessor::before{content:"\e477"}.fa-arrow-up-long::before{content:"\f176"}.fa-long-arrow-up::before{content:"\f176"}.fa-fire-flame-simple::before{content:"\f46a"}.fa-burn::before{content:"\f46a"}.fa-person::before{content:"\f183"}.fa-male::before{content:"\f183"}.fa-laptop::before{content:"\f109"}.fa-file-csv::before{content:"\f6dd"}.fa-menorah::before{content:"\f676"}.fa-truck-plane::before{content:"\e58f"}.fa-record-vinyl::before{content:"\f8d9"}.fa-face-grin-stars::before{content:"\f587"}.fa-grin-stars::before{content:"\f587"}.fa-bong::before{content:"\f55c"}.fa-spaghetti-monster-flying::before{content:"\f67b"}.fa-pastafarianism::before{content:"\f67b"}.fa-arrow-down-up-across-line::before{content:"\e4af"}.fa-spoon::before{content:"\f2e5"}.fa-utensil-spoon::before{content:"\f2e5"}.fa-jar-wheat::before{content:"\e517"}.fa-envelopes-bulk::before{content:"\f674"}.fa-mail-bulk::before{content:"\f674"}.fa-file-circle-exclamation::before{content:"\e4eb"}.fa-circle-h::before{content:"\f47e"}.fa-hospital-symbol::before{content:"\f47e"}.fa-pager::before{content:"\f815"}.fa-address-book::before{content:"\f2b9"}.fa-contact-book::before{content:"\f2b9"}.fa-strikethrough::before{content:"\f0cc"}.fa-k::before{content:"\4b"}.fa-landmark-flag::before{content:"\e51c"}.fa-pencil::before{content:"\f303"}.fa-pencil-alt::before{content:"\f303"}.fa-backward::before{content:"\f04a"}.fa-caret-right::before{content:"\f0da"}.fa-comments::before{content:"\f086"}.fa-paste::before{content:"\f0ea"}.fa-file-clipboard::before{content:"\f0ea"}.fa-code-pull-request::before{content:"\e13c"}.fa-clipboard-list::before{content:"\f46d"}.fa-truck-ramp-box::before{content:"\f4de"}.fa-truck-loading::before{content:"\f4de"}.fa-user-check::before{content:"\f4fc"}.fa-vial-virus::before{content:"\e597"}.fa-sheet-plastic::before{content:"\e571"}.fa-blog::before{content:"\f781"}.fa-user-ninja::before{content:"\f504"}.fa-person-arrow-up-from-line::before{content:"\e539"}.fa-scroll-torah::before{content:"\f6a0"}.fa-torah::before{content:"\f6a0"}.fa-broom-ball::before{content:"\f458"}.fa-quidditch::before{content:"\f458"}.fa-quidditch-broom-ball::before{content:"\f458"}.fa-toggle-off::before{content:"\f204"}.fa-box-archive::before{content:"\f187"}.fa-archive::before{content:"\f187"}.fa-person-drowning::before{content:"\e545"}.fa-arrow-down-9-1::before{content:"\f886"}.fa-sort-numeric-desc::before{content:"\f886"}.fa-sort-numeric-down-alt::before{content:"\f886"}.fa-face-grin-tongue-squint::before{content:"\f58a"}.fa-grin-tongue-squint::before{content:"\f58a"}.fa-spray-can::before{content:"\f5bd"}.fa-truck-monster::before{content:"\f63b"}.fa-w::before{content:"\57"}.fa-earth-africa::before{content:"\f57c"}.fa-globe-africa::before{content:"\f57c"}.fa-rainbow::before{content:"\f75b"}.fa-circle-notch::before{content:"\f1ce"}.fa-tablet-screen-button::before{content:"\f3fa"}.fa-tablet-alt::before{content:"\f3fa"}.fa-paw::before{content:"\f1b0"}.fa-cloud::before{content:"\f0c2"}.fa-trowel-bricks::before{content:"\e58a"}.fa-face-flushed::before{content:"\f579"}.fa-flushed::before{content:"\f579"}.fa-hospital-user::before{content:"\f80d"}.fa-tent-arrow-left-right::before{content:"\e57f"}.fa-gavel::before{content:"\f0e3"}.fa-legal::before{content:"\f0e3"}.fa-binoculars::before{content:"\f1e5"}.fa-microphone-slash::before{content:"\f131"}.fa-box-tissue::before{content:"\e05b"}.fa-motorcycle::before{content:"\f21c"}.fa-bell-concierge::before{content:"\f562"}.fa-concierge-bell::before{content:"\f562"}.fa-pen-ruler::before{content:"\f5ae"}.fa-pencil-ruler::before{content:"\f5ae"}.fa-people-arrows::before{content:"\e068"}.fa-people-arrows-left-right::before{content:"\e068"}.fa-mars-and-venus-burst::before{content:"\e523"}.fa-square-caret-right::before{content:"\f152"}.fa-caret-square-right::before{content:"\f152"}.fa-scissors::before{content:"\f0c4"}.fa-cut::before{content:"\f0c4"}.fa-sun-plant-wilt::before{content:"\e57a"}.fa-toilets-portable::before{content:"\e584"}.fa-hockey-puck::before{content:"\f453"}.fa-table::before{content:"\f0ce"}.fa-magnifying-glass-arrow-right::before{content:"\e521"}.fa-tachograph-digital::before{content:"\f566"}.fa-digital-tachograph::before{content:"\f566"}.fa-users-slash::before{content:"\e073"}.fa-clover::before{content:"\e139"}.fa-reply::before{content:"\f3e5"}.fa-mail-reply::before{content:"\f3e5"}.fa-star-and-crescent::before{content:"\f699"}.fa-house-fire::before{content:"\e50c"}.fa-square-minus::before{content:"\f146"}.fa-minus-square::before{content:"\f146"}.fa-helicopter::before{content:"\f533"}.fa-compass::before{content:"\f14e"}.fa-square-caret-down::before{content:"\f150"}.fa-caret-square-down::before{content:"\f150"}.fa-file-circle-question::before{content:"\e4ef"}.fa-laptop-code::before{content:"\f5fc"}.fa-swatchbook::before{content:"\f5c3"}.fa-prescription-bottle::before{content:"\f485"}.fa-bars::before{content:"\f0c9"}.fa-navicon::before{content:"\f0c9"}.fa-people-group::before{content:"\e533"}.fa-hourglass-end::before{content:"\f253"}.fa-hourglass-3::before{content:"\f253"}.fa-heart-crack::before{content:"\f7a9"}.fa-heart-broken::before{content:"\f7a9"}.fa-square-up-right::before{content:"\f360"}.fa-external-link-square-alt::before{content:"\f360"}.fa-face-kiss-beam::before{content:"\f597"}.fa-kiss-beam::before{content:"\f597"}.fa-film::before{content:"\f008"}.fa-ruler-horizontal::before{content:"\f547"}.fa-people-robbery::before{content:"\e536"}.fa-lightbulb::before{content:"\f0eb"}.fa-caret-left::before{content:"\f0d9"}.fa-circle-exclamation::before{content:"\f06a"}.fa-exclamation-circle::before{content:"\f06a"}.fa-school-circle-xmark::before{content:"\e56d"}.fa-arrow-right-from-bracket::before{content:"\f08b"}.fa-sign-out::before{content:"\f08b"}.fa-circle-chevron-down::before{content:"\f13a"}.fa-chevron-circle-down::before{content:"\f13a"}.fa-unlock-keyhole::before{content:"\f13e"}.fa-unlock-alt::before{content:"\f13e"}.fa-cloud-showers-heavy::before{content:"\f740"}.fa-headphones-simple::before{content:"\f58f"}.fa-headphones-alt::before{content:"\f58f"}.fa-sitemap::before{content:"\f0e8"}.fa-circle-dollar-to-slot::before{content:"\f4b9"}.fa-donate::before{content:"\f4b9"}.fa-memory::before{content:"\f538"}.fa-road-spikes::before{content:"\e568"}.fa-fire-burner::before{content:"\e4f1"}.fa-flag::before{content:"\f024"}.fa-hanukiah::before{content:"\f6e6"}.fa-feather::before{content:"\f52d"}.fa-volume-low::before{content:"\f027"}.fa-volume-down::before{content:"\f027"}.fa-comment-slash::before{content:"\f4b3"}.fa-cloud-sun-rain::before{content:"\f743"}.fa-compress::before{content:"\f066"}.fa-wheat-awn::before{content:"\e2cd"}.fa-wheat-alt::before{content:"\e2cd"}.fa-ankh::before{content:"\f644"}.fa-hands-holding-child::before{content:"\e4fa"}.fa-asterisk::before{content:"\2a"}.fa-square-check::before{content:"\f14a"}.fa-check-square::before{content:"\f14a"}.fa-peseta-sign::before{content:"\e221"}.fa-heading::before{content:"\f1dc"}.fa-header::before{content:"\f1dc"}.fa-ghost::before{content:"\f6e2"}.fa-list::before{content:"\f03a"}.fa-list-squares::before{content:"\f03a"}.fa-square-phone-flip::before{content:"\f87b"}.fa-phone-square-alt::before{content:"\f87b"}.fa-cart-plus::before{content:"\f217"}.fa-gamepad::before{content:"\f11b"}.fa-circle-dot::before{content:"\f192"}.fa-dot-circle::before{content:"\f192"}.fa-face-dizzy::before{content:"\f567"}.fa-dizzy::before{content:"\f567"}.fa-egg::before{content:"\f7fb"}.fa-house-medical-circle-xmark::before{content:"\e513"}.fa-campground::before{content:"\f6bb"}.fa-folder-plus::before{content:"\f65e"}.fa-futbol::before{content:"\f1e3"}.fa-futbol-ball::before{content:"\f1e3"}.fa-soccer-ball::before{content:"\f1e3"}.fa-paintbrush::before{content:"\f1fc"}.fa-paint-brush::before{content:"\f1fc"}.fa-lock::before{content:"\f023"}.fa-gas-pump::before{content:"\f52f"}.fa-hot-tub-person::before{content:"\f593"}.fa-hot-tub::before{content:"\f593"}.fa-map-location::before{content:"\f59f"}.fa-map-marked::before{content:"\f59f"}.fa-house-flood-water::before{content:"\e50e"}.fa-tree::before{content:"\f1bb"}.fa-bridge-lock::before{content:"\e4cc"}.fa-sack-dollar::before{content:"\f81d"}.fa-pen-to-square::before{content:"\f044"}.fa-edit::before{content:"\f044"}.fa-car-side::before{content:"\f5e4"}.fa-share-nodes::before{content:"\f1e0"}.fa-share-alt::before{content:"\f1e0"}.fa-heart-circle-minus::before{content:"\e4ff"}.fa-hourglass-half::before{content:"\f252"}.fa-hourglass-2::before{content:"\f252"}.fa-microscope::before{content:"\f610"}.fa-sink::before{content:"\e06d"}.fa-bag-shopping::before{content:"\f290"}.fa-shopping-bag::before{content:"\f290"}.fa-arrow-down-z-a::before{content:"\f881"}.fa-sort-alpha-desc::before{content:"\f881"}.fa-sort-alpha-down-alt::before{content:"\f881"}.fa-mitten::before{content:"\f7b5"}.fa-person-rays::before{content:"\e54d"}.fa-users::before{content:"\f0c0"}.fa-eye-slash::before{content:"\f070"}.fa-flask-vial::before{content:"\e4f3"}.fa-hand::before{content:"\f256"}.fa-hand-paper::before{content:"\f256"}.fa-om::before{content:"\f679"}.fa-worm::before{content:"\e599"}.fa-house-circle-xmark::before{content:"\e50b"}.fa-plug::before{content:"\f1e6"}.fa-chevron-up::before{content:"\f077"}.fa-hand-spock::before{content:"\f259"}.fa-stopwatch::before{content:"\f2f2"}.fa-face-kiss::before{content:"\f596"}.fa-kiss::before{content:"\f596"}.fa-bridge-circle-xmark::before{content:"\e4cb"}.fa-face-grin-tongue::before{content:"\f589"}.fa-grin-tongue::before{content:"\f589"}.fa-chess-bishop::before{content:"\f43a"}.fa-face-grin-wink::before{content:"\f58c"}.fa-grin-wink::before{content:"\f58c"}.fa-ear-deaf::before{content:"\f2a4"}.fa-deaf::before{content:"\f2a4"}.fa-deafness::before{content:"\f2a4"}.fa-hard-of-hearing::before{content:"\f2a4"}.fa-road-circle-check::before{content:"\e564"}.fa-dice-five::before{content:"\f523"}.fa-square-rss::before{content:"\f143"}.fa-rss-square::before{content:"\f143"}.fa-land-mine-on::before{content:"\e51b"}.fa-i-cursor::before{content:"\f246"}.fa-stamp::before{content:"\f5bf"}.fa-stairs::before{content:"\e289"}.fa-i::before{content:"\49"}.fa-hryvnia-sign::before{content:"\f6f2"}.fa-hryvnia::before{content:"\f6f2"}.fa-pills::before{content:"\f484"}.fa-face-grin-wide::before{content:"\f581"}.fa-grin-alt::before{content:"\f581"}.fa-tooth::before{content:"\f5c9"}.fa-v::before{content:"\56"}.fa-bangladeshi-taka-sign::before{content:"\e2e6"}.fa-bicycle::before{content:"\f206"}.fa-staff-snake::before{content:"\e579"}.fa-rod-asclepius::before{content:"\e579"}.fa-rod-snake::before{content:"\e579"}.fa-staff-aesculapius::before{content:"\e579"}.fa-head-side-cough-slash::before{content:"\e062"}.fa-truck-medical::before{content:"\f0f9"}.fa-ambulance::before{content:"\f0f9"}.fa-wheat-awn-circle-exclamation::before{content:"\e598"}.fa-snowman::before{content:"\f7d0"}.fa-mortar-pestle::before{content:"\f5a7"}.fa-road-barrier::before{content:"\e562"}.fa-school::before{content:"\f549"}.fa-igloo::before{content:"\f7ae"}.fa-joint::before{content:"\f595"}.fa-angle-right::before{content:"\f105"}.fa-horse::before{content:"\f6f0"}.fa-q::before{content:"\51"}.fa-g::before{content:"\47"}.fa-notes-medical::before{content:"\f481"}.fa-temperature-half::before{content:"\f2c9"}.fa-temperature-2::before{content:"\f2c9"}.fa-thermometer-2::before{content:"\f2c9"}.fa-thermometer-half::before{content:"\f2c9"}.fa-dong-sign::before{content:"\e169"}.fa-capsules::before{content:"\f46b"}.fa-poo-storm::before{content:"\f75a"}.fa-poo-bolt::before{content:"\f75a"}.fa-face-frown-open::before{content:"\f57a"}.fa-frown-open::before{content:"\f57a"}.fa-hand-point-up::before{content:"\f0a6"}.fa-money-bill::before{content:"\f0d6"}.fa-bookmark::before{content:"\f02e"}.fa-align-justify::before{content:"\f039"}.fa-umbrella-beach::before{content:"\f5ca"}.fa-helmet-un::before{content:"\e503"}.fa-bullseye::before{content:"\f140"}.fa-bacon::before{content:"\f7e5"}.fa-hand-point-down::before{content:"\f0a7"}.fa-arrow-up-from-bracket::before{content:"\e09a"}.fa-folder::before{content:"\f07b"}.fa-folder-blank::before{content:"\f07b"}.fa-file-waveform::before{content:"\f478"}.fa-file-medical-alt::before{content:"\f478"}.fa-radiation::before{content:"\f7b9"}.fa-chart-simple::before{content:"\e473"}.fa-mars-stroke::before{content:"\f229"}.fa-vial::before{content:"\f492"}.fa-gauge::before{content:"\f624"}.fa-dashboard::before{content:"\f624"}.fa-gauge-med::before{content:"\f624"}.fa-tachometer-alt-average::before{content:"\f624"}.fa-wand-magic-sparkles::before{content:"\e2ca"}.fa-magic-wand-sparkles::before{content:"\e2ca"}.fa-e::before{content:"\45"}.fa-pen-clip::before{content:"\f305"}.fa-pen-alt::before{content:"\f305"}.fa-bridge-circle-exclamation::before{content:"\e4ca"}.fa-user::before{content:"\f007"}.fa-school-circle-check::before{content:"\e56b"}.fa-dumpster::before{content:"\f793"}.fa-van-shuttle::before{content:"\f5b6"}.fa-shuttle-van::before{content:"\f5b6"}.fa-building-user::before{content:"\e4da"}.fa-square-caret-left::before{content:"\f191"}.fa-caret-square-left::before{content:"\f191"}.fa-highlighter::before{content:"\f591"}.fa-key::before{content:"\f084"}.fa-bullhorn::before{content:"\f0a1"}.fa-globe::before{content:"\f0ac"}.fa-synagogue::before{content:"\f69b"}.fa-person-half-dress::before{content:"\e548"}.fa-road-bridge::before{content:"\e563"}.fa-location-arrow::before{content:"\f124"}.fa-c::before{content:"\43"}.fa-tablet-button::before{content:"\f10a"}.fa-building-lock::before{content:"\e4d6"}.fa-pizza-slice::before{content:"\f818"}.fa-money-bill-wave::before{content:"\f53a"}.fa-chart-area::before{content:"\f1fe"}.fa-area-chart::before{content:"\f1fe"}.fa-house-flag::before{content:"\e50d"}.fa-person-circle-minus::before{content:"\e540"}.fa-ban::before{content:"\f05e"}.fa-cancel::before{content:"\f05e"}.fa-camera-rotate::before{content:"\e0d8"}.fa-spray-can-sparkles::before{content:"\f5d0"}.fa-air-freshener::before{content:"\f5d0"}.fa-star::before{content:"\f005"}.fa-repeat::before{content:"\f363"}.fa-cross::before{content:"\f654"}.fa-box::before{content:"\f466"}.fa-venus-mars::before{content:"\f228"}.fa-arrow-pointer::before{content:"\f245"}.fa-mouse-pointer::before{content:"\f245"}.fa-maximize::before{content:"\f31e"}.fa-expand-arrows-alt::before{content:"\f31e"}.fa-charging-station::before{content:"\f5e7"}.fa-shapes::before{content:"\f61f"}.fa-triangle-circle-square::before{content:"\f61f"}.fa-shuffle::before{content:"\f074"}.fa-random::before{content:"\f074"}.fa-person-running::before{content:"\f70c"}.fa-running::before{content:"\f70c"}.fa-mobile-retro::before{content:"\e527"}.fa-grip-lines-vertical::before{content:"\f7a5"}.fa-spider::before{content:"\f717"}.fa-hands-bound::before{content:"\e4f9"}.fa-file-invoice-dollar::before{content:"\f571"}.fa-plane-circle-exclamation::before{content:"\e556"}.fa-x-ray::before{content:"\f497"}.fa-spell-check::before{content:"\f891"}.fa-slash::before{content:"\f715"}.fa-computer-mouse::before{content:"\f8cc"}.fa-mouse::before{content:"\f8cc"}.fa-arrow-right-to-bracket::before{content:"\f090"}.fa-sign-in::before{content:"\f090"}.fa-shop-slash::before{content:"\e070"}.fa-store-alt-slash::before{content:"\e070"}.fa-server::before{content:"\f233"}.fa-virus-covid-slash::before{content:"\e4a9"}.fa-shop-lock::before{content:"\e4a5"}.fa-hourglass-start::before{content:"\f251"}.fa-hourglass-1::before{content:"\f251"}.fa-blender-phone::before{content:"\f6b6"}.fa-building-wheat::before{content:"\e4db"}.fa-person-breastfeeding::before{content:"\e53a"}.fa-right-to-bracket::before{content:"\f2f6"}.fa-sign-in-alt::before{content:"\f2f6"}.fa-venus::before{content:"\f221"}.fa-passport::before{content:"\f5ab"}.fa-thumbtack-slash::before{content:"\e68f"}.fa-thumb-tack-slash::before{content:"\e68f"}.fa-heart-pulse::before{content:"\f21e"}.fa-heartbeat::before{content:"\f21e"}.fa-people-carry-box::before{content:"\f4ce"}.fa-people-carry::before{content:"\f4ce"}.fa-temperature-high::before{content:"\f769"}.fa-microchip::before{content:"\f2db"}.fa-crown::before{content:"\f521"}.fa-weight-hanging::before{content:"\f5cd"}.fa-xmarks-lines::before{content:"\e59a"}.fa-file-prescription::before{content:"\f572"}.fa-weight-scale::before{content:"\f496"}.fa-weight::before{content:"\f496"}.fa-user-group::before{content:"\f500"}.fa-user-friends::before{content:"\f500"}.fa-arrow-up-a-z::before{content:"\f15e"}.fa-sort-alpha-up::before{content:"\f15e"}.fa-chess-knight::before{content:"\f441"}.fa-face-laugh-squint::before{content:"\f59b"}.fa-laugh-squint::before{content:"\f59b"}.fa-wheelchair::before{content:"\f193"}.fa-circle-arrow-up::before{content:"\f0aa"}.fa-arrow-circle-up::before{content:"\f0aa"}.fa-toggle-on::before{content:"\f205"}.fa-person-walking::before{content:"\f554"}.fa-walking::before{content:"\f554"}.fa-l::before{content:"\4c"}.fa-fire::before{content:"\f06d"}.fa-bed-pulse::before{content:"\f487"}.fa-procedures::before{content:"\f487"}.fa-shuttle-space::before{content:"\f197"}.fa-space-shuttle::before{content:"\f197"}.fa-face-laugh::before{content:"\f599"}.fa-laugh::before{content:"\f599"}.fa-folder-open::before{content:"\f07c"}.fa-heart-circle-plus::before{content:"\e500"}.fa-code-fork::before{content:"\e13b"}.fa-city::before{content:"\f64f"}.fa-microphone-lines::before{content:"\f3c9"}.fa-microphone-alt::before{content:"\f3c9"}.fa-pepper-hot::before{content:"\f816"}.fa-unlock::before{content:"\f09c"}.fa-colon-sign::before{content:"\e140"}.fa-headset::before{content:"\f590"}.fa-store-slash::before{content:"\e071"}.fa-road-circle-xmark::before{content:"\e566"}.fa-user-minus::before{content:"\f503"}.fa-mars-stroke-up::before{content:"\f22a"}.fa-mars-stroke-v::before{content:"\f22a"}.fa-champagne-glasses::before{content:"\f79f"}.fa-glass-cheers::before{content:"\f79f"}.fa-clipboard::before{content:"\f328"}.fa-house-circle-exclamation::before{content:"\e50a"}.fa-file-arrow-up::before{content:"\f574"}.fa-file-upload::before{content:"\f574"}.fa-wifi::before{content:"\f1eb"}.fa-wifi-3::before{content:"\f1eb"}.fa-wifi-strong::before{content:"\f1eb"}.fa-bath::before{content:"\f2cd"}.fa-bathtub::before{content:"\f2cd"}.fa-underline::before{content:"\f0cd"}.fa-user-pen::before{content:"\f4ff"}.fa-user-edit::before{content:"\f4ff"}.fa-signature::before{content:"\f5b7"}.fa-stroopwafel::before{content:"\f551"}.fa-bold::before{content:"\f032"}.fa-anchor-lock::before{content:"\e4ad"}.fa-building-ngo::before{content:"\e4d7"}.fa-manat-sign::before{content:"\e1d5"}.fa-not-equal::before{content:"\f53e"}.fa-border-top-left::before{content:"\f853"}.fa-border-style::before{content:"\f853"}.fa-map-location-dot::before{content:"\f5a0"}.fa-map-marked-alt::before{content:"\f5a0"}.fa-jedi::before{content:"\f669"}.fa-square-poll-vertical::before{content:"\f681"}.fa-poll::before{content:"\f681"}.fa-mug-hot::before{content:"\f7b6"}.fa-car-battery::before{content:"\f5df"}.fa-battery-car::before{content:"\f5df"}.fa-gift::before{content:"\f06b"}.fa-dice-two::before{content:"\f528"}.fa-chess-queen::before{content:"\f445"}.fa-glasses::before{content:"\f530"}.fa-chess-board::before{content:"\f43c"}.fa-building-circle-check::before{content:"\e4d2"}.fa-person-chalkboard::before{content:"\e53d"}.fa-mars-stroke-right::before{content:"\f22b"}.fa-mars-stroke-h::before{content:"\f22b"}.fa-hand-back-fist::before{content:"\f255"}.fa-hand-rock::before{content:"\f255"}.fa-square-caret-up::before{content:"\f151"}.fa-caret-square-up::before{content:"\f151"}.fa-cloud-showers-water::before{content:"\e4e4"}.fa-chart-bar::before{content:"\f080"}.fa-bar-chart::before{content:"\f080"}.fa-hands-bubbles::before{content:"\e05e"}.fa-hands-wash::before{content:"\e05e"}.fa-less-than-equal::before{content:"\f537"}.fa-train::before{content:"\f238"}.fa-eye-low-vision::before{content:"\f2a8"}.fa-low-vision::before{content:"\f2a8"}.fa-crow::before{content:"\f520"}.fa-sailboat::before{content:"\e445"}.fa-window-restore::before{content:"\f2d2"}.fa-square-plus::before{content:"\f0fe"}.fa-plus-square::before{content:"\f0fe"}.fa-torii-gate::before{content:"\f6a1"}.fa-frog::before{content:"\f52e"}.fa-bucket::before{content:"\e4cf"}.fa-image::before{content:"\f03e"}.fa-microphone::before{content:"\f130"}.fa-cow::before{content:"\f6c8"}.fa-caret-up::before{content:"\f0d8"}.fa-screwdriver::before{content:"\f54a"}.fa-folder-closed::before{content:"\e185"}.fa-house-tsunami::before{content:"\e515"}.fa-square-nfi::before{content:"\e576"}.fa-arrow-up-from-ground-water::before{content:"\e4b5"}.fa-martini-glass::before{content:"\f57b"}.fa-glass-martini-alt::before{content:"\f57b"}.fa-rotate-left::before{content:"\f2ea"}.fa-rotate-back::before{content:"\f2ea"}.fa-rotate-backward::before{content:"\f2ea"}.fa-undo-alt::before{content:"\f2ea"}.fa-table-columns::before{content:"\f0db"}.fa-columns::before{content:"\f0db"}.fa-lemon::before{content:"\f094"}.fa-head-side-mask::before{content:"\e063"}.fa-handshake::before{content:"\f2b5"}.fa-gem::before{content:"\f3a5"}.fa-dolly::before{content:"\f472"}.fa-dolly-box::before{content:"\f472"}.fa-smoking::before{content:"\f48d"}.fa-minimize::before{content:"\f78c"}.fa-compress-arrows-alt::before{content:"\f78c"}.fa-monument::before{content:"\f5a6"}.fa-snowplow::before{content:"\f7d2"}.fa-angles-right::before{content:"\f101"}.fa-angle-double-right::before{content:"\f101"}.fa-cannabis::before{content:"\f55f"}.fa-circle-play::before{content:"\f144"}.fa-play-circle::before{content:"\f144"}.fa-tablets::before{content:"\f490"}.fa-ethernet::before{content:"\f796"}.fa-euro-sign::before{content:"\f153"}.fa-eur::before{content:"\f153"}.fa-euro::before{content:"\f153"}.fa-chair::before{content:"\f6c0"}.fa-circle-check::before{content:"\f058"}.fa-check-circle::before{content:"\f058"}.fa-circle-stop::before{content:"\f28d"}.fa-stop-circle::before{content:"\f28d"}.fa-compass-drafting::before{content:"\f568"}.fa-drafting-compass::before{content:"\f568"}.fa-plate-wheat::before{content:"\e55a"}.fa-icicles::before{content:"\f7ad"}.fa-person-shelter::before{content:"\e54f"}.fa-neuter::before{content:"\f22c"}.fa-id-badge::before{content:"\f2c1"}.fa-marker::before{content:"\f5a1"}.fa-face-laugh-beam::before{content:"\f59a"}.fa-laugh-beam::before{content:"\f59a"}.fa-helicopter-symbol::before{content:"\e502"}.fa-universal-access::before{content:"\f29a"}.fa-circle-chevron-up::before{content:"\f139"}.fa-chevron-circle-up::before{content:"\f139"}.fa-lari-sign::before{content:"\e1c8"}.fa-volcano::before{content:"\f770"}.fa-person-walking-dashed-line-arrow-right::before{content:"\e553"}.fa-sterling-sign::before{content:"\f154"}.fa-gbp::before{content:"\f154"}.fa-pound-sign::before{content:"\f154"}.fa-viruses::before{content:"\e076"}.fa-square-person-confined::before{content:"\e577"}.fa-user-tie::before{content:"\f508"}.fa-arrow-down-long::before{content:"\f175"}.fa-long-arrow-down::before{content:"\f175"}.fa-tent-arrow-down-to-line::before{content:"\e57e"}.fa-certificate::before{content:"\f0a3"}.fa-reply-all::before{content:"\f122"}.fa-mail-reply-all::before{content:"\f122"}.fa-suitcase::before{content:"\f0f2"}.fa-person-skating::before{content:"\f7c5"}.fa-skating::before{content:"\f7c5"}.fa-filter-circle-dollar::before{content:"\f662"}.fa-funnel-dollar::before{content:"\f662"}.fa-camera-retro::before{content:"\f083"}.fa-circle-arrow-down::before{content:"\f0ab"}.fa-arrow-circle-down::before{content:"\f0ab"}.fa-file-import::before{content:"\f56f"}.fa-arrow-right-to-file::before{content:"\f56f"}.fa-square-arrow-up-right::before{content:"\f14c"}.fa-external-link-square::before{content:"\f14c"}.fa-box-open::before{content:"\f49e"}.fa-scroll::before{content:"\f70e"}.fa-spa::before{content:"\f5bb"}.fa-location-pin-lock::before{content:"\e51f"}.fa-pause::before{content:"\f04c"}.fa-hill-avalanche::before{content:"\e507"}.fa-temperature-empty::before{content:"\f2cb"}.fa-temperature-0::before{content:"\f2cb"}.fa-thermometer-0::before{content:"\f2cb"}.fa-thermometer-empty::before{content:"\f2cb"}.fa-bomb::before{content:"\f1e2"}.fa-registered::before{content:"\f25d"}.fa-address-card::before{content:"\f2bb"}.fa-contact-card::before{content:"\f2bb"}.fa-vcard::before{content:"\f2bb"}.fa-scale-unbalanced-flip::before{content:"\f516"}.fa-balance-scale-right::before{content:"\f516"}.fa-subscript::before{content:"\f12c"}.fa-diamond-turn-right::before{content:"\f5eb"}.fa-directions::before{content:"\f5eb"}.fa-burst::before{content:"\e4dc"}.fa-house-laptop::before{content:"\e066"}.fa-laptop-house::before{content:"\e066"}.fa-face-tired::before{content:"\f5c8"}.fa-tired::before{content:"\f5c8"}.fa-money-bills::before{content:"\e1f3"}.fa-smog::before{content:"\f75f"}.fa-crutch::before{content:"\f7f7"}.fa-cloud-arrow-up::before{content:"\f0ee"}.fa-cloud-upload::before{content:"\f0ee"}.fa-cloud-upload-alt::before{content:"\f0ee"}.fa-palette::before{content:"\f53f"}.fa-arrows-turn-right::before{content:"\e4c0"}.fa-vest::before{content:"\e085"}.fa-ferry::before{content:"\e4ea"}.fa-arrows-down-to-people::before{content:"\e4b9"}.fa-seedling::before{content:"\f4d8"}.fa-sprout::before{content:"\f4d8"}.fa-left-right::before{content:"\f337"}.fa-arrows-alt-h::before{content:"\f337"}.fa-boxes-packing::before{content:"\e4c7"}.fa-circle-arrow-left::before{content:"\f0a8"}.fa-arrow-circle-left::before{content:"\f0a8"}.fa-group-arrows-rotate::before{content:"\e4f6"}.fa-bowl-food::before{content:"\e4c6"}.fa-candy-cane::before{content:"\f786"}.fa-arrow-down-wide-short::before{content:"\f160"}.fa-sort-amount-asc::before{content:"\f160"}.fa-sort-amount-down::before{content:"\f160"}.fa-cloud-bolt::before{content:"\f76c"}.fa-thunderstorm::before{content:"\f76c"}.fa-text-slash::before{content:"\f87d"}.fa-remove-format::before{content:"\f87d"}.fa-face-smile-wink::before{content:"\f4da"}.fa-smile-wink::before{content:"\f4da"}.fa-file-word::before{content:"\f1c2"}.fa-file-powerpoint::before{content:"\f1c4"}.fa-arrows-left-right::before{content:"\f07e"}.fa-arrows-h::before{content:"\f07e"}.fa-house-lock::before{content:"\e510"}.fa-cloud-arrow-down::before{content:"\f0ed"}.fa-cloud-download::before{content:"\f0ed"}.fa-cloud-download-alt::before{content:"\f0ed"}.fa-children::before{content:"\e4e1"}.fa-chalkboard::before{content:"\f51b"}.fa-blackboard::before{content:"\f51b"}.fa-user-large-slash::before{content:"\f4fa"}.fa-user-alt-slash::before{content:"\f4fa"}.fa-envelope-open::before{content:"\f2b6"}.fa-handshake-simple-slash::before{content:"\e05f"}.fa-handshake-alt-slash::before{content:"\e05f"}.fa-mattress-pillow::before{content:"\e525"}.fa-guarani-sign::before{content:"\e19a"}.fa-arrows-rotate::before{content:"\f021"}.fa-refresh::before{content:"\f021"}.fa-sync::before{content:"\f021"}.fa-fire-extinguisher::before{content:"\f134"}.fa-cruzeiro-sign::before{content:"\e152"}.fa-greater-than-equal::before{content:"\f532"}.fa-shield-halved::before{content:"\f3ed"}.fa-shield-alt::before{content:"\f3ed"}.fa-book-atlas::before{content:"\f558"}.fa-atlas::before{content:"\f558"}.fa-virus::before{content:"\e074"}.fa-envelope-circle-check::before{content:"\e4e8"}.fa-layer-group::before{content:"\f5fd"}.fa-arrows-to-dot::before{content:"\e4be"}.fa-archway::before{content:"\f557"}.fa-heart-circle-check::before{content:"\e4fd"}.fa-house-chimney-crack::before{content:"\f6f1"}.fa-house-damage::before{content:"\f6f1"}.fa-file-zipper::before{content:"\f1c6"}.fa-file-archive::before{content:"\f1c6"}.fa-square::before{content:"\f0c8"}.fa-martini-glass-empty::before{content:"\f000"}.fa-glass-martini::before{content:"\f000"}.fa-couch::before{content:"\f4b8"}.fa-cedi-sign::before{content:"\e0df"}.fa-italic::before{content:"\f033"}.fa-table-cells-column-lock::before{content:"\e678"}.fa-church::before{content:"\f51d"}.fa-comments-dollar::before{content:"\f653"}.fa-democrat::before{content:"\f747"}.fa-z::before{content:"\5a"}.fa-person-skiing::before{content:"\f7c9"}.fa-skiing::before{content:"\f7c9"}.fa-road-lock::before{content:"\e567"}.fa-a::before{content:"\41"}.fa-temperature-arrow-down::before{content:"\e03f"}.fa-temperature-down::before{content:"\e03f"}.fa-feather-pointed::before{content:"\f56b"}.fa-feather-alt::before{content:"\f56b"}.fa-p::before{content:"\50"}.fa-snowflake::before{content:"\f2dc"}.fa-newspaper::before{content:"\f1ea"}.fa-rectangle-ad::before{content:"\f641"}.fa-ad::before{content:"\f641"}.fa-circle-arrow-right::before{content:"\f0a9"}.fa-arrow-circle-right::before{content:"\f0a9"}.fa-filter-circle-xmark::before{content:"\e17b"}.fa-locust::before{content:"\e520"}.fa-sort::before{content:"\f0dc"}.fa-unsorted::before{content:"\f0dc"}.fa-list-ol::before{content:"\f0cb"}.fa-list-1-2::before{content:"\f0cb"}.fa-list-numeric::before{content:"\f0cb"}.fa-person-dress-burst::before{content:"\e544"}.fa-money-check-dollar::before{content:"\f53d"}.fa-money-check-alt::before{content:"\f53d"}.fa-vector-square::before{content:"\f5cb"}.fa-bread-slice::before{content:"\f7ec"}.fa-language::before{content:"\f1ab"}.fa-face-kiss-wink-heart::before{content:"\f598"}.fa-kiss-wink-heart::before{content:"\f598"}.fa-filter::before{content:"\f0b0"}.fa-question::before{content:"\3f"}.fa-file-signature::before{content:"\f573"}.fa-up-down-left-right::before{content:"\f0b2"}.fa-arrows-alt::before{content:"\f0b2"}.fa-house-chimney-user::before{content:"\e065"}.fa-hand-holding-heart::before{content:"\f4be"}.fa-puzzle-piece::before{content:"\f12e"}.fa-money-check::before{content:"\f53c"}.fa-star-half-stroke::before{content:"\f5c0"}.fa-star-half-alt::before{content:"\f5c0"}.fa-code::before{content:"\f121"}.fa-whiskey-glass::before{content:"\f7a0"}.fa-glass-whiskey::before{content:"\f7a0"}.fa-building-circle-exclamation::before{content:"\e4d3"}.fa-magnifying-glass-chart::before{content:"\e522"}.fa-arrow-up-right-from-square::before{content:"\f08e"}.fa-external-link::before{content:"\f08e"}.fa-cubes-stacked::before{content:"\e4e6"}.fa-won-sign::before{content:"\f159"}.fa-krw::before{content:"\f159"}.fa-won::before{content:"\f159"}.fa-virus-covid::before{content:"\e4a8"}.fa-austral-sign::before{content:"\e0a9"}.fa-f::before{content:"\46"}.fa-leaf::before{content:"\f06c"}.fa-road::before{content:"\f018"}.fa-taxi::before{content:"\f1ba"}.fa-cab::before{content:"\f1ba"}.fa-person-circle-plus::before{content:"\e541"}.fa-chart-pie::before{content:"\f200"}.fa-pie-chart::before{content:"\f200"}.fa-bolt-lightning::before{content:"\e0b7"}.fa-sack-xmark::before{content:"\e56a"}.fa-file-excel::before{content:"\f1c3"}.fa-file-contract::before{content:"\f56c"}.fa-fish-fins::before{content:"\e4f2"}.fa-building-flag::before{content:"\e4d5"}.fa-face-grin-beam::before{content:"\f582"}.fa-grin-beam::before{content:"\f582"}.fa-object-ungroup::before{content:"\f248"}.fa-poop::before{content:"\f619"}.fa-location-pin::before{content:"\f041"}.fa-map-marker::before{content:"\f041"}.fa-kaaba::before{content:"\f66b"}.fa-toilet-paper::before{content:"\f71e"}.fa-helmet-safety::before{content:"\f807"}.fa-hard-hat::before{content:"\f807"}.fa-hat-hard::before{content:"\f807"}.fa-eject::before{content:"\f052"}.fa-circle-right::before{content:"\f35a"}.fa-arrow-alt-circle-right::before{content:"\f35a"}.fa-plane-circle-check::before{content:"\e555"}.fa-face-rolling-eyes::before{content:"\f5a5"}.fa-meh-rolling-eyes::before{content:"\f5a5"}.fa-object-group::before{content:"\f247"}.fa-chart-line::before{content:"\f201"}.fa-line-chart::before{content:"\f201"}.fa-mask-ventilator::before{content:"\e524"}.fa-arrow-right::before{content:"\f061"}.fa-signs-post::before{content:"\f277"}.fa-map-signs::before{content:"\f277"}.fa-cash-register::before{content:"\f788"}.fa-person-circle-question::before{content:"\e542"}.fa-h::before{content:"\48"}.fa-tarp::before{content:"\e57b"}.fa-screwdriver-wrench::before{content:"\f7d9"}.fa-tools::before{content:"\f7d9"}.fa-arrows-to-eye::before{content:"\e4bf"}.fa-plug-circle-bolt::before{content:"\e55b"}.fa-heart::before{content:"\f004"}.fa-mars-and-venus::before{content:"\f224"}.fa-house-user::before{content:"\e1b0"}.fa-home-user::before{content:"\e1b0"}.fa-dumpster-fire::before{content:"\f794"}.fa-house-crack::before{content:"\e3b1"}.fa-martini-glass-citrus::before{content:"\f561"}.fa-cocktail::before{content:"\f561"}.fa-face-surprise::before{content:"\f5c2"}.fa-surprise::before{content:"\f5c2"}.fa-bottle-water::before{content:"\e4c5"}.fa-circle-pause::before{content:"\f28b"}.fa-pause-circle::before{content:"\f28b"}.fa-toilet-paper-slash::before{content:"\e072"}.fa-apple-whole::before{content:"\f5d1"}.fa-apple-alt::before{content:"\f5d1"}.fa-kitchen-set::before{content:"\e51a"}.fa-r::before{content:"\52"}.fa-temperature-quarter::before{content:"\f2ca"}.fa-temperature-1::before{content:"\f2ca"}.fa-thermometer-1::before{content:"\f2ca"}.fa-thermometer-quarter::before{content:"\f2ca"}.fa-cube::before{content:"\f1b2"}.fa-bitcoin-sign::before{content:"\e0b4"}.fa-shield-dog::before{content:"\e573"}.fa-solar-panel::before{content:"\f5ba"}.fa-lock-open::before{content:"\f3c1"}.fa-elevator::before{content:"\e16d"}.fa-money-bill-transfer::before{content:"\e528"}.fa-money-bill-trend-up::before{content:"\e529"}.fa-house-flood-water-circle-arrow-right::before{content:"\e50f"}.fa-square-poll-horizontal::before{content:"\f682"}.fa-poll-h::before{content:"\f682"}.fa-circle::before{content:"\f111"}.fa-backward-fast::before{content:"\f049"}.fa-fast-backward::before{content:"\f049"}.fa-recycle::before{content:"\f1b8"}.fa-user-astronaut::before{content:"\f4fb"}.fa-plane-slash::before{content:"\e069"}.fa-trademark::before{content:"\f25c"}.fa-basketball::before{content:"\f434"}.fa-basketball-ball::before{content:"\f434"}.fa-satellite-dish::before{content:"\f7c0"}.fa-circle-up::before{content:"\f35b"}.fa-arrow-alt-circle-up::before{content:"\f35b"}.fa-mobile-screen-button::before{content:"\f3cd"}.fa-mobile-alt::before{content:"\f3cd"}.fa-volume-high::before{content:"\f028"}.fa-volume-up::before{content:"\f028"}.fa-users-rays::before{content:"\e593"}.fa-wallet::before{content:"\f555"}.fa-clipboard-check::before{content:"\f46c"}.fa-file-audio::before{content:"\f1c7"}.fa-burger::before{content:"\f805"}.fa-hamburger::before{content:"\f805"}.fa-wrench::before{content:"\f0ad"}.fa-bugs::before{content:"\e4d0"}.fa-rupee-sign::before{content:"\f156"}.fa-rupee::before{content:"\f156"}.fa-file-image::before{content:"\f1c5"}.fa-circle-question::before{content:"\f059"}.fa-question-circle::before{content:"\f059"}.fa-plane-departure::before{content:"\f5b0"}.fa-handshake-slash::before{content:"\e060"}.fa-book-bookmark::before{content:"\e0bb"}.fa-code-branch::before{content:"\f126"}.fa-hat-cowboy::before{content:"\f8c0"}.fa-bridge::before{content:"\e4c8"}.fa-phone-flip::before{content:"\f879"}.fa-phone-alt::before{content:"\f879"}.fa-truck-front::before{content:"\e2b7"}.fa-cat::before{content:"\f6be"}.fa-anchor-circle-exclamation::before{content:"\e4ab"}.fa-truck-field::before{content:"\e58d"}.fa-route::before{content:"\f4d7"}.fa-clipboard-question::before{content:"\e4e3"}.fa-panorama::before{content:"\e209"}.fa-comment-medical::before{content:"\f7f5"}.fa-teeth-open::before{content:"\f62f"}.fa-file-circle-minus::before{content:"\e4ed"}.fa-tags::before{content:"\f02c"}.fa-wine-glass::before{content:"\f4e3"}.fa-forward-fast::before{content:"\f050"}.fa-fast-forward::before{content:"\f050"}.fa-face-meh-blank::before{content:"\f5a4"}.fa-meh-blank::before{content:"\f5a4"}.fa-square-parking::before{content:"\f540"}.fa-parking::before{content:"\f540"}.fa-house-signal::before{content:"\e012"}.fa-bars-progress::before{content:"\f828"}.fa-tasks-alt::before{content:"\f828"}.fa-faucet-drip::before{content:"\e006"}.fa-cart-flatbed::before{content:"\f474"}.fa-dolly-flatbed::before{content:"\f474"}.fa-ban-smoking::before{content:"\f54d"}.fa-smoking-ban::before{content:"\f54d"}.fa-terminal::before{content:"\f120"}.fa-mobile-button::before{content:"\f10b"}.fa-house-medical-flag::before{content:"\e514"}.fa-basket-shopping::before{content:"\f291"}.fa-shopping-basket::before{content:"\f291"}.fa-tape::before{content:"\f4db"}.fa-bus-simple::before{content:"\f55e"}.fa-bus-alt::before{content:"\f55e"}.fa-eye::before{content:"\f06e"}.fa-face-sad-cry::before{content:"\f5b3"}.fa-sad-cry::before{content:"\f5b3"}.fa-audio-description::before{content:"\f29e"}.fa-person-military-to-person::before{content:"\e54c"}.fa-file-shield::before{content:"\e4f0"}.fa-user-slash::before{content:"\f506"}.fa-pen::before{content:"\f304"}.fa-tower-observation::before{content:"\e586"}.fa-file-code::before{content:"\f1c9"}.fa-signal::before{content:"\f012"}.fa-signal-5::before{content:"\f012"}.fa-signal-perfect::before{content:"\f012"}.fa-bus::before{content:"\f207"}.fa-heart-circle-xmark::before{content:"\e501"}.fa-house-chimney::before{content:"\e3af"}.fa-home-lg::before{content:"\e3af"}.fa-window-maximize::before{content:"\f2d0"}.fa-face-frown::before{content:"\f119"}.fa-frown::before{content:"\f119"}.fa-prescription::before{content:"\f5b1"}.fa-shop::before{content:"\f54f"}.fa-store-alt::before{content:"\f54f"}.fa-floppy-disk::before{content:"\f0c7"}.fa-save::before{content:"\f0c7"}.fa-vihara::before{content:"\f6a7"}.fa-scale-unbalanced::before{content:"\f515"}.fa-balance-scale-left::before{content:"\f515"}.fa-sort-up::before{content:"\f0de"}.fa-sort-asc::before{content:"\f0de"}.fa-comment-dots::before{content:"\f4ad"}.fa-commenting::before{content:"\f4ad"}.fa-plant-wilt::before{content:"\e5aa"}.fa-diamond::before{content:"\f219"}.fa-face-grin-squint::before{content:"\f585"}.fa-grin-squint::before{content:"\f585"}.fa-hand-holding-dollar::before{content:"\f4c0"}.fa-hand-holding-usd::before{content:"\f4c0"}.fa-bacterium::before{content:"\e05a"}.fa-hand-pointer::before{content:"\f25a"}.fa-drum-steelpan::before{content:"\f56a"}.fa-hand-scissors::before{content:"\f257"}.fa-hands-praying::before{content:"\f684"}.fa-praying-hands::before{content:"\f684"}.fa-arrow-rotate-right::before{content:"\f01e"}.fa-arrow-right-rotate::before{content:"\f01e"}.fa-arrow-rotate-forward::before{content:"\f01e"}.fa-redo::before{content:"\f01e"}.fa-biohazard::before{content:"\f780"}.fa-location-crosshairs::before{content:"\f601"}.fa-location::before{content:"\f601"}.fa-mars-double::before{content:"\f227"}.fa-child-dress::before{content:"\e59c"}.fa-users-between-lines::before{content:"\e591"}.fa-lungs-virus::before{content:"\e067"}.fa-face-grin-tears::before{content:"\f588"}.fa-grin-tears::before{content:"\f588"}.fa-phone::before{content:"\f095"}.fa-calendar-xmark::before{content:"\f273"}.fa-calendar-times::before{content:"\f273"}.fa-child-reaching::before{content:"\e59d"}.fa-head-side-virus::before{content:"\e064"}.fa-user-gear::before{content:"\f4fe"}.fa-user-cog::before{content:"\f4fe"}.fa-arrow-up-1-9::before{content:"\f163"}.fa-sort-numeric-up::before{content:"\f163"}.fa-door-closed::before{content:"\f52a"}.fa-shield-virus::before{content:"\e06c"}.fa-dice-six::before{content:"\f526"}.fa-mosquito-net::before{content:"\e52c"}.fa-bridge-water::before{content:"\e4ce"}.fa-person-booth::before{content:"\f756"}.fa-text-width::before{content:"\f035"}.fa-hat-wizard::before{content:"\f6e8"}.fa-pen-fancy::before{content:"\f5ac"}.fa-person-digging::before{content:"\f85e"}.fa-digging::before{content:"\f85e"}.fa-trash::before{content:"\f1f8"}.fa-gauge-simple::before{content:"\f629"}.fa-gauge-simple-med::before{content:"\f629"}.fa-tachometer-average::before{content:"\f629"}.fa-book-medical::before{content:"\f7e6"}.fa-poo::before{content:"\f2fe"}.fa-quote-right::before{content:"\f10e"}.fa-quote-right-alt::before{content:"\f10e"}.fa-shirt::before{content:"\f553"}.fa-t-shirt::before{content:"\f553"}.fa-tshirt::before{content:"\f553"}.fa-cubes::before{content:"\f1b3"}.fa-divide::before{content:"\f529"}.fa-tenge-sign::before{content:"\f7d7"}.fa-tenge::before{content:"\f7d7"}.fa-headphones::before{content:"\f025"}.fa-hands-holding::before{content:"\f4c2"}.fa-hands-clapping::before{content:"\e1a8"}.fa-republican::before{content:"\f75e"}.fa-arrow-left::before{content:"\f060"}.fa-person-circle-xmark::before{content:"\e543"}.fa-ruler::before{content:"\f545"}.fa-align-left::before{content:"\f036"}.fa-dice-d6::before{content:"\f6d1"}.fa-restroom::before{content:"\f7bd"}.fa-j::before{content:"\4a"}.fa-users-viewfinder::before{content:"\e595"}.fa-file-video::before{content:"\f1c8"}.fa-up-right-from-square::before{content:"\f35d"}.fa-external-link-alt::before{content:"\f35d"}.fa-table-cells::before{content:"\f00a"}.fa-th::before{content:"\f00a"}.fa-file-pdf::before{content:"\f1c1"}.fa-book-bible::before{content:"\f647"}.fa-bible::before{content:"\f647"}.fa-o::before{content:"\4f"}.fa-suitcase-medical::before{content:"\f0fa"}.fa-medkit::before{content:"\f0fa"}.fa-user-secret::before{content:"\f21b"}.fa-otter::before{content:"\f700"}.fa-person-dress::before{content:"\f182"}.fa-female::before{content:"\f182"}.fa-comment-dollar::before{content:"\f651"}.fa-business-time::before{content:"\f64a"}.fa-briefcase-clock::before{content:"\f64a"}.fa-table-cells-large::before{content:"\f009"}.fa-th-large::before{content:"\f009"}.fa-book-tanakh::before{content:"\f827"}.fa-tanakh::before{content:"\f827"}.fa-phone-volume::before{content:"\f2a0"}.fa-volume-control-phone::before{content:"\f2a0"}.fa-hat-cowboy-side::before{content:"\f8c1"}.fa-clipboard-user::before{content:"\f7f3"}.fa-child::before{content:"\f1ae"}.fa-lira-sign::before{content:"\f195"}.fa-satellite::before{content:"\f7bf"}.fa-plane-lock::before{content:"\e558"}.fa-tag::before{content:"\f02b"}.fa-comment::before{content:"\f075"}.fa-cake-candles::before{content:"\f1fd"}.fa-birthday-cake::before{content:"\f1fd"}.fa-cake::before{content:"\f1fd"}.fa-envelope::before{content:"\f0e0"}.fa-angles-up::before{content:"\f102"}.fa-angle-double-up::before{content:"\f102"}.fa-paperclip::before{content:"\f0c6"}.fa-arrow-right-to-city::before{content:"\e4b3"}.fa-ribbon::before{content:"\f4d6"}.fa-lungs::before{content:"\f604"}.fa-arrow-up-9-1::before{content:"\f887"}.fa-sort-numeric-up-alt::before{content:"\f887"}.fa-litecoin-sign::before{content:"\e1d3"}.fa-border-none::before{content:"\f850"}.fa-circle-nodes::before{content:"\e4e2"}.fa-parachute-box::before{content:"\f4cd"}.fa-indent::before{content:"\f03c"}.fa-truck-field-un::before{content:"\e58e"}.fa-hourglass::before{content:"\f254"}.fa-hourglass-empty::before{content:"\f254"}.fa-mountain::before{content:"\f6fc"}.fa-user-doctor::before{content:"\f0f0"}.fa-user-md::before{content:"\f0f0"}.fa-circle-info::before{content:"\f05a"}.fa-info-circle::before{content:"\f05a"}.fa-cloud-meatball::before{content:"\f73b"}.fa-camera::before{content:"\f030"}.fa-camera-alt::before{content:"\f030"}.fa-square-virus::before{content:"\e578"}.fa-meteor::before{content:"\f753"}.fa-car-on::before{content:"\e4dd"}.fa-sleigh::before{content:"\f7cc"}.fa-arrow-down-1-9::before{content:"\f162"}.fa-sort-numeric-asc::before{content:"\f162"}.fa-sort-numeric-down::before{content:"\f162"}.fa-hand-holding-droplet::before{content:"\f4c1"}.fa-hand-holding-water::before{content:"\f4c1"}.fa-water::before{content:"\f773"}.fa-calendar-check::before{content:"\f274"}.fa-braille::before{content:"\f2a1"}.fa-prescription-bottle-medical::before{content:"\f486"}.fa-prescription-bottle-alt::before{content:"\f486"}.fa-landmark::before{content:"\f66f"}.fa-truck::before{content:"\f0d1"}.fa-crosshairs::before{content:"\f05b"}.fa-person-cane::before{content:"\e53c"}.fa-tent::before{content:"\e57d"}.fa-vest-patches::before{content:"\e086"}.fa-check-double::before{content:"\f560"}.fa-arrow-down-a-z::before{content:"\f15d"}.fa-sort-alpha-asc::before{content:"\f15d"}.fa-sort-alpha-down::before{content:"\f15d"}.fa-money-bill-wheat::before{content:"\e52a"}.fa-cookie::before{content:"\f563"}.fa-arrow-rotate-left::before{content:"\f0e2"}.fa-arrow-left-rotate::before{content:"\f0e2"}.fa-arrow-rotate-back::before{content:"\f0e2"}.fa-arrow-rotate-backward::before{content:"\f0e2"}.fa-undo::before{content:"\f0e2"}.fa-hard-drive::before{content:"\f0a0"}.fa-hdd::before{content:"\f0a0"}.fa-face-grin-squint-tears::before{content:"\f586"}.fa-grin-squint-tears::before{content:"\f586"}.fa-dumbbell::before{content:"\f44b"}.fa-rectangle-list::before{content:"\f022"}.fa-list-alt::before{content:"\f022"}.fa-tarp-droplet::before{content:"\e57c"}.fa-house-medical-circle-check::before{content:"\e511"}.fa-person-skiing-nordic::before{content:"\f7ca"}.fa-skiing-nordic::before{content:"\f7ca"}.fa-calendar-plus::before{content:"\f271"}.fa-plane-arrival::before{content:"\f5af"}.fa-circle-left::before{content:"\f359"}.fa-arrow-alt-circle-left::before{content:"\f359"}.fa-train-subway::before{content:"\f239"}.fa-subway::before{content:"\f239"}.fa-chart-gantt::before{content:"\e0e4"}.fa-indian-rupee-sign::before{content:"\e1bc"}.fa-indian-rupee::before{content:"\e1bc"}.fa-inr::before{content:"\e1bc"}.fa-crop-simple::before{content:"\f565"}.fa-crop-alt::before{content:"\f565"}.fa-money-bill-1::before{content:"\f3d1"}.fa-money-bill-alt::before{content:"\f3d1"}.fa-left-long::before{content:"\f30a"}.fa-long-arrow-alt-left::before{content:"\f30a"}.fa-dna::before{content:"\f471"}.fa-virus-slash::before{content:"\e075"}.fa-minus::before{content:"\f068"}.fa-subtract::before{content:"\f068"}.fa-chess::before{content:"\f439"}.fa-arrow-left-long::before{content:"\f177"}.fa-long-arrow-left::before{content:"\f177"}.fa-plug-circle-check::before{content:"\e55c"}.fa-street-view::before{content:"\f21d"}.fa-franc-sign::before{content:"\e18f"}.fa-volume-off::before{content:"\f026"}.fa-hands-asl-interpreting::before{content:"\f2a3"}.fa-american-sign-language-interpreting::before{content:"\f2a3"}.fa-asl-interpreting::before{content:"\f2a3"}.fa-hands-american-sign-language-interpreting::before{content:"\f2a3"}.fa-gear::before{content:"\f013"}.fa-cog::before{content:"\f013"}.fa-droplet-slash::before{content:"\f5c7"}.fa-tint-slash::before{content:"\f5c7"}.fa-mosque::before{content:"\f678"}.fa-mosquito::before{content:"\e52b"}.fa-star-of-david::before{content:"\f69a"}.fa-person-military-rifle::before{content:"\e54b"}.fa-cart-shopping::before{content:"\f07a"}.fa-shopping-cart::before{content:"\f07a"}.fa-vials::before{content:"\f493"}.fa-plug-circle-plus::before{content:"\e55f"}.fa-place-of-worship::before{content:"\f67f"}.fa-grip-vertical::before{content:"\f58e"}.fa-arrow-turn-up::before{content:"\f148"}.fa-level-up::before{content:"\f148"}.fa-u::before{content:"\55"}.fa-square-root-variable::before{content:"\f698"}.fa-square-root-alt::before{content:"\f698"}.fa-clock::before{content:"\f017"}.fa-clock-four::before{content:"\f017"}.fa-backward-step::before{content:"\f048"}.fa-step-backward::before{content:"\f048"}.fa-pallet::before{content:"\f482"}.fa-faucet::before{content:"\e005"}.fa-baseball-bat-ball::before{content:"\f432"}.fa-s::before{content:"\53"}.fa-timeline::before{content:"\e29c"}.fa-keyboard::before{content:"\f11c"}.fa-caret-down::before{content:"\f0d7"}.fa-house-chimney-medical::before{content:"\f7f2"}.fa-clinic-medical::before{content:"\f7f2"}.fa-temperature-three-quarters::before{content:"\f2c8"}.fa-temperature-3::before{content:"\f2c8"}.fa-thermometer-3::before{content:"\f2c8"}.fa-thermometer-three-quarters::before{content:"\f2c8"}.fa-mobile-screen::before{content:"\f3cf"}.fa-mobile-android-alt::before{content:"\f3cf"}.fa-plane-up::before{content:"\e22d"}.fa-piggy-bank::before{content:"\f4d3"}.fa-battery-half::before{content:"\f242"}.fa-battery-3::before{content:"\f242"}.fa-mountain-city::before{content:"\e52e"}.fa-coins::before{content:"\f51e"}.fa-khanda::before{content:"\f66d"}.fa-sliders::before{content:"\f1de"}.fa-sliders-h::before{content:"\f1de"}.fa-folder-tree::before{content:"\f802"}.fa-network-wired::before{content:"\f6ff"}.fa-map-pin::before{content:"\f276"}.fa-hamsa::before{content:"\f665"}.fa-cent-sign::before{content:"\e3f5"}.fa-flask::before{content:"\f0c3"}.fa-person-pregnant::before{content:"\e31e"}.fa-wand-sparkles::before{content:"\f72b"}.fa-ellipsis-vertical::before{content:"\f142"}.fa-ellipsis-v::before{content:"\f142"}.fa-ticket::before{content:"\f145"}.fa-power-off::before{content:"\f011"}.fa-right-long::before{content:"\f30b"}.fa-long-arrow-alt-right::before{content:"\f30b"}.fa-flag-usa::before{content:"\f74d"}.fa-laptop-file::before{content:"\e51d"}.fa-tty::before{content:"\f1e4"}.fa-teletype::before{content:"\f1e4"}.fa-diagram-next::before{content:"\e476"}.fa-person-rifle::before{content:"\e54e"}.fa-house-medical-circle-exclamation::before{content:"\e512"}.fa-closed-captioning::before{content:"\f20a"}.fa-person-hiking::before{content:"\f6ec"}.fa-hiking::before{content:"\f6ec"}.fa-venus-double::before{content:"\f226"}.fa-images::before{content:"\f302"}.fa-calculator::before{content:"\f1ec"}.fa-people-pulling::before{content:"\e535"}.fa-n::before{content:"\4e"}.fa-cable-car::before{content:"\f7da"}.fa-tram::before{content:"\f7da"}.fa-cloud-rain::before{content:"\f73d"}.fa-building-circle-xmark::before{content:"\e4d4"}.fa-ship::before{content:"\f21a"}.fa-arrows-down-to-line::before{content:"\e4b8"}.fa-download::before{content:"\f019"}.fa-face-grin::before{content:"\f580"}.fa-grin::before{content:"\f580"}.fa-delete-left::before{content:"\f55a"}.fa-backspace::before{content:"\f55a"}.fa-eye-dropper::before{content:"\f1fb"}.fa-eye-dropper-empty::before{content:"\f1fb"}.fa-eyedropper::before{content:"\f1fb"}.fa-file-circle-check::before{content:"\e5a0"}.fa-forward::before{content:"\f04e"}.fa-mobile::before{content:"\f3ce"}.fa-mobile-android::before{content:"\f3ce"}.fa-mobile-phone::before{content:"\f3ce"}.fa-face-meh::before{content:"\f11a"}.fa-meh::before{content:"\f11a"}.fa-align-center::before{content:"\f037"}.fa-book-skull::before{content:"\f6b7"}.fa-book-dead::before{content:"\f6b7"}.fa-id-card::before{content:"\f2c2"}.fa-drivers-license::before{content:"\f2c2"}.fa-outdent::before{content:"\f03b"}.fa-dedent::before{content:"\f03b"}.fa-heart-circle-exclamation::before{content:"\e4fe"}.fa-house::before{content:"\f015"}.fa-home::before{content:"\f015"}.fa-home-alt::before{content:"\f015"}.fa-home-lg-alt::before{content:"\f015"}.fa-calendar-week::before{content:"\f784"}.fa-laptop-medical::before{content:"\f812"}.fa-b::before{content:"\42"}.fa-file-medical::before{content:"\f477"}.fa-dice-one::before{content:"\f525"}.fa-kiwi-bird::before{content:"\f535"}.fa-arrow-right-arrow-left::before{content:"\f0ec"}.fa-exchange::before{content:"\f0ec"}.fa-rotate-right::before{content:"\f2f9"}.fa-redo-alt::before{content:"\f2f9"}.fa-rotate-forward::before{content:"\f2f9"}.fa-utensils::before{content:"\f2e7"}.fa-cutlery::before{content:"\f2e7"}.fa-arrow-up-wide-short::before{content:"\f161"}.fa-sort-amount-up::before{content:"\f161"}.fa-mill-sign::before{content:"\e1ed"}.fa-bowl-rice::before{content:"\e2eb"}.fa-skull::before{content:"\f54c"}.fa-tower-broadcast::before{content:"\f519"}.fa-broadcast-tower::before{content:"\f519"}.fa-truck-pickup::before{content:"\f63c"}.fa-up-long::before{content:"\f30c"}.fa-long-arrow-alt-up::before{content:"\f30c"}.fa-stop::before{content:"\f04d"}.fa-code-merge::before{content:"\f387"}.fa-upload::before{content:"\f093"}.fa-hurricane::before{content:"\f751"}.fa-mound::before{content:"\e52d"}.fa-toilet-portable::before{content:"\e583"}.fa-compact-disc::before{content:"\f51f"}.fa-file-arrow-down::before{content:"\f56d"}.fa-file-download::before{content:"\f56d"}.fa-caravan::before{content:"\f8ff"}.fa-shield-cat::before{content:"\e572"}.fa-bolt::before{content:"\f0e7"}.fa-zap::before{content:"\f0e7"}.fa-glass-water::before{content:"\e4f4"}.fa-oil-well::before{content:"\e532"}.fa-vault::before{content:"\e2c5"}.fa-mars::before{content:"\f222"}.fa-toilet::before{content:"\f7d8"}.fa-plane-circle-xmark::before{content:"\e557"}.fa-yen-sign::before{content:"\f157"}.fa-cny::before{content:"\f157"}.fa-jpy::before{content:"\f157"}.fa-rmb::before{content:"\f157"}.fa-yen::before{content:"\f157"}.fa-ruble-sign::before{content:"\f158"}.fa-rouble::before{content:"\f158"}.fa-rub::before{content:"\f158"}.fa-ruble::before{content:"\f158"}.fa-sun::before{content:"\f185"}.fa-guitar::before{content:"\f7a6"}.fa-face-laugh-wink::before{content:"\f59c"}.fa-laugh-wink::before{content:"\f59c"}.fa-horse-head::before{content:"\f7ab"}.fa-bore-hole::before{content:"\e4c3"}.fa-industry::before{content:"\f275"}.fa-circle-down::before{content:"\f358"}.fa-arrow-alt-circle-down::before{content:"\f358"}.fa-arrows-turn-to-dots::before{content:"\e4c1"}.fa-florin-sign::before{content:"\e184"}.fa-arrow-down-short-wide::before{content:"\f884"}.fa-sort-amount-desc::before{content:"\f884"}.fa-sort-amount-down-alt::before{content:"\f884"}.fa-less-than::before{content:"\3c"}.fa-angle-down::before{content:"\f107"}.fa-car-tunnel::before{content:"\e4de"}.fa-head-side-cough::before{content:"\e061"}.fa-grip-lines::before{content:"\f7a4"}.fa-thumbs-down::before{content:"\f165"}.fa-user-lock::before{content:"\f502"}.fa-arrow-right-long::before{content:"\f178"}.fa-long-arrow-right::before{content:"\f178"}.fa-anchor-circle-xmark::before{content:"\e4ac"}.fa-ellipsis::before{content:"\f141"}.fa-ellipsis-h::before{content:"\f141"}.fa-chess-pawn::before{content:"\f443"}.fa-kit-medical::before{content:"\f479"}.fa-first-aid::before{content:"\f479"}.fa-person-through-window::before{content:"\e5a9"}.fa-toolbox::before{content:"\f552"}.fa-hands-holding-circle::before{content:"\e4fb"}.fa-bug::before{content:"\f188"}.fa-credit-card::before{content:"\f09d"}.fa-credit-card-alt::before{content:"\f09d"}.fa-car::before{content:"\f1b9"}.fa-automobile::before{content:"\f1b9"}.fa-hand-holding-hand::before{content:"\e4f7"}.fa-book-open-reader::before{content:"\f5da"}.fa-book-reader::before{content:"\f5da"}.fa-mountain-sun::before{content:"\e52f"}.fa-arrows-left-right-to-line::before{content:"\e4ba"}.fa-dice-d20::before{content:"\f6cf"}.fa-truck-droplet::before{content:"\e58c"}.fa-file-circle-xmark::before{content:"\e5a1"}.fa-temperature-arrow-up::before{content:"\e040"}.fa-temperature-up::before{content:"\e040"}.fa-medal::before{content:"\f5a2"}.fa-bed::before{content:"\f236"}.fa-square-h::before{content:"\f0fd"}.fa-h-square::before{content:"\f0fd"}.fa-podcast::before{content:"\f2ce"}.fa-temperature-full::before{content:"\f2c7"}.fa-temperature-4::before{content:"\f2c7"}.fa-thermometer-4::before{content:"\f2c7"}.fa-thermometer-full::before{content:"\f2c7"}.fa-bell::before{content:"\f0f3"}.fa-superscript::before{content:"\f12b"}.fa-plug-circle-xmark::before{content:"\e560"}.fa-star-of-life::before{content:"\f621"}.fa-phone-slash::before{content:"\f3dd"}.fa-paint-roller::before{content:"\f5aa"}.fa-handshake-angle::before{content:"\f4c4"}.fa-hands-helping::before{content:"\f4c4"}.fa-location-dot::before{content:"\f3c5"}.fa-map-marker-alt::before{content:"\f3c5"}.fa-file::before{content:"\f15b"}.fa-greater-than::before{content:"\3e"}.fa-person-swimming::before{content:"\f5c4"}.fa-swimmer::before{content:"\f5c4"}.fa-arrow-down::before{content:"\f063"}.fa-droplet::before{content:"\f043"}.fa-tint::before{content:"\f043"}.fa-eraser::before{content:"\f12d"}.fa-earth-americas::before{content:"\f57d"}.fa-earth::before{content:"\f57d"}.fa-earth-america::before{content:"\f57d"}.fa-globe-americas::before{content:"\f57d"}.fa-person-burst::before{content:"\e53b"}.fa-dove::before{content:"\f4ba"}.fa-battery-empty::before{content:"\f244"}.fa-battery-0::before{content:"\f244"}.fa-socks::before{content:"\f696"}.fa-inbox::before{content:"\f01c"}.fa-section::before{content:"\e447"}.fa-gauge-high::before{content:"\f625"}.fa-tachometer-alt::before{content:"\f625"}.fa-tachometer-alt-fast::before{content:"\f625"}.fa-envelope-open-text::before{content:"\f658"}.fa-hospital::before{content:"\f0f8"}.fa-hospital-alt::before{content:"\f0f8"}.fa-hospital-wide::before{content:"\f0f8"}.fa-wine-bottle::before{content:"\f72f"}.fa-chess-rook::before{content:"\f447"}.fa-bars-staggered::before{content:"\f550"}.fa-reorder::before{content:"\f550"}.fa-stream::before{content:"\f550"}.fa-dharmachakra::before{content:"\f655"}.fa-hotdog::before{content:"\f80f"}.fa-person-walking-with-cane::before{content:"\f29d"}.fa-blind::before{content:"\f29d"}.fa-drum::before{content:"\f569"}.fa-ice-cream::before{content:"\f810"}.fa-heart-circle-bolt::before{content:"\e4fc"}.fa-fax::before{content:"\f1ac"}.fa-paragraph::before{content:"\f1dd"}.fa-check-to-slot::before{content:"\f772"}.fa-vote-yea::before{content:"\f772"}.fa-star-half::before{content:"\f089"}.fa-boxes-stacked::before{content:"\f468"}.fa-boxes::before{content:"\f468"}.fa-boxes-alt::before{content:"\f468"}.fa-link::before{content:"\f0c1"}.fa-chain::before{content:"\f0c1"}.fa-ear-listen::before{content:"\f2a2"}.fa-assistive-listening-systems::before{content:"\f2a2"}.fa-tree-city::before{content:"\e587"}.fa-play::before{content:"\f04b"}.fa-font::before{content:"\f031"}.fa-table-cells-row-lock::before{content:"\e67a"}.fa-rupiah-sign::before{content:"\e23d"}.fa-magnifying-glass::before{content:"\f002"}.fa-search::before{content:"\f002"}.fa-table-tennis-paddle-ball::before{content:"\f45d"}.fa-ping-pong-paddle-ball::before{content:"\f45d"}.fa-table-tennis::before{content:"\f45d"}.fa-person-dots-from-line::before{content:"\f470"}.fa-diagnoses::before{content:"\f470"}.fa-trash-can-arrow-up::before{content:"\f82a"}.fa-trash-restore-alt::before{content:"\f82a"}.fa-naira-sign::before{content:"\e1f6"}.fa-cart-arrow-down::before{content:"\f218"}.fa-walkie-talkie::before{content:"\f8ef"}.fa-file-pen::before{content:"\f31c"}.fa-file-edit::before{content:"\f31c"}.fa-receipt::before{content:"\f543"}.fa-square-pen::before{content:"\f14b"}.fa-pen-square::before{content:"\f14b"}.fa-pencil-square::before{content:"\f14b"}.fa-suitcase-rolling::before{content:"\f5c1"}.fa-person-circle-exclamation::before{content:"\e53f"}.fa-chevron-down::before{content:"\f078"}.fa-battery-full::before{content:"\f240"}.fa-battery::before{content:"\f240"}.fa-battery-5::before{content:"\f240"}.fa-skull-crossbones::before{content:"\f714"}.fa-code-compare::before{content:"\e13a"}.fa-list-ul::before{content:"\f0ca"}.fa-list-dots::before{content:"\f0ca"}.fa-school-lock::before{content:"\e56f"}.fa-tower-cell::before{content:"\e585"}.fa-down-long::before{content:"\f309"}.fa-long-arrow-alt-down::before{content:"\f309"}.fa-ranking-star::before{content:"\e561"}.fa-chess-king::before{content:"\f43f"}.fa-person-harassing::before{content:"\e549"}.fa-brazilian-real-sign::before{content:"\e46c"}.fa-landmark-dome::before{content:"\f752"}.fa-landmark-alt::before{content:"\f752"}.fa-arrow-up::before{content:"\f062"}.fa-tv::before{content:"\f26c"}.fa-television::before{content:"\f26c"}.fa-tv-alt::before{content:"\f26c"}.fa-shrimp::before{content:"\e448"}.fa-list-check::before{content:"\f0ae"}.fa-tasks::before{content:"\f0ae"}.fa-jug-detergent::before{content:"\e519"}.fa-circle-user::before{content:"\f2bd"}.fa-user-circle::before{content:"\f2bd"}.fa-user-shield::before{content:"\f505"}.fa-wind::before{content:"\f72e"}.fa-car-burst::before{content:"\f5e1"}.fa-car-crash::before{content:"\f5e1"}.fa-y::before{content:"\59"}.fa-person-snowboarding::before{content:"\f7ce"}.fa-snowboarding::before{content:"\f7ce"}.fa-truck-fast::before{content:"\f48b"}.fa-shipping-fast::before{content:"\f48b"}.fa-fish::before{content:"\f578"}.fa-user-graduate::before{content:"\f501"}.fa-circle-half-stroke::before{content:"\f042"}.fa-adjust::before{content:"\f042"}.fa-clapperboard::before{content:"\e131"}.fa-circle-radiation::before{content:"\f7ba"}.fa-radiation-alt::before{content:"\f7ba"}.fa-baseball::before{content:"\f433"}.fa-baseball-ball::before{content:"\f433"}.fa-jet-fighter-up::before{content:"\e518"}.fa-diagram-project::before{content:"\f542"}.fa-project-diagram::before{content:"\f542"}.fa-copy::before{content:"\f0c5"}.fa-volume-xmark::before{content:"\f6a9"}.fa-volume-mute::before{content:"\f6a9"}.fa-volume-times::before{content:"\f6a9"}.fa-hand-sparkles::before{content:"\e05d"}.fa-grip::before{content:"\f58d"}.fa-grip-horizontal::before{content:"\f58d"}.fa-share-from-square::before{content:"\f14d"}.fa-share-square::before{content:"\f14d"}.fa-child-combatant::before{content:"\e4e0"}.fa-child-rifle::before{content:"\e4e0"}.fa-gun::before{content:"\e19b"}.fa-square-phone::before{content:"\f098"}.fa-phone-square::before{content:"\f098"}.fa-plus::before{content:"\2b"}.fa-add::before{content:"\2b"}.fa-expand::before{content:"\f065"}.fa-computer::before{content:"\e4e5"}.fa-xmark::before{content:"\f00d"}.fa-close::before{content:"\f00d"}.fa-multiply::before{content:"\f00d"}.fa-remove::before{content:"\f00d"}.fa-times::before{content:"\f00d"}.fa-arrows-up-down-left-right::before{content:"\f047"}.fa-arrows::before{content:"\f047"}.fa-chalkboard-user::before{content:"\f51c"}.fa-chalkboard-teacher::before{content:"\f51c"}.fa-peso-sign::before{content:"\e222"}.fa-building-shield::before{content:"\e4d8"}.fa-baby::before{content:"\f77c"}.fa-users-line::before{content:"\e592"}.fa-quote-left::before{content:"\f10d"}.fa-quote-left-alt::before{content:"\f10d"}.fa-tractor::before{content:"\f722"}.fa-trash-arrow-up::before{content:"\f829"}.fa-trash-restore::before{content:"\f829"}.fa-arrow-down-up-lock::before{content:"\e4b0"}.fa-lines-leaning::before{content:"\e51e"}.fa-ruler-combined::before{content:"\f546"}.fa-copyright::before{content:"\f1f9"}.fa-equals::before{content:"\3d"}.fa-blender::before{content:"\f517"}.fa-teeth::before{content:"\f62e"}.fa-shekel-sign::before{content:"\f20b"}.fa-ils::before{content:"\f20b"}.fa-shekel::before{content:"\f20b"}.fa-sheqel::before{content:"\f20b"}.fa-sheqel-sign::before{content:"\f20b"}.fa-map::before{content:"\f279"}.fa-rocket::before{content:"\f135"}.fa-photo-film::before{content:"\f87c"}.fa-photo-video::before{content:"\f87c"}.fa-folder-minus::before{content:"\f65d"}.fa-store::before{content:"\f54e"}.fa-arrow-trend-up::before{content:"\e098"}.fa-plug-circle-minus::before{content:"\e55e"}.fa-sign-hanging::before{content:"\f4d9"}.fa-sign::before{content:"\f4d9"}.fa-bezier-curve::before{content:"\f55b"}.fa-bell-slash::before{content:"\f1f6"}.fa-tablet::before{content:"\f3fb"}.fa-tablet-android::before{content:"\f3fb"}.fa-school-flag::before{content:"\e56e"}.fa-fill::before{content:"\f575"}.fa-angle-up::before{content:"\f106"}.fa-drumstick-bite::before{content:"\f6d7"}.fa-holly-berry::before{content:"\f7aa"}.fa-chevron-left::before{content:"\f053"}.fa-bacteria::before{content:"\e059"}.fa-hand-lizard::before{content:"\f258"}.fa-notdef::before{content:"\e1fe"}.fa-disease::before{content:"\f7fa"}.fa-briefcase-medical::before{content:"\f469"}.fa-genderless::before{content:"\f22d"}.fa-chevron-right::before{content:"\f054"}.fa-retweet::before{content:"\f079"}.fa-car-rear::before{content:"\f5de"}.fa-car-alt::before{content:"\f5de"}.fa-pump-soap::before{content:"\e06b"}.fa-video-slash::before{content:"\f4e2"}.fa-battery-quarter::before{content:"\f243"}.fa-battery-2::before{content:"\f243"}.fa-radio::before{content:"\f8d7"}.fa-baby-carriage::before{content:"\f77d"}.fa-carriage-baby::before{content:"\f77d"}.fa-traffic-light::before{content:"\f637"}.fa-thermometer::before{content:"\f491"}.fa-vr-cardboard::before{content:"\f729"}.fa-hand-middle-finger::before{content:"\f806"}.fa-percent::before{content:"\25"}.fa-percentage::before{content:"\25"}.fa-truck-moving::before{content:"\f4df"}.fa-glass-water-droplet::before{content:"\e4f5"}.fa-display::before{content:"\e163"}.fa-face-smile::before{content:"\f118"}.fa-smile::before{content:"\f118"}.fa-thumbtack::before{content:"\f08d"}.fa-thumb-tack::before{content:"\f08d"}.fa-trophy::before{content:"\f091"}.fa-person-praying::before{content:"\f683"}.fa-pray::before{content:"\f683"}.fa-hammer::before{content:"\f6e3"}.fa-hand-peace::before{content:"\f25b"}.fa-rotate::before{content:"\f2f1"}.fa-sync-alt::before{content:"\f2f1"}.fa-spinner::before{content:"\f110"}.fa-robot::before{content:"\f544"}.fa-peace::before{content:"\f67c"}.fa-gears::before{content:"\f085"}.fa-cogs::before{content:"\f085"}.fa-warehouse::before{content:"\f494"}.fa-arrow-up-right-dots::before{content:"\e4b7"}.fa-splotch::before{content:"\f5bc"}.fa-face-grin-hearts::before{content:"\f584"}.fa-grin-hearts::before{content:"\f584"}.fa-dice-four::before{content:"\f524"}.fa-sim-card::before{content:"\f7c4"}.fa-transgender::before{content:"\f225"}.fa-transgender-alt::before{content:"\f225"}.fa-mercury::before{content:"\f223"}.fa-arrow-turn-down::before{content:"\f149"}.fa-level-down::before{content:"\f149"}.fa-person-falling-burst::before{content:"\e547"}.fa-award::before{content:"\f559"}.fa-ticket-simple::before{content:"\f3ff"}.fa-ticket-alt::before{content:"\f3ff"}.fa-building::before{content:"\f1ad"}.fa-angles-left::before{content:"\f100"}.fa-angle-double-left::before{content:"\f100"}.fa-qrcode::before{content:"\f029"}.fa-clock-rotate-left::before{content:"\f1da"}.fa-history::before{content:"\f1da"}.fa-face-grin-beam-sweat::before{content:"\f583"}.fa-grin-beam-sweat::before{content:"\f583"}.fa-file-export::before{content:"\f56e"}.fa-arrow-right-from-file::before{content:"\f56e"}.fa-shield::before{content:"\f132"}.fa-shield-blank::before{content:"\f132"}.fa-arrow-up-short-wide::before{content:"\f885"}.fa-sort-amount-up-alt::before{content:"\f885"}.fa-house-medical::before{content:"\e3b2"}.fa-golf-ball-tee::before{content:"\f450"}.fa-golf-ball::before{content:"\f450"}.fa-circle-chevron-left::before{content:"\f137"}.fa-chevron-circle-left::before{content:"\f137"}.fa-house-chimney-window::before{content:"\e00d"}.fa-pen-nib::before{content:"\f5ad"}.fa-tent-arrow-turn-left::before{content:"\e580"}.fa-tents::before{content:"\e582"}.fa-wand-magic::before{content:"\f0d0"}.fa-magic::before{content:"\f0d0"}.fa-dog::before{content:"\f6d3"}.fa-carrot::before{content:"\f787"}.fa-moon::before{content:"\f186"}.fa-wine-glass-empty::before{content:"\f5ce"}.fa-wine-glass-alt::before{content:"\f5ce"}.fa-cheese::before{content:"\f7ef"}.fa-yin-yang::before{content:"\f6ad"}.fa-music::before{content:"\f001"}.fa-code-commit::before{content:"\f386"}.fa-temperature-low::before{content:"\f76b"}.fa-person-biking::before{content:"\f84a"}.fa-biking::before{content:"\f84a"}.fa-broom::before{content:"\f51a"}.fa-shield-heart::before{content:"\e574"}.fa-gopuram::before{content:"\f664"}.fa-earth-oceania::before{content:"\e47b"}.fa-globe-oceania::before{content:"\e47b"}.fa-square-xmark::before{content:"\f2d3"}.fa-times-square::before{content:"\f2d3"}.fa-xmark-square::before{content:"\f2d3"}.fa-hashtag::before{content:"\23"}.fa-up-right-and-down-left-from-center::before{content:"\f424"}.fa-expand-alt::before{content:"\f424"}.fa-oil-can::before{content:"\f613"}.fa-t::before{content:"\54"}.fa-hippo::before{content:"\f6ed"}.fa-chart-column::before{content:"\e0e3"}.fa-infinity::before{content:"\f534"}.fa-vial-circle-check::before{content:"\e596"}.fa-person-arrow-down-to-line::before{content:"\e538"}.fa-voicemail::before{content:"\f897"}.fa-fan::before{content:"\f863"}.fa-person-walking-luggage::before{content:"\e554"}.fa-up-down::before{content:"\f338"}.fa-arrows-alt-v::before{content:"\f338"}.fa-cloud-moon-rain::before{content:"\f73c"}.fa-calendar::before{content:"\f133"}.fa-trailer::before{content:"\e041"}.fa-bahai::before{content:"\f666"}.fa-haykal::before{content:"\f666"}.fa-sd-card::before{content:"\f7c2"}.fa-dragon::before{content:"\f6d5"}.fa-shoe-prints::before{content:"\f54b"}.fa-circle-plus::before{content:"\f055"}.fa-plus-circle::before{content:"\f055"}.fa-face-grin-tongue-wink::before{content:"\f58b"}.fa-grin-tongue-wink::before{content:"\f58b"}.fa-hand-holding::before{content:"\f4bd"}.fa-plug-circle-exclamation::before{content:"\e55d"}.fa-link-slash::before{content:"\f127"}.fa-chain-broken::before{content:"\f127"}.fa-chain-slash::before{content:"\f127"}.fa-unlink::before{content:"\f127"}.fa-clone::before{content:"\f24d"}.fa-person-walking-arrow-loop-left::before{content:"\e551"}.fa-arrow-up-z-a::before{content:"\f882"}.fa-sort-alpha-up-alt::before{content:"\f882"}.fa-fire-flame-curved::before{content:"\f7e4"}.fa-fire-alt::before{content:"\f7e4"}.fa-tornado::before{content:"\f76f"}.fa-file-circle-plus::before{content:"\e494"}.fa-book-quran::before{content:"\f687"}.fa-quran::before{content:"\f687"}.fa-anchor::before{content:"\f13d"}.fa-border-all::before{content:"\f84c"}.fa-face-angry::before{content:"\f556"}.fa-angry::before{content:"\f556"}.fa-cookie-bite::before{content:"\f564"}.fa-arrow-trend-down::before{content:"\e097"}.fa-rss::before{content:"\f09e"}.fa-feed::before{content:"\f09e"}.fa-draw-polygon::before{content:"\f5ee"}.fa-scale-balanced::before{content:"\f24e"}.fa-balance-scale::before{content:"\f24e"}.fa-gauge-simple-high::before{content:"\f62a"}.fa-tachometer::before{content:"\f62a"}.fa-tachometer-fast::before{content:"\f62a"}.fa-shower::before{content:"\f2cc"}.fa-desktop::before{content:"\f390"}.fa-desktop-alt::before{content:"\f390"}.fa-m::before{content:"\4d"}.fa-table-list::before{content:"\f00b"}.fa-th-list::before{content:"\f00b"}.fa-comment-sms::before{content:"\f7cd"}.fa-sms::before{content:"\f7cd"}.fa-book::before{content:"\f02d"}.fa-user-plus::before{content:"\f234"}.fa-check::before{content:"\f00c"}.fa-battery-three-quarters::before{content:"\f241"}.fa-battery-4::before{content:"\f241"}.fa-house-circle-check::before{content:"\e509"}.fa-angle-left::before{content:"\f104"}.fa-diagram-successor::before{content:"\e47a"}.fa-truck-arrow-right::before{content:"\e58b"}.fa-arrows-split-up-and-left::before{content:"\e4bc"}.fa-hand-fist::before{content:"\f6de"}.fa-fist-raised::before{content:"\f6de"}.fa-cloud-moon::before{content:"\f6c3"}.fa-briefcase::before{content:"\f0b1"}.fa-person-falling::before{content:"\e546"}.fa-image-portrait::before{content:"\f3e0"}.fa-portrait::before{content:"\f3e0"}.fa-user-tag::before{content:"\f507"}.fa-rug::before{content:"\e569"}.fa-earth-europe::before{content:"\f7a2"}.fa-globe-europe::before{content:"\f7a2"}.fa-cart-flatbed-suitcase::before{content:"\f59d"}.fa-luggage-cart::before{content:"\f59d"}.fa-rectangle-xmark::before{content:"\f410"}.fa-rectangle-times::before{content:"\f410"}.fa-times-rectangle::before{content:"\f410"}.fa-window-close::before{content:"\f410"}.fa-baht-sign::before{content:"\e0ac"}.fa-book-open::before{content:"\f518"}.fa-book-journal-whills::before{content:"\f66a"}.fa-journal-whills::before{content:"\f66a"}.fa-handcuffs::before{content:"\e4f8"}.fa-triangle-exclamation::before{content:"\f071"}.fa-exclamation-triangle::before{content:"\f071"}.fa-warning::before{content:"\f071"}.fa-database::before{content:"\f1c0"}.fa-share::before{content:"\f064"}.fa-mail-forward::before{content:"\f064"}.fa-bottle-droplet::before{content:"\e4c4"}.fa-mask-face::before{content:"\e1d7"}.fa-hill-rockslide::before{content:"\e508"}.fa-right-left::before{content:"\f362"}.fa-exchange-alt::before{content:"\f362"}.fa-paper-plane::before{content:"\f1d8"}.fa-road-circle-exclamation::before{content:"\e565"}.fa-dungeon::before{content:"\f6d9"}.fa-align-right::before{content:"\f038"}.fa-money-bill-1-wave::before{content:"\f53b"}.fa-money-bill-wave-alt::before{content:"\f53b"}.fa-life-ring::before{content:"\f1cd"}.fa-hands::before{content:"\f2a7"}.fa-sign-language::before{content:"\f2a7"}.fa-signing::before{content:"\f2a7"}.fa-calendar-day::before{content:"\f783"}.fa-water-ladder::before{content:"\f5c5"}.fa-ladder-water::before{content:"\f5c5"}.fa-swimming-pool::before{content:"\f5c5"}.fa-arrows-up-down::before{content:"\f07d"}.fa-arrows-v::before{content:"\f07d"}.fa-face-grimace::before{content:"\f57f"}.fa-grimace::before{content:"\f57f"}.fa-wheelchair-move::before{content:"\e2ce"}.fa-wheelchair-alt::before{content:"\e2ce"}.fa-turn-down::before{content:"\f3be"}.fa-level-down-alt::before{content:"\f3be"}.fa-person-walking-arrow-right::before{content:"\e552"}.fa-square-envelope::before{content:"\f199"}.fa-envelope-square::before{content:"\f199"}.fa-dice::before{content:"\f522"}.fa-bowling-ball::before{content:"\f436"}.fa-brain::before{content:"\f5dc"}.fa-bandage::before{content:"\f462"}.fa-band-aid::before{content:"\f462"}.fa-calendar-minus::before{content:"\f272"}.fa-circle-xmark::before{content:"\f057"}.fa-times-circle::before{content:"\f057"}.fa-xmark-circle::before{content:"\f057"}.fa-gifts::before{content:"\f79c"}.fa-hotel::before{content:"\f594"}.fa-earth-asia::before{content:"\f57e"}.fa-globe-asia::before{content:"\f57e"}.fa-id-card-clip::before{content:"\f47f"}.fa-id-card-alt::before{content:"\f47f"}.fa-magnifying-glass-plus::before{content:"\f00e"}.fa-search-plus::before{content:"\f00e"}.fa-thumbs-up::before{content:"\f164"}.fa-user-clock::before{content:"\f4fd"}.fa-hand-dots::before{content:"\f461"}.fa-allergies::before{content:"\f461"}.fa-file-invoice::before{content:"\f570"}.fa-window-minimize::before{content:"\f2d1"}.fa-mug-saucer::before{content:"\f0f4"}.fa-coffee::before{content:"\f0f4"}.fa-brush::before{content:"\f55d"}.fa-mask::before{content:"\f6fa"}.fa-magnifying-glass-minus::before{content:"\f010"}.fa-search-minus::before{content:"\f010"}.fa-ruler-vertical::before{content:"\f548"}.fa-user-large::before{content:"\f406"}.fa-user-alt::before{content:"\f406"}.fa-train-tram::before{content:"\e5b4"}.fa-user-nurse::before{content:"\f82f"}.fa-syringe::before{content:"\f48e"}.fa-cloud-sun::before{content:"\f6c4"}.fa-stopwatch-20::before{content:"\e06f"}.fa-square-full::before{content:"\f45c"}.fa-magnet::before{content:"\f076"}.fa-jar::before{content:"\e516"}.fa-note-sticky::before{content:"\f249"}.fa-sticky-note::before{content:"\f249"}.fa-bug-slash::before{content:"\e490"}.fa-arrow-up-from-water-pump::before{content:"\e4b6"}.fa-bone::before{content:"\f5d7"}.fa-table-cells-row-unlock::before{content:"\e691"}.fa-user-injured::before{content:"\f728"}.fa-face-sad-tear::before{content:"\f5b4"}.fa-sad-tear::before{content:"\f5b4"}.fa-plane::before{content:"\f072"}.fa-tent-arrows-down::before{content:"\e581"}.fa-exclamation::before{content:"\21"}.fa-arrows-spin::before{content:"\e4bb"}.fa-print::before{content:"\f02f"}.fa-turkish-lira-sign::before{content:"\e2bb"}.fa-try::before{content:"\e2bb"}.fa-turkish-lira::before{content:"\e2bb"}.fa-dollar-sign::before{content:"\24"}.fa-dollar::before{content:"\24"}.fa-usd::before{content:"\24"}.fa-x::before{content:"\58"}.fa-magnifying-glass-dollar::before{content:"\f688"}.fa-search-dollar::before{content:"\f688"}.fa-users-gear::before{content:"\f509"}.fa-users-cog::before{content:"\f509"}.fa-person-military-pointing::before{content:"\e54a"}.fa-building-columns::before{content:"\f19c"}.fa-bank::before{content:"\f19c"}.fa-institution::before{content:"\f19c"}.fa-museum::before{content:"\f19c"}.fa-university::before{content:"\f19c"}.fa-umbrella::before{content:"\f0e9"}.fa-trowel::before{content:"\e589"}.fa-d::before{content:"\44"}.fa-stapler::before{content:"\e5af"}.fa-masks-theater::before{content:"\f630"}.fa-theater-masks::before{content:"\f630"}.fa-kip-sign::before{content:"\e1c4"}.fa-hand-point-left::before{content:"\f0a5"}.fa-handshake-simple::before{content:"\f4c6"}.fa-handshake-alt::before{content:"\f4c6"}.fa-jet-fighter::before{content:"\f0fb"}.fa-fighter-jet::before{content:"\f0fb"}.fa-square-share-nodes::before{content:"\f1e1"}.fa-share-alt-square::before{content:"\f1e1"}.fa-barcode::before{content:"\f02a"}.fa-plus-minus::before{content:"\e43c"}.fa-video::before{content:"\f03d"}.fa-video-camera::before{content:"\f03d"}.fa-graduation-cap::before{content:"\f19d"}.fa-mortar-board::before{content:"\f19d"}.fa-hand-holding-medical::before{content:"\e05c"}.fa-person-circle-check::before{content:"\e53e"}.fa-turn-up::before{content:"\f3bf"}.fa-level-up-alt::before{content:"\f3bf"}.sr-only,.fa-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.sr-only-focusable:not(:focus),.fa-sr-only-focusable:not(:focus){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}/*!* Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com +* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) +* Copyright 2024 Fonticons, Inc.*/:root,:host{--fa-style-family-classic:'Font Awesome 6 Free';--fa-font-solid:normal 900 1em/1 'Font Awesome 6 Free'}@font-face{font-family:'font awesome 6 free';font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2)format("woff2"),url(../webfonts/fa-solid-900.ttf)format("truetype")}.fas,.td-offline-search-results__close-button:after,.fa-solid{font-weight:900}/*!* Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com +* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) +* Copyright 2024 Fonticons, Inc.*/:root,:host{--fa-style-family-brands:'Font Awesome 6 Brands';--fa-font-brands:normal 400 1em/1 'Font Awesome 6 Brands'}@font-face{font-family:'font awesome 6 brands';font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.woff2)format("woff2"),url(../webfonts/fa-brands-400.ttf)format("truetype")}.fab,.fa-brands{font-weight:400}.fa-monero:before{content:"\f3d0"}.fa-hooli:before{content:"\f427"}.fa-yelp:before{content:"\f1e9"}.fa-cc-visa:before{content:"\f1f0"}.fa-lastfm:before{content:"\f202"}.fa-shopware:before{content:"\f5b5"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-aws:before{content:"\f375"}.fa-redhat:before{content:"\f7bc"}.fa-yoast:before{content:"\f2b1"}.fa-cloudflare:before{content:"\e07d"}.fa-ups:before{content:"\f7e0"}.fa-pixiv:before{content:"\e640"}.fa-wpexplorer:before{content:"\f2de"}.fa-dyalog:before{content:"\f399"}.fa-bity:before{content:"\f37a"}.fa-stackpath:before{content:"\f842"}.fa-buysellads:before{content:"\f20d"}.fa-first-order:before{content:"\f2b0"}.fa-modx:before{content:"\f285"}.fa-guilded:before{content:"\e07e"}.fa-vnv:before{content:"\f40b"}.fa-square-js:before{content:"\f3b9"}.fa-js-square:before{content:"\f3b9"}.fa-microsoft:before{content:"\f3ca"}.fa-qq:before{content:"\f1d6"}.fa-orcid:before{content:"\f8d2"}.fa-java:before{content:"\f4e4"}.fa-invision:before{content:"\f7b0"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-centercode:before{content:"\f380"}.fa-glide-g:before{content:"\f2a6"}.fa-drupal:before{content:"\f1a9"}.fa-jxl:before{content:"\e67b"}.fa-dart-lang:before{content:"\e693"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-unity:before{content:"\e049"}.fa-whmcs:before{content:"\f40d"}.fa-rocketchat:before{content:"\f3e8"}.fa-vk:before{content:"\f189"}.fa-untappd:before{content:"\f405"}.fa-mailchimp:before{content:"\f59e"}.fa-css3-alt:before{content:"\f38b"}.fa-square-reddit:before{content:"\f1a2"}.fa-reddit-square:before{content:"\f1a2"}.fa-vimeo-v:before{content:"\f27d"}.fa-contao:before{content:"\f26d"}.fa-square-font-awesome:before{content:"\e5ad"}.fa-deskpro:before{content:"\f38f"}.fa-brave:before{content:"\e63c"}.fa-sistrix:before{content:"\f3ee"}.fa-square-instagram:before{content:"\e055"}.fa-instagram-square:before{content:"\e055"}.fa-battle-net:before{content:"\f835"}.fa-the-red-yeti:before{content:"\f69d"}.fa-square-hacker-news:before{content:"\f3af"}.fa-hacker-news-square:before{content:"\f3af"}.fa-edge:before{content:"\f282"}.fa-threads:before{content:"\e618"}.fa-napster:before{content:"\f3d2"}.fa-square-snapchat:before{content:"\f2ad"}.fa-snapchat-square:before{content:"\f2ad"}.fa-google-plus-g:before{content:"\f0d5"}.fa-artstation:before{content:"\f77a"}.fa-markdown:before{content:"\f60f"}.fa-sourcetree:before{content:"\f7d3"}.fa-google-plus:before{content:"\f2b3"}.fa-diaspora:before{content:"\f791"}.fa-foursquare:before{content:"\f180"}.fa-stack-overflow:before{content:"\f16c"}.fa-github-alt:before{content:"\f113"}.fa-phoenix-squadron:before{content:"\f511"}.fa-pagelines:before{content:"\f18c"}.fa-algolia:before{content:"\f36c"}.fa-red-river:before{content:"\f3e3"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-safari:before{content:"\f267"}.fa-google:before{content:"\f1a0"}.fa-square-font-awesome-stroke:before{content:"\f35c"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-atlassian:before{content:"\f77b"}.fa-linkedin-in:before{content:"\f0e1"}.fa-digital-ocean:before{content:"\f391"}.fa-nimblr:before{content:"\f5a8"}.fa-chromecast:before{content:"\f838"}.fa-evernote:before{content:"\f839"}.fa-hacker-news:before{content:"\f1d4"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-adversal:before{content:"\f36a"}.fa-creative-commons:before{content:"\f25e"}.fa-watchman-monitoring:before{content:"\e087"}.fa-fonticons:before{content:"\f280"}.fa-weixin:before{content:"\f1d7"}.fa-shirtsinbulk:before{content:"\f214"}.fa-codepen:before{content:"\f1cb"}.fa-git-alt:before{content:"\f841"}.fa-lyft:before{content:"\f3c3"}.fa-rev:before{content:"\f5b2"}.fa-windows:before{content:"\f17a"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-square-viadeo:before{content:"\f2aa"}.fa-viadeo-square:before{content:"\f2aa"}.fa-meetup:before{content:"\f2e0"}.fa-centos:before{content:"\f789"}.fa-adn:before{content:"\f170"}.fa-cloudsmith:before{content:"\f384"}.fa-opensuse:before{content:"\e62b"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-square-dribbble:before{content:"\f397"}.fa-dribbble-square:before{content:"\f397"}.fa-codiepie:before{content:"\f284"}.fa-node:before{content:"\f419"}.fa-mix:before{content:"\f3cb"}.fa-steam:before{content:"\f1b6"}.fa-cc-apple-pay:before{content:"\f416"}.fa-scribd:before{content:"\f28a"}.fa-debian:before{content:"\e60b"}.fa-openid:before{content:"\f19b"}.fa-instalod:before{content:"\e081"}.fa-expeditedssl:before{content:"\f23e"}.fa-sellcast:before{content:"\f2da"}.fa-square-twitter:before{content:"\f081"}.fa-twitter-square:before{content:"\f081"}.fa-r-project:before{content:"\f4f7"}.fa-delicious:before{content:"\f1a5"}.fa-freebsd:before{content:"\f3a4"}.fa-vuejs:before{content:"\f41f"}.fa-accusoft:before{content:"\f369"}.fa-ioxhost:before{content:"\f208"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-app-store:before{content:"\f36f"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-itunes-note:before{content:"\f3b5"}.fa-golang:before{content:"\e40f"}.fa-kickstarter:before{content:"\f3bb"}.fa-square-kickstarter:before{content:"\f3bb"}.fa-grav:before{content:"\f2d6"}.fa-weibo:before{content:"\f18a"}.fa-uncharted:before{content:"\e084"}.fa-firstdraft:before{content:"\f3a1"}.fa-square-youtube:before{content:"\f431"}.fa-youtube-square:before{content:"\f431"}.fa-wikipedia-w:before{content:"\f266"}.fa-wpressr:before{content:"\f3e4"}.fa-rendact:before{content:"\f3e4"}.fa-angellist:before{content:"\f209"}.fa-galactic-republic:before{content:"\f50c"}.fa-nfc-directional:before{content:"\e530"}.fa-skype:before{content:"\f17e"}.fa-joget:before{content:"\f3b7"}.fa-fedora:before{content:"\f798"}.fa-stripe-s:before{content:"\f42a"}.fa-meta:before{content:"\e49b"}.fa-laravel:before{content:"\f3bd"}.fa-hotjar:before{content:"\f3b1"}.fa-bluetooth-b:before{content:"\f294"}.fa-square-letterboxd:before{content:"\e62e"}.fa-sticker-mule:before{content:"\f3f7"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-hips:before{content:"\f452"}.fa-behance:before{content:"\f1b4"}.fa-reddit:before{content:"\f1a1"}.fa-discord:before{content:"\f392"}.fa-chrome:before{content:"\f268"}.fa-app-store-ios:before{content:"\f370"}.fa-cc-discover:before{content:"\f1f2"}.fa-wpbeginner:before{content:"\f297"}.fa-confluence:before{content:"\f78d"}.fa-shoelace:before{content:"\e60c"}.fa-mdb:before{content:"\f8ca"}.fa-dochub:before{content:"\f394"}.fa-accessible-icon:before{content:"\f368"}.fa-ebay:before{content:"\f4f4"}.fa-amazon:before{content:"\f270"}.fa-unsplash:before{content:"\e07c"}.fa-yarn:before{content:"\f7e3"}.fa-square-steam:before{content:"\f1b7"}.fa-steam-square:before{content:"\f1b7"}.fa-500px:before{content:"\f26e"}.fa-square-vimeo:before{content:"\f194"}.fa-vimeo-square:before{content:"\f194"}.fa-asymmetrik:before{content:"\f372"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-flag:before{content:"\f2b4"}.fa-font-awesome-logo-full:before{content:"\f2b4"}.fa-gratipay:before{content:"\f184"}.fa-apple:before{content:"\f179"}.fa-hive:before{content:"\e07f"}.fa-gitkraken:before{content:"\f3a6"}.fa-keybase:before{content:"\f4f5"}.fa-apple-pay:before{content:"\f415"}.fa-padlet:before{content:"\e4a0"}.fa-amazon-pay:before{content:"\f42c"}.fa-square-github:before{content:"\f092"}.fa-github-square:before{content:"\f092"}.fa-stumbleupon:before{content:"\f1a4"}.fa-fedex:before{content:"\f797"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-shopify:before{content:"\e057"}.fa-neos:before{content:"\f612"}.fa-square-threads:before{content:"\e619"}.fa-hackerrank:before{content:"\f5f7"}.fa-researchgate:before{content:"\f4f8"}.fa-swift:before{content:"\f8e1"}.fa-angular:before{content:"\f420"}.fa-speakap:before{content:"\f3f3"}.fa-angrycreative:before{content:"\f36e"}.fa-y-combinator:before{content:"\f23b"}.fa-empire:before{content:"\f1d1"}.fa-envira:before{content:"\f299"}.fa-google-scholar:before{content:"\e63b"}.fa-square-gitlab:before{content:"\e5ae"}.fa-gitlab-square:before{content:"\e5ae"}.fa-studiovinari:before{content:"\f3f8"}.fa-pied-piper:before{content:"\f2ae"}.fa-wordpress:before{content:"\f19a"}.fa-product-hunt:before{content:"\f288"}.fa-firefox:before{content:"\f269"}.fa-linode:before{content:"\f2b8"}.fa-goodreads:before{content:"\f3a8"}.fa-square-odnoklassniki:before{content:"\f264"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-jsfiddle:before{content:"\f1cc"}.fa-sith:before{content:"\f512"}.fa-themeisle:before{content:"\f2b2"}.fa-page4:before{content:"\f3d7"}.fa-hashnode:before{content:"\e499"}.fa-react:before{content:"\f41b"}.fa-cc-paypal:before{content:"\f1f4"}.fa-squarespace:before{content:"\f5be"}.fa-cc-stripe:before{content:"\f1f5"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-bitcoin:before{content:"\f379"}.fa-keycdn:before{content:"\f3ba"}.fa-opera:before{content:"\f26a"}.fa-itch-io:before{content:"\f83a"}.fa-umbraco:before{content:"\f8e8"}.fa-galactic-senate:before{content:"\f50d"}.fa-ubuntu:before{content:"\f7df"}.fa-draft2digital:before{content:"\f396"}.fa-stripe:before{content:"\f429"}.fa-houzz:before{content:"\f27c"}.fa-gg:before{content:"\f260"}.fa-dhl:before{content:"\f790"}.fa-square-pinterest:before{content:"\f0d3"}.fa-pinterest-square:before{content:"\f0d3"}.fa-xing:before{content:"\f168"}.fa-blackberry:before{content:"\f37b"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-playstation:before{content:"\f3df"}.fa-quinscape:before{content:"\f459"}.fa-less:before{content:"\f41d"}.fa-blogger-b:before{content:"\f37d"}.fa-opencart:before{content:"\f23d"}.fa-vine:before{content:"\f1ca"}.fa-signal-messenger:before{content:"\e663"}.fa-paypal:before{content:"\f1ed"}.fa-gitlab:before{content:"\f296"}.fa-typo3:before{content:"\f42b"}.fa-reddit-alien:before{content:"\f281"}.fa-yahoo:before{content:"\f19e"}.fa-dailymotion:before{content:"\e052"}.fa-affiliatetheme:before{content:"\f36b"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-bootstrap:before{content:"\f836"}.fa-odnoklassniki:before{content:"\f263"}.fa-nfc-symbol:before{content:"\e531"}.fa-mintbit:before{content:"\e62f"}.fa-ethereum:before{content:"\f42e"}.fa-speaker-deck:before{content:"\f83c"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-patreon:before{content:"\f3d9"}.fa-avianex:before{content:"\f374"}.fa-ello:before{content:"\f5f1"}.fa-gofore:before{content:"\f3a7"}.fa-bimobject:before{content:"\f378"}.fa-brave-reverse:before{content:"\e63d"}.fa-facebook-f:before{content:"\f39e"}.fa-square-google-plus:before{content:"\f0d4"}.fa-google-plus-square:before{content:"\f0d4"}.fa-web-awesome:before{content:"\e682"}.fa-mandalorian:before{content:"\f50f"}.fa-first-order-alt:before{content:"\f50a"}.fa-osi:before{content:"\f41a"}.fa-google-wallet:before{content:"\f1ee"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-periscope:before{content:"\f3da"}.fa-fulcrum:before{content:"\f50b"}.fa-cloudscale:before{content:"\f383"}.fa-forumbee:before{content:"\f211"}.fa-mizuni:before{content:"\f3cc"}.fa-schlix:before{content:"\f3ea"}.fa-square-xing:before{content:"\f169"}.fa-xing-square:before{content:"\f169"}.fa-bandcamp:before{content:"\f2d5"}.fa-wpforms:before{content:"\f298"}.fa-cloudversify:before{content:"\f385"}.fa-usps:before{content:"\f7e1"}.fa-megaport:before{content:"\f5a3"}.fa-magento:before{content:"\f3c4"}.fa-spotify:before{content:"\f1bc"}.fa-optin-monster:before{content:"\f23c"}.fa-fly:before{content:"\f417"}.fa-aviato:before{content:"\f421"}.fa-itunes:before{content:"\f3b4"}.fa-cuttlefish:before{content:"\f38c"}.fa-blogger:before{content:"\f37c"}.fa-flickr:before{content:"\f16e"}.fa-viber:before{content:"\f409"}.fa-soundcloud:before{content:"\f1be"}.fa-digg:before{content:"\f1a6"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-letterboxd:before{content:"\e62d"}.fa-symfony:before{content:"\f83d"}.fa-maxcdn:before{content:"\f136"}.fa-etsy:before{content:"\f2d7"}.fa-facebook-messenger:before{content:"\f39f"}.fa-audible:before{content:"\f373"}.fa-think-peaks:before{content:"\f731"}.fa-bilibili:before{content:"\e3d9"}.fa-erlang:before{content:"\f39d"}.fa-x-twitter:before{content:"\e61b"}.fa-cotton-bureau:before{content:"\f89e"}.fa-dashcube:before{content:"\f210"}.fa-42-group:before{content:"\e080"}.fa-innosoft:before{content:"\e080"}.fa-stack-exchange:before{content:"\f18d"}.fa-elementor:before{content:"\f430"}.fa-square-pied-piper:before{content:"\e01e"}.fa-pied-piper-square:before{content:"\e01e"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-palfed:before{content:"\f3d8"}.fa-superpowers:before{content:"\f2dd"}.fa-resolving:before{content:"\f3e7"}.fa-xbox:before{content:"\f412"}.fa-square-web-awesome-stroke:before{content:"\e684"}.fa-searchengin:before{content:"\f3eb"}.fa-tiktok:before{content:"\e07b"}.fa-square-facebook:before{content:"\f082"}.fa-facebook-square:before{content:"\f082"}.fa-renren:before{content:"\f18b"}.fa-linux:before{content:"\f17c"}.fa-glide:before{content:"\f2a5"}.fa-linkedin:before{content:"\f08c"}.fa-hubspot:before{content:"\f3b2"}.fa-deploydog:before{content:"\f38e"}.fa-twitch:before{content:"\f1e8"}.fa-flutter:before{content:"\e694"}.fa-ravelry:before{content:"\f2d9"}.fa-mixer:before{content:"\e056"}.fa-square-lastfm:before{content:"\f203"}.fa-lastfm-square:before{content:"\f203"}.fa-vimeo:before{content:"\f40a"}.fa-mendeley:before{content:"\f7b3"}.fa-uniregistry:before{content:"\f404"}.fa-figma:before{content:"\f799"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-dropbox:before{content:"\f16b"}.fa-instagram:before{content:"\f16d"}.fa-cmplid:before{content:"\e360"}.fa-upwork:before{content:"\e641"}.fa-facebook:before{content:"\f09a"}.fa-gripfire:before{content:"\f3ac"}.fa-jedi-order:before{content:"\f50e"}.fa-uikit:before{content:"\f403"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-phabricator:before{content:"\f3db"}.fa-ussunnah:before{content:"\f407"}.fa-earlybirds:before{content:"\f39a"}.fa-trade-federation:before{content:"\f513"}.fa-autoprefixer:before{content:"\f41c"}.fa-whatsapp:before{content:"\f232"}.fa-square-upwork:before{content:"\e67c"}.fa-slideshare:before{content:"\f1e7"}.fa-google-play:before{content:"\f3ab"}.fa-viadeo:before{content:"\f2a9"}.fa-line:before{content:"\f3c0"}.fa-google-drive:before{content:"\f3aa"}.fa-servicestack:before{content:"\f3ec"}.fa-simplybuilt:before{content:"\f215"}.fa-bitbucket:before{content:"\f171"}.fa-imdb:before{content:"\f2d8"}.fa-deezer:before{content:"\e077"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-jira:before{content:"\f7b1"}.fa-docker:before{content:"\f395"}.fa-screenpal:before{content:"\e570"}.fa-bluetooth:before{content:"\f293"}.fa-gitter:before{content:"\f426"}.fa-d-and-d:before{content:"\f38d"}.fa-microblog:before{content:"\e01a"}.fa-cc-diners-club:before{content:"\f24c"}.fa-gg-circle:before{content:"\f261"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-yandex:before{content:"\f413"}.fa-readme:before{content:"\f4d5"}.fa-html5:before{content:"\f13b"}.fa-sellsy:before{content:"\f213"}.fa-square-web-awesome:before{content:"\e683"}.fa-sass:before{content:"\f41e"}.fa-wirsindhandwerk:before{content:"\e2d0"}.fa-wsh:before{content:"\e2d0"}.fa-buromobelexperte:before{content:"\f37f"}.fa-salesforce:before{content:"\f83b"}.fa-octopus-deploy:before{content:"\e082"}.fa-medapps:before{content:"\f3c6"}.fa-ns8:before{content:"\f3d5"}.fa-pinterest-p:before{content:"\f231"}.fa-apper:before{content:"\f371"}.fa-fort-awesome:before{content:"\f286"}.fa-waze:before{content:"\f83f"}.fa-bluesky:before{content:"\e671"}.fa-cc-jcb:before{content:"\f24b"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ab"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-rust:before{content:"\e07a"}.fa-wix:before{content:"\f5cf"}.fa-square-behance:before{content:"\f1b5"}.fa-behance-square:before{content:"\f1b5"}.fa-supple:before{content:"\f3f9"}.fa-webflow:before{content:"\e65c"}.fa-rebel:before{content:"\f1d0"}.fa-css3:before{content:"\f13c"}.fa-staylinked:before{content:"\f3f5"}.fa-kaggle:before{content:"\f5fa"}.fa-space-awesome:before{content:"\e5ac"}.fa-deviantart:before{content:"\f1bd"}.fa-cpanel:before{content:"\f388"}.fa-goodreads-g:before{content:"\f3a9"}.fa-square-git:before{content:"\f1d2"}.fa-git-square:before{content:"\f1d2"}.fa-square-tumblr:before{content:"\f174"}.fa-tumblr-square:before{content:"\f174"}.fa-trello:before{content:"\f181"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-get-pocket:before{content:"\f265"}.fa-perbyte:before{content:"\e083"}.fa-grunt:before{content:"\f3ad"}.fa-weebly:before{content:"\f5cc"}.fa-connectdevelop:before{content:"\f20e"}.fa-leanpub:before{content:"\f212"}.fa-black-tie:before{content:"\f27e"}.fa-themeco:before{content:"\f5c6"}.fa-python:before{content:"\f3e2"}.fa-android:before{content:"\f17b"}.fa-bots:before{content:"\e340"}.fa-free-code-camp:before{content:"\f2c5"}.fa-hornbill:before{content:"\f592"}.fa-js:before{content:"\f3b8"}.fa-ideal:before{content:"\e013"}.fa-git:before{content:"\f1d3"}.fa-dev:before{content:"\f6cc"}.fa-sketch:before{content:"\f7c6"}.fa-yandex-international:before{content:"\f414"}.fa-cc-amex:before{content:"\f1f3"}.fa-uber:before{content:"\f402"}.fa-github:before{content:"\f09b"}.fa-php:before{content:"\f457"}.fa-alipay:before{content:"\f642"}.fa-youtube:before{content:"\f167"}.fa-skyatlas:before{content:"\f216"}.fa-firefox-browser:before{content:"\e007"}.fa-replyd:before{content:"\f3e6"}.fa-suse:before{content:"\f7d6"}.fa-jenkins:before{content:"\f3b6"}.fa-twitter:before{content:"\f099"}.fa-rockrms:before{content:"\f3e9"}.fa-pinterest:before{content:"\f0d2"}.fa-buffer:before{content:"\f837"}.fa-npm:before{content:"\f3d4"}.fa-yammer:before{content:"\f840"}.fa-btc:before{content:"\f15a"}.fa-dribbble:before{content:"\f17d"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-internet-explorer:before{content:"\f26b"}.fa-stubber:before{content:"\e5c7"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f2c6"}.fa-old-republic:before{content:"\f510"}.fa-odysee:before{content:"\e5c6"}.fa-square-whatsapp:before{content:"\f40c"}.fa-whatsapp-square:before{content:"\f40c"}.fa-node-js:before{content:"\f3d3"}.fa-edge-legacy:before{content:"\e078"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f198"}.fa-medrt:before{content:"\f3c8"}.fa-usb:before{content:"\f287"}.fa-tumblr:before{content:"\f173"}.fa-vaadin:before{content:"\f408"}.fa-quora:before{content:"\f2c4"}.fa-square-x-twitter:before{content:"\e61a"}.fa-reacteurope:before{content:"\f75d"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f23a"}.fa-amilia:before{content:"\f36d"}.fa-mixcloud:before{content:"\f289"}.fa-flipboard:before{content:"\f44d"}.fa-viacoin:before{content:"\f237"}.fa-critical-role:before{content:"\f6c9"}.fa-sitrox:before{content:"\e44a"}.fa-discourse:before{content:"\f393"}.fa-joomla:before{content:"\f1aa"}.fa-mastodon:before{content:"\f4f6"}.fa-airbnb:before{content:"\f834"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-buy-n-large:before{content:"\f8a6"}.fa-gulp:before{content:"\f3ae"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-strava:before{content:"\f428"}.fa-ember:before{content:"\f423"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-teamspeak:before{content:"\f4f9"}.fa-pushed:before{content:"\f3e1"}.fa-wordpress-simple:before{content:"\f411"}.fa-nutritionix:before{content:"\f3d6"}.fa-wodu:before{content:"\e088"}.fa-google-pay:before{content:"\e079"}.fa-intercom:before{content:"\f7af"}.fa-zhihu:before{content:"\f63f"}.fa-korvue:before{content:"\f42f"}.fa-pix:before{content:"\e43a"}.fa-steam-symbol:before{content:"\f3f6"}.td-border-top{border:none;border-top:1px solid #eee}.td-border-none{border:none}.td-block-padding,.td-default main section{padding-top:4rem;padding-bottom:4rem}@media(min-width:768px){.td-block-padding,.td-default main section{padding-top:5rem;padding-bottom:5rem}}.td-overlay{position:relative}.td-overlay::after{content:"";position:absolute;top:0;right:0;bottom:0;left:0}.td-overlay--dark::after{background-color:rgba(64,63,76,.3)}.td-overlay--light::after{background-color:rgba(211,243,238,.3)}.td-overlay__inner{position:relative;z-index:1}@media(min-width:992px){.td-max-width-on-larger-screens,.td-card.card,.td-card-group.card-group,.td-content>.tab-content .tab-pane,.td-content .footnotes,.td-content>.alert,.td-content>.highlight,.td-content>.lead,.td-content>.td-table,.td-box .td-content>table,.td-content>table,.td-content>blockquote,.td-content>dl dd,.td-content>h1,.td-content>.h1,.td-content>h2,.td-content>.h2,.td-content>ol,.td-content>p,.td-content>pre,.td-content>ul{max-width:80%}}.-bg-blue{color:#fff;background-color:#0d6efd}.-bg-blue p:not(.p-initial)>a{color:#81b3fe}.-bg-blue p:not(.p-initial)>a:hover{color:#094db1}.-text-blue{color:#0d6efd}.-bg-indigo{color:#fff;background-color:#6610f2}.-bg-indigo p:not(.p-initial)>a{color:#85b6fe}.-bg-indigo p:not(.p-initial)>a:hover{color:#094db1}.-text-indigo{color:#6610f2}.-bg-purple{color:#fff;background-color:#6f42c1}.-bg-purple p:not(.p-initial)>a{color:#84b5fe}.-bg-purple p:not(.p-initial)>a:hover{color:#094db1}.-text-purple{color:#6f42c1}.-bg-pink{color:#fff;background-color:#d63384}.-bg-pink p:not(.p-initial)>a{color:#81b4fe}.-bg-pink p:not(.p-initial)>a:hover{color:#094db1}.-text-pink{color:#d63384}.-bg-red{color:#fff;background-color:#dc3545}.-bg-red p:not(.p-initial)>a{color:#7db1fe}.-bg-red p:not(.p-initial)>a:hover{color:#094db1}.-text-red{color:#dc3545}.-bg-orange{color:#000;background-color:#fd7e14}.-bg-orange p:not(.p-initial)>a{color:#073b87}.-bg-orange p:not(.p-initial)>a:hover{color:#094db1}.-text-orange{color:#fd7e14}.-bg-yellow{color:#000;background-color:#ffc107}.-bg-yellow p:not(.p-initial)>a{color:#073982}.-bg-yellow p:not(.p-initial)>a:hover{color:#094db1}.-text-yellow{color:#ffc107}.-bg-green{color:#fff;background-color:#198754}.-bg-green p:not(.p-initial)>a{color:#b3d2fe}.-bg-green p:not(.p-initial)>a:hover{color:#094db1}.-text-green{color:#198754}.-bg-teal{color:#000;background-color:#20c997}.-bg-teal p:not(.p-initial)>a{color:#063274}.-bg-teal p:not(.p-initial)>a:hover{color:#094db1}.-text-teal{color:#20c997}.-bg-cyan{color:#000;background-color:#0dcaf0}.-bg-cyan p:not(.p-initial)>a{color:#06377e}.-bg-cyan p:not(.p-initial)>a:hover{color:#094db1}.-text-cyan{color:#0dcaf0}.-bg-black{color:#fff;background-color:#000}.-bg-black p:not(.p-initial)>a{color:#fff}.-bg-black p:not(.p-initial)>a:hover{color:#094db1}.-text-black{color:#000}.-bg-white{color:#000;background-color:#fff}.-bg-white p:not(.p-initial)>a{color:#0d6efd}.-bg-white p:not(.p-initial)>a:hover{color:#094db1}.-text-white{color:#fff}.-bg-gray{color:#fff;background-color:#6c757d}.-bg-gray p:not(.p-initial)>a{color:#90bdfe}.-bg-gray p:not(.p-initial)>a:hover{color:#094db1}.-text-gray{color:#6c757d}.-bg-gray-dark{color:#fff;background-color:#343a40}.-bg-gray-dark p:not(.p-initial)>a{color:#c8deff}.-bg-gray-dark p:not(.p-initial)>a:hover{color:#094db1}.-text-gray-dark{color:#343a40}.-bg-primary{color:#fff;background-color:#30638e}.-bg-primary p:not(.p-initial)>a{color:#a5c9fe}.-bg-primary p:not(.p-initial)>a:hover{color:#094db1}.-text-primary{color:#30638e}.-bg-secondary{color:#000;background-color:#ffa630}.-bg-secondary p:not(.p-initial)>a{color:#084196}.-bg-secondary p:not(.p-initial)>a:hover{color:#094db1}.-text-secondary{color:#ffa630}.-bg-success{color:#000;background-color:#3772ff}.-bg-success p:not(.p-initial)>a{color:#08439a}.-bg-success p:not(.p-initial)>a:hover{color:#094db1}.-text-success{color:#3772ff}.-bg-info{color:#000;background-color:#c0e0de}.-bg-info p:not(.p-initial)>a{color:#0b5ace}.-bg-info p:not(.p-initial)>a:hover{color:#094db1}.-text-info{color:#c0e0de}.-bg-warning{color:#000;background-color:#ed6a5a}.-bg-warning p:not(.p-initial)>a{color:#0847a2}.-bg-warning p:not(.p-initial)>a:hover{color:#094db1}.-text-warning{color:#ed6a5a}.-bg-danger{color:#000;background-color:#ed6a5a}.-bg-danger p:not(.p-initial)>a{color:#0847a2}.-bg-danger p:not(.p-initial)>a:hover{color:#094db1}.-text-danger{color:#ed6a5a}.-bg-light{color:#000;background-color:#d3f3ee}.-bg-light p:not(.p-initial)>a{color:#0c62e1}.-bg-light p:not(.p-initial)>a:hover{color:#094db1}.-text-light{color:#d3f3ee}.-bg-dark{color:#fff;background-color:#403f4c}.-bg-dark p:not(.p-initial)>a{color:#bdd7fe}.-bg-dark p:not(.p-initial)>a:hover{color:#094db1}.-text-dark{color:#403f4c}.-bg-100{color:#000;background-color:#f8f9fa}.-bg-100 p:not(.p-initial)>a{color:#0d6bf7}.-bg-100 p:not(.p-initial)>a:hover{color:#094db1}.-text-100{color:#f8f9fa}.-bg-200{color:#000;background-color:#e9ecef}.-bg-200 p:not(.p-initial)>a{color:#0c66ea}.-bg-200 p:not(.p-initial)>a:hover{color:#094db1}.-text-200{color:#e9ecef}.-bg-300{color:#000;background-color:#dee2e6}.-bg-300 p:not(.p-initial)>a{color:#0c61e0}.-bg-300 p:not(.p-initial)>a:hover{color:#094db1}.-text-300{color:#dee2e6}.-bg-400{color:#000;background-color:#ced4da}.-bg-400 p:not(.p-initial)>a{color:#0b5bd2}.-bg-400 p:not(.p-initial)>a:hover{color:#094db1}.-text-400{color:#ced4da}.-bg-500{color:#000;background-color:#adb5bd}.-bg-500 p:not(.p-initial)>a{color:#094eb4}.-bg-500 p:not(.p-initial)>a:hover{color:#094db1}.-text-500{color:#adb5bd}.-bg-600{color:#fff;background-color:#6c757d}.-bg-600 p:not(.p-initial)>a{color:#90bdfe}.-bg-600 p:not(.p-initial)>a:hover{color:#094db1}.-text-600{color:#6c757d}.-bg-700{color:#fff;background-color:#495057}.-bg-700 p:not(.p-initial)>a{color:#b3d2fe}.-bg-700 p:not(.p-initial)>a:hover{color:#094db1}.-text-700{color:#495057}.-bg-800{color:#fff;background-color:#343a40}.-bg-800 p:not(.p-initial)>a{color:#c8deff}.-bg-800 p:not(.p-initial)>a:hover{color:#094db1}.-text-800{color:#343a40}.-bg-900{color:#fff;background-color:#212529}.-bg-900 p:not(.p-initial)>a{color:#dceaff}.-bg-900 p:not(.p-initial)>a:hover{color:#094db1}.-text-900{color:#212529}.-bg-0{color:#fff;background-color:#403f4c}.-bg-0 p:not(.p-initial)>a{color:#bdd7fe}.-bg-0 p:not(.p-initial)>a:hover{color:#094db1}.-text-0{color:#403f4c}.-bg-1{color:#fff;background-color:#30638e}.-bg-1 p:not(.p-initial)>a{color:#a5c9fe}.-bg-1 p:not(.p-initial)>a:hover{color:#094db1}.-text-1{color:#30638e}.-bg-2{color:#000;background-color:#ffa630}.-bg-2 p:not(.p-initial)>a{color:#084196}.-bg-2 p:not(.p-initial)>a:hover{color:#094db1}.-text-2{color:#ffa630}.-bg-3{color:#000;background-color:#c0e0de}.-bg-3 p:not(.p-initial)>a{color:#0b5ace}.-bg-3 p:not(.p-initial)>a:hover{color:#094db1}.-text-3{color:#c0e0de}.-bg-4{color:#000;background-color:#fff}.-bg-4 p:not(.p-initial)>a{color:#0d6efd}.-bg-4 p:not(.p-initial)>a:hover{color:#094db1}.-text-4{color:#fff}.-bg-5{color:#fff;background-color:#6c757d}.-bg-5 p:not(.p-initial)>a{color:#90bdfe}.-bg-5 p:not(.p-initial)>a:hover{color:#094db1}.-text-5{color:#6c757d}.-bg-6{color:#000;background-color:#3772ff}.-bg-6 p:not(.p-initial)>a{color:#08439a}.-bg-6 p:not(.p-initial)>a:hover{color:#094db1}.-text-6{color:#3772ff}.-bg-7{color:#000;background-color:#ed6a5a}.-bg-7 p:not(.p-initial)>a{color:#0847a2}.-bg-7 p:not(.p-initial)>a:hover{color:#094db1}.-text-7{color:#ed6a5a}.-bg-8{color:#fff;background-color:#403f4c}.-bg-8 p:not(.p-initial)>a{color:#bdd7fe}.-bg-8 p:not(.p-initial)>a:hover{color:#094db1}.-text-8{color:#403f4c}.-bg-9{color:#000;background-color:#ed6a5a}.-bg-9 p:not(.p-initial)>a{color:#0847a2}.-bg-9 p:not(.p-initial)>a:hover{color:#094db1}.-text-9{color:#ed6a5a}.-bg-10{color:#fff;background-color:#30638e}.-bg-10 p:not(.p-initial)>a{color:#a5c9fe}.-bg-10 p:not(.p-initial)>a:hover{color:#094db1}.-text-10{color:#30638e}.-bg-11{color:#000;background-color:#ffa630}.-bg-11 p:not(.p-initial)>a{color:#084196}.-bg-11 p:not(.p-initial)>a:hover{color:#094db1}.-text-11{color:#ffa630}.-bg-12{color:#000;background-color:#c0e0de}.-bg-12 p:not(.p-initial)>a{color:#0b5ace}.-bg-12 p:not(.p-initial)>a:hover{color:#094db1}.-text-12{color:#c0e0de}.td-table:not(.td-initial),.td-content table:not(.td-initial),.td-box table:not(.td-initial){display:block}.td-box--height-min{min-height:300px}.td-box--height-med{min-height:400px}.td-box--height-max{min-height:500px}.td-box--height-full{min-height:100vh}@media(min-width:768px){.td-box--height-min{min-height:450px}.td-box--height-med{min-height:500px}.td-box--height-max{min-height:650px}}.td-box .row{padding-left:5vw;padding-right:5vw}.td-box.linkbox{padding:5vh 5vw}.td-box--0{color:#fff;background-color:#403f4c}.td-box--0 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#403f4c transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--0 p>a,.td-box--0 span>a{color:#bdd7fe}.td-box--0 p>a:hover,.td-box--0 span>a:hover{color:#d1e3fe}.td-box--1{color:#fff;background-color:#30638e}.td-box--1 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#30638e transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--1 p>a,.td-box--1 span>a{color:#a5c9fe}.td-box--1 p>a:hover,.td-box--1 span>a:hover{color:#c0d9fe}.td-box--2{color:#000;background-color:#ffa630}.td-box--2 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#ffa630 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--2 p>a,.td-box--2 span>a{color:#084196}.td-box--2 p>a:hover,.td-box--2 span>a:hover{color:#062e69}.td-box--3{color:#000;background-color:#c0e0de}.td-box--3 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#c0e0de transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--3 p>a,.td-box--3 span>a{color:#0b5ace}.td-box--3 p>a:hover,.td-box--3 span>a:hover{color:#083f90}.td-box--4{color:#000;background-color:#fff}.td-box--4 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#fff transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--4 p>a,.td-box--4 span>a{color:#0d6efd}.td-box--4 p>a:hover,.td-box--4 span>a:hover{color:#094db1}.td-box--5{color:#fff;background-color:#6c757d}.td-box--5 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#6c757d transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--5 p>a,.td-box--5 span>a{color:#90bdfe}.td-box--5 p>a:hover,.td-box--5 span>a:hover{color:#b1d1fe}.td-box--6{color:#000;background-color:#3772ff}.td-box--6 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#3772ff transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--6 p>a,.td-box--6 span>a{color:#08439a}.td-box--6 p>a:hover,.td-box--6 span>a:hover{color:#062f6c}.td-box--7{color:#000;background-color:#ed6a5a}.td-box--7 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#ed6a5a transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--7 p>a,.td-box--7 span>a{color:#0847a2}.td-box--7 p>a:hover,.td-box--7 span>a:hover{color:#063271}.td-box--8{color:#fff;background-color:#403f4c}.td-box--8 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#403f4c transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--8 p>a,.td-box--8 span>a{color:#bdd7fe}.td-box--8 p>a:hover,.td-box--8 span>a:hover{color:#d1e3fe}.td-box--9{color:#000;background-color:#ed6a5a}.td-box--9 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#ed6a5a transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--9 p>a,.td-box--9 span>a{color:#0847a2}.td-box--9 p>a:hover,.td-box--9 span>a:hover{color:#063271}.td-box--10{color:#fff;background-color:#30638e}.td-box--10 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#30638e transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--10 p>a,.td-box--10 span>a{color:#a5c9fe}.td-box--10 p>a:hover,.td-box--10 span>a:hover{color:#c0d9fe}.td-box--11{color:#000;background-color:#ffa630}.td-box--11 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#ffa630 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--11 p>a,.td-box--11 span>a{color:#084196}.td-box--11 p>a:hover,.td-box--11 span>a:hover{color:#062e69}.td-box--12{color:#000;background-color:#c0e0de}.td-box--12 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#c0e0de transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--12 p>a,.td-box--12 span>a{color:#0b5ace}.td-box--12 p>a:hover,.td-box--12 span>a:hover{color:#083f90}.td-box--blue{color:#fff;background-color:#0d6efd}.td-box--blue .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#0d6efd transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--blue p>a,.td-box--blue span>a{color:#81b3fe}.td-box--blue p>a:hover,.td-box--blue span>a:hover{color:#a7cafe}.td-box--indigo{color:#fff;background-color:#6610f2}.td-box--indigo .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#6610f2 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--indigo p>a,.td-box--indigo span>a{color:#85b6fe}.td-box--indigo p>a:hover,.td-box--indigo span>a:hover{color:#aaccfe}.td-box--purple{color:#fff;background-color:#6f42c1}.td-box--purple .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#6f42c1 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--purple p>a,.td-box--purple span>a{color:#84b5fe}.td-box--purple p>a:hover,.td-box--purple span>a:hover{color:#a9cbfe}.td-box--pink{color:#fff;background-color:#d63384}.td-box--pink .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#d63384 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--pink p>a,.td-box--pink span>a{color:#81b4fe}.td-box--pink p>a:hover,.td-box--pink span>a:hover{color:#a7cbfe}.td-box--red{color:#fff;background-color:#dc3545}.td-box--red .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#dc3545 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--red p>a,.td-box--red span>a{color:#7db1fe}.td-box--red p>a:hover,.td-box--red span>a:hover{color:#a4c8fe}.td-box--orange{color:#000;background-color:#fd7e14}.td-box--orange .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#fd7e14 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--orange p>a,.td-box--orange span>a{color:#073b87}.td-box--orange p>a:hover,.td-box--orange span>a:hover{color:#05295f}.td-box--yellow{color:#000;background-color:#ffc107}.td-box--yellow .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#ffc107 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--yellow p>a,.td-box--yellow span>a{color:#073982}.td-box--yellow p>a:hover,.td-box--yellow span>a:hover{color:#05285b}.td-box--green{color:#fff;background-color:#198754}.td-box--green .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#198754 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--green p>a,.td-box--green span>a{color:#b3d2fe}.td-box--green p>a:hover,.td-box--green span>a:hover{color:#cae0fe}.td-box--teal{color:#000;background-color:#20c997}.td-box--teal .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#20c997 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--teal p>a,.td-box--teal span>a{color:#063274}.td-box--teal p>a:hover,.td-box--teal span>a:hover{color:#042351}.td-box--cyan{color:#000;background-color:#0dcaf0}.td-box--cyan .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#0dcaf0 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--cyan p>a,.td-box--cyan span>a{color:#06377e}.td-box--cyan p>a:hover,.td-box--cyan span>a:hover{color:#042758}.td-box--black{color:#fff;background-color:#000}.td-box--black .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#000 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--black p>a,.td-box--black span>a{color:#fff}.td-box--black p>a:hover,.td-box--black span>a:hover{color:#fff}.td-box--white{color:#000;background-color:#fff}.td-box--white .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#fff transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--white p>a,.td-box--white span>a{color:#0d6efd}.td-box--white p>a:hover,.td-box--white span>a:hover{color:#094db1}.td-box--gray{color:#fff;background-color:#6c757d}.td-box--gray .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#6c757d transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--gray p>a,.td-box--gray span>a{color:#90bdfe}.td-box--gray p>a:hover,.td-box--gray span>a:hover{color:#b1d1fe}.td-box--gray-dark{color:#fff;background-color:#343a40}.td-box--gray-dark .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#343a40 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--gray-dark p>a,.td-box--gray-dark span>a{color:#c8deff}.td-box--gray-dark p>a:hover,.td-box--gray-dark span>a:hover{color:#d9e8ff}.td-box--primary{color:#fff;background-color:#30638e}.td-box--primary .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#30638e transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--primary p>a,.td-box--primary span>a{color:#a5c9fe}.td-box--primary p>a:hover,.td-box--primary span>a:hover{color:#c0d9fe}.td-box--secondary{color:#000;background-color:#ffa630}.td-box--secondary .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#ffa630 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--secondary p>a,.td-box--secondary span>a{color:#084196}.td-box--secondary p>a:hover,.td-box--secondary span>a:hover{color:#062e69}.td-box--success{color:#000;background-color:#3772ff}.td-box--success .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#3772ff transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--success p>a,.td-box--success span>a{color:#08439a}.td-box--success p>a:hover,.td-box--success span>a:hover{color:#062f6c}.td-box--info{color:#000;background-color:#c0e0de}.td-box--info .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#c0e0de transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--info p>a,.td-box--info span>a{color:#0b5ace}.td-box--info p>a:hover,.td-box--info span>a:hover{color:#083f90}.td-box--warning{color:#000;background-color:#ed6a5a}.td-box--warning .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#ed6a5a transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--warning p>a,.td-box--warning span>a{color:#0847a2}.td-box--warning p>a:hover,.td-box--warning span>a:hover{color:#063271}.td-box--danger{color:#000;background-color:#ed6a5a}.td-box--danger .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#ed6a5a transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--danger p>a,.td-box--danger span>a{color:#0847a2}.td-box--danger p>a:hover,.td-box--danger span>a:hover{color:#063271}.td-box--light{color:#000;background-color:#d3f3ee}.td-box--light .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#d3f3ee transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--light p>a,.td-box--light span>a{color:#0c62e1}.td-box--light p>a:hover,.td-box--light span>a:hover{color:#08459e}.td-box--dark,.td-footer{color:#fff;background-color:#403f4c}.td-box--dark .td-arrow-down::before,.td-footer .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#403f4c transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--dark p>a,.td-footer p>a,.td-box--dark span>a,.td-footer span>a{color:#bdd7fe}.td-box--dark p>a:hover,.td-footer p>a:hover,.td-box--dark span>a:hover,.td-footer span>a:hover{color:#d1e3fe}.td-box--100{color:#000;background-color:#f8f9fa}.td-box--100 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#f8f9fa transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--100 p>a,.td-box--100 span>a{color:#0d6bf7}.td-box--100 p>a:hover,.td-box--100 span>a:hover{color:#094bad}.td-box--200{color:#000;background-color:#e9ecef}.td-box--200 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#e9ecef transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--200 p>a,.td-box--200 span>a{color:#0c66ea}.td-box--200 p>a:hover,.td-box--200 span>a:hover{color:#0847a4}.td-box--300{color:#000;background-color:#dee2e6}.td-box--300 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#dee2e6 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--300 p>a,.td-box--300 span>a{color:#0c61e0}.td-box--300 p>a:hover,.td-box--300 span>a:hover{color:#08449d}.td-box--400{color:#000;background-color:#ced4da}.td-box--400 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#ced4da transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--400 p>a,.td-box--400 span>a{color:#0b5bd2}.td-box--400 p>a:hover,.td-box--400 span>a:hover{color:#084093}.td-box--500{color:#000;background-color:#adb5bd}.td-box--500 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#adb5bd transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--500 p>a,.td-box--500 span>a{color:#094eb4}.td-box--500 p>a:hover,.td-box--500 span>a:hover{color:#06377e}.td-box--600{color:#fff;background-color:#6c757d}.td-box--600 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#6c757d transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--600 p>a,.td-box--600 span>a{color:#90bdfe}.td-box--600 p>a:hover,.td-box--600 span>a:hover{color:#b1d1fe}.td-box--700{color:#fff;background-color:#495057}.td-box--700 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#495057 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--700 p>a,.td-box--700 span>a{color:#b3d2fe}.td-box--700 p>a:hover,.td-box--700 span>a:hover{color:#cae0fe}.td-box--800{color:#fff;background-color:#343a40}.td-box--800 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#343a40 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--800 p>a,.td-box--800 span>a{color:#c8deff}.td-box--800 p>a:hover,.td-box--800 span>a:hover{color:#d9e8ff}.td-box--900{color:#fff;background-color:#212529}.td-box--900 .td-arrow-down::before{left:50%;margin-left:-30px;bottom:-25px;border-style:solid;border-width:25px 30px 0;border-color:#212529 transparent transparent transparent;z-index:3;position:absolute;content:""}.td-box--900 p>a,.td-box--900 span>a{color:#dceaff}.td-box--900 p>a:hover,.td-box--900 span>a:hover{color:#e7f0ff}[data-bs-theme=dark] .td-box--white{color:var(--bs-body-color);background-color:var(--bs-body-bg)}[data-bs-theme=dark] .td-box--white p>a,[data-bs-theme=dark] .td-box--white span>a{color:var(--bs-link-color)}[data-bs-theme=dark] .td-box--white p>a:focus,[data-bs-theme=dark] .td-box--white p>a:hover,[data-bs-theme=dark] .td-box--white span>a:focus,[data-bs-theme=dark] .td-box--white span>a:hover{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1))}[data-bs-theme=dark] .td-box--white .td-arrow-down::before{border-color:var(--bs-body-bg)transparent transparent transparent}.td-blog .td-rss-button{border-radius:2rem;float:right;display:none}.td-blog-posts-list{margin-top:1.5rem!important}.td-blog-posts-list__item{display:flex;align-items:flex-start;margin-bottom:1.5rem!important}.td-blog-posts-list__item__body{flex:1}[data-bs-theme=dark]{--td-pre-bg:#1b1f22}.td-content .highlight{margin:2rem 0;padding:0;position:relative}.td-content .highlight .click-to-copy{display:block;text-align:right}.td-content .highlight pre{margin:0;padding:1rem;border-radius:inherit}.td-content .highlight pre button.td-click-to-copy{position:absolute;color:var(--bs-tertiary-color);border-width:0;background-color:transparent;background-image:none;--bs-btn-box-shadow:0;padding:var(--bs-btn-padding-y)calc(var(--bs-btn-padding-x)/2);right:4px;top:2px}.td-content .highlight pre button.td-click-to-copy:hover{color:var(--bs-secondary-color);background-color:var(--bs-dark-bg-subtle)}.td-content .highlight pre button.td-click-to-copy:active{color:var(--bs-secondary-color);background-color:var(--bs-dark-bg-subtle);transform:translateY(2px)}.td-content p code,.td-content li>code,.td-content table code{color:inherit;padding:.2em .4em;margin:0;font-size:85%;word-break:normal;background-color:var(--td-pre-bg);border-radius:.375rem}.td-content p code br,.td-content li>code br,.td-content table code br{display:none}.td-content pre{word-wrap:normal;background-color:var(--td-pre-bg);border:solid var(--bs-border-color);border-width:1px;padding:1rem}.td-content pre>code{background-color:inherit!important;padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;border:0}.td-content pre.mermaid{background-color:inherit;font-size:0;padding:0}@media(min-width:768px){.td-navbar-cover{background:0 0!important}.td-navbar-cover .nav-link{text-shadow:1px 1px 2px #403f4c}}.td-navbar-cover.navbar-bg-onscroll .nav-link{text-shadow:none}.navbar-bg-onscroll{background:#30638e!important;opacity:inherit}.td-navbar{background:#30638e;min-height:4rem;margin:0;z-index:32}.td-navbar .navbar-brand{text-transform:none}.td-navbar .navbar-brand__name{font-weight:700}.td-navbar .navbar-brand svg{display:inline-block;margin:0 10px;height:30px}.td-navbar .navbar-nav{padding-top:.5rem;white-space:nowrap}.td-navbar .nav-link{text-transform:none;font-weight:700}.td-navbar .dropdown{min-width:50px}@media(min-width:768px){.td-navbar{position:fixed;top:0;width:100%}.td-navbar .nav-item{padding-inline-end:.5rem}.td-navbar .navbar-nav{padding-top:0!important}}@media(max-width:991.98px){.td-navbar .td-navbar-nav-scroll{max-width:100%;height:2.5rem;overflow:hidden;font-size:.9rem}.td-navbar .navbar-brand{margin-right:0}.td-navbar .navbar-nav{padding-bottom:2rem;overflow-x:auto}}.td-navbar .td-light-dark-menu .bi{width:1em;height:1em;vertical-align:-.125em;fill:currentcolor}@media(max-width:991.98px){.td-navbar .td-light-dark-menu.dropdown{position:unset}}#main_navbar li i{padding-right:.5em}#main_navbar li i:before{display:inline-block;text-align:center;min-width:1em}#main_navbar .alert{background-color:inherit;padding:0;color:#ffa630;border:0;font-weight:inherit}#main_navbar .alert:before{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;-webkit-font-smoothing:antialiased;font-family:"font awesome 6 free";font-weight:900;content:"\f0d9";padding-left:.5em;padding-right:.5em}nav.foldable-nav#td-section-nav{position:relative}nav.foldable-nav#td-section-nav label{margin-bottom:0;width:100%}nav.foldable-nav .td-sidebar-nav__section,nav.foldable-nav .with-child ul{list-style:none;padding:0;margin:0}nav.foldable-nav .ul-1>li{padding-left:1.5em}nav.foldable-nav ul.foldable{display:none}nav.foldable-nav input:checked~ul.foldable{display:block}nav.foldable-nav input[type=checkbox]{display:none}nav.foldable-nav .with-child,nav.foldable-nav .without-child{position:relative;padding-left:1.5em}nav.foldable-nav .ul-1 .with-child>label:before{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;-webkit-font-smoothing:antialiased;font-family:"font awesome 6 free";font-weight:900;content:"\f0da";position:absolute;left:.1em;padding-left:.4em;padding-right:.4em;font-size:1em;color:var(--bs-secondary-color);transition:all .5s}nav.foldable-nav .ul-1 .with-child>label:before:hover{transform:rotate(90deg)}nav.foldable-nav .ul-1 .with-child>input:checked~label:before{color:var(--bs-secondary-color);transform:rotate(90deg);transition:transform .5s}nav.foldable-nav .with-child ul{margin-top:.1em}@media(hover:hover) and (pointer:fine){nav.foldable-nav .ul-1 .with-child>label:hover:before{color:var(--bs-link-color);transition:color .3s}nav.foldable-nav .ul-1 .with-child>input:checked~label:hover:before{color:var(--bs-link-color);transition:color .3s}}.td-sidebar-nav{padding-right:.5rem;margin-right:-15px;margin-left:-15px}@media(min-width:768px){@supports(position:sticky){.td-sidebar-nav{max-height:calc(100vh - 8.5rem);overflow-y:auto}}}@media(min-width:992px){.td-sidebar-nav.td-sidebar-nav--search-disabled{padding-top:1rem}@supports(position:sticky){.td-sidebar-nav.td-sidebar-nav--search-disabled{max-height:calc(calc(100vh - 8.5rem) + 4.5rem)}}}@media(min-width:768px){.td-sidebar-nav{display:block!important}}.td-sidebar-nav__section{padding-left:0}.td-sidebar-nav__section li{list-style:none}.td-sidebar-nav__section.ul-0,.td-sidebar-nav__section ul{padding:0;margin:0}@media(min-width:768px){.td-sidebar-nav__section .ul-1 ul{padding-left:1.5em}}.td-sidebar-nav__section-title{display:block;font-weight:500}.td-sidebar-nav__section-title .active{font-weight:700}.td-sidebar-nav__section-title a{color:var(--bs-secondary-color)}.td-sidebar-nav .td-sidebar-link{display:block;padding-bottom:.375rem}.td-sidebar-nav .td-sidebar-link__page{color:var(--bs-body-color);font-weight:300}.td-sidebar-nav a:focus,.td-sidebar-nav a:hover{color:var(--bs-link-color)}.td-sidebar-nav a.active{font-weight:700}.td-sidebar-nav .dropdown a{color:var(--bs-tertiary-color)}.td-sidebar-nav .dropdown .nav-link{padding:0 0 1rem}.td-sidebar-nav>.td-sidebar-nav__section{padding-left:1.5rem}.td-sidebar-nav li i{padding-right:.5em}.td-sidebar-nav li i:before{display:inline-block;text-align:center;min-width:1em}.td-sidebar-nav .td-sidebar-link.tree-root{font-weight:700;border-bottom:1px solid var(--bs-tertiary-color);margin-bottom:1rem}.td-sidebar{padding-bottom:1rem}.td-sidebar a{text-decoration:none}.td-sidebar a:focus,.td-sidebar a:hover{text-decoration:initial}.td-sidebar .btn-link{text-decoration:none}@media(min-width:768px){.td-sidebar{padding-top:4rem;background-color:var(--bs-body-tertiary-bg);padding-right:1rem;border-right:1px solid var(--bs-border-color)}}.td-sidebar__toggle{line-height:1;color:var(--bs-body-color);margin:1rem}.td-sidebar__search{padding:1rem 0}.td-sidebar__inner{order:0}@media(min-width:768px){@supports(position:sticky){.td-sidebar__inner{position:sticky;top:4rem;z-index:10;height:calc(100vh - 5rem)}}}@media(min-width:1200px){.td-sidebar__inner{flex:0 1 320px}}.td-sidebar__inner .td-search-box{width:100%}.td-sidebar #content-desktop{display:block}.td-sidebar #content-mobile{display:none}@media(max-width:991.98px){.td-sidebar #content-desktop{display:none}.td-sidebar #content-mobile{display:block}}.td-sidebar-toc{border-left:1px solid var(--bs-border-color);order:2;padding-top:.75rem;padding-bottom:1.5rem;vertical-align:top}.td-sidebar-toc a{text-decoration:none}.td-sidebar-toc a:focus,.td-sidebar-toc a:hover{text-decoration:initial}.td-sidebar-toc .btn-link{text-decoration:none}@supports(position:sticky){.td-sidebar-toc{position:sticky;top:4rem;height:calc(100vh - 4rem);overflow-y:auto}}.td-sidebar-toc .td-page-meta a{display:block;font-weight:500}.td-toc a{display:block;font-weight:300;padding-bottom:.25rem}.td-toc li{list-style:none;display:block}.td-toc li li{margin-left:.5rem}.td-toc #TableOfContents a{color:var(--bs-secondary-color)}.td-toc #TableOfContents a:focus,.td-toc #TableOfContents a:hover{color:initial}.td-toc ul{padding-left:0}@media print{.td-breadcrumbs{display:none!important}}.td-breadcrumbs .breadcrumb{background:inherit;padding-left:0;padding-top:0}.alert{font-weight:500;color:inherit;border-radius:0}.alert-primary,.pageinfo-primary{border-style:solid;border-color:#30638e;border-width:0 0 0 4px}.alert-primary .alert-heading,.pageinfo-primary .alert-heading{color:#30638e}.alert-secondary,.pageinfo-secondary{border-style:solid;border-color:#ffa630;border-width:0 0 0 4px}.alert-secondary .alert-heading,.pageinfo-secondary .alert-heading{color:#ffa630}.alert-success,.pageinfo-success{border-style:solid;border-color:#3772ff;border-width:0 0 0 4px}.alert-success .alert-heading,.pageinfo-success .alert-heading{color:#3772ff}.alert-info,.pageinfo-info{border-style:solid;border-color:#c0e0de;border-width:0 0 0 4px}.alert-info .alert-heading,.pageinfo-info .alert-heading{color:#c0e0de}.alert-warning,.pageinfo-warning{border-style:solid;border-color:#ed6a5a;border-width:0 0 0 4px}.alert-warning .alert-heading,.pageinfo-warning .alert-heading{color:#ed6a5a}.alert-danger,.pageinfo-danger{border-style:solid;border-color:#ed6a5a;border-width:0 0 0 4px}.alert-danger .alert-heading,.pageinfo-danger .alert-heading{color:#ed6a5a}.alert-light,.pageinfo-light{border-style:solid;border-color:#d3f3ee;border-width:0 0 0 4px}.alert-light .alert-heading,.pageinfo-light .alert-heading{color:#d3f3ee}.alert-dark,.pageinfo-dark{border-style:solid;border-color:#403f4c;border-width:0 0 0 4px}.alert-dark .alert-heading,.pageinfo-dark .alert-heading{color:#403f4c}.td-content{order:1}.td-content p,.td-content li,.td-content td{font-weight:400}.td-content>h1,.td-content>.h1{font-weight:700;margin-bottom:1rem}.td-content>h2,.td-content>.h2{margin-bottom:1rem}.td-content>h2:not(:first-child),.td-content>.h2:not(:first-child){margin-top:3rem}.td-content>h2+h3,.td-content>.h2+h3,.td-content>h2+.h3,.td-content>h2+.td-footer__links-item,.td-content>.h2+.h3,.td-content>.h2+.td-footer__links-item{margin-top:1rem}.td-content>h3,.td-content>.h3,.td-content>.td-footer__links-item,.td-content>h4,.td-content>.h4,.td-content>h5,.td-content>.h5,.td-content>h6,.td-content>.h6{margin-bottom:1rem;margin-top:2rem}.td-content blockquote{padding:0 0 0 1rem;margin-bottom:1rem;color:var(--bs-secondary-color);border-left:6px solid var(--bs-primary)}.td-content ul li,.td-content ol li{margin-bottom:.25rem}.td-content strong{font-weight:700}.td-content .alert:not(:first-child){margin-top:2rem;margin-bottom:2rem}.td-content .lead{margin-bottom:1.5rem}.td-title{margin-top:1rem;margin-bottom:.5rem}@media(min-width:576px){.td-title{font-size:3rem}}.td-heading-self-link{font-size:90%;padding-left:.25em;text-decoration:none;visibility:hidden}.td-heading-self-link:before{content:'#'}@media(hover:none) and (pointer:coarse),(max-width:576px){.td-heading-self-link{visibility:visible}}h1:hover>.td-heading-self-link,.h1:hover>.td-heading-self-link{visibility:visible}h2:hover>.td-heading-self-link,.h2:hover>.td-heading-self-link{visibility:visible}h3:hover>.td-heading-self-link,.h3:hover>.td-heading-self-link,.td-footer__links-item:hover>.td-heading-self-link{visibility:visible}h4:hover>.td-heading-self-link,.h4:hover>.td-heading-self-link{visibility:visible}h5:hover>.td-heading-self-link,.h5:hover>.td-heading-self-link{visibility:visible}h6:hover>.td-heading-self-link,.h6:hover>.td-heading-self-link{visibility:visible}.td-search{background:0 0;position:relative;width:100%}.td-search__icon{display:flex;align-items:center;height:100%;position:absolute;left:.75em;pointer-events:none}.td-search__icon:before{content:"\f002"}.td-navbar .td-search__icon{color:inherit}.td-search__input{width:100%;text-indent:1.25em}.td-search__input:not(:focus){background:0 0}.td-search__input.form-control:focus{border-color:#f5f7f9;box-shadow:0 0 0 2px #83a1bb;color:var(--bs-body-color)}.td-navbar .td-search__input{border:none;color:inherit}.td-navbar .td-search__input::-webkit-input-placeholder{color:inherit}.td-navbar .td-search__input:-moz-placeholder{color:inherit}.td-navbar .td-search__input::-moz-placeholder{color:inherit}.td-navbar .td-search__input:-ms-input-placeholder{color:inherit}.td-search:focus-within .td-search__icon{display:none}.td-search:focus-within .td-search-input{text-indent:0}.td-search:not(:focus-within){color:var(--bs-secondary-color)}.td-sidebar .td-search--algolia{display:block;padding:0 .5rem}.td-sidebar .td-search--algolia>button{margin:0;width:100%}.td-search--offline:focus-within .td-search__icon{display:flex;color:var(--bs-secondary-color)}.td-offline-search-results{max-width:90%}.td-offline-search-results .card{margin-bottom:.5rem}.td-offline-search-results .card .card-header{font-weight:700}.td-offline-search-results__close-button{float:right}.td-offline-search-results__close-button:after{content:"\f00d"}.td-outer{display:flex;flex-direction:column;min-height:100vh}@media(min-width:768px){.td-default main>section:first-of-type{padding-top:8rem}}.td-main{flex-grow:1}.td-404 main,.td-main main{padding-top:1.5rem;padding-bottom:2rem}@media(min-width:768px){.td-404 main,.td-main main{padding-top:5.5rem}}.td-cover-block--height-min{min-height:300px}.td-cover-block--height-med{min-height:400px}.td-cover-block--height-max{min-height:500px}.td-cover-block--height-full{min-height:100vh}@media(min-width:768px){.td-cover-block--height-min{min-height:450px}.td-cover-block--height-med{min-height:500px}.td-cover-block--height-max{min-height:650px}}.td-cover-logo{margin-right:.5em}.td-cover-block{position:relative;padding-top:5rem;padding-bottom:5rem;background-repeat:no-repeat;background-position:50% 0;background-size:cover}.td-cover-block>.byline{position:absolute;bottom:2px;right:4px}.td-bg-arrow-wrapper{position:relative}.section-index .entry{padding:.75rem}.section-index h5,.section-index .h5{margin-bottom:0}.section-index h5 a,.section-index .h5 a{font-weight:700}.section-index p{margin-top:0}.pageinfo{font-weight:500;background:var(--bs-alert-bg);color:inherit;margin:2rem auto;padding:1.5rem;padding-bottom:.5rem}.pageinfo-primary{border-width:0}.pageinfo-secondary{border-width:0}.pageinfo-success{border-width:0}.pageinfo-info{border-width:0}.pageinfo-warning{border-width:0}.pageinfo-danger{border-width:0}.pageinfo-light{border-width:0}.pageinfo-dark{border-width:0}.td-page-meta__lastmod{margin-top:3rem!important;padding-top:1rem!important}.taxonomy-terms-article{width:100%;clear:both;font-size:.8rem}.taxonomy-terms-article .taxonomy-title{display:inline;font-size:1.25em;height:1em;line-height:1em;margin-right:.5em;padding:0}.taxonomy-terms-cloud{width:100%;clear:both;font-size:.8rem}.taxonomy-terms-cloud .taxonomy-title{display:inline-block;width:100%;font-size:1rem;font-weight:700;color:var(--bs-primary-text-emphasis);border-bottom:1px solid var(--bs-tertiary-color);margin-bottom:1em;padding-bottom:.375rem;margin-top:1em}.taxonomy-terms-page{max-width:800px;margin:auto}.taxonomy-terms-page h1,.taxonomy-terms-page .h1{margin-bottom:1em}.taxonomy-terms-page .taxonomy-terms-cloud{font-size:1em}.taxonomy-terms-page .taxonomy-terms-cloud li{display:block}.taxonomy-terms-page .taxo-text-tags li+li::before{content:none}.taxonomy-terms-page .taxo-fruits .taxonomy-count,.taxonomy-terms-page .taxo-fruits .taxonomy-label{display:inherit;font-size:1rem;margin:0;padding:0;padding-right:.5em}.taxonomy-terms-page .taxo-fruits .taxonomy-count::before{content:"("}.taxonomy-terms-page .taxo-fruits .taxonomy-count::after{content:")"}.taxonomy-terms{list-style:none;margin:0;overflow:hidden;padding:0;display:inline}.taxonomy-terms li{display:inline;overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;hyphens:auto}.taxonomy-count{font-size:.8em;line-height:1.25em;display:inline-block;padding-left:.6em;padding-right:.6em;margin-left:.6em;text-align:center;border-radius:1em;background-color:var(--bs-body-bg)}.taxonomy-term{background:var(--bs-secondary-bg);border-width:0;border-radius:0 3px 3px 0;color:var(--bs-body-color);display:inline-block;font-size:1em;line-height:1.5em;min-height:1.5em;max-width:100%;padding:0 .5em 0 1em;position:relative;margin:0 .5em .2em 0;text-decoration:none;-webkit-transition:color .2s;clip-path:polygon(100% 0,100% 100%,.8em 100%,0 50%,.8em 0)}.taxonomy-term:hover{background-color:var(--bs-primary-bg-subtle);color:var(--bs-body-color-dark)}.taxonomy-term:hover .taxonomy-count{color:var(--bs-body-color-dark)}.taxonomy-term:hover::before{background:#30638e}.taxo-text-tags .taxonomy-term{background:0 0;border-width:0;border-radius:0;color:#6c757d;font-size:1em;line-height:1.5em;min-height:1.5em;max-width:100%;padding:0;position:relative;margin:0;text-decoration:none;clip-path:none}.taxo-text-tags .taxonomy-term:hover{background:0 0;color:#0d6efd}.taxo-text-tags .taxonomy-term:hover .taxonomy-count{color:#403f4c!important}.taxo-text-tags .taxonomy-term:hover::before{background:0 0}.taxo-text-tags li+li::before{content:"|";color:#6c757d;margin-right:.2em}.taxo-text-tags .taxonomy-count{font-size:1em;line-height:1.25em;display:inline-block;padding:0;margin:0;text-align:center;border-radius:0;background:0 0;vertical-align:super;font-size:.75em}.taxo-text-tags .taxonomy-term:hover .taxonomy-count{color:#0d6efd!important}.taxo-fruits .taxonomy-term[data-taxonomy-term]::before{font-style:normal;font-variant:normal;text-rendering:auto;-webkit-font-smoothing:antialiased;font-family:"font awesome 6 free";padding-right:.5em;font-size:2em;min-width:1.5em;display:inline-block}.taxo-fruits .taxonomy-term[data-taxonomy-term=apple]::before{content:"\f5d1";color:red}.taxo-fruits .taxonomy-term[data-taxonomy-term=carrot]::before{content:"\f787";color:orange}.taxo-fruits .taxonomy-term[data-taxonomy-term=lemon]::before{content:"\f094";color:#32cd32}.taxo-fruits .taxonomy-term[data-taxonomy-term=pepper]::before{content:"\f816";color:darkred}.taxo-fruits .taxonomy-term{background:0 0;border-width:0;border-radius:0;color:#6c757d;font-size:1em;line-height:2.5em;max-width:100%;padding:0;position:relative;margin:0;text-decoration:none;clip-path:none}.taxo-fruits .taxonomy-term:hover{background:0 0;color:#0d6efd}.taxo-fruits .taxonomy-term:hover .taxonomy-count{color:#403f4c!important}.taxo-fruits .taxonomy-term:hover::before{background:0 0;text-shadow:0 0 3px #212529}.taxo-fruits .taxonomy-count,.taxo-fruits .taxonomy-label{display:none}.taxo-fruits.taxonomy-terms-article{margin-bottom:1rem}.taxo-fruits.taxonomy-terms-article .taxonomy-title{display:none}.taxonomy-taxonomy-page{max-width:800px;margin:auto}.taxonomy-taxonomy-page h1,.taxonomy-taxonomy-page .h1{margin-bottom:1em}.article-meta{margin-bottom:1.5rem}.article-teaser.article-type-docs h3 a:before,.article-teaser.article-type-docs .h3 a:before,.article-teaser.article-type-docs .td-footer__links-item a:before{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;-webkit-font-smoothing:antialiased;font-family:"font awesome 6 free";content:"\f02d";padding-right:.5em}.article-teaser.article-type-blog h3 a:before,.article-teaser.article-type-blog .h3 a:before,.article-teaser.article-type-blog .td-footer__links-item a:before{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;-webkit-font-smoothing:antialiased;font-family:"font awesome 6 free";content:"\f781";padding-right:.5em}.all-taxonomy-terms{font-weight:500;line-height:1.2;font-size:1.5rem}.all-taxonomy-terms:before{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;-webkit-font-smoothing:antialiased;font-family:"font awesome 6 free";content:"\f122";padding-right:.5em}.article-teaser.card{padding:1em;margin-bottom:1.5em}.article-teaser .breadcrumb{margin-bottom:0;font-size:.85rem}.article-teaser .article-meta{margin-bottom:0}div.drawio{display:inline-block;position:relative}div.drawio button{position:absolute;bottom:5px;right:5px;padding:.4em .5em;font-size:.8em;display:none}div.drawio:hover button{display:inline}div.drawioframe{position:fixed;height:100%;width:100%;top:0;left:0;z-index:1000;background:#000b;border:0}div.drawioframe iframe{position:absolute;height:90%;width:90%;top:5%;left:5%;z-index:1010}.tab-content .tab-pane{margin-top:0;margin-bottom:1.5rem;border-left:var(--bs-border-width)solid var(--bs-border-color);border-right:var(--bs-border-width)solid var(--bs-border-color);border-bottom:var(--bs-border-width)solid var(--bs-border-color)}.tab-content .tab-pane .highlight{margin:0;border:none;max-width:100%}.tab-body{font-weight:500;background:var(--td-pre-bg);color:var(--bs-body-color);border-radius:0;padding:1.5rem}.tab-body>:last-child{margin-bottom:0}.tab-body>.highlight:only-child{margin:-1.5rem;max-width:calc(100% + 3rem)}.tab-body-primary{border-style:solid;border-color:#30638e}.tab-body-secondary{border-style:solid;border-color:#ffa630}.tab-body-success{border-style:solid;border-color:#3772ff}.tab-body-info{border-style:solid;border-color:#c0e0de}.tab-body-warning{border-style:solid;border-color:#ed6a5a}.tab-body-danger{border-style:solid;border-color:#ed6a5a}.tab-body-light{border-style:solid;border-color:#d3f3ee}.tab-body-dark{border-style:solid;border-color:#403f4c}.td-card.card .highlight{border:none;margin:0}.td-card .card-header.code{background-color:var(--bs-body-bg)}.td-card .card-body.code{background-color:var(--bs-body-bg);padding:0 0 0 1ex}.td-card .card-body pre{margin:0;padding:0 1rem 1rem}.swagger-ui .info .title small pre,.swagger-ui .info .title .small pre,.swagger-ui .info .title .td-footer__center pre,.swagger-ui .info .title .td-cover-block>.byline pre{background:#7d8492}.td-footer{min-height:150px;padding-top:3rem}@media(max-width:991.98px){.td-footer{min-height:200px}}.td-footer__center{text-align:center}.td-footer__right{text-align:right}.td-footer__about{font-size:initial}.td-footer__links-list{margin-bottom:0}.td-footer__links-item a{color:inherit!important}.td-footer__authors,.td-footer__all_rights_reserved{padding-left:.25rem}.td-footer__all_rights_reserved{display:none}@media(min-width:768px){.td-offset-anchor:target{display:block;position:relative;top:-4rem;visibility:hidden}h2[id]:before,[id].h2:before,h3[id]:before,[id].h3:before,[id].td-footer__links-item:before,h4[id]:before,[id].h4:before,h5[id]:before,[id].h5:before{display:block;content:" ";margin-top:-5rem;height:5rem;visibility:hidden}} \ No newline at end of file diff --git a/search/index.html b/search/index.html new file mode 100644 index 000000000..e33a72978 --- /dev/null +++ b/search/index.html @@ -0,0 +1,4 @@ +Search Results | Protocol Buffers Documentation +

Search Results

\ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 000000000..ba9eb0e12 --- /dev/null +++ b/sitemap.xml @@ -0,0 +1 @@ +https://protobuf.dev/https://protobuf.dev/overview/https://protobuf.dev/installation/https://protobuf.dev/news/https://protobuf.dev/programming-guides/https://protobuf.dev/programming-guides/editions/https://protobuf.dev/programming-guides/proto2/https://protobuf.dev/programming-guides/proto3/https://protobuf.dev/editions/https://protobuf.dev/editions/overview/https://protobuf.dev/editions/features/https://protobuf.dev/editions/implementation/https://protobuf.dev/programming-guides/proto-limits/https://protobuf.dev/programming-guides/style/https://protobuf.dev/programming-guides/enum/https://protobuf.dev/programming-guides/encoding/https://protobuf.dev/programming-guides/json/https://protobuf.dev/programming-guides/techniques/https://protobuf.dev/programming-guides/addons/https://protobuf.dev/programming-guides/extension_declarations/https://protobuf.dev/programming-guides/field_presence/https://protobuf.dev/programming-guides/symbol_visibility/https://protobuf.dev/design-decisions/https://protobuf.dev/programming-guides/serialization-not-canonical/https://protobuf.dev/programming-guides/deserialize-debug/https://protobuf.dev/design-decisions/nullable-getters-setters/https://protobuf.dev/best-practices/no-cargo-cults/https://protobuf.dev/best-practices/https://protobuf.dev/best-practices/dos-donts/https://protobuf.dev/best-practices/1-1-1/https://protobuf.dev/getting-started/https://protobuf.dev/getting-started/cpptutorial/https://protobuf.dev/getting-started/csharptutorial/https://protobuf.dev/getting-started/darttutorial/https://protobuf.dev/getting-started/gotutorial/https://protobuf.dev/getting-started/javatutorial/https://protobuf.dev/getting-started/kotlintutorial/https://protobuf.dev/getting-started/pythontutorial/https://protobuf.dev/reference/https://protobuf.dev/reference/cpp/https://protobuf.dev/reference/cpp/cpp-generated/https://protobuf.dev/reference/cpp/string-view/https://protobuf.dev/reference/cpp/arenas/https://protobuf.dev/reference/cpp/abseil/https://protobuf.dev/reference/cpp/api-docs-link/https://protobuf.dev/reference/csharp/https://protobuf.dev/reference/csharp/csharp-generated/https://protobuf.dev/reference/csharp/api-docs-link/https://protobuf.dev/reference/dart/https://protobuf.dev/reference/dart/dart-generated/https://protobuf.dev/reference/dart/api-docs-link/https://protobuf.dev/reference/go/https://protobuf.dev/reference/go/go-generated/https://protobuf.dev/reference/go/go-generated-opaque/https://protobuf.dev/reference/go/faq/https://protobuf.dev/reference/go/size/https://protobuf.dev/reference/go/api-docs-link/https://protobuf.dev/reference/java/https://protobuf.dev/reference/java/java-generated/https://protobuf.dev/reference/go/opaque-migration/https://protobuf.dev/reference/java/java-proto-names/https://protobuf.dev/reference/java/api-docs-link/https://protobuf.dev/reference/go/opaque-migration-manual/https://protobuf.dev/reference/kotlin/https://protobuf.dev/reference/kotlin/api-docs/https://protobuf.dev/reference/go/opaque-faq/https://protobuf.dev/reference/kotlin/kotlin-generated/https://protobuf.dev/reference/objective-c/https://protobuf.dev/reference/objective-c/objective-c-generated/https://protobuf.dev/reference/php/https://protobuf.dev/reference/php/php-generated/https://protobuf.dev/reference/php/api-docs-link/https://protobuf.dev/reference/python/https://protobuf.dev/reference/python/python-generated/https://protobuf.dev/reference/python/python-comparison/https://protobuf.dev/reference/python/api-docs-link/https://protobuf.dev/reference/ruby/https://protobuf.dev/reference/ruby/ruby-generated/https://protobuf.dev/reference/rust/https://protobuf.dev/reference/rust/rust-generated/https://protobuf.dev/reference/rust/rust-redaction/https://protobuf.dev/reference/rust/building-rust-protos/https://protobuf.dev/reference/rust/rust-design-decisions/https://protobuf.dev/reference/protobuf/https://protobuf.dev/reference/protobuf/edition-2023-spec/https://protobuf.dev/reference/protobuf/proto2-spec/https://protobuf.dev/reference/protobuf/edition-2024-spec/https://protobuf.dev/reference/protobuf/proto3-spec/https://protobuf.dev/reference/protobuf/textformat-spec/https://protobuf.dev/reference/protobuf/mime-types/https://protobuf.dev/reference/protobuf/google.protobuf/https://protobuf.dev/reference/other/https://protobuf.dev/support/https://protobuf.dev/support/version-support/https://protobuf.dev/support/debugging-playbook/https://protobuf.dev/support/migration/https://protobuf.dev/support/cross-version-runtime-guarantee/https://protobuf.dev/downloads/https://protobuf.dev/history/https://protobuf.dev/forum-link/https://protobuf.dev/navbar/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/-dsl-list/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/equals/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/hash-code/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/iterator/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/list-iterator/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-list/to-string/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/-dsl-map/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/entries/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/equals/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/hash-code/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/keys/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/to-string/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-map/values/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-dsl-proxy/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/-extension-list/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/equals/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/extension/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/hash-code/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/iterator/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/list-iterator/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-extension-list/to-string/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/-only-for-use-by-generated-proto-code/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-only-for-use-by-generated-proto-code/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/-proto-dsl-marker/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/-proto-dsl-marker/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/contains/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/get/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/is-a/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/plus/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/set/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string-utf8/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/to-byte-string/https://protobuf.dev/reference/kotlin/api-docs/protobuf-kotlin/com.google.protobuf.kotlin/unpack/https://protobuf.dev/news/2023-04-11/https://protobuf.dev/news/2023-04-20/https://protobuf.dev/news/2023-04-28/https://protobuf.dev/news/2023-08-15/https://protobuf.dev/news/2022-08-03/https://protobuf.dev/news/2023-08-09/https://protobuf.dev/reference/cpp/api-docs/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.arena/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.common/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.code_generator/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.command_line_interface/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.cpp_generator/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.csharp_generator/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.csharp_names/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.importer/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.java_generator/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.java_names/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.javanano_generator/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.js_generator/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.objectivec_generator/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.objectivec_helpers/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.parser/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.plugin/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.plugin.pb/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.python_generator/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.compiler.ruby_generator/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.descriptor/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.descriptor.pb/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.descriptor_database/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.dynamic_message/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.coded_stream/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.gzip_stream/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.printer/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.tokenizer/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.io.zero_copy_stream_impl_lite/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.map/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.message/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.message_lite/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.repeated_field/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.service/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.text_format/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.unknown_field_set/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.field_comparator/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.field_mask_util/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.json_util/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.message_differencer/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.time_util/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.type_resolver/https://protobuf.dev/reference/cpp/api-docs/google.protobuf.util.type_resolver_util/https://protobuf.dev/categories/https://protobuf.dev/news/2023-12-13/https://protobuf.dev/news/2024-12-13/https://protobuf.dev/news/2024-12-18/https://protobuf.dev/news/2023-12-27/https://protobuf.dev/news/2024-12-04/https://protobuf.dev/news/2023-12-05/https://protobuf.dev/news/2024-02-27/https://protobuf.dev/news/2024-02-05/https://protobuf.dev/news/2026-01-16/https://protobuf.dev/news/2025-01-23/https://protobuf.dev/news/2024-01-31/https://protobuf.dev/news/2024-01-05/https://protobuf.dev/news/2025-07-14/https://protobuf.dev/news/2025-07-16/https://protobuf.dev/news/2023-07-17/https://protobuf.dev/news/2022-07-06/https://protobuf.dev/news/2023-07-06/https://protobuf.dev/news/2024-06-26/https://protobuf.dev/news/2025-06-27/https://protobuf.dev/news/2023-06-29/https://protobuf.dev/news/2026-03-13/https://protobuf.dev/news/2025-03-18/https://protobuf.dev/news/2022-05-06/https://protobuf.dev/news/2024-11-07/https://protobuf.dev/news/2024-10-01/https://protobuf.dev/news/2023-10-10/https://protobuf.dev/news/2024-10-02/https://protobuf.dev/search/https://protobuf.dev/news/2023-09-15/https://protobuf.dev/news/2025-09-19/https://protobuf.dev/tags/https://protobuf.dev/news/v21/https://protobuf.dev/news/v22/https://protobuf.dev/news/v23/https://protobuf.dev/news/v24/https://protobuf.dev/news/v25/https://protobuf.dev/news/v26/https://protobuf.dev/news/v29/https://protobuf.dev/news/v30/https://protobuf.dev/news/v31/https://protobuf.dev/news/v32/https://protobuf.dev/news/v34/ \ No newline at end of file diff --git a/support/cross-version-runtime-guarantee/index.html b/support/cross-version-runtime-guarantee/index.html new file mode 100644 index 000000000..d55061473 --- /dev/null +++ b/support/cross-version-runtime-guarantee/index.html @@ -0,0 +1,58 @@ +Cross-Version Runtime Guarantee | Protocol Buffers Documentation +

Cross-Version Runtime Guarantee

The guarantees that the language has for cross-version runtime compatibility.

Protobuf language bindings have two components. The generated code (gencode) and +the runtime libraries that implement common functionality for that generated +code. When these come from different releases of protobuf, we are in a “cross +version runtime” situation.

We intend to offer the following guarantees across most languages. These are the +default guarantees; however, owners of protobuf code generators and runtimes may +explicitly override them with more specific guarantees for that language. +C++ and Rust have stricter guarantees than typical, and +Python has looser ones.

Protobuf cross-version usages outside the guarantees are error-prone and not +supported. Version skews can lead to flakes and undefined behaviors that are +hard to diagnose, even if it can often seem to work as long as nothing has +changed in a source-incompatible way. For Protobuf, the proliferation of tools +and services that rely on using unsupported Protobuf language bindings prevents +the protobuf team from updating the protobuf implementation in response to bug +reports or security vulnerabilities.

New Gencode + Old Runtime = Never Allowed

We may add new runtime APIs in any kind of release (Major, Minor, or Patch). +Gencode in that release is allowed to use those new APIs. The consequence is +that gencode should never be paired with a runtime that predates the protoc +and plugin that was used to generate those bindings.

We will add “poison pills” where possible to prevent attempts to pair newer +gencode with an older runtime.

Major Versions

Protobuf implements sliding window compatibility for major versions. Code +generated for a major version V (full version: V.x.y) will be supported by +protobuf runtimes of major version V and V+1.

Protobuf will not support using gencode from version V with runtime >= +V+2 and will be using a “poison pill” mechanism to fail with a clear error +message when a software assembly attempts to use such a configuration.

For Example:

  • Java code generated by protobuf version 3.0.0 will work with runtimes 3.0.0 +to 4.x.y but not with runtimes 2.0.0 to 2.x.y or runtimes >= 5.0.0.
  • Java code generated by protobuf version 4.27.2 will work with runtimes +4.27.2 to 5.x.y but not runtimes 2.0.0 to 4.27.1 or runtimes >= 6.0.0

Exceptions may be made in case where compatibility with older gencode cannot +be maintained, such as in the case of security fixes requiring +updated gencode.

Note: Poison pills were introduced in the protobuf 26.0 release. Java +gencode older than 4.26.0 may appear to work with runtimes that are older than +the gencode. However, the combination of +newer gencode and older runtime may have serious bugs that do not +manifest until runtime.

Note: C++ and Rust do not support compatibility windows, and +Python supports much longer ones.

Minor Versions

Within a single major runtime version, generated code from an older version of +protoc will run on a newer runtime.

Note: C++ and Rust do not support compatibility across minor +versions.

Security Exception

We reserve the right to violate the above promises if needed for security +reasons. We expect these exceptions to be rare, but will always prioritize +security above these guarantees. For example, +the footmitten CVE required paired updates +to both the runtime and the generated code for Java. As a result, code generated +by 3.20.3 (which contained the footmitten fix) would not load with runtime +library 3.21.6 (which predates the footmitten fix), creating the following +compatibility matrix:

Generated Code Version
3.20.23.20.33.21.63.21.7
Runtime
Version
3.20.2Vuln!Broken!!Vuln!!Broken!
3.20.3VulnWorks!Vuln!!Works?!
3.21.6VulnBrokenVuln!Broken!
3.21.7VulnWorksVulnWorks
  • “Vuln” indicates that the combination will successfully start, but the +security vulnerability still exists.
  • “Works” indicates that the combination will successfully start and does not +have the vulnerability.
  • “Broken” indicates that the combination will not successfully start.
  • !Bold! indicates configurations that mix newer gencode with older +runtime and were never intended to work together.

No Coexistence of Multiple Major Runtime Versions

Coexistence of multiple major versions in the same process is not supported.

C++ and Rust-specific Guarantees

Protobuf C++ and Rust disclaim all cross-runtime support and require an exact +match between the generated code version and the runtime version at all times.

Additionally, Protobuf C++ makes no guarantees about ABI stability across any +releases (major, minor, or micro).

Python-specific Guarantees

Since the 3.20.0 release, the Protobuf Python generated code became a thin +wrapper around an embedded FileDescriptorProto. Because these protos are +supported on extremely long timeframes, our usual +major version compatibility windows aren’t typically necessary.

Python may break generated code compatibility in specific future major version +releases, but it will be coupled with poison pill warnings and errors in +advance. As of 6.32.0, all generated code since 3.20.0 will be supported until +at least 8.x.y.

\ No newline at end of file diff --git a/support/debugging-playbook/index.html b/support/debugging-playbook/index.html new file mode 100644 index 000000000..ec2dfae3c --- /dev/null +++ b/support/debugging-playbook/index.html @@ -0,0 +1,22 @@ +Debugging | Protocol Buffers Documentation +

Debugging

Debugging common issues in Protocol Buffers.

Frequently asked questions and debugging scenarios encountered by protobuf +users.

Bazel: Resolving Issues with Prebuilt Protoc

As mentioned in this news article, +Bazel 7 and later support builds that use a prebuilt protoc. When everything is +configured correctly, this can save a lot of time building, reduce logging +volume, and eliminate the need for C++ toolchain in non-C++ implementations.

To prevent protoc compilation from source, add the following to your .bazelrc +file:

common --per_file_copt=external/.*protobuf.*@--PROTOBUF_WAS_NOT_SUPPOSED_TO_BE_BUILT
+common --host_per_file_copt=external/.*protobuf.*@--PROTOBUF_WAS_NOT_SUPPOSED_TO_BE_BUILT
+common --per_file_copt=external/.*grpc.*@--GRPC_WAS_NOT_SUPPOSED_TO_BE_BUILT
+common --host_per_file_copt=external/.*grpc.*@--GRPC_WAS_NOT_SUPPOSED_TO_BE_BUILT
+

When there are hard-coded references to @com_google_protobuf//:protoc that are +reachable by the dependency graph, protoc will force it to be built for those +cases, negating this benefit. To resolve this, you’ll need to find where the +dependencies are and request that those rulesets be updated.

To find where you depend on protoc, use the following command:

bazel cquery 'somepath("//...", "@com_google_protobuf//:all")'
+

Note: Prebuilts are only available for our standard set of platforms. Anyone +on a nonstandard platform will have to build protoc from source.

\ No newline at end of file diff --git a/support/index.html b/support/index.html new file mode 100644 index 000000000..a0715a46b --- /dev/null +++ b/support/index.html @@ -0,0 +1,11 @@ +Support | Protocol Buffers Documentation +

Support

Resources to support using Protocol Buffers.

This section of the documentation contains topics related to the support that +the Protocol Buffers team provides to developers, including the timeframes for +support for each version of a language library and migration guides to help you +keep up with major version bumps.


Version Support

A list of the support windows provided for language implementations.

Debugging

Debugging common issues in Protocol Buffers.

Migration Guide

A list of the breaking changes made to versions of the libraries, and how to update your code to accommodate the changes.

Cross-Version Runtime Guarantee

The guarantees that the language has for cross-version runtime compatibility.

\ No newline at end of file diff --git a/support/index.xml b/support/index.xml new file mode 100644 index 000000000..10032a87c --- /dev/null +++ b/support/index.xml @@ -0,0 +1,7 @@ +Support on Protocol Buffers Documentationhttps://protobuf.dev/support/Recent content in Support on Protocol Buffers DocumentationHugoenVersion Supporthttps://protobuf.dev/support/version-support/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/support/version-support/Currently Supported Release Versions Language Active Support Maintenance Only Minimum Gencode protoc 34.x 29.x, 25.x (for Java) C++ 7.34.x 5.29.x Exact Match C# 3.34.x 3.0.0 Java 4.34.x 3.25.x 3.0.0 PHP 5.34.x 4.0.0 Python 7.34.x 5.29.x 3.20.0 Ruby 4.34.x 3.0.0 Minimum Supported Gencode While each language runtime has a minimum supported gencode version, we recommend regenerating your gencode with every release update. Support for older generated code exists solely to ensure backwards compatibility for existing projects, not for new adoption of older gencode versions.Debugginghttps://protobuf.dev/support/debugging-playbook/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/support/debugging-playbook/Frequently asked questions and debugging scenarios encountered by protobuf users. +Bazel: Resolving Issues with Prebuilt Protoc As mentioned in this news article, Bazel 7 and later support builds that use a prebuilt protoc. When everything is configured correctly, this can save a lot of time building, reduce logging volume, and eliminate the need for C++ toolchain in non-C++ implementations. +To prevent protoc compilation from source, add the following to your .Migration Guidehttps://protobuf.dev/support/migration/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/support/migration/Changes in v34.0 The following is a list of the breaking changes made to versions of the libraries, and how to update your code to accommodate the changes. +This covers breaking changes announced in News Announcements for v34.x and Release Notes for v34.0. +Changes in C++ C++ bumped its major version to 7 with the 7.34.0 release. 6.33 is the final minor version release on 6.x. +Removal of Future Macros The following macros, introduced for staged roll-out of breaking changes, were removed and their behavior is now the default:Cross-Version Runtime Guaranteehttps://protobuf.dev/support/cross-version-runtime-guarantee/Mon, 01 Jan 0001 00:00:00 +0000https://protobuf.dev/support/cross-version-runtime-guarantee/Protobuf language bindings have two components. The generated code (gencode) and the runtime libraries that implement common functionality for that generated code. When these come from different releases of protobuf, we are in a &ldquo;cross version runtime&rdquo; situation. +We intend to offer the following guarantees across most languages. These are the default guarantees; however, owners of protobuf code generators and runtimes may explicitly override them with more specific guarantees for that language. \ No newline at end of file diff --git a/support/migration/index.html b/support/migration/index.html new file mode 100644 index 000000000..0ca8d7fa5 --- /dev/null +++ b/support/migration/index.html @@ -0,0 +1,346 @@ +Migration Guide | Protocol Buffers Documentation +

Migration Guide

A list of the breaking changes made to versions of the libraries, and how to update your code to accommodate the changes.

Changes in v34.0

The following is a list of the breaking changes made to versions of the +libraries, and how to update your code to accommodate the changes.

This covers breaking changes announced in +News Announcements for v34.x and +Release Notes for v34.0.

Changes in C++

C++ bumped its major version to 7 with the 7.34.0 release. 6.33 is the final +minor version release on 6.x.

Removal of Future Macros

The following macros, introduced for staged roll-out of breaking changes, were +removed and their behavior is now the default:

  • PROTOBUF_FUTURE_RENAME_ADD_UNUSED_IMPORT
  • PROTOBUF_FUTURE_REMOVE_ADD_IGNORE_CRITERIA
  • PROTOBUF_FUTURE_STRING_VIEW_DESCRIPTOR_DATABASE
  • PROTOBUF_FUTURE_NO_RECURSIVE_MESSAGE_COPY
  • PROTOBUF_FUTURE_REMOVE_REPEATED_PTR_FIELD_ARENA_CONSTRUCTOR
  • PROTOBUF_FUTURE_REMOVE_MAP_FIELD_ARENA_CONSTRUCTOR
  • PROTOBUF_FUTURE_REMOVE_REPEATED_FIELD_ARENA_CONSTRUCTOR

New RepeatedPtrField Layout

RepeatedPtrField were transitioned to a new internal element layout in which +elements are stored in contiguous chunks of preallocated memory, similar to +std::deque. This results in some changes to copy/move semantics of some APIs, +and some UnsafeArena APIs may become functional equivalents of their +arena-safe counterparts and be deprecated.

MSB Hardening Check on RepeatedField::Get and RepeatedPtrField::Get

Protobufs were hardened against OOB errors by adding comprehensive bounds +checking to repeated field accesses.

Remove Arena-enabled constructors from Repeated/Map Fields

The RepeatedField(Arena*), RepeatedPtrField(Arena*), and Map(Arena*) +constructors were deleted.

Remove Deprecated APIs

We removed the following public runtime APIs.

AddUnusedImportTrackFile() and ClearUnusedImportTrackFiles()

API: AddUnusedImportTrackFile(), ClearUnusedImportTrackFiles()

Replacement: AddDirectInputFile() and ClearDirectInputFiles()

AddIgnoreCriteria from message differencer

PROTOBUF_FUTURE_REMOVE_ADD_IGNORE_CRITERIA was added for the breaking change. +We removed the macro.

API: AddIgnoreCriteria()

Replacement: Wrap the raw pointer in a unique_ptr.

FieldDescriptor::has_optional_keyword()

API: FieldDescriptor::has_optional_keyword()

Replacement: has_presence()

FieldDescriptor::label()

API: FieldDescriptor::label()

Replacement: is_repeated() or is_required()

FieldDescriptor::is_optional()

API: FieldDescriptor::is_optional()

Replacement: !is_required() && !is_repeated()

UseDeprecatedLegacyJsonFieldConflicts()

API: UseDeprecatedLegacyJsonFieldConflicts()

Replacement: No replacement.

Stricter Name Length Limits

The protobuf compiler enforces stricter limits on the length of symbol names, +such as field names, to prevent potential issues. If the length of any field +name is > 2^16, it generates an error.

Hide Private Generator Headers in CMake

The protoc generator headers are no longer installed by CMake. This should not +affect most users.

[[nodiscard]] on Logically Constant Operations

[[nodiscard]] was added to several logically constant protobuf APIs where +failure to consume the returned value indicates a probable bug. This follows +patterns used commonly in the C++ standard library.

Changes in Python

Python bumped its major version to 7 with the 7.34.0 release. 6.33 is the final +minor version release on 6.x.

Dropped Python 3.9 Support

The minimum supported Python version is 3.10. Users should upgrade.

Relax Poison Pill Warnings

We relaxed the poison pills. No warnings or errors are raised for old generated +files for 7.34.x.

Raise TypeError on Incorrect Conversion to Timestamp or Duration

We now raise a TypeError instead of an AttributeError when converting an +incorrect type to a Timestamp or Duration.

Reject bool to enum and int field

We now reject setting enum or int fields with boolean values. The API raises +an error instead of implicitly converting them.

Remove float_precision from json_format

We removed the deprecated float_precision option from the json_format +serializer. This option does not exist in other ProtoJSON serializers and has +confusing semantics.

Remove float_format/double_format from text_format

We removed the deprecated float_format and double_format options from +text_format. These options are not available in other proto text format +serializers.

Removed Deprecated APIs

We removed the following public runtime APIs.

FieldDescriptor.label

API: FieldDescriptor.label

Replacement: is_repeated() or is_required()

Changes in PHP

PHP bumped its major version to 5 with the 5.34.0 release. 4.33 is the final +minor version release on 4.x.

Dropped PHP 8.1 Support

The minimum supported PHP version is 8.2. Users should upgrade.

Removed Deprecated APIs

We removed the following public runtime APIs.

FieldDescriptor getLabel

API: FieldDescriptor getLabel

Replacement: isRepeated() or isRequired()

Google\Protobuf\Field_Kind

API: Google\Protobuf\Field_Kind

Replacement: Google\Protobuf\Field\Kind

Google\Protobuf\Field_Cardinality

API: Google\Protobuf\Field_Cardinality

Replacement: Google\Protobuf\Field\Cardinality

Google\Protobuf\Internal\RepeatedField

API: Google\Protobuf\Internal\RepeatedField

Replacement: Google\Protobuf\RepeatedField

Fix Silent Ignoring of Default Values

The PHP runtime is fixed to honor default values on scalar fields in proto2 and +editions, instead of silently ignoring them.

Type Checking Alignment

Type checking for pure-PHP and upb-PHP implementations are aligned. Notably, +pure-PHP now rejects null for string fields, matching the behavior of upb-PHP.

Changes in Objective-C

Objective-C bumped its major version to 5 with the 5.34.0 release. 4.33 is the +final minor version release on 4.x.

Nullability Annotations

The nullability annotations for some GPB*Dictionary APIs were corrected to +mark when APIs could return nil. This results in Swift code getting a Swift +Optional<T>. For Objective-C callers, the annotation correction is less likely +to have any impact on the source code.

Removed Deprecated API

We removed the following public runtime APIs.

GPBFieldDescriptor optional

API: -[GPBFieldDescriptor optional]

Replacement: !required && fieldType == GPBFieldTypeSingle

Other Changes

Dropped Bazel 7 Support

The minimum supported Bazel version is 8, which changes the default from +WORKSPACE to Bzlmod. Users should upgrade to Bazel 8 or higher and migrate to +Bzlmod.

Bazel: Remove deprecated ProtoInfo.transitive_imports

The deprecated transitive_imports field in ProtoInfo was removed. Users +should migrate to transitive_sources.

Remove protobuf_allow_msvc flag and continue support Bazel+MSVC

Due to Bazel’s recent improvements on Windows, we now continue to support +Bazel+MSVC. The --define=protobuf_allow_msvc flag was removed.

Changes in v30.0

The following is a list of the breaking changes made to versions of the +libraries, and how to update your code to accommodate the changes.

This covers breaking changes announced in +News Announcements for v30.x and +Release Notes for v30.0.

Changes in C++

Replaced CMake Submodules with Fetched Deps

Previously, our default CMake behavior was to use Git submodules to grab pinned +dependencies. Specifying -Dprotobuf_ABSL_PROVIDER=package would flip our CMake +configs to look for local installations of Abseil (with similar options for +jsoncpp and gtest). These options no longer exist, and the default behavior is +to first look for installations of all our dependencies, falling back to +fetching pinned versions from GitHub if needed.

To prevent any fallback fetching (similar to the old package behavior), you +can call CMake with:

cmake . -Dprotobuf_LOCAL_DEPENDENCIES_ONLY=ON
+

To always fetch dependencies from a fixed version (similar to the old default +behavior), you can call CMake with:

cmake . -Dprotobuf_FORCE_FETCH_DEPENDENCIES=ON
+

string_view return type

Return types are now absl::string_view for the following descriptor APIs, +which opens up memory savings:

  • MessageLite::GetTypeName
  • UnknownField::length_delimited
  • Descriptor API name functions, such as FieldDescriptor::full_name

We expect future breaking releases to continue migrating additional APIs to +absl::string_view.

In most cases, you should try to update types to use absl::string_view where +safe, or explicitly copy to the original type where needed. You may need to +update callers as well if this is returned in a function.

If the string returned by the affected API methods is being used as:

TypeMigration

std::string

Explicitly convert to std::string to preserve the existing behavior.

Or, switch to the more performant absl::string_view

const std::string&

Migrate to absl::string_view

If infeasible (such as due to large number of dependencies), copying to a std::string might be easier.

const std::string*

const char*

If nullable, migrate to std::optional<absl::string_view>.

Otherwise, migrate to absl::string_view.

Be careful when calling data() since absl::string_view isn't guaranteed to be null-terminated.

For common containers and other APIs, you may be able to migrate to variants +compatible with absl::string_view. Below are some common examples.

CategoryPre-MigrationMigration
Insertion into std::vector<std::string>

push_back()

push_front()

push()

emplace_back()

emplace_front()

emplace()

Insertion for map or 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...)

Lookup for map or sets

find()

count()

contains()

Migrate to Abseil containers.

Or, define a transparent comparator.

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

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

String Concatenation

operator+

operator+=

absl::StrCat()

absl::StrAppend()

These are recommended for performance reasons anyways. See https://abseil.io/tips/3.

See also https://abseil.io/tips/1 for general tips +around using absl::string_view.

Poison MSVC + Bazel

Bazel users on Windows should switch to using clang-cl by adding the following +to their project, like in this +example.

.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

For users that need compatibility with Bazel 8 only.

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

For users that need compatibility with Bazel 7 and 8.

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",
+    ],
+)
+

Users can also temporarily silence the error by setting the opt-out flag +--define=protobuf_allow_msvc=true until the next breaking release.

Alternatively, users that wish to continue using MSVC may switch to using CMake. +This can be done with +Visual Studio, +or by supplying the CMake command-line an MSVC generator. For example:

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

ctype Removed from FieldDescriptor Options

We stopped exposing the ctype from FieldDescriptor options. You can use the +FieldDescriptor::cpp_string_type() API, added in the +v28 release, +in its place.

Modified Debug APIs to Redact Sensitive Fields

The Protobuf C++ debug APIs (including Protobuf AbslStringify, +proto2::ShortFormat, proto2::Utf8Format, Message::DebugString, +Message::ShortDebugString, Message::Utf8DebugString) changed to redact +sensitive fields annotated by debug_redact; the outputs of these APIs contain +a per-process randomized prefix, and are no longer parseable by Protobuf +TextFormat Parsers. Users should adopt the new redacted debug format for most +cases requiring a human-readable output (such as logging), or consider switching +to binary format for serialization and deserialization. Users who need the old +deserializable format can use TextFormat.printer().printToString(proto), but +this does not redact sensitive fields and so should be used with caution.

Read more about this in the +news article released December 4, 2024.

Removed Deprecated APIs

We removed the following public runtime APIs, which have been marked deprecated +(such as ABSL_DEPRECATED) for at least one minor or major release and that are +obsolete or replaced.

API: +Arena::CreateMessage

Replacement: +Arena::Create

API: +Arena::GetArena

Replacement: value->GetArena()

API: +RepeatedPtrField::ClearedCount

Replacement: Migrate to Arenas +(migration guide).

API: +JsonOptions

Replacement: JsonPrintOptions

Dropped C++14 Support

This release dropped C++ 14 as the minimum supported version and raised it to +17, as per the +Foundational C++ Support matrix.

Users should upgrade to C++17.

Introduced ASAN Poisoning After Clearing Oneof Messages on Arena

This change added a hardening check that affects C++ protobufs using Arenas. +Oneof messages allocated on the protobuf arena are now cleared in debug and +poisoned in ASAN mode. After calling clear, future attempts to use the memory +region will cause a crash in ASAN as a use-after-free error.

This implementation requires C++17.

Dropped our C++ CocoaPods release

We dropped our C++ CocoaPods release, which has been broken since v4.x.x. C++ +users should use our +GitHub release directly +instead.

Changes in Python

Python bumped its major version from 5.29.x to 6.30.x.

Dropped Python 3.8 Support

The minimum supported Python version is 3.9. Users should upgrade.

Removed bazel/system_python.bzl Alias

We removed the legacy bazel/system_python.bzl alias.

Remove direct references to system_python.bzl in favor of using +protobuf_deps.bzl instead. Use python/dist/system_python.bzl where it was +moved +in v5.27.0 +if you need a direct reference.

Field Setter Validation Changes

Python’s and upb’s field setters now validate closed enums under edition 2023. +Closed enum fields updated with invalid values generate errors.

Removed Deprecated py_proto_library Macro

The deprecated internal py_proto_library Bazel macro in protobuf.bzl was +removed. It was replaced by the official py_proto_library which was moved to +protobuf in bazel/py_proto_library in v29.x. This implementation was +previously available in rules_python prior to v29.x.

Remove Deprecated APIs

We removed the following public runtime APIs, which had been marked deprecated +for at least one minor or major release.

Reflection Methods

APIs: +reflection.ParseMessage, +reflection.MakeClass

Replacement: message_factory.GetMessageClass()

RPC Service Interfaces

APIs: +service.RpcException, +service.Service, +service.RpcController, +and +service.RpcChannel

Replacement: Starting with version 2.3.0, RPC implementations should not try +to build on these, but should instead provide code generator plugins which +generate code specific to the particular RPC implementation.

MessageFactory and SymbolDatabase Methods

APIs: +MessageFactory.GetPrototype, +MessageFactory.CreatePrototype, +MessageFactory.GetMessages, +SymbolDatabase.GetPrototype, +SymbolDatabase.CreatePrototype, +and +SymbolDatabase.GetMessages

Replacement: message_factory.GetMessageClass() and +message_factory.GetMessageClassesForFiles().

GetDebugString

APIs: +GetDebugString

Replacement:

No replacement. It’s only in Python C++ which is no longer released. It is not +supported in pure Python or UPB.

Python setdefault Behavior Change for Map Fields

setdefault is similar to dict for ScalarMap, except that both key and +value must be set. setdefault is rejected for MessageMaps.

Python Nested Message Class __qualname__ Contains the Outer Message Name

Python nested message class __qualname__ now contains the outer message name. +Previously, __qualname__ had the same result with __name__ for nested +message, in that the outer message name was not included.

For example:

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
+

Changes in Objective-C

This is the first breaking release for Objective-C.

Objective-C bumped its major version from 3.x.x to 4.30.x.

Overhauled Unknown Field Handling APIs Deprecating Most of the Existing APIs

We deprecated GPBUnknownFieldSet and replaced it with GPBUnknownFields. The +new type preserves the ordering of unknown fields from the original input or API +calls, to ensure any semantic meaning to the ordering is maintained when a +message is written back out.

As part of this, the GPBUnknownField type also has APIs changes, with almost +all of the existing APIs deprecated and new ones added.

Deprecated property APIs:

  • varintList
  • fixed32List
  • fixed64List
  • lengthDelimitedList
  • groupList

Deprecated modification APIs:

  • addVarint:
  • addFixed32:
  • addFixed64:
  • addLengthDelimited:
  • addGroup:

Deprecated initializer initWithNumber:.

New property APIs:

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

This type models a single field number in its value, rather than grouping all +the values for a given field number. The APIs for creating new fields are the +add* APIs on the GPBUnknownFields class.

We also deprecated -[GPBMessage unknownFields]. In its place, there are new +APIs to extract and update the unknown fields of the message.

Removed Deprecated APIs

We removed the following public runtime APIs, which had been marked deprecated +for at least one minor or major release.

GPBFileDescriptor

API: +-[GPBFileDescriptor syntax]

Replacement: Obsolete.

GPBMessage mergeFrom:extensionRegistry

API: +-[GPBMessage mergeFrom:extensionRegistry:]

Replacement: +-[GPBMessage mergeFrom:extensionRegistry:error:]

GPBDuration timeIntervalSince1970

API: +-[GPBDuration timeIntervalSince1970]

Replacement: +-[GPBDuration timeInterval]

GPBTextFormatForUnknownFieldSet

API: +GPBTextFormatForUnknownFieldSet()

Replacement: Obsolete - Use +GPBTextFormatForMessage(), +which includes any unknown fields.

GPBUnknownFieldSet

API: +GPBUnknownFieldSet

Replacement: +GPBUnknownFields

GPBMessage unknownFields

API: +GPBMessage unknownFields property

Replacement: +-[GPBUnknownFields initFromMessage:], +-[GPBMessage mergeUnknownFields:extensionRegistry:error:], +and +-[GPBMessage clearUnknownFields]

Removed Deprecated Runtime APIs for Old Gencode

This release removed deprecated runtime methods that supported the Objective-C +gencode from before the 3.22.x release. The library also issues a log message at +runtime when old generated code is starting up.

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

Replacement: Regenerate with a current version of the library.

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

Replacement: Regenerate with a current version of the library.

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

Replacement: Regenerate with a current version of the library.

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

Replacement: Regenerate with a current version of the library.

API: +-[GPBExtensionDescriptor initWithExtensionDescription:]

Replacement: Regenerate with a current version of the library.

Other Changes

Poison Pill Warnings

We updated poison pills to emit warnings for old gencode + new runtime +combinations that work under the new rolling upgrade policy, but will break in +the next major bump. For example, Python 4.x.x gencode should work against +5.x.x runtime but warn of upcoming breakage against 6.x.x runtime.

Changes to UTF-8 Enforcement in C# and Ruby

We included a fix to make UTF-8 enforcement consistent across languages. Users +with bad non-UTF8 data in string fields may see surfaced UTF-8 enforcement +errors earlier.

Ruby and PHP Errors in JSON Parsing

We fixed non-conformance in JSON parsing of strings in numeric fields per the +JSON spec.

This fix is not accompanied by a major version bump, but Ruby and PHP now raise +errors for non-numeric strings (such as "", "12abc", "abc") in numeric +fields. v29.x includes a warning for these error cases.

Compiler Changes in v22.0

JSON Field Name Conflicts

Source of changes: PR #11349, PR #10750

We’ve made some subtle changes in how we handle field name conflicts with +respect to JSON mappings. In proto3, we’ve partially loosened the restrictions +and only give errors when field names produce case-sensitive JSON mappings +(camel case of the original name). We now also check the json_name option, and +give errors for case-sensitive conflicts. In proto2, we’ve tightened +restrictions a bit and will give errors if two json_name specifications +conflict. If implicit JSON mappings (camel case) have conflicts, we will give +warnings in proto2.

We’ve provided a temporary message/enum option for restoring the legacy +behavior. If renaming the conflicting fields isn’t an option you can take +immediately, set the deprecated_legacy_json_field_conflicts option on the +specific message/enum. This option will be removed in a future release, but +gives you more time to migrate.

C++ API Changes in v22.0

4.22.0 has breaking changes for C++ runtime and protoc, as +announced in August.

Autotools Turndown

Source of changes: +PR #10132

In v22.0, we removed all Autotools support from the protobuf compiler and the +C++ runtime. If you’re using Autotools to build either of these, you must +migrate to CMake or Bazel. We have +some +dedicated instructions +for setting up protobuf with CMake.

Abseil Dependency

Source of changes: +PR #10416

With v22.0, we’ve taken on an explicit dependency on +Abseil. This allowed us to remove most +of our +stubs, +which were branched from old internal code that later became Abseil. There are a +number of subtle behavior changes, but most should be transparent to users. Some +notable changes include:

  • string_view - absl::string_view has replaced const std::string& in +many of our APIs. This is most-commonly used for input arguments, where +there should be no noticeable change for users. In a few cases (such as +virtual method arguments or return types) users may need to make an explicit +change to use the new signature.

  • tables - Instead of STL sets/maps, we now use Abseil’s flat_hash_map, +flat_hash_set, btree_map, and btree_set. These are more efficient and +allow for heterogeneous lookup. This should be +mostly invisible to users, but may cause some subtle behavior changes +related to table ordering.

  • logging - Abseil’s +logging library is very similar +to our old logging code, with just a slightly different spelling (for +example, ABSL_CHECK instead of GOOGLE_CHECK). The biggest difference is +that it doesn’t support exceptions, and will now always crash when FATAL +assertions fail. (Previously we had a PROTOBUF_USE_EXCEPTIONS flag to +switch to exceptions.) Since these only occur when serious issues are +encountered, we feel unconditional crashing is a suitable response.

    Source of logging changes: PR #11623

  • Build dependency - A new build dependency can always cause breakages for +downstream users. We require +Abseil LTS 20230125 +or later to build.

    • For Bazel builds, Abseil will be automatically downloaded and built at a +pinned LTS release when +protobuf_deps +is run from your WORKSPACE. This should be transparent, but if you +depend on an older version of Abseil, you’ll need to upgrade your +dependency.

    • For CMake builds, we will first look for an existing Abseil installation +pulled in by the top-level CMake configuration (see +instructions). +Otherwise, if protobuf_ABSL_PROVIDER is set to module (its default) +we will attempt to build and link Abseil from our git +submodule. +If protobuf_ABSL_PROVIDER is set to package, we will look for a +pre-installed system version of Abseil.

Changes in GetCurrentTime Method

On Windows, GetCurrentTime() is the name of a macro provided by the system. +Prior to v22.x, Protobuf incorrectly removed the macro definition for +GetCurrentTime(). That made the macro unusable for Windows developers after +including <protobuf/util/time_util.h>. Starting with v22.x, Protobuf preserves +the macro definition. This may break customer code relying on the previous +behavior, such as if they use the expression +google::protobuf::util::TimeUtil::GetCurrentTime().

To migrate your app to the new behavior, change your code to do one of the +following:

  • if the GetCurrent macro is defined, explicitly undefine the +GetCurrentTime macro
  • prevent the macro expansion by using +(google::protobuf::util::TimeUtil::GetCurrentTime)() or a similar +expression

Example: Undefining the macro

Use this approach if you don’t use the macro from Windows.

Before:

#include <google/protobuf/util/time_util.h>
+
+void F() {
+  auto time = google::protobuf::util::TimeUtil::GetCurrentTime();
+}
+

After:

#include <google/protobuf/util/time_util.h>
+#ifdef GetCurrentTime
+#undef GetCurrentTime
+#endif
+
+void F() {
+  auto time = google::protobuf::util::TimeUtil::GetCurrentTime();
+}
+

Example 2: Preventing macro expansion

Before:

#include <google/protobuf/util/time_util.h>
+
+void F() {
+  auto time = google::protobuf::util::TimeUtil::GetCurrentTime();
+}
+

After:

#include <google/protobuf/util/time_util.h>
+
+void F() {
+  auto time = (google::protobuf::util::TimeUtil::GetCurrentTime)();
+}
+

C++20 Support

Source of changes: PR #10796

To support C++20, we’ve reserved the new +keywords in C++ generated protobuf +code. As with other reserved keywords, if you use them for any fields, enums, or +messages, we will add an underscore suffix to make them valid C++. For example, +a concept field will generate a concept_() getter. In the scenario where you +have existing protos that use these keywords, you’ll need to update the C++ code +that references them to add the appropriate underscores.

Final Classes

Source of changes: PR #11604

As part of a larger effort to harden assumptions made in the Protobuf library, +we’ve marked some classes final that were never intended to be inherited from. +There are no known use cases for inheriting from these, and doing so would +likely cause problems. There is no mitigation if your code is inheriting from +these classes, but if you think you have some valid reason for the inheritance +you’re using, you can +open an issue.

Container Static Assertions

Source of changes: PR #11550

As part of a larger effort to harden assumptions made in the Protobuf library, +we’ve added static assertions to the Map, RepeatedField, and +RepeatedPtrField containers. These ensure that you’re using these containers +with only expected types, as +covered in our documentation. +If you hit these static assertions, you should migrate your code to use Abseil +or STL containers. std::vector is a good drop-in replacement for repeated +field containers, and std::unordered_map or absl::flat_hash_map for Map +(the former gives similar pointer stability, while the latter is more +efficient).

Cleared Element Deprecation

Source of changes: PR #11588, PR #11639

The RepeatedPtrField API around “cleared fields” has been deprecated, and will +be fully removed in a later breaking release. This was originally added as an +optimization for reusing elements after they’ve been cleared, but ended up not +working well. If you’re using this API, you should consider migrating to arenas +for better memory reuse.

UnsafeArena Deprecation

Source of changes: PR #10325

As part of a larger effort to remove arena-unsafe APIs, we’ve hidden +RepeatedField::UnsafeArenaSwap. This is the only one we’ve removed so far, but +in later releases we will continue to remove them and provide helpers to handle +efficient borrowing patterns between arenas. Within a single arena (or the +stack/heap), Swap is just as efficient as UnsafeArenaSwap. The benefit is +that it won’t cause invalid memory operations if you accidentally call it across +different arenas.

Map Pair Upgrades

Source of changes: PR #11625

For v22.0 we’ve started cleaning up the Map API to make it more consistent +with Abseil and STL. Notably, we’ve replaced the MapPair class with an alias +to std::pair. This should be transparent for most users, but if you were using +the class directly you may need to update your code.

New JSON Parser

Source of changes: PR #10729

We have rewritten the C++ JSON parser this release. It should be mostly a hidden +change, but inevitably some undocumented quirks my have changed; test +accordingly. Parsing documents that are not valid RFC-8219 JSON (such as those +that are missing quotes or using non-standard bools) is deprecated and will be +removed in a future release. The serialization order of fields is now guaranteed +to match the field number order, where before it was less deterministic.

As part of this migration, all of the files under +util/internal +have been deleted. These were used in the old parser, and were never intended to +be used externally.

Arena::Init

Source of changes: PR #10623

The Init method in Arena was code that didn’t do anything, and has now been +removed. If you were calling this method, you likely meant to call the Arena +constructor directly with a set of ArenaOptions. You should either delete the +call or migrate to that constructor.

ErrorCollector Migration

Source of changes: PR #11555

As part of our Abseil migration, we’re moving from const std::string& to +absl::string_view. For our three error collector classes, this can’t be done +without breaking existing code. For v22.0, we’ve decided to release both +variants, and rename the methods from AddError and AddWarning to +RecordError and RecordWarning. The old signature has been marked deprecated, +and will be slightly less efficient (due to string copies), but will otherwise +still work. You should migrate these to the new version, as the Add* methods +will be removed in a later breaking release.

\ No newline at end of file diff --git a/support/version-support/index.html b/support/version-support/index.html new file mode 100644 index 000000000..f2689d7f7 --- /dev/null +++ b/support/version-support/index.html @@ -0,0 +1,82 @@ +Version Support | Protocol Buffers Documentation +

Version Support

A list of the support windows provided for language implementations.

Currently Supported Release Versions

LanguageActive SupportMaintenance OnlyMinimum Gencode
protoc34.x29.x, 25.x (for Java)
C++7.34.x5.29.xExact Match
C#3.34.x3.0.0
Java4.34.x3.25.x3.0.0
PHP5.34.x4.0.0
Python7.34.x5.29.x3.20.0
Ruby4.34.x3.0.0

Minimum Supported Gencode

While each language runtime has a minimum supported gencode version, we +recommend regenerating your gencode with every release update. Support for older +generated code exists solely to ensure backwards compatibility for existing +projects, not for new adoption of older gencode versions.

See +Cross Version Runtime Guarantee +for more information.

Supported Editions

Protobuf release versions are independent of edition “versions” (proto2, proto3, +2023, 2024). All currently supported release versions support all editions.

The current supported editions are:

EditionReleased VersionDate Released
202432.023 May 2025
202327.013 Aug 2024
proto33.02016
proto22.02008

Numbering Scheme

Version numbers use SemVer conventions. In the version +“3.21.7”, “3” is the major version, “21” is the minor version, and “7” is the +patch number.

Protobuf releases use only a minor.point format, for example 29.5.

Each language runtime shares this minor.point but uses a language-specific +major version. For example, Protobuf release 29.5 corresponds to Java runtime +4.29.5 and C# runtime 3.29.5. We recommend using protoc 29.5 with Java +4.29.5 and C# 3.29.5.

This scheme unifies release numbers across all languages while decoupling major +version changes. For example, release 30.0 contained breaking changes for +Python but not for Java. Therefore, Python advanced from 5.29.0 to 6.30.0, +while Java advanced from 4.29.0 to 4.30.0.

We introduced this versioning scheme in 2022 with release 21. Previously, all +languages used major version 3.

Release Cadence

Protobuf releases updates quarterly. We target major (breaking) releases for Q1. +Security fixes and other urgent needs will require additional releases.

Our +library breaking change policy +defines our support windows.

Enforcing documented language, tooling, platform, and library support policies +is not a breaking change. For example, we might drop support for an +End-of-Life (EOL) language version without bumping the major version.

What Changes in a Release?

The binary wire format never changes. You can read old binary wire format +data with newer Protobuf versions. You can read new binary wire format data with +older Protobuf versions (as long as the .proto syntax is supported). ProtoJSON +format offers these same stability guarantees. TextProto is intended to be used +for configuration use-cases and should not be used as a wire format between two +servers.

The descriptor.proto schema can change. In minor or patch releases, we +might add or deprecate elements (messages, fields, enums, enum values, editions, +or editions features). In releases +with breaking changes (major releases), we might remove deprecated elements.

The .proto language grammar can change with new Editions. In minor +release, support for a new Edition may be added, which will add language +constructs or deprecate existing behaviors. Adopting a new Edition may require +client code updates. A future release may drop support for an old syntax. +However, we have no current concrete plans to do so.

Gencode and runtime APIs can change. Minor and patch releases include purely +additive or source-compatible updates. You can simply recompile your code. +Releases with breaking changes (major releases) introduce incompatible API +changes that require callsite updates. We minimize these changes. Bug fixes for +undefined behavior do not require a major release.

Operating system, programming language, and tooling support can change. +Minor or patch releases might add or drop support for specific operating +systems, programming languages, or tools. See the +foundational support matrices +for supported languages.

In general:

  • Minor or patch releases include purely additive or source-compatible updates +based on our +Cross Version Runtime Guarantee.
  • Major releases might remove functionality, features, or change APIs in ways +that require updates to callsites.

Support Duration

We always support the most recent release. Releasing a new minor version +immediately ends support for the previous minor version. Releasing a major +version ends support for the previous major version four quarters later.

For example, Protobuf Python 5.26.0 launched in Q1 2024. Therefore, Protobuf +Python 4.25.x support ended in Q1 2025.

The following sections detail support timelines for each language. Future plans +appear in italics and might change.

Legend

ActiveMinor and patch releases with new features, compatible changes, and bug fixes.
MaintenancePatch releases with critical bug and security vulnerability fixes.
End of LifeRelease is unsupported. Users should upgrade to a supported release.
FutureProjected release. Shown for planning purposes.

C++

Release Support Dates

Protobuf C++Release dateEnd of support
3.x25 May 202231 Mar 2024
4.x16 Feb 202331 Mar 2025
5.x13 Mar 202431 Mar 2026
6.x4 Mar 202531 Mar 2027
7.x25 Feb 2026TBD

Release Support Chart

Protobuf C++protoc23Q223Q323Q424Q124Q224Q324Q425Q125Q225Q325Q426Q1
3.x21.x3.21
4.x22.x-25.x4.234.244.254.25
5.x26.x-29.x5.265.275.285.295.29
6.x30.x-33.x6.306.316.326.336.33
7.x34.x+7.34

C++ Tooling, Platform, and Library Support

Protobuf follows the +Foundational C++ Support Policy. +For supported versions, see the +Foundational C++ Support Matrix.

C#

Release Support Dates

Protobuf C#Release dateEnd of support
3.x25 May 2022TBD

Release Support Chart

Protobuf C#protoc23Q223Q323Q424Q124Q224Q324Q425Q125Q225Q325Q426Q1
3.x21.x+3.233.243.253.263.273.283.293.303.313.323.333.34

C# Platform and Library Support

Protobuf is committed to following the platform and library support policy +described in +.NET Support Policy. +For specific versions supported, see +Foundational .NET Support Matrix.

Java

Release Support Dates

Protobuf JavaRelease dateEnd of support
3.x25 May 202231 Mar 2027*
4.x13 Mar 202431 Mar 2028
5.xQ1 2027*31 Mar 2029

Release Support Chart

Protobuf Javaprotoc23Q223Q323Q424Q124Q224Q324Q425Q125Q225Q325Q426Q1
3.x21.x-25.x3.233.243.253.25
4.x26.x+4.264.274.284.294.304.314.324.334.34

Java Platform and Library Support

Protobuf follows the +Java Support Policy. +For supported versions, see the +Foundational Java Support Matrix.

On Android, Protobuf supports the minimum SDK version defined by +Google Play services or +the default in +Jetpack. +We support whichever version is lower.

PHP

Release Support Dates

Protobuf PHPRelease dateEnd of support
3.x25 May 202231 Mar 2025
4.x13 Mar 202431 Mar 2026
5.x25 Feb 2026TBD

Release Support Chart

Protobuf PHPprotoc23Q223Q323Q424Q124Q224Q324Q425Q125Q225Q325Q426Q1
3.x21.x-25.x3.233.243.253.25
4.x26.x - 33.x4.264.274.284.294.304.314.324.334.33
5.x34.x+5.34

PHP Platform and Library Support

Protobuf follows the +PHP Support Policy. +For supported versions, see the +Foundational PHP Support Matrix.

Python

Release Support Dates

Protobuf PythonRelease dateEnd of support
4.x25 May 202231 Mar 2025
5.x13 Mar 202431 Mar 2026
6.x4 Mar 202531 Mar 2027
7.x25 Feb 2026TBD

Release Support Chart

Protobuf Pythonprotoc23Q223Q323Q424Q124Q224Q324Q425Q125Q225Q325Q426Q1
4.x21.x-25.x4.234.244.254.25
5.x26.x-29.x5.265.275.285.295.29
6.x30.x-33.x6.306.316.326.336.33
7.x34.x+7.34

Python Platform and Library Support

Protobuf follows the +Python Support Policy. +For supported versions, see the +Foundational Python Support Matrix.

Ruby

Release Support Dates

Protobuf RubyRelease dateEnd of support
3.x25 May 202231 Mar 2025
4.x13 Mar 2024TBD

Release Support Chart

Protobuf Rubyprotoc23Q223Q323Q424Q124Q224Q324Q425Q125Q225Q325Q426Q1
3.x21.x-25.x3.233.243.253.25
4.x26.x+4.264.274.284.294.304.314.324.334.34

Ruby Platform and Library Support

Protobuf follows the +Ruby Support Policy. +For supported versions, see the +Foundational Ruby Support Matrix.

We do not officially support JRuby. However, we provide unofficial, best-effort +support for the latest JRuby version. This targets compatibility with our +minimum supported Ruby version.

\ No newline at end of file diff --git a/tags/index.html b/tags/index.html new file mode 100644 index 000000000..22ec67066 --- /dev/null +++ b/tags/index.html @@ -0,0 +1,4 @@ +Tags | Protocol Buffers Documentation +

Tags

\ No newline at end of file diff --git a/tags/index.xml b/tags/index.xml new file mode 100644 index 000000000..669c830ad --- /dev/null +++ b/tags/index.xml @@ -0,0 +1 @@ +Tags on Protocol Buffers Documentationhttps://protobuf.dev/tags/Recent content in Tags on Protocol Buffers DocumentationHugoen \ No newline at end of file diff --git a/version-support/index.html b/version-support/index.html new file mode 100644 index 000000000..fac193936 --- /dev/null +++ b/version-support/index.html @@ -0,0 +1,2 @@ +https://protobuf.dev/support/version-support/ + \ No newline at end of file diff --git a/webfonts/fa-brands-400.ttf b/webfonts/fa-brands-400.ttf new file mode 100644 index 000000000..38f72c3b6 Binary files /dev/null and b/webfonts/fa-brands-400.ttf differ diff --git a/webfonts/fa-brands-400.woff2 b/webfonts/fa-brands-400.woff2 new file mode 100644 index 000000000..2f101cad4 Binary files /dev/null and b/webfonts/fa-brands-400.woff2 differ diff --git a/webfonts/fa-regular-400.ttf b/webfonts/fa-regular-400.ttf new file mode 100644 index 000000000..5ebf37944 Binary files /dev/null and b/webfonts/fa-regular-400.ttf differ diff --git a/webfonts/fa-regular-400.woff2 b/webfonts/fa-regular-400.woff2 new file mode 100644 index 000000000..a32eda28e Binary files /dev/null and b/webfonts/fa-regular-400.woff2 differ diff --git a/webfonts/fa-solid-900.ttf b/webfonts/fa-solid-900.ttf new file mode 100644 index 000000000..cee3c5bb4 Binary files /dev/null and b/webfonts/fa-solid-900.ttf differ diff --git a/webfonts/fa-solid-900.woff2 b/webfonts/fa-solid-900.woff2 new file mode 100644 index 000000000..13fe8df5c Binary files /dev/null and b/webfonts/fa-solid-900.woff2 differ diff --git a/webfonts/fa-v4compatibility.ttf b/webfonts/fa-v4compatibility.ttf new file mode 100644 index 000000000..8e945afc6 Binary files /dev/null and b/webfonts/fa-v4compatibility.ttf differ diff --git a/webfonts/fa-v4compatibility.woff2 b/webfonts/fa-v4compatibility.woff2 new file mode 100644 index 000000000..ec917b6ed Binary files /dev/null and b/webfonts/fa-v4compatibility.woff2 differ