From a3826ca12e8e18d15eedc0b7ffd3ee1c3b993621 Mon Sep 17 00:00:00 2001 From: Adrien Vannson Date: Thu, 16 Jan 2025 14:21:52 +0100 Subject: [PATCH 1/3] Update the betterproto dependency --- poetry.lock | 22 +- pyproject.toml | 17 +- .../compile/importing.py | 3 +- src/betterproto2_compiler/known_types/any.py | 3 +- .../known_types/duration.py | 2 +- .../known_types/timestamp.py | 2 +- .../lib/google/protobuf/__init__.py | 3338 +++++++++++++++++ .../lib/google/protobuf/compiler/__init__.py | 60 +- src/betterproto2_compiler/lib/message_pool.py | 3 + src/betterproto2_compiler/plugin/main.py | 5 - src/betterproto2_compiler/plugin/models.py | 20 +- src/betterproto2_compiler/plugin/parser.py | 3 +- 12 files changed, 3419 insertions(+), 59 deletions(-) create mode 100644 src/betterproto2_compiler/lib/message_pool.py diff --git a/poetry.lock b/poetry.lock index 06b7ff45..dd038e46 100644 --- a/poetry.lock +++ b/poetry.lock @@ -74,20 +74,24 @@ name = "betterproto2" version = "0.1.3" description = "A better Protobuf / gRPC generator & library" optional = false -python-versions = "<4.0,>=3.8" -files = [ - {file = "betterproto2-0.1.3-py3-none-any.whl", hash = "sha256:2f09de59fd82dd7549392bc922b989ae6cd6b9b9c4a6d34cccb2def78f10cea0"}, - {file = "betterproto2-0.1.3.tar.gz", hash = "sha256:d35da716773a1eda703944d9b5561ea182992a47f1c3ad887f29411cab622eb4"}, -] +python-versions = "^3.8" +files = [] +develop = false [package.dependencies] -grpclib = ">=0.4.1,<0.5.0" -python-dateutil = ">=2.8,<3.0" -typing-extensions = ">=4.7.1,<5.0.0" +grpclib = "^0.4.1" +python-dateutil = "^2.8" +typing-extensions = "^4.7.1" [package.extras] rust-codec = ["betterproto-rust-codec (==0.1.1)"] +[package.source] +type = "git" +url = "https://github.com/betterproto/python-betterproto2" +reference = "HEAD" +resolved_reference = "bbde43b56211741cdb87dad56c252cebec083803" + [[package]] name = "certifi" version = "2024.12.14" @@ -2178,4 +2182,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "61ea727da81cfdf7f8700cad861d8b859f17494fdbdbb596b40f7cc1c409b2c9" +content-hash = "14c1da07e2394ff96ac77edbe307cdb176524248e24936bf090f5f1aea6496d2" diff --git a/pyproject.toml b/pyproject.toml index eaf44a87..057e3d18 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,8 @@ packages = [ [tool.poetry.dependencies] python = "^3.10" -betterproto2 = "^0.1.3" +# betterproto2 = "^0.1.3" +betterproto2 = { git = "https://github.com/betterproto/python-betterproto2" } # The Ruff version is pinned. To update it, also update it in .pre-commit-config.yaml ruff = "~0.7.4" grpclib = "^0.4.1" @@ -139,3 +140,17 @@ help = "Serve the documentation locally" [build-system] requires = ["poetry-core>=1.0.0,<2"] build-backend = "poetry.core.masonry.api" + +# python -m grpc.tools.protoc \ +# --python_betterproto2_out=src/lib2 \ +# google/protobuf/any.proto \ +# google/protobuf/api.proto \ +# google/protobuf/duration.proto \ +# google/protobuf/empty.proto \ +# google/protobuf/field_mask.proto \ +# google/protobuf/source_context.proto \ +# google/protobuf/struct.proto \ +# google/protobuf/timestamp.proto \ +# google/protobuf/type.proto \ +# google/protobuf/wrappers.proto \ +# google/protobuf/compiler/plugin.proto \ No newline at end of file diff --git a/src/betterproto2_compiler/compile/importing.py b/src/betterproto2_compiler/compile/importing.py index ec73f329..c954aa95 100644 --- a/src/betterproto2_compiler/compile/importing.py +++ b/src/betterproto2_compiler/compile/importing.py @@ -5,8 +5,7 @@ TYPE_CHECKING, ) -from betterproto2.lib.google import protobuf as google_protobuf - +from betterproto2_compiler.lib.google import protobuf as google_protobuf from betterproto2_compiler.settings import Settings from ..casing import safe_snake_case diff --git a/src/betterproto2_compiler/known_types/any.py b/src/betterproto2_compiler/known_types/any.py index 7d0b8e9e..6ed4d631 100644 --- a/src/betterproto2_compiler/known_types/any.py +++ b/src/betterproto2_compiler/known_types/any.py @@ -1,5 +1,6 @@ import betterproto2 -from betterproto2.lib.std.google.protobuf import Any as VanillaAny + +from betterproto2_compiler.lib.google.protobuf import Any as VanillaAny # TODO put back # default_message_pool = betterproto2.MessagePool() # Only for typing purpose diff --git a/src/betterproto2_compiler/known_types/duration.py b/src/betterproto2_compiler/known_types/duration.py index 70d2ab89..14e7d81f 100644 --- a/src/betterproto2_compiler/known_types/duration.py +++ b/src/betterproto2_compiler/known_types/duration.py @@ -1,6 +1,6 @@ import datetime -from betterproto2.lib.std.google.protobuf import Duration as VanillaDuration +from betterproto2_compiler.lib.google.protobuf import Duration as VanillaDuration class Duration(VanillaDuration): diff --git a/src/betterproto2_compiler/known_types/timestamp.py b/src/betterproto2_compiler/known_types/timestamp.py index ee651cfa..79d7f3ef 100644 --- a/src/betterproto2_compiler/known_types/timestamp.py +++ b/src/betterproto2_compiler/known_types/timestamp.py @@ -1,6 +1,6 @@ import datetime -from betterproto2.lib.std.google.protobuf import Timestamp as VanillaTimestamp +from betterproto2_compiler.lib.google.protobuf import Timestamp as VanillaTimestamp class Timestamp(VanillaTimestamp): diff --git a/src/betterproto2_compiler/lib/google/protobuf/__init__.py b/src/betterproto2_compiler/lib/google/protobuf/__init__.py index e69de29b..341fb49c 100644 --- a/src/betterproto2_compiler/lib/google/protobuf/__init__.py +++ b/src/betterproto2_compiler/lib/google/protobuf/__init__.py @@ -0,0 +1,3338 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# sources: google/protobuf/any.proto, google/protobuf/api.proto, google/protobuf/descriptor.proto, google/protobuf/duration.proto, google/protobuf/empty.proto, google/protobuf/field_mask.proto, google/protobuf/source_context.proto, google/protobuf/struct.proto, google/protobuf/timestamp.proto, google/protobuf/type.proto, google/protobuf/wrappers.proto +# plugin: python-betterproto2 +# This file has been @generated + +__all__ = ( + "Edition", + "ExtensionRangeOptionsVerificationState", + "FeatureSetEnumType", + "FeatureSetFieldPresence", + "FeatureSetJsonFormat", + "FeatureSetMessageEncoding", + "FeatureSetRepeatedFieldEncoding", + "FeatureSetUtf8Validation", + "FieldCardinality", + "FieldKind", + "FieldDescriptorProtoLabel", + "FieldDescriptorProtoType", + "FieldOptionsCType", + "FieldOptionsJsType", + "FieldOptionsOptionRetention", + "FieldOptionsOptionTargetType", + "FileOptionsOptimizeMode", + "GeneratedCodeInfoAnnotationSemantic", + "MethodOptionsIdempotencyLevel", + "NullValue", + "Syntax", + "Any", + "Api", + "BoolValue", + "BytesValue", + "DescriptorProto", + "DescriptorProtoExtensionRange", + "DescriptorProtoReservedRange", + "DoubleValue", + "Duration", + "Empty", + "Enum", + "EnumDescriptorProto", + "EnumDescriptorProtoEnumReservedRange", + "EnumOptions", + "EnumValue", + "EnumValueDescriptorProto", + "EnumValueOptions", + "ExtensionRangeOptions", + "ExtensionRangeOptionsDeclaration", + "FeatureSet", + "FeatureSetDefaults", + "FeatureSetDefaultsFeatureSetEditionDefault", + "Field", + "FieldDescriptorProto", + "FieldMask", + "FieldOptions", + "FieldOptionsEditionDefault", + "FileDescriptorProto", + "FileDescriptorSet", + "FileOptions", + "FloatValue", + "GeneratedCodeInfo", + "GeneratedCodeInfoAnnotation", + "Int32Value", + "Int64Value", + "ListValue", + "MessageOptions", + "Method", + "MethodDescriptorProto", + "MethodOptions", + "Mixin", + "OneofDescriptorProto", + "OneofOptions", + "Option", + "ServiceDescriptorProto", + "ServiceOptions", + "SourceCodeInfo", + "SourceCodeInfoLocation", + "SourceContext", + "StringValue", + "Struct", + "Timestamp", + "Type", + "UInt32Value", + "UInt64Value", + "UninterpretedOption", + "UninterpretedOptionNamePart", + "Value", +) + +import datetime +import warnings +from dataclasses import dataclass +from typing import ( + Dict, + List, + Optional, +) + +import betterproto2 + +from ...message_pool import default_message_pool + +betterproto2.check_compiler_version("0.1.1") + + +class Edition(betterproto2.Enum): + """ + The full set of known editions. + """ + + UNKNOWN = 0 + """ + A placeholder for an unknown edition value. + """ + + PROTO2 = 998 + """ + Legacy syntax "editions". These pre-date editions, but behave much like + distinct editions. These can't be used to specify the edition of proto + files, but feature definitions must supply proto2/proto3 defaults for + backwards compatibility. + """ + + PROTO3 = 999 + + _2023 = 1000 + """ + Editions that have been released. The specific values are arbitrary and + should not be depended on, but they will always be time-ordered for easy + comparison. + """ + + _1_TEST_ONLY = 1 + """ + Placeholder editions for testing feature resolution. These should not be + used or relyed on outside of tests. + """ + + _2_TEST_ONLY = 2 + + _99997_TEST_ONLY = 99997 + + _99998_TEST_ONLY = 99998 + + _99999_TEST_ONLY = 99999 + + +class ExtensionRangeOptionsVerificationState(betterproto2.Enum): + """ + The verification state of the extension range. + """ + + DECLARATION = 0 + """ + All the extensions of the range must be declared. + """ + + UNVERIFIED = 1 + + +class FeatureSetEnumType(betterproto2.Enum): + ENUM_TYPE_UNKNOWN = 0 + + OPEN = 1 + + CLOSED = 2 + + +class FeatureSetFieldPresence(betterproto2.Enum): + FIELD_PRESENCE_UNKNOWN = 0 + + EXPLICIT = 1 + + IMPLICIT = 2 + + LEGACY_REQUIRED = 3 + + +class FeatureSetJsonFormat(betterproto2.Enum): + JSON_FORMAT_UNKNOWN = 0 + + ALLOW = 1 + + LEGACY_BEST_EFFORT = 2 + + +class FeatureSetMessageEncoding(betterproto2.Enum): + MESSAGE_ENCODING_UNKNOWN = 0 + + LENGTH_PREFIXED = 1 + + DELIMITED = 2 + + +class FeatureSetRepeatedFieldEncoding(betterproto2.Enum): + REPEATED_FIELD_ENCODING_UNKNOWN = 0 + + PACKED = 1 + + EXPANDED = 2 + + +class FeatureSetUtf8Validation(betterproto2.Enum): + UTF8_VALIDATION_UNKNOWN = 0 + + NONE = 1 + + VERIFY = 2 + + +class FieldCardinality(betterproto2.Enum): + """ + Whether a field is optional, required, or repeated. + """ + + CARDINALITY_UNKNOWN = 0 + """ + For fields with unknown cardinality. + """ + + CARDINALITY_OPTIONAL = 1 + """ + For optional fields. + """ + + CARDINALITY_REQUIRED = 2 + """ + For required fields. Proto2 syntax only. + """ + + CARDINALITY_REPEATED = 3 + """ + For repeated fields. + """ + + +class FieldKind(betterproto2.Enum): + """ + Basic field types. + """ + + TYPE_UNKNOWN = 0 + """ + Field type unknown. + """ + + TYPE_DOUBLE = 1 + """ + Field type double. + """ + + TYPE_FLOAT = 2 + """ + Field type float. + """ + + TYPE_INT64 = 3 + """ + Field type int64. + """ + + TYPE_UINT64 = 4 + """ + Field type uint64. + """ + + TYPE_INT32 = 5 + """ + Field type int32. + """ + + TYPE_FIXED64 = 6 + """ + Field type fixed64. + """ + + TYPE_FIXED32 = 7 + """ + Field type fixed32. + """ + + TYPE_BOOL = 8 + """ + Field type bool. + """ + + TYPE_STRING = 9 + """ + Field type string. + """ + + TYPE_GROUP = 10 + """ + Field type group. Proto2 syntax only, and deprecated. + """ + + TYPE_MESSAGE = 11 + """ + Field type message. + """ + + TYPE_BYTES = 12 + """ + Field type bytes. + """ + + TYPE_UINT32 = 13 + """ + Field type uint32. + """ + + TYPE_ENUM = 14 + """ + Field type enum. + """ + + TYPE_SFIXED32 = 15 + """ + Field type sfixed32. + """ + + TYPE_SFIXED64 = 16 + """ + Field type sfixed64. + """ + + TYPE_SINT32 = 17 + """ + Field type sint32. + """ + + TYPE_SINT64 = 18 + """ + Field type sint64. + """ + + +class FieldDescriptorProtoLabel(betterproto2.Enum): + LABEL_OPTIONAL = 1 + """ + 0 is reserved for errors + """ + + LABEL_REPEATED = 3 + + LABEL_REQUIRED = 2 + """ + The required label is only allowed in google.protobuf. In proto3 and Editions + it's explicitly prohibited. In Editions, the `field_presence` feature + can be used to get this behavior. + """ + + +class FieldDescriptorProtoType(betterproto2.Enum): + TYPE_DOUBLE = 1 + """ + 0 is reserved for errors. + Order is weird for historical reasons. + """ + + TYPE_FLOAT = 2 + + TYPE_INT64 = 3 + """ + Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + negative values are likely. + """ + + TYPE_UINT64 = 4 + + TYPE_INT32 = 5 + """ + Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + negative values are likely. + """ + + TYPE_FIXED64 = 6 + + TYPE_FIXED32 = 7 + + TYPE_BOOL = 8 + + TYPE_STRING = 9 + + TYPE_GROUP = 10 + """ + Tag-delimited aggregate. + Group type is deprecated and not supported after google.protobuf. However, Proto3 + implementations should still be able to parse the group wire format and + treat group fields as unknown fields. In Editions, the group wire format + can be enabled via the `message_encoding` feature. + """ + + TYPE_MESSAGE = 11 + """ + Length-delimited aggregate. + """ + + TYPE_BYTES = 12 + """ + New in version 2. + """ + + TYPE_UINT32 = 13 + + TYPE_ENUM = 14 + + TYPE_SFIXED32 = 15 + + TYPE_SFIXED64 = 16 + + TYPE_SINT32 = 17 + """ + Uses ZigZag encoding. + """ + + TYPE_SINT64 = 18 + """ + Uses ZigZag encoding. + """ + + +class FieldOptionsCType(betterproto2.Enum): + STRING = 0 + """ + Default mode. + """ + + CORD = 1 + """ + The option [ctype=CORD] may be applied to a non-repeated field of type + "bytes". It indicates that in C++, the data should be stored in a Cord + instead of a string. For very large strings, this may reduce memory + fragmentation. It may also allow better performance when parsing from a + Cord, or when parsing with aliasing enabled, as the parsed Cord may then + alias the original buffer. + """ + + STRING_PIECE = 2 + + +class FieldOptionsJsType(betterproto2.Enum): + JS_NORMAL = 0 + """ + Use the default type. + """ + + JS_STRING = 1 + """ + Use JavaScript strings. + """ + + JS_NUMBER = 2 + """ + Use JavaScript numbers. + """ + + +class FieldOptionsOptionRetention(betterproto2.Enum): + """ + If set to RETENTION_SOURCE, the option will be omitted from the binary. + Note: as of January 2023, support for this is in progress and does not yet + have an effect (b/264593489). + """ + + RETENTION_UNKNOWN = 0 + + RETENTION_RUNTIME = 1 + + RETENTION_SOURCE = 2 + + +class FieldOptionsOptionTargetType(betterproto2.Enum): + """ + This indicates the types of entities that the field may apply to when used + as an option. If it is unset, then the field may be freely used as an + option on any kind of entity. Note: as of January 2023, support for this is + in progress and does not yet have an effect (b/264593489). + """ + + TARGET_TYPE_UNKNOWN = 0 + + TARGET_TYPE_FILE = 1 + + TARGET_TYPE_EXTENSION_RANGE = 2 + + TARGET_TYPE_MESSAGE = 3 + + TARGET_TYPE_FIELD = 4 + + TARGET_TYPE_ONEOF = 5 + + TARGET_TYPE_ENUM = 6 + + TARGET_TYPE_ENUM_ENTRY = 7 + + TARGET_TYPE_SERVICE = 8 + + TARGET_TYPE_METHOD = 9 + + +class FileOptionsOptimizeMode(betterproto2.Enum): + """ + Generated classes can be optimized for speed or code size. + """ + + SPEED = 1 + """ + Generate complete code for parsing, serialization, + """ + + CODE_SIZE = 2 + """ + etc. + + Use ReflectionOps to implement these methods. + """ + + LITE_RUNTIME = 3 + """ + Generate code using MessageLite and the lite runtime. + """ + + +class GeneratedCodeInfoAnnotationSemantic(betterproto2.Enum): + """ + Represents the identified object's effect on the element in the original + .proto file. + """ + + NONE = 0 + """ + There is no effect or the effect is indescribable. + """ + + SET = 1 + """ + The element is set or otherwise mutated. + """ + + ALIAS = 2 + """ + An alias to the element is returned. + """ + + +class MethodOptionsIdempotencyLevel(betterproto2.Enum): + """ + 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. + """ + + IDEMPOTENCY_UNKNOWN = 0 + + NO_SIDE_EFFECTS = 1 + """ + implies idempotent + """ + + IDEMPOTENT = 2 + """ + idempotent, but may have side effects + """ + + +class NullValue(betterproto2.Enum): + """ + `NullValue` is a singleton enumeration to represent the null value for the + `Value` type union. + + The JSON representation for `NullValue` is JSON `null`. + """ + + _ = 0 + """ + Null value. + """ + + +class Syntax(betterproto2.Enum): + """ + The syntax in which a protocol buffer element is defined. + """ + + PROTO2 = 0 + """ + Syntax `proto2`. + """ + + PROTO3 = 1 + """ + Syntax `proto3`. + """ + + EDITIONS = 2 + """ + Syntax `editions`. + """ + + +@dataclass(eq=False, repr=False) +class Any(betterproto2.Message): + """ + `Any` contains an arbitrary serialized protocol buffer message along with a + URL that describes the type of the serialized message. + + Protobuf library provides support to pack/unpack Any values in the form + of utility functions or additional generated methods of the Any type. + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := anypb.New(foo) + if err != nil { + ... + } + ... + foo := &pb.Foo{} + if err := any.UnmarshalTo(foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by default use + 'type.googleapis.com/full.type.name' as the type URL and the unpack + methods only use the fully qualified type name after the last '/' + in the type URL, for example "foo.bar.com/x/y.z" will yield type + name "y.z". + + 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": , + "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][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + """ + + type_url: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + """ + A URL/resource name that uniquely identifies the type of the serialized + protocol buffer message. This string must contain at least + one "/" character. The last segment of the URL's path must represent + the fully qualified name of the type (as in + `path/google.protobuf.Duration`). The name should be in a canonical form + (e.g., leading "." is not accepted). + + In practice, teams usually precompile into the binary all types that they + expect it to use in the context of Any. However, for URLs which use the + scheme `http`, `https`, or no scheme, one can optionally set up a type + server that maps type URLs to message definitions as follows: + + * If no scheme is provided, `https` is assumed. + * 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.) + + Note: this functionality is not currently available in the official + protobuf release, and it is not used for type URLs beginning with + type.googleapis.com. As of May 2023, there are no widely used type server + implementations and no plans to implement one. + + Schemes other than `http`, `https` (or the empty scheme) might be + used with implementation specific semantics. + """ + + value: "bytes" = betterproto2.field(2, betterproto2.TYPE_BYTES) + """ + Must be a valid serialized protocol buffer of the above specified type. + """ + + def pack(self, message: betterproto2.Message, message_pool: "betterproto2.MessagePool | None" = None) -> None: + """ + Pack the given message in the `Any` object. + + The message type must be registered in the message pool, which is done automatically when the module defining + the message type is imported. + """ + message_pool = message_pool or default_message_pool + + self.type_url = message_pool.type_to_url[type(message)] + self.value = bytes(message) + + def unpack(self, message_pool: "betterproto2.MessagePool | None" = None) -> betterproto2.Message: + """ + Return the message packed inside the `Any` object. + + The target message type must be registered in the message pool, which is done automatically when the module + defining the message type is imported. + """ + message_pool = message_pool or default_message_pool + + message_type = message_pool.url_to_type[self.type_url] + + return message_type().parse(self.value) + + def to_dict(self) -> dict: # pyright: ignore [reportIncompatibleMethodOverride] + # TOOO improve when dict is updated + return {"@type": self.type_url, "value": self.unpack().to_dict()} + + +default_message_pool.register_message("google.protobuf", "Any", Any) + + +@dataclass(eq=False, repr=False) +class Api(betterproto2.Message): + """ + Api is a light-weight descriptor for an API Interface. + + Interfaces are also described as "protocol buffer services" in some contexts, + such as by the "service" keyword in a .proto file, but they are different + from API Services, which represent a concrete implementation of an interface + as opposed to simply a description of methods and bindings. They are also + sometimes simply referred to as "APIs" in other contexts, such as the name of + this message itself. See https://cloud.google.com/apis/design/glossary for + detailed terminology. + """ + + name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + """ + The fully qualified name of this interface, including package name + followed by the interface's simple name. + """ + + methods: "List[Method]" = betterproto2.field(2, betterproto2.TYPE_MESSAGE, repeated=True) + """ + The methods of this interface, in unspecified order. + """ + + options: "List[Option]" = betterproto2.field(3, betterproto2.TYPE_MESSAGE, repeated=True) + """ + Any metadata attached to the interface. + """ + + version: "str" = betterproto2.field(4, betterproto2.TYPE_STRING) + """ + A version string for this interface. 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](http://semver.org) 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 + interface, which must end in `v`, 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, non-GA interfaces. + """ + + source_context: "Optional[SourceContext]" = betterproto2.field(5, betterproto2.TYPE_MESSAGE, optional=True) + """ + Source context for the protocol buffer service represented by this + message. + """ + + mixins: "List[Mixin]" = betterproto2.field(6, betterproto2.TYPE_MESSAGE, repeated=True) + """ + Included interfaces. See [Mixin][]. + """ + + syntax: "Syntax" = betterproto2.field(7, betterproto2.TYPE_ENUM, default_factory=lambda: Syntax.try_value(0)) + """ + The source syntax of the service. + """ + + +default_message_pool.register_message("google.protobuf", "Api", Api) + + +@dataclass(eq=False, repr=False) +class BoolValue(betterproto2.Message): + """ + Wrapper message for `bool`. + + The JSON representation for `BoolValue` is JSON `true` and `false`. + """ + + value: "bool" = betterproto2.field(1, betterproto2.TYPE_BOOL) + """ + The bool value. + """ + + +default_message_pool.register_message("google.protobuf", "BoolValue", BoolValue) + + +@dataclass(eq=False, repr=False) +class BytesValue(betterproto2.Message): + """ + Wrapper message for `bytes`. + + The JSON representation for `BytesValue` is JSON string. + """ + + value: "bytes" = betterproto2.field(1, betterproto2.TYPE_BYTES) + """ + The bytes value. + """ + + +default_message_pool.register_message("google.protobuf", "BytesValue", BytesValue) + + +@dataclass(eq=False, repr=False) +class DescriptorProto(betterproto2.Message): + """ + Describes a message type. + """ + + name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + + field: "List[FieldDescriptorProto]" = betterproto2.field(2, betterproto2.TYPE_MESSAGE, repeated=True) + + extension: "List[FieldDescriptorProto]" = betterproto2.field(6, betterproto2.TYPE_MESSAGE, repeated=True) + + nested_type: "List[DescriptorProto]" = betterproto2.field(3, betterproto2.TYPE_MESSAGE, repeated=True) + + enum_type: "List[EnumDescriptorProto]" = betterproto2.field(4, betterproto2.TYPE_MESSAGE, repeated=True) + + extension_range: "List[DescriptorProtoExtensionRange]" = betterproto2.field( + 5, betterproto2.TYPE_MESSAGE, repeated=True + ) + + oneof_decl: "List[OneofDescriptorProto]" = betterproto2.field(8, betterproto2.TYPE_MESSAGE, repeated=True) + + options: "Optional[MessageOptions]" = betterproto2.field(7, betterproto2.TYPE_MESSAGE, optional=True) + + reserved_range: "List[DescriptorProtoReservedRange]" = betterproto2.field( + 9, betterproto2.TYPE_MESSAGE, repeated=True + ) + + reserved_name: "List[str]" = betterproto2.field(10, betterproto2.TYPE_STRING, repeated=True) + """ + Reserved field names, which may not be used by fields in the same message. + A given name may only be reserved once. + """ + + +default_message_pool.register_message("google.protobuf", "DescriptorProto", DescriptorProto) + + +@dataclass(eq=False, repr=False) +class DescriptorProtoExtensionRange(betterproto2.Message): + start: "int" = betterproto2.field(1, betterproto2.TYPE_INT32) + """ + Inclusive. + """ + + end: "int" = betterproto2.field(2, betterproto2.TYPE_INT32) + """ + Exclusive. + """ + + options: "Optional[ExtensionRangeOptions]" = betterproto2.field(3, betterproto2.TYPE_MESSAGE, optional=True) + + +default_message_pool.register_message( + "google.protobuf", "DescriptorProto.ExtensionRange", DescriptorProtoExtensionRange +) + + +@dataclass(eq=False, repr=False) +class DescriptorProtoReservedRange(betterproto2.Message): + """ + 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. + """ + + start: "int" = betterproto2.field(1, betterproto2.TYPE_INT32) + """ + Inclusive. + """ + + end: "int" = betterproto2.field(2, betterproto2.TYPE_INT32) + """ + Exclusive. + """ + + +default_message_pool.register_message("google.protobuf", "DescriptorProto.ReservedRange", DescriptorProtoReservedRange) + + +@dataclass(eq=False, repr=False) +class DoubleValue(betterproto2.Message): + """ + Wrapper message for `double`. + + The JSON representation for `DoubleValue` is JSON number. + """ + + value: "float" = betterproto2.field(1, betterproto2.TYPE_DOUBLE) + """ + The double value. + """ + + +default_message_pool.register_message("google.protobuf", "DoubleValue", DoubleValue) + + +@dataclass(eq=False, repr=False) +class Duration(betterproto2.Message): + """ + 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. + + # Examples + + 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; + } + + Example 3: Compute Duration from datetime.timedelta in Python. + + td = datetime.timedelta(days=3, minutes=10) + duration = Duration() + duration.FromTimedelta(td) + + # JSON Mapping + + In JSON format, the Duration type is encoded as a string rather than an + object, where the string ends in the suffix "s" (indicating seconds) and + is preceded by the number of seconds, with nanoseconds expressed as + fractional seconds. For example, 3 seconds with 0 nanoseconds should be + encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should + be expressed in JSON format as "3.000000001s", and 3 seconds and 1 + microsecond should be expressed in JSON format as "3.000001s". + """ + + seconds: "int" = betterproto2.field(1, betterproto2.TYPE_INT64) + """ + Signed seconds of the span of time. Must be from -315,576,000,000 + to +315,576,000,000 inclusive. Note: these bounds are computed from: + 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + """ + + nanos: "int" = betterproto2.field(2, betterproto2.TYPE_INT32) + """ + 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. + """ + + @classmethod + def from_timedelta( + cls, delta: datetime.timedelta, *, _1_microsecond: datetime.timedelta = datetime.timedelta(microseconds=1) + ) -> "Duration": + total_ms = delta // _1_microsecond + seconds = int(total_ms / 1e6) + nanos = int((total_ms % 1e6) * 1e3) + return cls(seconds, nanos) + + def to_timedelta(self) -> datetime.timedelta: + return datetime.timedelta(seconds=self.seconds, microseconds=self.nanos / 1e3) + + @staticmethod + def delta_to_json(delta: datetime.timedelta) -> str: + parts = str(delta.total_seconds()).split(".") + if len(parts) > 1: + while len(parts[1]) not in (3, 6, 9): + parts[1] = f"{parts[1]}0" + return f"{'.'.join(parts)}s" + + +default_message_pool.register_message("google.protobuf", "Duration", Duration) + + +@dataclass(eq=False, repr=False) +class Empty(betterproto2.Message): + """ + 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); + } + """ + + pass + + +default_message_pool.register_message("google.protobuf", "Empty", Empty) + + +@dataclass(eq=False, repr=False) +class Enum(betterproto2.Message): + """ + Enum type definition. + """ + + name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + """ + Enum type name. + """ + + enumvalue: "List[EnumValue]" = betterproto2.field( + 2, betterproto2.TYPE_MESSAGE, wraps=betterproto2.TYPE_ENUM, repeated=True + ) + """ + Enum value definitions. + """ + + options: "List[Option]" = betterproto2.field(3, betterproto2.TYPE_MESSAGE, repeated=True) + """ + Protocol buffer options. + """ + + source_context: "Optional[SourceContext]" = betterproto2.field(4, betterproto2.TYPE_MESSAGE, optional=True) + """ + The source context. + """ + + syntax: "Syntax" = betterproto2.field(5, betterproto2.TYPE_ENUM, default_factory=lambda: Syntax.try_value(0)) + """ + The source syntax. + """ + + edition: "str" = betterproto2.field(6, betterproto2.TYPE_STRING) + """ + The source edition string, only valid when syntax is SYNTAX_EDITIONS. + """ + + +default_message_pool.register_message("google.protobuf", "Enum", Enum) + + +@dataclass(eq=False, repr=False) +class EnumDescriptorProto(betterproto2.Message): + """ + Describes an enum type. + """ + + name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + + value: "List[EnumValueDescriptorProto]" = betterproto2.field(2, betterproto2.TYPE_MESSAGE, repeated=True) + + options: "Optional[EnumOptions]" = betterproto2.field(3, betterproto2.TYPE_MESSAGE, optional=True) + + reserved_range: "List[EnumDescriptorProtoEnumReservedRange]" = betterproto2.field( + 4, betterproto2.TYPE_MESSAGE, repeated=True + ) + """ + 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. + """ + + reserved_name: "List[str]" = betterproto2.field(5, betterproto2.TYPE_STRING, repeated=True) + """ + Reserved enum value names, which may not be reused. A given name may only + be reserved once. + """ + + +default_message_pool.register_message("google.protobuf", "EnumDescriptorProto", EnumDescriptorProto) + + +@dataclass(eq=False, repr=False) +class EnumDescriptorProtoEnumReservedRange(betterproto2.Message): + """ + 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. + """ + + start: "int" = betterproto2.field(1, betterproto2.TYPE_INT32) + """ + Inclusive. + """ + + end: "int" = betterproto2.field(2, betterproto2.TYPE_INT32) + """ + Inclusive. + """ + + +default_message_pool.register_message( + "google.protobuf", "EnumDescriptorProto.EnumReservedRange", EnumDescriptorProtoEnumReservedRange +) + + +@dataclass(eq=False, repr=False) +class EnumOptions(betterproto2.Message): + allow_alias: "bool" = betterproto2.field(2, betterproto2.TYPE_BOOL) + """ + Set this option to true to allow mapping different tag names to the same + value. + """ + + deprecated: "bool" = betterproto2.field(3, betterproto2.TYPE_BOOL) + """ + 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. + """ + + deprecated_legacy_json_field_conflicts: "bool" = betterproto2.field(6, betterproto2.TYPE_BOOL) + """ + Enable the legacy handling of JSON field name conflicts. This lowercases + and strips underscored from the fields before comparison in proto3 only. + The new behavior takes `json_name` into account and applies to proto2 as + well. + TODO Remove this legacy behavior once downstream teams have + had time to migrate. + """ + + features: "Optional[FeatureSet]" = betterproto2.field(7, betterproto2.TYPE_MESSAGE, optional=True) + """ + Any features defined in the specific edition. + """ + + uninterpreted_option: "List[UninterpretedOption]" = betterproto2.field( + 999, betterproto2.TYPE_MESSAGE, repeated=True + ) + """ + The parser stores options it doesn't recognize here. See above. + """ + + def __post_init__(self) -> None: + super().__post_init__() + if self.is_set("deprecated_legacy_json_field_conflicts"): + warnings.warn("EnumOptions.deprecated_legacy_json_field_conflicts is deprecated", DeprecationWarning) + + +default_message_pool.register_message("google.protobuf", "EnumOptions", EnumOptions) + + +@dataclass(eq=False, repr=False) +class EnumValue(betterproto2.Message): + """ + Enum value definition. + """ + + name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + """ + Enum value name. + """ + + number: "int" = betterproto2.field(2, betterproto2.TYPE_INT32) + """ + Enum value number. + """ + + options: "List[Option]" = betterproto2.field(3, betterproto2.TYPE_MESSAGE, repeated=True) + """ + Protocol buffer options. + """ + + +default_message_pool.register_message("google.protobuf", "EnumValue", EnumValue) + + +@dataclass(eq=False, repr=False) +class EnumValueDescriptorProto(betterproto2.Message): + """ + Describes a value within an enum. + """ + + name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + + number: "int" = betterproto2.field(2, betterproto2.TYPE_INT32) + + options: "Optional[EnumValueOptions]" = betterproto2.field(3, betterproto2.TYPE_MESSAGE, optional=True) + + +default_message_pool.register_message("google.protobuf", "EnumValueDescriptorProto", EnumValueDescriptorProto) + + +@dataclass(eq=False, repr=False) +class EnumValueOptions(betterproto2.Message): + deprecated: "bool" = betterproto2.field(1, betterproto2.TYPE_BOOL) + """ + 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. + """ + + features: "Optional[FeatureSet]" = betterproto2.field(2, betterproto2.TYPE_MESSAGE, optional=True) + """ + Any features defined in the specific edition. + """ + + debug_redact: "bool" = betterproto2.field(3, betterproto2.TYPE_BOOL) + """ + Indicate that fields annotated with this enum value should not be printed + out when using debug formats, e.g. when the field contains sensitive + credentials. + """ + + uninterpreted_option: "List[UninterpretedOption]" = betterproto2.field( + 999, betterproto2.TYPE_MESSAGE, repeated=True + ) + """ + The parser stores options it doesn't recognize here. See above. + """ + + +default_message_pool.register_message("google.protobuf", "EnumValueOptions", EnumValueOptions) + + +@dataclass(eq=False, repr=False) +class ExtensionRangeOptions(betterproto2.Message): + uninterpreted_option: "List[UninterpretedOption]" = betterproto2.field( + 999, betterproto2.TYPE_MESSAGE, repeated=True + ) + """ + The parser stores options it doesn't recognize here. See above. + """ + + declaration: "List[ExtensionRangeOptionsDeclaration]" = betterproto2.field( + 2, betterproto2.TYPE_MESSAGE, repeated=True + ) + """ + For external users: DO NOT USE. We are in the process of open sourcing + extension declaration and executing internal cleanups before it can be + used externally. + """ + + features: "Optional[FeatureSet]" = betterproto2.field(50, betterproto2.TYPE_MESSAGE, optional=True) + """ + Any features defined in the specific edition. + """ + + verification: "ExtensionRangeOptionsVerificationState" = betterproto2.field( + 3, betterproto2.TYPE_ENUM, default_factory=lambda: ExtensionRangeOptionsVerificationState.try_value(0) + ) + """ + The verification state of the range. + TODO: flip the default to DECLARATION once all empty ranges + are marked as UNVERIFIED. + """ + + +default_message_pool.register_message("google.protobuf", "ExtensionRangeOptions", ExtensionRangeOptions) + + +@dataclass(eq=False, repr=False) +class ExtensionRangeOptionsDeclaration(betterproto2.Message): + number: "int" = betterproto2.field(1, betterproto2.TYPE_INT32) + """ + The extension number declared within the extension range. + """ + + full_name: "str" = betterproto2.field(2, betterproto2.TYPE_STRING) + """ + The fully-qualified name of the extension field. There must be a leading + dot in front of the full name. + """ + + type: "str" = betterproto2.field(3, betterproto2.TYPE_STRING) + """ + The fully-qualified type name of the extension field. Unlike + Metadata.type, Declaration.type must have a leading dot for messages + and enums. + """ + + reserved: "bool" = betterproto2.field(5, betterproto2.TYPE_BOOL) + """ + If true, indicates that the number is reserved in the extension range, + and any extension field with the number will fail to compile. Set this + when a declared extension field is deleted. + """ + + repeated: "bool" = betterproto2.field(6, betterproto2.TYPE_BOOL) + """ + If true, indicates that the extension must be defined as repeated. + Otherwise the extension must be defined as optional. + """ + + +default_message_pool.register_message( + "google.protobuf", "ExtensionRangeOptions.Declaration", ExtensionRangeOptionsDeclaration +) + + +@dataclass(eq=False, repr=False) +class FeatureSet(betterproto2.Message): + """ + =================================================================== + Features + + TODO Enums in C++ gencode (and potentially other languages) are + not well scoped. This means that each of the feature enums below can clash + with each other. The short names we've chosen maximize call-site + readability, but leave us very open to this scenario. A future feature will + be designed and implemented to handle this, hopefully before we ever hit a + conflict here. + """ + + field_presence: "FeatureSetFieldPresence" = betterproto2.field( + 1, betterproto2.TYPE_ENUM, default_factory=lambda: FeatureSetFieldPresence.try_value(0) + ) + + enum_type: "FeatureSetEnumType" = betterproto2.field( + 2, betterproto2.TYPE_ENUM, default_factory=lambda: FeatureSetEnumType.try_value(0) + ) + + repeated_field_encoding: "FeatureSetRepeatedFieldEncoding" = betterproto2.field( + 3, betterproto2.TYPE_ENUM, default_factory=lambda: FeatureSetRepeatedFieldEncoding.try_value(0) + ) + + utf8_validation: "FeatureSetUtf8Validation" = betterproto2.field( + 4, betterproto2.TYPE_ENUM, default_factory=lambda: FeatureSetUtf8Validation.try_value(0) + ) + + message_encoding: "FeatureSetMessageEncoding" = betterproto2.field( + 5, betterproto2.TYPE_ENUM, default_factory=lambda: FeatureSetMessageEncoding.try_value(0) + ) + + json_format: "FeatureSetJsonFormat" = betterproto2.field( + 6, betterproto2.TYPE_ENUM, default_factory=lambda: FeatureSetJsonFormat.try_value(0) + ) + + +default_message_pool.register_message("google.protobuf", "FeatureSet", FeatureSet) + + +@dataclass(eq=False, repr=False) +class FeatureSetDefaults(betterproto2.Message): + """ + A compiled specification for the defaults of a set of features. These + messages are generated from FeatureSet extensions and can be used to seed + feature resolution. The resolution with this object becomes a simple search + for the closest matching edition, followed by proto merges. + """ + + defaults: "List[FeatureSetDefaultsFeatureSetEditionDefault]" = betterproto2.field( + 1, betterproto2.TYPE_MESSAGE, repeated=True + ) + + minimum_edition: "Edition" = betterproto2.field( + 4, betterproto2.TYPE_ENUM, default_factory=lambda: Edition.try_value(0) + ) + """ + The minimum supported edition (inclusive) when this was constructed. + Editions before this will not have defaults. + """ + + maximum_edition: "Edition" = betterproto2.field( + 5, betterproto2.TYPE_ENUM, default_factory=lambda: Edition.try_value(0) + ) + """ + The maximum known edition (inclusive) when this was constructed. Editions + after this will not have reliable defaults. + """ + + +default_message_pool.register_message("google.protobuf", "FeatureSetDefaults", FeatureSetDefaults) + + +@dataclass(eq=False, repr=False) +class FeatureSetDefaultsFeatureSetEditionDefault(betterproto2.Message): + """ + A map from every known edition with a unique set of defaults to its + defaults. Not all editions may be contained here. For a given edition, + the defaults at the closest matching edition ordered at or before it should + be used. This field must be in strict ascending order by edition. + """ + + edition: "Edition" = betterproto2.field(3, betterproto2.TYPE_ENUM, default_factory=lambda: Edition.try_value(0)) + + features: "Optional[FeatureSet]" = betterproto2.field(2, betterproto2.TYPE_MESSAGE, optional=True) + + +default_message_pool.register_message( + "google.protobuf", "FeatureSetDefaults.FeatureSetEditionDefault", FeatureSetDefaultsFeatureSetEditionDefault +) + + +@dataclass(eq=False, repr=False) +class Field(betterproto2.Message): + """ + A single field of a message type. + """ + + kind: "FieldKind" = betterproto2.field(1, betterproto2.TYPE_ENUM, default_factory=lambda: FieldKind.try_value(0)) + """ + The field type. + """ + + cardinality: "FieldCardinality" = betterproto2.field( + 2, betterproto2.TYPE_ENUM, default_factory=lambda: FieldCardinality.try_value(0) + ) + """ + The field cardinality. + """ + + number: "int" = betterproto2.field(3, betterproto2.TYPE_INT32) + """ + The field number. + """ + + name: "str" = betterproto2.field(4, betterproto2.TYPE_STRING) + """ + The field name. + """ + + type_url: "str" = betterproto2.field(6, betterproto2.TYPE_STRING) + """ + The field type URL, without the scheme, for message or enumeration + types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. + """ + + oneof_index: "int | None" = betterproto2.field(7, betterproto2.TYPE_INT32, optional=True) + """ + 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. + """ + + packed: "bool" = betterproto2.field(8, betterproto2.TYPE_BOOL) + """ + Whether to use alternative packed wire representation. + """ + + options: "List[Option]" = betterproto2.field(9, betterproto2.TYPE_MESSAGE, repeated=True) + """ + The protocol buffer options. + """ + + json_name: "str" = betterproto2.field(10, betterproto2.TYPE_STRING) + """ + The field JSON name. + """ + + default_value: "str" = betterproto2.field(11, betterproto2.TYPE_STRING) + """ + The string value of the default value of this field. Proto2 syntax only. + """ + + +default_message_pool.register_message("google.protobuf", "Field", Field) + + +@dataclass(eq=False, repr=False) +class FieldDescriptorProto(betterproto2.Message): + """ + Describes a field within a message. + """ + + name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + + number: "int" = betterproto2.field(3, betterproto2.TYPE_INT32) + + label: "FieldDescriptorProtoLabel" = betterproto2.field( + 4, betterproto2.TYPE_ENUM, default_factory=lambda: FieldDescriptorProtoLabel.try_value(0) + ) + + type: "FieldDescriptorProtoType" = betterproto2.field( + 5, betterproto2.TYPE_ENUM, default_factory=lambda: FieldDescriptorProtoType.try_value(0) + ) + """ + 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. + """ + + type_name: "str" = betterproto2.field(6, betterproto2.TYPE_STRING) + """ + 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). + """ + + extendee: "str" = betterproto2.field(2, betterproto2.TYPE_STRING) + """ + For extensions, this is the name of the type being extended. It is + resolved in the same manner as type_name. + """ + + default_value: "str" = betterproto2.field(7, betterproto2.TYPE_STRING) + """ + 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. + """ + + oneof_index: "int | None" = betterproto2.field(9, betterproto2.TYPE_INT32, optional=True) + """ + If set, gives the index of a oneof in the containing type's oneof_decl + list. This field is a member of that oneof. + """ + + json_name: "str" = betterproto2.field(10, betterproto2.TYPE_STRING) + """ + 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. + """ + + options: "Optional[FieldOptions]" = betterproto2.field(8, betterproto2.TYPE_MESSAGE, optional=True) + + proto3_optional: "bool" = betterproto2.field(17, betterproto2.TYPE_BOOL) + """ + 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`. + """ + + +default_message_pool.register_message("google.protobuf", "FieldDescriptorProto", FieldDescriptorProto) + + +@dataclass(eq=False, repr=False) +class FieldMask(betterproto2.Message): + """ + `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 or modified by an update operation. + Field masks also have a custom JSON encoding (see below). + + # Field Masks in Projections + + When used in the context of a projection, a response message or + sub-message is filtered by the API to only contain those fields as + specified in the mask. For example, if the mask in the previous + example is applied to a response message as follows: + + f { + a : 22 + b { + d : 1 + x : 2 + } + y : 13 + } + z: 8 + + The result will not contain specific values for fields x,y and 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 + paths string. + + 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. + + If a repeated field is specified for an update operation, new values will + be appended to the existing repeated field in the target resource. Note that + a repeated field is only allowed in the last position of a `paths` string. + + If a sub-message is specified in the last position of the field mask for an + update operation, then new value will be merged into the existing sub-message + in the target resource. + + For example, given the target message: + + f { + b { + d: 1 + x: 2 + } + c: [1] + } + + And an update message: + + f { + b { + d: 10 + } + c: [2] + } + + then if the field mask is: + + paths: ["f.b", "f.c"] + + then the result will be: + + f { + b { + d: 10 + x: 2 + } + c: [1, 2] + } + + An implementation may provide options to override this default behavior for + repeated and message fields. + + 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 Masks and Oneof Fields + + Field masks treat fields in oneofs just as regular fields. Consider the + following message: + + message SampleMessage { + oneof test_oneof { + string name = 4; + SubMessage sub_message = 9; + } + } + + The field mask can be: + + mask { + paths: "name" + } + + Or: + + mask { + paths: "sub_message" + } + + Note that oneof type names ("test_oneof" in this case) cannot be used in + paths. + + ## Field Mask Verification + + The implementation of any API method which has a FieldMask type field in the + request should verify the included field paths, and return an + `INVALID_ARGUMENT` error if any path is unmappable. + """ + + paths: "List[str]" = betterproto2.field(1, betterproto2.TYPE_STRING, repeated=True) + """ + The set of field mask paths. + """ + + +default_message_pool.register_message("google.protobuf", "FieldMask", FieldMask) + + +@dataclass(eq=False, repr=False) +class FieldOptions(betterproto2.Message): + ctype: "FieldOptionsCType" = betterproto2.field( + 1, betterproto2.TYPE_ENUM, default_factory=lambda: FieldOptionsCType.try_value(0) + ) + """ + 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 only implemented to support use of + [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of + type "bytes" in the open source release -- sorry, we'll try to include + other types in a future version! + """ + + packed: "bool" = betterproto2.field(2, betterproto2.TYPE_BOOL) + """ + 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. This option is prohibited in + Editions, but the `repeated_field_encoding` feature can be used to control + the behavior. + """ + + jstype: "FieldOptionsJsType" = betterproto2.field( + 6, betterproto2.TYPE_ENUM, default_factory=lambda: FieldOptionsJsType.try_value(0) + ) + """ + 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. + """ + + lazy: "bool" = betterproto2.field(5, betterproto2.TYPE_BOOL) + """ + 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. + + As of May 2022, lazy verifies the contents of the byte stream during + parsing. An invalid byte stream will cause the overall parsing to fail. + """ + + unverified_lazy: "bool" = betterproto2.field(15, betterproto2.TYPE_BOOL) + """ + unverified_lazy does no correctness checks on the byte stream. This should + only be used where lazy with verification is prohibitive for performance + reasons. + """ + + deprecated: "bool" = betterproto2.field(3, betterproto2.TYPE_BOOL) + """ + 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. + """ + + weak: "bool" = betterproto2.field(10, betterproto2.TYPE_BOOL) + """ + For Google-internal migration only. Do not use. + """ + + debug_redact: "bool" = betterproto2.field(16, betterproto2.TYPE_BOOL) + """ + Indicate that the field value should not be printed out when using debug + formats, e.g. when the field contains sensitive credentials. + """ + + retention: "FieldOptionsOptionRetention" = betterproto2.field( + 17, betterproto2.TYPE_ENUM, default_factory=lambda: FieldOptionsOptionRetention.try_value(0) + ) + + targets: "List[FieldOptionsOptionTargetType]" = betterproto2.field(19, betterproto2.TYPE_ENUM, repeated=True) + + edition_defaults: "List[FieldOptionsEditionDefault]" = betterproto2.field( + 20, betterproto2.TYPE_MESSAGE, repeated=True + ) + + features: "Optional[FeatureSet]" = betterproto2.field(21, betterproto2.TYPE_MESSAGE, optional=True) + """ + Any features defined in the specific edition. + """ + + uninterpreted_option: "List[UninterpretedOption]" = betterproto2.field( + 999, betterproto2.TYPE_MESSAGE, repeated=True + ) + """ + The parser stores options it doesn't recognize here. See above. + """ + + +default_message_pool.register_message("google.protobuf", "FieldOptions", FieldOptions) + + +@dataclass(eq=False, repr=False) +class FieldOptionsEditionDefault(betterproto2.Message): + edition: "Edition" = betterproto2.field(3, betterproto2.TYPE_ENUM, default_factory=lambda: Edition.try_value(0)) + + value: "str" = betterproto2.field(2, betterproto2.TYPE_STRING) + """ + Textproto value. + """ + + +default_message_pool.register_message("google.protobuf", "FieldOptions.EditionDefault", FieldOptionsEditionDefault) + + +@dataclass(eq=False, repr=False) +class FileDescriptorProto(betterproto2.Message): + """ + Describes a complete .proto file. + """ + + name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + """ + file name, relative to root of source tree + """ + + package: "str" = betterproto2.field(2, betterproto2.TYPE_STRING) + """ + e.g. "foo", "foo.bar", etc. + """ + + dependency: "List[str]" = betterproto2.field(3, betterproto2.TYPE_STRING, repeated=True) + """ + Names of files imported by this file. + """ + + public_dependency: "List[int]" = betterproto2.field(10, betterproto2.TYPE_INT32, repeated=True) + """ + Indexes of the public imported files in the dependency list above. + """ + + weak_dependency: "List[int]" = betterproto2.field(11, betterproto2.TYPE_INT32, repeated=True) + """ + Indexes of the weak imported files in the dependency list. + For Google-internal migration only. Do not use. + """ + + message_type: "List[DescriptorProto]" = betterproto2.field(4, betterproto2.TYPE_MESSAGE, repeated=True) + """ + All top-level definitions in this file. + """ + + enum_type: "List[EnumDescriptorProto]" = betterproto2.field(5, betterproto2.TYPE_MESSAGE, repeated=True) + + service: "List[ServiceDescriptorProto]" = betterproto2.field(6, betterproto2.TYPE_MESSAGE, repeated=True) + + extension: "List[FieldDescriptorProto]" = betterproto2.field(7, betterproto2.TYPE_MESSAGE, repeated=True) + + options: "Optional[FileOptions]" = betterproto2.field(8, betterproto2.TYPE_MESSAGE, optional=True) + + source_code_info: "Optional[SourceCodeInfo]" = betterproto2.field(9, betterproto2.TYPE_MESSAGE, optional=True) + """ + 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. + """ + + syntax: "str" = betterproto2.field(12, betterproto2.TYPE_STRING) + """ + The syntax of the proto file. + The supported values are "proto2", "proto3", and "editions". + + If `edition` is present, this value must be "editions". + """ + + edition: "Edition" = betterproto2.field(14, betterproto2.TYPE_ENUM, default_factory=lambda: Edition.try_value(0)) + """ + The edition of the proto file. + """ + + +default_message_pool.register_message("google.protobuf", "FileDescriptorProto", FileDescriptorProto) + + +@dataclass(eq=False, repr=False) +class FileDescriptorSet(betterproto2.Message): + """ + The protocol compiler can output a FileDescriptorSet containing the .proto + files it parses. + """ + + file: "List[FileDescriptorProto]" = betterproto2.field(1, betterproto2.TYPE_MESSAGE, repeated=True) + + +default_message_pool.register_message("google.protobuf", "FileDescriptorSet", FileDescriptorSet) + + +@dataclass(eq=False, repr=False) +class FileOptions(betterproto2.Message): + """ + =================================================================== + 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: + https://developers.google.com/protocol-buffers/docs/proto#options + If this turns out to be popular, a web service will be set up + to automatically assign option numbers. + """ + + java_package: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + """ + 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. + """ + + java_outer_classname: "str" = betterproto2.field(8, betterproto2.TYPE_STRING) + """ + 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. + """ + + java_multiple_files: "bool" = betterproto2.field(10, betterproto2.TYPE_BOOL) + """ + 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. + """ + + java_generate_equals_and_hash: "bool" = betterproto2.field(20, betterproto2.TYPE_BOOL) + """ + This option does nothing. + """ + + java_string_check_utf8: "bool" = betterproto2.field(27, betterproto2.TYPE_BOOL) + """ + 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. + """ + + optimize_for: "FileOptionsOptimizeMode" = betterproto2.field( + 9, betterproto2.TYPE_ENUM, default_factory=lambda: FileOptionsOptimizeMode.try_value(0) + ) + + go_package: "str" = betterproto2.field(11, betterproto2.TYPE_STRING) + """ + 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. + """ + + cc_generic_services: "bool" = betterproto2.field(16, betterproto2.TYPE_BOOL) + """ + 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. + """ + + java_generic_services: "bool" = betterproto2.field(17, betterproto2.TYPE_BOOL) + + py_generic_services: "bool" = betterproto2.field(18, betterproto2.TYPE_BOOL) + + php_generic_services: "bool" = betterproto2.field(42, betterproto2.TYPE_BOOL) + + deprecated: "bool" = betterproto2.field(23, betterproto2.TYPE_BOOL) + """ + 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. + """ + + cc_enable_arenas: "bool" = betterproto2.field(31, betterproto2.TYPE_BOOL) + """ + Enables the use of arenas for the proto messages in this file. This applies + only to generated classes for C++. + """ + + objc_class_prefix: "str" = betterproto2.field(36, betterproto2.TYPE_STRING) + """ + Sets the objective c class prefix which is prepended to all objective c + generated classes from this .proto. There is no default. + """ + + csharp_namespace: "str" = betterproto2.field(37, betterproto2.TYPE_STRING) + """ + Namespace for generated classes; defaults to the package. + """ + + swift_prefix: "str" = betterproto2.field(39, betterproto2.TYPE_STRING) + """ + 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. + """ + + php_class_prefix: "str" = betterproto2.field(40, betterproto2.TYPE_STRING) + """ + Sets the php class prefix which is prepended to all php generated classes + from this .proto. Default is empty. + """ + + php_namespace: "str" = betterproto2.field(41, betterproto2.TYPE_STRING) + """ + 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. + """ + + php_metadata_namespace: "str" = betterproto2.field(44, betterproto2.TYPE_STRING) + """ + 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. + """ + + ruby_package: "str" = betterproto2.field(45, betterproto2.TYPE_STRING) + """ + 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. + """ + + features: "Optional[FeatureSet]" = betterproto2.field(50, betterproto2.TYPE_MESSAGE, optional=True) + """ + Any features defined in the specific edition. + """ + + uninterpreted_option: "List[UninterpretedOption]" = betterproto2.field( + 999, betterproto2.TYPE_MESSAGE, repeated=True + ) + """ + The parser stores options it doesn't recognize here. + See the documentation for the "Options" section above. + """ + + def __post_init__(self) -> None: + super().__post_init__() + if self.is_set("java_generate_equals_and_hash"): + warnings.warn("FileOptions.java_generate_equals_and_hash is deprecated", DeprecationWarning) + + +default_message_pool.register_message("google.protobuf", "FileOptions", FileOptions) + + +@dataclass(eq=False, repr=False) +class FloatValue(betterproto2.Message): + """ + Wrapper message for `float`. + + The JSON representation for `FloatValue` is JSON number. + """ + + value: "float" = betterproto2.field(1, betterproto2.TYPE_FLOAT) + """ + The float value. + """ + + +default_message_pool.register_message("google.protobuf", "FloatValue", FloatValue) + + +@dataclass(eq=False, repr=False) +class GeneratedCodeInfo(betterproto2.Message): + """ + 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. + """ + + annotation: "List[GeneratedCodeInfoAnnotation]" = betterproto2.field(1, betterproto2.TYPE_MESSAGE, repeated=True) + """ + An Annotation connects some span of text in generated code to an element + of its generating .proto file. + """ + + +default_message_pool.register_message("google.protobuf", "GeneratedCodeInfo", GeneratedCodeInfo) + + +@dataclass(eq=False, repr=False) +class GeneratedCodeInfoAnnotation(betterproto2.Message): + path: "List[int]" = betterproto2.field(1, betterproto2.TYPE_INT32, repeated=True) + """ + Identifies the element in the original source .proto file. This field + is formatted the same as SourceCodeInfo.Location.path. + """ + + source_file: "str" = betterproto2.field(2, betterproto2.TYPE_STRING) + """ + Identifies the filesystem path to the original source .proto. + """ + + begin: "int" = betterproto2.field(3, betterproto2.TYPE_INT32) + """ + Identifies the starting offset in bytes in the generated code + that relates to the identified object. + """ + + end: "int" = betterproto2.field(4, betterproto2.TYPE_INT32) + """ + Identifies the ending offset in bytes in the generated code that + relates to the identified object. The end offset should be one past + the last relevant byte (so the length of the text = end - begin). + """ + + semantic: "GeneratedCodeInfoAnnotationSemantic" = betterproto2.field( + 5, betterproto2.TYPE_ENUM, default_factory=lambda: GeneratedCodeInfoAnnotationSemantic.try_value(0) + ) + + +default_message_pool.register_message("google.protobuf", "GeneratedCodeInfo.Annotation", GeneratedCodeInfoAnnotation) + + +@dataclass(eq=False, repr=False) +class Int32Value(betterproto2.Message): + """ + Wrapper message for `int32`. + + The JSON representation for `Int32Value` is JSON number. + """ + + value: "int" = betterproto2.field(1, betterproto2.TYPE_INT32) + """ + The int32 value. + """ + + +default_message_pool.register_message("google.protobuf", "Int32Value", Int32Value) + + +@dataclass(eq=False, repr=False) +class Int64Value(betterproto2.Message): + """ + Wrapper message for `int64`. + + The JSON representation for `Int64Value` is JSON string. + """ + + value: "int" = betterproto2.field(1, betterproto2.TYPE_INT64) + """ + The int64 value. + """ + + +default_message_pool.register_message("google.protobuf", "Int64Value", Int64Value) + + +@dataclass(eq=False, repr=False) +class ListValue(betterproto2.Message): + """ + `ListValue` is a wrapper around a repeated field of values. + + The JSON representation for `ListValue` is JSON array. + """ + + values: "List[Value]" = betterproto2.field(1, betterproto2.TYPE_MESSAGE, repeated=True) + """ + Repeated field of dynamically typed values. + """ + + +default_message_pool.register_message("google.protobuf", "ListValue", ListValue) + + +@dataclass(eq=False, repr=False) +class MessageOptions(betterproto2.Message): + message_set_wire_format: "bool" = betterproto2.field(1, betterproto2.TYPE_BOOL) + """ + 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. + """ + + no_standard_descriptor_accessor: "bool" = betterproto2.field(2, betterproto2.TYPE_BOOL) + """ + 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". + """ + + deprecated: "bool" = betterproto2.field(3, betterproto2.TYPE_BOOL) + """ + 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. + """ + + map_entry: "bool" = betterproto2.field(7, betterproto2.TYPE_BOOL) + """ + 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. + + Whether the message is an automatically generated map entry type for the + maps field. + + For maps fields: + map 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. + """ + + deprecated_legacy_json_field_conflicts: "bool" = betterproto2.field(11, betterproto2.TYPE_BOOL) + """ + Enable the legacy handling of JSON field name conflicts. This lowercases + and strips underscored from the fields before comparison in proto3 only. + The new behavior takes `json_name` into account and applies to proto2 as + well. + + This should only be used as a temporary measure against broken builds due + to the change in behavior for JSON field name conflicts. + + TODO This is legacy behavior we plan to remove once downstream + teams have had time to migrate. + """ + + features: "Optional[FeatureSet]" = betterproto2.field(12, betterproto2.TYPE_MESSAGE, optional=True) + """ + Any features defined in the specific edition. + """ + + uninterpreted_option: "List[UninterpretedOption]" = betterproto2.field( + 999, betterproto2.TYPE_MESSAGE, repeated=True + ) + """ + The parser stores options it doesn't recognize here. See above. + """ + + def __post_init__(self) -> None: + super().__post_init__() + if self.is_set("deprecated_legacy_json_field_conflicts"): + warnings.warn("MessageOptions.deprecated_legacy_json_field_conflicts is deprecated", DeprecationWarning) + + +default_message_pool.register_message("google.protobuf", "MessageOptions", MessageOptions) + + +@dataclass(eq=False, repr=False) +class Method(betterproto2.Message): + """ + Method represents a method of an API interface. + """ + + name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + """ + The simple name of this method. + """ + + request_type_url: "str" = betterproto2.field(2, betterproto2.TYPE_STRING) + """ + A URL of the input message type. + """ + + request_streaming: "bool" = betterproto2.field(3, betterproto2.TYPE_BOOL) + """ + If true, the request is streamed. + """ + + response_type_url: "str" = betterproto2.field(4, betterproto2.TYPE_STRING) + """ + The URL of the output message type. + """ + + response_streaming: "bool" = betterproto2.field(5, betterproto2.TYPE_BOOL) + """ + If true, the response is streamed. + """ + + options: "List[Option]" = betterproto2.field(6, betterproto2.TYPE_MESSAGE, repeated=True) + """ + Any metadata attached to the method. + """ + + syntax: "Syntax" = betterproto2.field(7, betterproto2.TYPE_ENUM, default_factory=lambda: Syntax.try_value(0)) + """ + The source syntax of this method. + """ + + +default_message_pool.register_message("google.protobuf", "Method", Method) + + +@dataclass(eq=False, repr=False) +class MethodDescriptorProto(betterproto2.Message): + """ + Describes a method of a service. + """ + + name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + + input_type: "str" = betterproto2.field(2, betterproto2.TYPE_STRING) + """ + Input and output type names. These are resolved in the same way as + FieldDescriptorProto.type_name, but must refer to a message type. + """ + + output_type: "str" = betterproto2.field(3, betterproto2.TYPE_STRING) + + options: "Optional[MethodOptions]" = betterproto2.field(4, betterproto2.TYPE_MESSAGE, optional=True) + + client_streaming: "bool" = betterproto2.field(5, betterproto2.TYPE_BOOL) + """ + Identifies if client streams multiple client messages + """ + + server_streaming: "bool" = betterproto2.field(6, betterproto2.TYPE_BOOL) + """ + Identifies if server streams multiple server messages + """ + + +default_message_pool.register_message("google.protobuf", "MethodDescriptorProto", MethodDescriptorProto) + + +@dataclass(eq=False, repr=False) +class MethodOptions(betterproto2.Message): + deprecated: "bool" = betterproto2.field(33, betterproto2.TYPE_BOOL) + """ + 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. + """ + + idempotency_level: "MethodOptionsIdempotencyLevel" = betterproto2.field( + 34, betterproto2.TYPE_ENUM, default_factory=lambda: MethodOptionsIdempotencyLevel.try_value(0) + ) + + features: "Optional[FeatureSet]" = betterproto2.field(35, betterproto2.TYPE_MESSAGE, optional=True) + """ + Any features defined in the specific edition. + """ + + uninterpreted_option: "List[UninterpretedOption]" = betterproto2.field( + 999, betterproto2.TYPE_MESSAGE, repeated=True + ) + """ + The parser stores options it doesn't recognize here. See above. + """ + + +default_message_pool.register_message("google.protobuf", "MethodOptions", MethodOptions) + + +@dataclass(eq=False, repr=False) +class Mixin(betterproto2.Message): + """ + Declares an API Interface to be included in this interface. The including + interface must redeclare all the methods from the included interface, 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 interface 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 inherting + 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"; + } + ... + } + """ + + name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + """ + The fully qualified name of the interface which is included. + """ + + root: "str" = betterproto2.field(2, betterproto2.TYPE_STRING) + """ + If non-empty specifies a path under which inherited HTTP paths + are rooted. + """ + + +default_message_pool.register_message("google.protobuf", "Mixin", Mixin) + + +@dataclass(eq=False, repr=False) +class OneofDescriptorProto(betterproto2.Message): + """ + Describes a oneof. + """ + + name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + + options: "Optional[OneofOptions]" = betterproto2.field(2, betterproto2.TYPE_MESSAGE, optional=True) + + +default_message_pool.register_message("google.protobuf", "OneofDescriptorProto", OneofDescriptorProto) + + +@dataclass(eq=False, repr=False) +class OneofOptions(betterproto2.Message): + features: "Optional[FeatureSet]" = betterproto2.field(1, betterproto2.TYPE_MESSAGE, optional=True) + """ + Any features defined in the specific edition. + """ + + uninterpreted_option: "List[UninterpretedOption]" = betterproto2.field( + 999, betterproto2.TYPE_MESSAGE, repeated=True + ) + """ + The parser stores options it doesn't recognize here. See above. + """ + + +default_message_pool.register_message("google.protobuf", "OneofOptions", OneofOptions) + + +@dataclass(eq=False, repr=False) +class Option(betterproto2.Message): + """ + A protocol buffer option, which can be attached to a message, field, + enumeration, etc. + """ + + name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + """ + The option's name. For protobuf built-in options (options defined in + descriptor.proto), this is the short name. For example, `"map_entry"`. + For custom options, it should be the fully-qualified name. For example, + `"google.api.http"`. + """ + + value: "Optional[Any]" = betterproto2.field(2, betterproto2.TYPE_MESSAGE, optional=True) + """ + The option's value packed in an Any message. If the value is a primitive, + the corresponding wrapper type defined in google/protobuf/wrappers.proto + should be used. If the value is an enum, it should be stored as an int32 + value using the google.protobuf.Int32Value type. + """ + + +default_message_pool.register_message("google.protobuf", "Option", Option) + + +@dataclass(eq=False, repr=False) +class ServiceDescriptorProto(betterproto2.Message): + """ + Describes a service. + """ + + name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + + method: "List[MethodDescriptorProto]" = betterproto2.field(2, betterproto2.TYPE_MESSAGE, repeated=True) + + options: "Optional[ServiceOptions]" = betterproto2.field(3, betterproto2.TYPE_MESSAGE, optional=True) + + +default_message_pool.register_message("google.protobuf", "ServiceDescriptorProto", ServiceDescriptorProto) + + +@dataclass(eq=False, repr=False) +class ServiceOptions(betterproto2.Message): + features: "Optional[FeatureSet]" = betterproto2.field(34, betterproto2.TYPE_MESSAGE, optional=True) + """ + Any features defined in the specific edition. + """ + + deprecated: "bool" = betterproto2.field(33, betterproto2.TYPE_BOOL) + """ + 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. + """ + + uninterpreted_option: "List[UninterpretedOption]" = betterproto2.field( + 999, betterproto2.TYPE_MESSAGE, repeated=True + ) + """ + The parser stores options it doesn't recognize here. See above. + """ + + +default_message_pool.register_message("google.protobuf", "ServiceOptions", ServiceOptions) + + +@dataclass(eq=False, repr=False) +class SourceCodeInfo(betterproto2.Message): + """ + =================================================================== + Optional source code info + + Encapsulates information about the original source file from which a + FileDescriptorProto was generated. + """ + + location: "List[SourceCodeInfoLocation]" = betterproto2.field(1, betterproto2.TYPE_MESSAGE, repeated=True) + """ + 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. + """ + + +default_message_pool.register_message("google.protobuf", "SourceCodeInfo", SourceCodeInfo) + + +@dataclass(eq=False, repr=False) +class SourceCodeInfoLocation(betterproto2.Message): + path: "List[int]" = betterproto2.field(1, betterproto2.TYPE_INT32, repeated=True) + """ + 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 occurs. + 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). + """ + + span: "List[int]" = betterproto2.field(2, betterproto2.TYPE_INT32, repeated=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. + """ + + leading_comments: "str" = betterproto2.field(3, betterproto2.TYPE_STRING) + """ + 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 moo. + // + // Another line attached to moo. + optional double moo = 4; + + // Detached comment for corge. This is not leading or trailing comments + // to moo 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. + """ + + trailing_comments: "str" = betterproto2.field(4, betterproto2.TYPE_STRING) + + leading_detached_comments: "List[str]" = betterproto2.field(6, betterproto2.TYPE_STRING, repeated=True) + + +default_message_pool.register_message("google.protobuf", "SourceCodeInfo.Location", SourceCodeInfoLocation) + + +@dataclass(eq=False, repr=False) +class SourceContext(betterproto2.Message): + """ + `SourceContext` represents information about the source of a + protobuf element, like the file in which it is defined. + """ + + file_name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + """ + The path-qualified name of the .proto file that contained the associated + protobuf element. For example: `"google/protobuf/source_context.proto"`. + """ + + +default_message_pool.register_message("google.protobuf", "SourceContext", SourceContext) + + +@dataclass(eq=False, repr=False) +class StringValue(betterproto2.Message): + """ + Wrapper message for `string`. + + The JSON representation for `StringValue` is JSON string. + """ + + value: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + """ + The string value. + """ + + +default_message_pool.register_message("google.protobuf", "StringValue", StringValue) + + +@dataclass(eq=False, repr=False) +class Struct(betterproto2.Message): + """ + `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. + """ + + fields: "Dict[str, Value]" = betterproto2.field( + 1, betterproto2.TYPE_MAP, map_types=(betterproto2.TYPE_STRING, betterproto2.TYPE_MESSAGE) + ) + """ + Unordered map of dynamically typed values. + """ + + +default_message_pool.register_message("google.protobuf", "Struct", Struct) + + +@dataclass(eq=False, repr=False) +class Timestamp(betterproto2.Message): + """ + A Timestamp represents a point in time independent of any time zone or local + calendar, encoded as a count of seconds and fractions of seconds at + nanosecond resolution. The count is relative to an epoch at UTC midnight on + January 1, 1970, in the proleptic Gregorian calendar which extends the + Gregorian calendar backwards to year one. + + All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap + second table is needed for interpretation, using a [24-hour linear + smear](https://developers.google.com/time/smear). + + The 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](https://www.ietf.org/rfc/rfc3339.txt) date strings. + + # Examples + + 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 Java `Instant.now()`. + + Instant now = Instant.now(); + + Timestamp timestamp = + Timestamp.newBuilder().setSeconds(now.getEpochSecond()) + .setNanos(now.getNano()).build(); + + Example 6: Compute Timestamp from current time in Python. + + timestamp = Timestamp() + timestamp.GetCurrentTime() + + # JSON Mapping + + In JSON format, the Timestamp type is encoded as a string in the + [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the + format is "{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 (i.e. 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). + + For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past + 01:30 UTC on January 15, 2017. + + In JavaScript, one can convert a Date object to this format using the + standard + [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) + method. In Python, a standard `datetime.datetime` object can be converted + to this format using + [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with + the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use + the Joda Time's [`ISODateTimeFormat.dateTime()`]( + http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime() + ) to obtain a formatter capable of generating timestamps in this format. + """ + + seconds: "int" = betterproto2.field(1, betterproto2.TYPE_INT64) + """ + 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. + """ + + nanos: "int" = betterproto2.field(2, betterproto2.TYPE_INT32) + """ + 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. + """ + + @classmethod + def from_datetime(cls, dt: datetime.datetime) -> "Timestamp": + # manual epoch offset calulation to avoid rounding errors, + # to support negative timestamps (before 1970) and skirt + # around datetime bugs (apparently 0 isn't a year in [0, 9999]??) + offset = dt - datetime.datetime(1970, 1, 1, tzinfo=datetime.timezone.utc) + # below is the same as timedelta.total_seconds() but without dividing by 1e6 + # so we end up with microseconds as integers instead of seconds as float + offset_us = (offset.days * 24 * 60 * 60 + offset.seconds) * 10**6 + offset.microseconds + seconds, us = divmod(offset_us, 10**6) + return cls(seconds, us * 1000) + + def to_datetime(self) -> datetime.datetime: + # datetime.fromtimestamp() expects a timestamp in seconds, not microseconds + # if we pass it as a floating point number, we will run into rounding errors + # see also #407 + offset = datetime.timedelta(seconds=self.seconds, microseconds=self.nanos // 1000) + return datetime.datetime(1970, 1, 1, tzinfo=datetime.timezone.utc) + offset + + @staticmethod + def timestamp_to_json(dt: datetime.datetime) -> str: + nanos = dt.microsecond * 1e3 + if dt.tzinfo is not None: + # change timezone aware datetime objects to utc + dt = dt.astimezone(datetime.timezone.utc) + copy = dt.replace(microsecond=0, tzinfo=None) + result = copy.isoformat() + if (nanos % 1e9) == 0: + # If there are 0 fractional digits, the fractional + # point '.' should be omitted when serializing. + return f"{result}Z" + if (nanos % 1e6) == 0: + # Serialize 3 fractional digits. + return f"{result}.{int(nanos // 1e6) :03d}Z" + if (nanos % 1e3) == 0: + # Serialize 6 fractional digits. + return f"{result}.{int(nanos // 1e3) :06d}Z" + # Serialize 9 fractional digits. + return f"{result}.{nanos:09d}" + + +default_message_pool.register_message("google.protobuf", "Timestamp", Timestamp) + + +@dataclass(eq=False, repr=False) +class Type(betterproto2.Message): + """ + A protocol buffer message type. + """ + + name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + """ + The fully qualified message name. + """ + + fields: "List[Field]" = betterproto2.field(2, betterproto2.TYPE_MESSAGE, repeated=True) + """ + The list of fields. + """ + + oneofs: "List[str]" = betterproto2.field(3, betterproto2.TYPE_STRING, repeated=True) + """ + The list of types appearing in `oneof` definitions in this type. + """ + + options: "List[Option]" = betterproto2.field(4, betterproto2.TYPE_MESSAGE, repeated=True) + """ + The protocol buffer options. + """ + + source_context: "Optional[SourceContext]" = betterproto2.field(5, betterproto2.TYPE_MESSAGE, optional=True) + """ + The source context. + """ + + syntax: "Syntax" = betterproto2.field(6, betterproto2.TYPE_ENUM, default_factory=lambda: Syntax.try_value(0)) + """ + The source syntax. + """ + + edition: "str" = betterproto2.field(7, betterproto2.TYPE_STRING) + """ + The source edition string, only valid when syntax is SYNTAX_EDITIONS. + """ + + +default_message_pool.register_message("google.protobuf", "Type", Type) + + +@dataclass(eq=False, repr=False) +class UInt32Value(betterproto2.Message): + """ + Wrapper message for `uint32`. + + The JSON representation for `UInt32Value` is JSON number. + """ + + value: "int" = betterproto2.field(1, betterproto2.TYPE_UINT32) + """ + The uint32 value. + """ + + +default_message_pool.register_message("google.protobuf", "UInt32Value", UInt32Value) + + +@dataclass(eq=False, repr=False) +class UInt64Value(betterproto2.Message): + """ + Wrapper message for `uint64`. + + The JSON representation for `UInt64Value` is JSON string. + """ + + value: "int" = betterproto2.field(1, betterproto2.TYPE_UINT64) + """ + The uint64 value. + """ + + +default_message_pool.register_message("google.protobuf", "UInt64Value", UInt64Value) + + +@dataclass(eq=False, repr=False) +class UninterpretedOption(betterproto2.Message): + """ + 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. + """ + + name: "List[UninterpretedOptionNamePart]" = betterproto2.field(2, betterproto2.TYPE_MESSAGE, repeated=True) + + identifier_value: "str" = betterproto2.field(3, betterproto2.TYPE_STRING) + """ + The value of the uninterpreted option, in whatever type the tokenizer + identified it as during parsing. Exactly one of these should be set. + """ + + positive_int_value: "int" = betterproto2.field(4, betterproto2.TYPE_UINT64) + + negative_int_value: "int" = betterproto2.field(5, betterproto2.TYPE_INT64) + + double_value: "float" = betterproto2.field(6, betterproto2.TYPE_DOUBLE) + + string_value: "bytes" = betterproto2.field(7, betterproto2.TYPE_BYTES) + + aggregate_value: "str" = betterproto2.field(8, betterproto2.TYPE_STRING) + + +default_message_pool.register_message("google.protobuf", "UninterpretedOption", UninterpretedOption) + + +@dataclass(eq=False, repr=False) +class UninterpretedOptionNamePart(betterproto2.Message): + """ + 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], ["moo", false] } represents + "foo.(bar.baz).moo". + """ + + name_part: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) + + is_extension: "bool" = betterproto2.field(2, betterproto2.TYPE_BOOL) + + +default_message_pool.register_message("google.protobuf", "UninterpretedOption.NamePart", UninterpretedOptionNamePart) + + +@dataclass(eq=False, repr=False) +class Value(betterproto2.Message): + """ + `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 these + variants. Absence of any variant indicates an error. + + The JSON representation for `Value` is JSON value. + + Oneofs: + - kind: The kind of value. + """ + + null_value: "Optional[NullValue]" = betterproto2.field(1, betterproto2.TYPE_ENUM, optional=True, group="kind") + """ + Represents a null value. + """ + + number_value: "Optional[float]" = betterproto2.field(2, betterproto2.TYPE_DOUBLE, optional=True, group="kind") + """ + Represents a double value. + """ + + string_value: "Optional[str]" = betterproto2.field(3, betterproto2.TYPE_STRING, optional=True, group="kind") + """ + Represents a string value. + """ + + bool_value: "Optional[bool]" = betterproto2.field(4, betterproto2.TYPE_BOOL, optional=True, group="kind") + """ + Represents a boolean value. + """ + + struct_value: "Optional[Struct]" = betterproto2.field(5, betterproto2.TYPE_MESSAGE, optional=True, group="kind") + """ + Represents a structured value. + """ + + list_value: "Optional[ListValue]" = betterproto2.field(6, betterproto2.TYPE_MESSAGE, optional=True, group="kind") + """ + Represents a repeated `Value`. + """ + + +default_message_pool.register_message("google.protobuf", "Value", Value) diff --git a/src/betterproto2_compiler/lib/google/protobuf/compiler/__init__.py b/src/betterproto2_compiler/lib/google/protobuf/compiler/__init__.py index da6f5df0..4f69a1af 100644 --- a/src/betterproto2_compiler/lib/google/protobuf/compiler/__init__.py +++ b/src/betterproto2_compiler/lib/google/protobuf/compiler/__init__.py @@ -1,5 +1,5 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! -# sources: plugin.proto +# sources: google/protobuf/compiler/plugin.proto # plugin: python-betterproto2 # This file has been @generated @@ -14,17 +14,15 @@ from dataclasses import dataclass from typing import ( - TYPE_CHECKING, List, Optional, ) import betterproto2 -if TYPE_CHECKING: - pass +from ....message_pool import default_message_pool -betterproto2.check_compiler_version("0.1.0") +betterproto2.check_compiler_version("0.1.1") class CodeGeneratorResponseFeature(betterproto2.Enum): @@ -43,7 +41,6 @@ class CodeGeneratorResponseFeature(betterproto2.Enum): class CodeGeneratorRequest(betterproto2.Message): """ An encoded CodeGeneratorRequest is written to the plugin's stdin. - """ file_to_generate: "List[str]" = betterproto2.field(1, betterproto2.TYPE_STRING, repeated=True) @@ -52,11 +49,13 @@ class CodeGeneratorRequest(betterproto2.Message): code generator should generate code only for these files. Each file's descriptor will be included in proto_file, below. """ + parameter: "str" = betterproto2.field(2, betterproto2.TYPE_STRING) """ The generator parameter passed on the command-line. """ - proto_file: "List[betterproto2_lib_google_protobuf.FileDescriptorProto]" = betterproto2.field( + + proto_file: "List[__protobuf__.FileDescriptorProto]" = betterproto2.field( 15, betterproto2.TYPE_MESSAGE, repeated=True ) """ @@ -80,7 +79,8 @@ class CodeGeneratorRequest(betterproto2.Message): Type names of fields and extensions in the FileDescriptorProto are always fully qualified. """ - source_file_descriptors: "List[betterproto2_lib_google_protobuf.FileDescriptorProto]" = betterproto2.field( + + source_file_descriptors: "List[__protobuf__.FileDescriptorProto]" = betterproto2.field( 17, betterproto2.TYPE_MESSAGE, repeated=True ) """ @@ -88,17 +88,20 @@ class CodeGeneratorRequest(betterproto2.Message): These descriptors are only provided for the files listed in files_to_generate. """ + compiler_version: "Optional[Version]" = betterproto2.field(3, betterproto2.TYPE_MESSAGE, optional=True) """ The version number of protocol compiler. """ +default_message_pool.register_message("google.protobuf.compiler", "CodeGeneratorRequest", CodeGeneratorRequest) + + @dataclass(eq=False, repr=False) class CodeGeneratorResponse(betterproto2.Message): """ The plugin writes an encoded CodeGeneratorResponse to stdout. - """ error: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) @@ -112,33 +115,23 @@ class CodeGeneratorResponse(betterproto2.Message): unparseable -- should be reported by writing a message to stderr and exiting with a non-zero status code. """ + supported_features: "int" = betterproto2.field(2, betterproto2.TYPE_UINT64) """ A bitmask of supported features that the code generator supports. This is a bitwise "or" of values from the Feature enum. """ - minimum_edition: "int" = betterproto2.field(3, betterproto2.TYPE_INT32) - """ - The minimum edition this plugin supports. This will be treated as an - Edition enum, but we want to allow unknown values. It should be specified - according the edition enum value, *not* the edition number. Only takes - effect for plugins that have FEATURE_SUPPORTS_EDITIONS set. - """ - maximum_edition: "int" = betterproto2.field(4, betterproto2.TYPE_INT32) - """ - The maximum edition this plugin supports. This will be treated as an - Edition enum, but we want to allow unknown values. It should be specified - according the edition enum value, *not* the edition number. Only takes - effect for plugins that have FEATURE_SUPPORTS_EDITIONS set. - """ + file: "List[CodeGeneratorResponseFile]" = betterproto2.field(15, betterproto2.TYPE_MESSAGE, repeated=True) +default_message_pool.register_message("google.protobuf.compiler", "CodeGeneratorResponse", CodeGeneratorResponse) + + @dataclass(eq=False, repr=False) class CodeGeneratorResponseFile(betterproto2.Message): """ Represents a single generated file. - """ name: "str" = betterproto2.field(1, betterproto2.TYPE_STRING) @@ -155,6 +148,7 @@ class CodeGeneratorResponseFile(betterproto2.Message): this writing protoc does not optimize for this -- it will read the entire CodeGeneratorResponse before writing files to disk. """ + insertion_point: "str" = betterproto2.field(2, betterproto2.TYPE_STRING) """ If non-empty, indicates that the named file should already exist, and the @@ -195,11 +189,13 @@ class CodeGeneratorResponseFile(betterproto2.Message): If |insertion_point| is present, |name| must also be present. """ + content: "str" = betterproto2.field(15, betterproto2.TYPE_STRING) """ The file contents. """ - generated_code_info: "Optional[betterproto2_lib_google_protobuf.GeneratedCodeInfo]" = betterproto2.field( + + generated_code_info: "Optional[__protobuf__.GeneratedCodeInfo]" = betterproto2.field( 16, betterproto2.TYPE_MESSAGE, optional=True ) """ @@ -209,16 +205,23 @@ class CodeGeneratorResponseFile(betterproto2.Message): """ +default_message_pool.register_message( + "google.protobuf.compiler", "CodeGeneratorResponse.File", CodeGeneratorResponseFile +) + + @dataclass(eq=False, repr=False) class Version(betterproto2.Message): """ The version number of protocol compiler. - """ major: "int" = betterproto2.field(1, betterproto2.TYPE_INT32) + minor: "int" = betterproto2.field(2, betterproto2.TYPE_INT32) + patch: "int" = betterproto2.field(3, betterproto2.TYPE_INT32) + suffix: "str" = betterproto2.field(4, betterproto2.TYPE_STRING) """ A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should @@ -226,4 +229,7 @@ class Version(betterproto2.Message): """ -import betterproto2.lib.google.protobuf as betterproto2_lib_google_protobuf +default_message_pool.register_message("google.protobuf.compiler", "Version", Version) + + +from ... import protobuf as __protobuf__ diff --git a/src/betterproto2_compiler/lib/message_pool.py b/src/betterproto2_compiler/lib/message_pool.py new file mode 100644 index 00000000..cab002cf --- /dev/null +++ b/src/betterproto2_compiler/lib/message_pool.py @@ -0,0 +1,3 @@ +import betterproto2 + +default_message_pool = betterproto2.MessagePool() diff --git a/src/betterproto2_compiler/plugin/main.py b/src/betterproto2_compiler/plugin/main.py index eaa3ef56..3a8d2f84 100755 --- a/src/betterproto2_compiler/plugin/main.py +++ b/src/betterproto2_compiler/plugin/main.py @@ -6,8 +6,6 @@ from betterproto2_compiler.lib.google.protobuf.compiler import ( CodeGeneratorRequest, ) - -# from betterproto.plugin.models import monkey_patch_oneof_index from betterproto2_compiler.plugin.parser import generate_code @@ -16,9 +14,6 @@ def main() -> None: # Read request message from stdin data = sys.stdin.buffer.read() - # Apply Work around for proto2/3 difference in protoc messages - # monkey_patch_oneof_index() - # Parse request request = CodeGeneratorRequest() request.parse(data) diff --git a/src/betterproto2_compiler/plugin/models.py b/src/betterproto2_compiler/plugin/models.py index 8d2029cd..71f91a72 100644 --- a/src/betterproto2_compiler/plugin/models.py +++ b/src/betterproto2_compiler/plugin/models.py @@ -35,7 +35,16 @@ import betterproto2 from betterproto2 import unwrap -from betterproto2.lib.google.protobuf import ( + +from betterproto2_compiler.compile.importing import get_type_reference, parse_source_type_name +from betterproto2_compiler.compile.naming import ( + pythonize_class_name, + pythonize_enum_member_name, + pythonize_field_name, + pythonize_method_name, +) +from betterproto2_compiler.known_types import KNOWN_METHODS +from betterproto2_compiler.lib.google.protobuf import ( DescriptorProto, EnumDescriptorProto, FieldDescriptorProto, @@ -47,15 +56,6 @@ OneofDescriptorProto, ServiceDescriptorProto, ) - -from betterproto2_compiler.compile.importing import get_type_reference, parse_source_type_name -from betterproto2_compiler.compile.naming import ( - pythonize_class_name, - pythonize_enum_member_name, - pythonize_field_name, - pythonize_method_name, -) -from betterproto2_compiler.known_types import KNOWN_METHODS from betterproto2_compiler.lib.google.protobuf.compiler import CodeGeneratorRequest from betterproto2_compiler.plugin.typing_compiler import TypingCompiler from betterproto2_compiler.settings import Settings diff --git a/src/betterproto2_compiler/plugin/parser.py b/src/betterproto2_compiler/plugin/parser.py index f3cb01d9..cdea4999 100644 --- a/src/betterproto2_compiler/plugin/parser.py +++ b/src/betterproto2_compiler/plugin/parser.py @@ -2,13 +2,12 @@ import sys from collections.abc import Generator -from betterproto2.lib.google.protobuf import ( +from betterproto2_compiler.lib.google.protobuf import ( DescriptorProto, EnumDescriptorProto, FileDescriptorProto, ServiceDescriptorProto, ) - from betterproto2_compiler.lib.google.protobuf.compiler import ( CodeGeneratorRequest, CodeGeneratorResponse, From a91ab5643a9560331e869f8f02e52689e9805f14 Mon Sep 17 00:00:00 2001 From: Adrien Vannson Date: Thu, 16 Jan 2025 14:51:50 +0100 Subject: [PATCH 2/3] Switch to betterproto release --- poetry.lock | 24 ++++++++----------- pyproject.toml | 5 ++-- .../lib/google/protobuf/__init__.py | 2 +- .../lib/google/protobuf/compiler/__init__.py | 2 +- 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index dd038e46..b3f690a9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -71,27 +71,23 @@ dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] [[package]] name = "betterproto2" -version = "0.1.3" +version = "0.2.1" description = "A better Protobuf / gRPC generator & library" optional = false -python-versions = "^3.8" -files = [] -develop = false +python-versions = "<4.0,>=3.8" +files = [ + {file = "betterproto2-0.2.1-py3-none-any.whl", hash = "sha256:d0da619a87a8b39a3322aa510abb817c8d72ef641a9438cadbd79df029edd802"}, + {file = "betterproto2-0.2.1.tar.gz", hash = "sha256:fc278c54e74d590a023e30f1e31ec3a9868c6ea84256c70e956557febf43eca9"}, +] [package.dependencies] -grpclib = "^0.4.1" -python-dateutil = "^2.8" -typing-extensions = "^4.7.1" +grpclib = ">=0.4.1,<0.5.0" +python-dateutil = ">=2.8,<3.0" +typing-extensions = ">=4.7.1,<5.0.0" [package.extras] rust-codec = ["betterproto-rust-codec (==0.1.1)"] -[package.source] -type = "git" -url = "https://github.com/betterproto/python-betterproto2" -reference = "HEAD" -resolved_reference = "bbde43b56211741cdb87dad56c252cebec083803" - [[package]] name = "certifi" version = "2024.12.14" @@ -2182,4 +2178,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "14c1da07e2394ff96ac77edbe307cdb176524248e24936bf090f5f1aea6496d2" +content-hash = "740f7295a79b9044161729117aa8f28c93af030c8b3fc2180ac06c42c9177c44" diff --git a/pyproject.toml b/pyproject.toml index 057e3d18..e5c9696f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "betterproto2_compiler" -version = "0.1.1" +version = "0.2.0" description = "Compiler for betterproto2" authors = ["Adrien Vannson ", "Daniel G. Taylor "] readme = "README.md" @@ -13,8 +13,7 @@ packages = [ [tool.poetry.dependencies] python = "^3.10" -# betterproto2 = "^0.1.3" -betterproto2 = { git = "https://github.com/betterproto/python-betterproto2" } +betterproto2 = "^0.2.1" # The Ruff version is pinned. To update it, also update it in .pre-commit-config.yaml ruff = "~0.7.4" grpclib = "^0.4.1" diff --git a/src/betterproto2_compiler/lib/google/protobuf/__init__.py b/src/betterproto2_compiler/lib/google/protobuf/__init__.py index 341fb49c..dbc4cf47 100644 --- a/src/betterproto2_compiler/lib/google/protobuf/__init__.py +++ b/src/betterproto2_compiler/lib/google/protobuf/__init__.py @@ -98,7 +98,7 @@ from ...message_pool import default_message_pool -betterproto2.check_compiler_version("0.1.1") +betterproto2.check_compiler_version("0.2.0") class Edition(betterproto2.Enum): diff --git a/src/betterproto2_compiler/lib/google/protobuf/compiler/__init__.py b/src/betterproto2_compiler/lib/google/protobuf/compiler/__init__.py index 4f69a1af..eeae42dc 100644 --- a/src/betterproto2_compiler/lib/google/protobuf/compiler/__init__.py +++ b/src/betterproto2_compiler/lib/google/protobuf/compiler/__init__.py @@ -22,7 +22,7 @@ from ....message_pool import default_message_pool -betterproto2.check_compiler_version("0.1.1") +betterproto2.check_compiler_version("0.2.0") class CodeGeneratorResponseFeature(betterproto2.Enum): From 0003c4fc7e3613ee3144047e8dec7a3ab26e5e9d Mon Sep 17 00:00:00 2001 From: Adrien Vannson Date: Thu, 16 Jan 2025 14:52:31 +0100 Subject: [PATCH 3/3] Fix typechecking --- src/betterproto2_compiler/known_types/any.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/betterproto2_compiler/known_types/any.py b/src/betterproto2_compiler/known_types/any.py index 6ed4d631..6952b52e 100644 --- a/src/betterproto2_compiler/known_types/any.py +++ b/src/betterproto2_compiler/known_types/any.py @@ -2,9 +2,7 @@ from betterproto2_compiler.lib.google.protobuf import Any as VanillaAny -# TODO put back -# default_message_pool = betterproto2.MessagePool() # Only for typing purpose -default_message_pool = ... +default_message_pool = betterproto2.MessagePool() # Only for typing purpose class Any(VanillaAny):