diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a4c3062..19e1593 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,17 +18,17 @@ jobs: os: [Ubuntu, MacOS, Windows] python-version: ['3.9', '3.10', '3.11', '3.12'] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Get full Python version id: full-python-version shell: bash - run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))") + run: echo "version=$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")" >> "$GITHUB_OUTPUT" - name: Install poetry shell: bash diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9e3f65a..4980047 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,9 +20,10 @@ repos: additional_dependencies: - toml - - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks - rev: v2.10.0 - hooks: - - id: pretty-format-java - args: [--autofix, --aosp] - files: ^.*\.java$ + # Removing since aristaproto don't use the java code and this breaks CI. + # - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks + # rev: v2.10.0 + # hooks: + # - id: pretty-format-java + # args: [--autofix, --aosp] + # files: ^.*\.java$ diff --git a/README.md b/README.md index a156123..31a18a9 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,15 @@ # Arista Protobuf / Python gRPC bindings generator & library -This project is forked from @ [b8a091ae7055dd949d193695a06c9536ad51eea8](https://github.com/danielgtaylor/python-betterproto/commit/b8a091ae7055dd949d193695a06c9536ad51eea8) +This was originally forked from @ [b8a091ae7055dd949d193695a06c9536ad51eea8](https://github.com/danielgtaylor/python-betterproto/commit/b8a091ae7055dd949d193695a06c9536ad51eea8). + +Afterwards commits up to `1f88b67eeb9871d33da154fd2c859b9d1aed62c1` on `python-betterproto` have been cherry-picked. Changes in this project compared with the base project: +- Renamed to `aristaproto`. +- Cut support for Python < 3.9. +- Updating various CI actions and dependencies. +- Merged docs from multiple `rst` files to MarkDown. - Keep nanosecond precision for `Timestamp`. - Subclass `datetime` to store the original nano-second value when converting from `Timestamp` to `datetime`. - On conversion from the subclass of `datetime` to `Timestamp` the original nano-second value is restored. @@ -20,8 +26,6 @@ pip install "aristaproto[compiler]" pip install aristaproto ``` -*Betterproto* is under active development. To install the latest beta version, use `pip install --pre aristaproto`. - ## Getting Started ### Compiling proto files @@ -244,7 +248,22 @@ message Test { } ``` -You can use `aristaproto.which_one_of(message, group_name)` to determine which of the fields was set. It returns a tuple of the field name and value, or a blank string and `None` if unset. +On Python 3.10 and later, you can use a `match` statement to access the provided one-of field, which supports type-checking: + +```py +test = Test() +match test: + case Test(on=value): + print(value) # value: bool + case Test(count=value): + print(value) # value: int + case Test(name=value): + print(value) # value: str + case _: + print("No value provided") +``` + +You can also use `aristaproto.which_one_of(message, group_name)` to determine which of the fields was set. It returns a tuple of the field name and value, or a blank string and `None` if unset. ```py >>> test = Test() @@ -259,17 +278,11 @@ You can use `aristaproto.which_one_of(message, group_name)` to determine which o >>> test.count = 57 >>> aristaproto.which_one_of(test, "foo") ["count", 57] ->>> test.on -False # Default (zero) values also work. >>> test.name = "" >>> aristaproto.which_one_of(test, "foo") ["name", ""] ->>> test.count -0 ->>> test.on -False ``` Again this is a little different than the official Google code generator: diff --git a/poetry.lock b/poetry.lock index d0100d9..eed3b66 100644 --- a/poetry.lock +++ b/poetry.lock @@ -54,22 +54,22 @@ dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] [[package]] name = "betterproto-rust-codec" -version = "0.1.0" +version = "0.1.1" description = "Fast conversion between betterproto messages and Protobuf wire format." optional = true python-versions = ">=3.7" files = [ - {file = "betterproto_rust_codec-0.1.0-cp37-abi3-macosx_10_7_x86_64.whl", hash = "sha256:3e7bea088f5f630cf123b56b1e1da7b35a22a295561825dd7c1446fa841876c3"}, - {file = "betterproto_rust_codec-0.1.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:d1706da37a162d72de557ae3e285d04bb66cf129584d380439266e6e0d60c70a"}, - {file = "betterproto_rust_codec-0.1.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07aeb3471e9ea3f142f79673b1057810a133c8285aa0a606c53a43a3e28c37da"}, - {file = "betterproto_rust_codec-0.1.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b905251be0eae0e7605ecf4a2d60f8c54f3a3c5e6d1d732a0060a18d69cf5e4"}, - {file = "betterproto_rust_codec-0.1.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c82353cd2a53f0ced0546d94dd5b18026eed1231a7658e6d5876cc09b1cfdae8"}, - {file = "betterproto_rust_codec-0.1.0-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b881d5a54e8ac7a898fc7f27971e91a6596d344faf342a262cecfa5b1f0dc1a"}, - {file = "betterproto_rust_codec-0.1.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fc2d2d11d62a91b75d94783518563673972ad2c99bee9fd16176d3cd4c15d76"}, - {file = "betterproto_rust_codec-0.1.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1f9b99f776ce1da52f83715b926b61f2ad52fdf1e6d7dec0aea5fb471cd468b1"}, - {file = "betterproto_rust_codec-0.1.0-cp37-abi3-win32.whl", hash = "sha256:2f98155920ff409551208820224ac62564e8dd89d7caed86f8cd519fc7e05568"}, - {file = "betterproto_rust_codec-0.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:8e32f75cf59d5faaa5efb00c268fa22f47def0855c3395e5accccf296b2243be"}, - {file = "betterproto_rust_codec-0.1.0.tar.gz", hash = "sha256:090c23accb23e8f167dabab6fab70d30ae20f587e677c2da4a88982c5fafc5d1"}, + {file = "betterproto_rust_codec-0.1.1-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:38ec2ec1743d815a04ffc020e8e3791955601b239b097e4ae0721528d4d8b608"}, + {file = "betterproto_rust_codec-0.1.1-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:96a6deef8cda4b4d084df98b621e39a3123d8878dab551b86bbe733d885c4965"}, + {file = "betterproto_rust_codec-0.1.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:72ce9f153c83b1d0559ab40b0d6a31d8b83ac486230cefc298c8a08f4a97738b"}, + {file = "betterproto_rust_codec-0.1.1-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b8a8485aabbe843208307a9a2c3fc8a8c09295fb22c840cebd5fa7ec6b8ddb36"}, + {file = "betterproto_rust_codec-0.1.1-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22a395bf0c9dc86b7d3783ba43f161cd9f7a42809f38c70673cd9999d40eb4f1"}, + {file = "betterproto_rust_codec-0.1.1-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea99bee659b33500bb1afc4e0dbfa63530f50a7c549d0687565a10a0de63d18f"}, + {file = "betterproto_rust_codec-0.1.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:913d73365780d8f3da04cbaa1b2428ca5dc5372a5ee6f4ff2b9f30127362dff7"}, + {file = "betterproto_rust_codec-0.1.1-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a16dbbbc48f4a27b3b70205a2a71baa53fe0e915bc347b75d9b3864326446fa"}, + {file = "betterproto_rust_codec-0.1.1-cp37-abi3-win32.whl", hash = "sha256:06f95ac4c92aa1f28bd1be884c6db86f0bed05c9b93a1e4e3d80bbe2fc66847c"}, + {file = "betterproto_rust_codec-0.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:5b70b3aea76f336cc243b966f2f7496cb6366ad2679d7a999ff521d873f9de48"}, + {file = "betterproto_rust_codec-0.1.1.tar.gz", hash = "sha256:6f7cbe80c8e3f87df992d71568771082c869ed6856521e01db833d9d3b012af5"}, ] [[package]] @@ -1398,7 +1398,6 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -1758,4 +1757,4 @@ rust-codec = ["betterproto-rust-codec"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "4e4a7861f06b1607ace55482237e68a5e8323280f4efdd8238eeb0278e041416" +content-hash = "220432db3c5f79d611514dcc019773c7d7ef3bed9b2dc6b1bc96e77585b559d2" diff --git a/pyproject.toml b/pyproject.toml index 198f599..6e737ab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aristaproto" -version = "0.1.1" +version = "0.1.2" description = "Arista Protobuf / Python gRPC bindings generator & library" authors = ["Arista Networks "] readme = "README.md" @@ -19,7 +19,7 @@ jinja2 = { version = ">=3.0.3", optional = true } python-dateutil = "^2.8" isort = {version = "^5.11.5", optional = true} typing-extensions = "^4.7.1" -betterproto-rust-codec = { version = "0.1.0", optional = true } +betterproto-rust-codec = { version = "0.1.1", optional = true } [tool.poetry.group.dev.dependencies] asv = "^0.4.2" @@ -94,11 +94,11 @@ cmd = """ protoc --plugin=protoc-gen-custom=src/aristaproto/plugin/main.py --custom_opt=INCLUDE_GOOGLE - --custom_out=src/aristaproto/lib + --custom_out=src/aristaproto/lib/std -I /usr/local/include/ /usr/local/include/google/protobuf/**/*.proto """ -help = "Regenerate the types in aristaproto.lib.google" +help = "Regenerate the types in aristaproto.lib.std.google" # CI tasks diff --git a/src/aristaproto/__init__.py b/src/aristaproto/__init__.py index 74cccf4..79d71c5 100644 --- a/src/aristaproto/__init__.py +++ b/src/aristaproto/__init__.py @@ -759,7 +759,7 @@ def __post_init__(self) -> None: group_current.setdefault(meta.group) value = self.__raw_get(field_name) - if value != PLACEHOLDER and not (meta.optional and value is None): + if value is not PLACEHOLDER and not (meta.optional and value is None): # Found a non-sentinel value all_sentinel = False diff --git a/src/aristaproto/compile/importing.py b/src/aristaproto/compile/importing.py index 118d7a4..8486ddd 100644 --- a/src/aristaproto/compile/importing.py +++ b/src/aristaproto/compile/importing.py @@ -43,7 +43,12 @@ def parse_source_type_name(field_type_name: str) -> Tuple[str, str]: def get_type_reference( - *, package: str, imports: set, source_type: str, unwrap: bool = True + *, + package: str, + imports: set, + source_type: str, + unwrap: bool = True, + pydantic: bool = False, ) -> str: """ Return a Python type name for a proto type reference. Adds the import if @@ -69,7 +74,9 @@ def get_type_reference( compiling_google_protobuf = current_package == ["google", "protobuf"] importing_google_protobuf = py_package == ["google", "protobuf"] if importing_google_protobuf and not compiling_google_protobuf: - py_package = ["aristaproto", "lib"] + py_package + py_package = ( + ["aristaproto", "lib"] + (["pydantic"] if pydantic else []) + py_package + ) if py_package[:1] == ["aristaproto"]: return reference_absolute(imports, py_package, py_type) diff --git a/src/aristaproto/enum.py b/src/aristaproto/enum.py index 0540426..8535e86 100644 --- a/src/aristaproto/enum.py +++ b/src/aristaproto/enum.py @@ -149,6 +149,12 @@ def __delattr__(self, item: Any) -> Never: f"{self.__class__.__name__} Cannot delete a member's attributes." ) + def __copy__(self) -> Self: + return self + + def __deepcopy__(self, memo: Any) -> Self: + return self + @classmethod def try_value(cls, value: int = 0) -> Self: """Return the value which corresponds to the value. diff --git a/src/aristaproto/lib/google/protobuf/__init__.py b/src/aristaproto/lib/google/protobuf/__init__.py index 99b6c17..f8aad1e 100644 --- a/src/aristaproto/lib/google/protobuf/__init__.py +++ b/src/aristaproto/lib/google/protobuf/__init__.py @@ -1,1670 +1 @@ -# 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-aristaproto -# This file has been @generated -import warnings -from dataclasses import dataclass -from typing import ( - Dict, - List, -) - -import aristaproto - - -class Syntax(aristaproto.Enum): - """The syntax in which a protocol buffer element is defined.""" - - SYNTAX_PROTO2 = 0 - """Syntax `proto2`.""" - - SYNTAX_PROTO3 = 1 - """Syntax `proto3`.""" - - -class FieldKind(aristaproto.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 FieldCardinality(aristaproto.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 FieldDescriptorProtoType(aristaproto.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 in - proto3. However, Proto3 implementations should still be able to parse the - group wire format and treat group fields as unknown fields. - """ - - TYPE_MESSAGE = 11 - TYPE_BYTES = 12 - """New in version 2.""" - - TYPE_UINT32 = 13 - TYPE_ENUM = 14 - TYPE_SFIXED32 = 15 - TYPE_SFIXED64 = 16 - TYPE_SINT32 = 17 - TYPE_SINT64 = 18 - - -class FieldDescriptorProtoLabel(aristaproto.Enum): - LABEL_OPTIONAL = 1 - """0 is reserved for errors""" - - LABEL_REQUIRED = 2 - LABEL_REPEATED = 3 - - -class FileOptionsOptimizeMode(aristaproto.Enum): - """Generated classes can be optimized for speed or code size.""" - - SPEED = 1 - CODE_SIZE = 2 - """etc.""" - - LITE_RUNTIME = 3 - - -class FieldOptionsCType(aristaproto.Enum): - STRING = 0 - """Default mode.""" - - CORD = 1 - STRING_PIECE = 2 - - -class FieldOptionsJsType(aristaproto.Enum): - JS_NORMAL = 0 - """Use the default type.""" - - JS_STRING = 1 - """Use JavaScript strings.""" - - JS_NUMBER = 2 - """Use JavaScript numbers.""" - - -class MethodOptionsIdempotencyLevel(aristaproto.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 - IDEMPOTENT = 2 - - -class NullValue(aristaproto.Enum): - """ - `NullValue` is a singleton enumeration to represent the null value for the - `Value` type union. The JSON representation for `NullValue` is JSON - `null`. - """ - - NULL_VALUE = 0 - """Null value.""" - - -@dataclass(eq=False, repr=False) -class Any(aristaproto.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); } - 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 = aristaproto.string_field(1) - """ - 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. - Schemes other than `http`, `https` (or the empty scheme) might be used with - implementation specific semantics. - """ - - value: bytes = aristaproto.bytes_field(2) - """ - Must be a valid serialized protocol buffer of the above specified type. - """ - - -@dataclass(eq=False, repr=False) -class SourceContext(aristaproto.Message): - """ - `SourceContext` represents information about the source of a protobuf - element, like the file in which it is defined. - """ - - file_name: str = aristaproto.string_field(1) - """ - The path-qualified name of the .proto file that contained the associated - protobuf element. For example: `"google/protobuf/source_context.proto"`. - """ - - -@dataclass(eq=False, repr=False) -class Type(aristaproto.Message): - """A protocol buffer message type.""" - - name: str = aristaproto.string_field(1) - """The fully qualified message name.""" - - fields: List["Field"] = aristaproto.message_field(2) - """The list of fields.""" - - oneofs: List[str] = aristaproto.string_field(3) - """The list of types appearing in `oneof` definitions in this type.""" - - options: List["Option"] = aristaproto.message_field(4) - """The protocol buffer options.""" - - source_context: "SourceContext" = aristaproto.message_field(5) - """The source context.""" - - syntax: "Syntax" = aristaproto.enum_field(6) - """The source syntax.""" - - -@dataclass(eq=False, repr=False) -class Field(aristaproto.Message): - """A single field of a message type.""" - - kind: "FieldKind" = aristaproto.enum_field(1) - """The field type.""" - - cardinality: "FieldCardinality" = aristaproto.enum_field(2) - """The field cardinality.""" - - number: int = aristaproto.int32_field(3) - """The field number.""" - - name: str = aristaproto.string_field(4) - """The field name.""" - - type_url: str = aristaproto.string_field(6) - """ - The field type URL, without the scheme, for message or enumeration types. - Example: `"type.googleapis.com/google.protobuf.Timestamp"`. - """ - - oneof_index: int = aristaproto.int32_field(7) - """ - 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 = aristaproto.bool_field(8) - """Whether to use alternative packed wire representation.""" - - options: List["Option"] = aristaproto.message_field(9) - """The protocol buffer options.""" - - json_name: str = aristaproto.string_field(10) - """The field JSON name.""" - - default_value: str = aristaproto.string_field(11) - """ - The string value of the default value of this field. Proto2 syntax only. - """ - - -@dataclass(eq=False, repr=False) -class Enum(aristaproto.Message): - """Enum type definition.""" - - name: str = aristaproto.string_field(1) - """Enum type name.""" - - enumvalue: List["EnumValue"] = aristaproto.message_field( - 2, wraps=aristaproto.TYPE_ENUM - ) - """Enum value definitions.""" - - options: List["Option"] = aristaproto.message_field(3) - """Protocol buffer options.""" - - source_context: "SourceContext" = aristaproto.message_field(4) - """The source context.""" - - syntax: "Syntax" = aristaproto.enum_field(5) - """The source syntax.""" - - -@dataclass(eq=False, repr=False) -class EnumValue(aristaproto.Message): - """Enum value definition.""" - - name: str = aristaproto.string_field(1) - """Enum value name.""" - - number: int = aristaproto.int32_field(2) - """Enum value number.""" - - options: List["Option"] = aristaproto.message_field(3) - """Protocol buffer options.""" - - -@dataclass(eq=False, repr=False) -class Option(aristaproto.Message): - """ - A protocol buffer option, which can be attached to a message, field, - enumeration, etc. - """ - - name: str = aristaproto.string_field(1) - """ - 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: "Any" = aristaproto.message_field(2) - """ - 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. - """ - - -@dataclass(eq=False, repr=False) -class Api(aristaproto.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 = aristaproto.string_field(1) - """ - The fully qualified name of this interface, including package name followed - by the interface's simple name. - """ - - methods: List["Method"] = aristaproto.message_field(2) - """The methods of this interface, in unspecified order.""" - - options: List["Option"] = aristaproto.message_field(3) - """Any metadata attached to the interface.""" - - version: str = aristaproto.string_field(4) - """ - 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: "SourceContext" = aristaproto.message_field(5) - """ - Source context for the protocol buffer service represented by this message. - """ - - mixins: List["Mixin"] = aristaproto.message_field(6) - """Included interfaces. See [Mixin][].""" - - syntax: "Syntax" = aristaproto.enum_field(7) - """The source syntax of the service.""" - - -@dataclass(eq=False, repr=False) -class Method(aristaproto.Message): - """Method represents a method of an API interface.""" - - name: str = aristaproto.string_field(1) - """The simple name of this method.""" - - request_type_url: str = aristaproto.string_field(2) - """A URL of the input message type.""" - - request_streaming: bool = aristaproto.bool_field(3) - """If true, the request is streamed.""" - - response_type_url: str = aristaproto.string_field(4) - """The URL of the output message type.""" - - response_streaming: bool = aristaproto.bool_field(5) - """If true, the response is streamed.""" - - options: List["Option"] = aristaproto.message_field(6) - """Any metadata attached to the method.""" - - syntax: "Syntax" = aristaproto.enum_field(7) - """The source syntax of this method.""" - - -@dataclass(eq=False, repr=False) -class Mixin(aristaproto.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 - inheriting documentation and annotations as follows: service Storage { - // Get the underlying ACL object. rpc GetAcl(GetAclRequest) returns - (Acl) { option (google.api.http).get = "/v2/{resource=**}:getAcl"; - } ... } Note how the version in the path pattern changed from - `v1` to `v2`. If the `root` field in the mixin is specified, it should be a - relative path under which inherited HTTP paths are placed. Example: - apis: - name: google.storage.v2.Storage mixins: - name: - google.acl.v1.AccessControl root: acls This implies the following - inherited HTTP annotation: service Storage { // Get the - underlying ACL object. rpc GetAcl(GetAclRequest) returns (Acl) { - option (google.api.http).get = "/v2/acls/{resource=**}:getAcl"; } - ... } - """ - - name: str = aristaproto.string_field(1) - """The fully qualified name of the interface which is included.""" - - root: str = aristaproto.string_field(2) - """ - If non-empty specifies a path under which inherited HTTP paths are rooted. - """ - - -@dataclass(eq=False, repr=False) -class FileDescriptorSet(aristaproto.Message): - """ - The protocol compiler can output a FileDescriptorSet containing the .proto - files it parses. - """ - - file: List["FileDescriptorProto"] = aristaproto.message_field(1) - - -@dataclass(eq=False, repr=False) -class FileDescriptorProto(aristaproto.Message): - """Describes a complete .proto file.""" - - name: str = aristaproto.string_field(1) - package: str = aristaproto.string_field(2) - dependency: List[str] = aristaproto.string_field(3) - """Names of files imported by this file.""" - - public_dependency: List[int] = aristaproto.int32_field(10) - """Indexes of the public imported files in the dependency list above.""" - - weak_dependency: List[int] = aristaproto.int32_field(11) - """ - Indexes of the weak imported files in the dependency list. For Google- - internal migration only. Do not use. - """ - - message_type: List["DescriptorProto"] = aristaproto.message_field(4) - """All top-level definitions in this file.""" - - enum_type: List["EnumDescriptorProto"] = aristaproto.message_field(5) - service: List["ServiceDescriptorProto"] = aristaproto.message_field(6) - extension: List["FieldDescriptorProto"] = aristaproto.message_field(7) - options: "FileOptions" = aristaproto.message_field(8) - source_code_info: "SourceCodeInfo" = aristaproto.message_field(9) - """ - 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 = aristaproto.string_field(12) - """ - The syntax of the proto file. The supported values are "proto2" and - "proto3". - """ - - -@dataclass(eq=False, repr=False) -class DescriptorProto(aristaproto.Message): - """Describes a message type.""" - - name: str = aristaproto.string_field(1) - field: List["FieldDescriptorProto"] = aristaproto.message_field(2) - extension: List["FieldDescriptorProto"] = aristaproto.message_field(6) - nested_type: List["DescriptorProto"] = aristaproto.message_field(3) - enum_type: List["EnumDescriptorProto"] = aristaproto.message_field(4) - extension_range: List["DescriptorProtoExtensionRange"] = aristaproto.message_field( - 5 - ) - oneof_decl: List["OneofDescriptorProto"] = aristaproto.message_field(8) - options: "MessageOptions" = aristaproto.message_field(7) - reserved_range: List["DescriptorProtoReservedRange"] = aristaproto.message_field(9) - reserved_name: List[str] = aristaproto.string_field(10) - """ - Reserved field names, which may not be used by fields in the same message. - A given name may only be reserved once. - """ - - -@dataclass(eq=False, repr=False) -class DescriptorProtoExtensionRange(aristaproto.Message): - start: int = aristaproto.int32_field(1) - end: int = aristaproto.int32_field(2) - options: "ExtensionRangeOptions" = aristaproto.message_field(3) - - -@dataclass(eq=False, repr=False) -class DescriptorProtoReservedRange(aristaproto.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 = aristaproto.int32_field(1) - end: int = aristaproto.int32_field(2) - - -@dataclass(eq=False, repr=False) -class ExtensionRangeOptions(aristaproto.Message): - uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) - """The parser stores options it doesn't recognize here. See above.""" - - -@dataclass(eq=False, repr=False) -class FieldDescriptorProto(aristaproto.Message): - """Describes a field within a message.""" - - name: str = aristaproto.string_field(1) - number: int = aristaproto.int32_field(3) - label: "FieldDescriptorProtoLabel" = aristaproto.enum_field(4) - type: "FieldDescriptorProtoType" = aristaproto.enum_field(5) - """ - 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 = aristaproto.string_field(6) - """ - 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 = aristaproto.string_field(2) - """ - For extensions, this is the name of the type being extended. It is - resolved in the same manner as type_name. - """ - - default_value: str = aristaproto.string_field(7) - """ - 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 = aristaproto.int32_field(9) - """ - 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 = aristaproto.string_field(10) - """ - 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: "FieldOptions" = aristaproto.message_field(8) - proto3_optional: bool = aristaproto.bool_field(17) - """ - 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`. - """ - - -@dataclass(eq=False, repr=False) -class OneofDescriptorProto(aristaproto.Message): - """Describes a oneof.""" - - name: str = aristaproto.string_field(1) - options: "OneofOptions" = aristaproto.message_field(2) - - -@dataclass(eq=False, repr=False) -class EnumDescriptorProto(aristaproto.Message): - """Describes an enum type.""" - - name: str = aristaproto.string_field(1) - value: List["EnumValueDescriptorProto"] = aristaproto.message_field(2) - options: "EnumOptions" = aristaproto.message_field(3) - reserved_range: List[ - "EnumDescriptorProtoEnumReservedRange" - ] = aristaproto.message_field(4) - """ - 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] = aristaproto.string_field(5) - """ - Reserved enum value names, which may not be reused. A given name may only - be reserved once. - """ - - -@dataclass(eq=False, repr=False) -class EnumDescriptorProtoEnumReservedRange(aristaproto.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 = aristaproto.int32_field(1) - end: int = aristaproto.int32_field(2) - - -@dataclass(eq=False, repr=False) -class EnumValueDescriptorProto(aristaproto.Message): - """Describes a value within an enum.""" - - name: str = aristaproto.string_field(1) - number: int = aristaproto.int32_field(2) - options: "EnumValueOptions" = aristaproto.message_field(3) - - -@dataclass(eq=False, repr=False) -class ServiceDescriptorProto(aristaproto.Message): - """Describes a service.""" - - name: str = aristaproto.string_field(1) - method: List["MethodDescriptorProto"] = aristaproto.message_field(2) - options: "ServiceOptions" = aristaproto.message_field(3) - - -@dataclass(eq=False, repr=False) -class MethodDescriptorProto(aristaproto.Message): - """Describes a method of a service.""" - - name: str = aristaproto.string_field(1) - input_type: str = aristaproto.string_field(2) - """ - 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 = aristaproto.string_field(3) - options: "MethodOptions" = aristaproto.message_field(4) - client_streaming: bool = aristaproto.bool_field(5) - """Identifies if client streams multiple client messages""" - - server_streaming: bool = aristaproto.bool_field(6) - """Identifies if server streams multiple server messages""" - - -@dataclass(eq=False, repr=False) -class FileOptions(aristaproto.Message): - java_package: str = aristaproto.string_field(1) - """ - 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 = aristaproto.string_field(8) - """ - 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 = aristaproto.bool_field(10) - """ - 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 = aristaproto.bool_field(20) - """This option does nothing.""" - - java_string_check_utf8: bool = aristaproto.bool_field(27) - """ - 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" = aristaproto.enum_field(9) - go_package: str = aristaproto.string_field(11) - """ - 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 = aristaproto.bool_field(16) - """ - 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 = aristaproto.bool_field(17) - py_generic_services: bool = aristaproto.bool_field(18) - php_generic_services: bool = aristaproto.bool_field(42) - deprecated: bool = aristaproto.bool_field(23) - """ - 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 = aristaproto.bool_field(31) - """ - Enables the use of arenas for the proto messages in this file. This applies - only to generated classes for C++. - """ - - objc_class_prefix: str = aristaproto.string_field(36) - """ - 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 = aristaproto.string_field(37) - """Namespace for generated classes; defaults to the package.""" - - swift_prefix: str = aristaproto.string_field(39) - """ - 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 = aristaproto.string_field(40) - """ - Sets the php class prefix which is prepended to all php generated classes - from this .proto. Default is empty. - """ - - php_namespace: str = aristaproto.string_field(41) - """ - 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 = aristaproto.string_field(44) - """ - 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 = aristaproto.string_field(45) - """ - 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. - """ - - uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) - """ - 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, - ) - - -@dataclass(eq=False, repr=False) -class MessageOptions(aristaproto.Message): - message_set_wire_format: bool = aristaproto.bool_field(1) - """ - 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 = aristaproto.bool_field(2) - """ - 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 = aristaproto.bool_field(3) - """ - 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 = aristaproto.bool_field(7) - """ - 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. 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. - """ - - uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) - """The parser stores options it doesn't recognize here. See above.""" - - -@dataclass(eq=False, repr=False) -class FieldOptions(aristaproto.Message): - ctype: "FieldOptionsCType" = aristaproto.enum_field(1) - """ - The ctype option instructs the C++ code generator to use a different - representation of the field than it normally would. See the specific - options below. This option is not yet implemented in the open source - release -- sorry, we'll try to include it in a future version! - """ - - packed: bool = aristaproto.bool_field(2) - """ - The packed option can be enabled for repeated primitive fields to enable a - more efficient representation on the wire. Rather than repeatedly writing - the tag and type for each element, the entire array is encoded as a single - length-delimited blob. In proto3, only explicit setting it to false will - avoid using packed encoding. - """ - - jstype: "FieldOptionsJsType" = aristaproto.enum_field(6) - """ - 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 = aristaproto.bool_field(5) - """ - 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 2021, lazy does no correctness checks on the byte stream - during parsing. This may lead to crashes if and when an invalid byte - stream is finally parsed upon access. TODO(b/211906113): Enable validation - on lazy fields. - """ - - unverified_lazy: bool = aristaproto.bool_field(15) - """ - 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 = aristaproto.bool_field(3) - """ - 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 = aristaproto.bool_field(10) - """For Google-internal migration only. Do not use.""" - - uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) - """The parser stores options it doesn't recognize here. See above.""" - - -@dataclass(eq=False, repr=False) -class OneofOptions(aristaproto.Message): - uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) - """The parser stores options it doesn't recognize here. See above.""" - - -@dataclass(eq=False, repr=False) -class EnumOptions(aristaproto.Message): - allow_alias: bool = aristaproto.bool_field(2) - """ - Set this option to true to allow mapping different tag names to the same - value. - """ - - deprecated: bool = aristaproto.bool_field(3) - """ - 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. - """ - - uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) - """The parser stores options it doesn't recognize here. See above.""" - - -@dataclass(eq=False, repr=False) -class EnumValueOptions(aristaproto.Message): - deprecated: bool = aristaproto.bool_field(1) - """ - 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. - """ - - uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) - """The parser stores options it doesn't recognize here. See above.""" - - -@dataclass(eq=False, repr=False) -class ServiceOptions(aristaproto.Message): - deprecated: bool = aristaproto.bool_field(33) - """ - 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"] = aristaproto.message_field(999) - """The parser stores options it doesn't recognize here. See above.""" - - -@dataclass(eq=False, repr=False) -class MethodOptions(aristaproto.Message): - deprecated: bool = aristaproto.bool_field(33) - """ - 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" = aristaproto.enum_field(34) - uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) - """The parser stores options it doesn't recognize here. See above.""" - - -@dataclass(eq=False, repr=False) -class UninterpretedOption(aristaproto.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"] = aristaproto.message_field(2) - identifier_value: str = aristaproto.string_field(3) - """ - 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 = aristaproto.uint64_field(4) - negative_int_value: int = aristaproto.int64_field(5) - double_value: float = aristaproto.double_field(6) - string_value: bytes = aristaproto.bytes_field(7) - aggregate_value: str = aristaproto.string_field(8) - - -@dataclass(eq=False, repr=False) -class UninterpretedOptionNamePart(aristaproto.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], ["qux", false] } represents - "foo.(bar.baz).qux". - """ - - name_part: str = aristaproto.string_field(1) - is_extension: bool = aristaproto.bool_field(2) - - -@dataclass(eq=False, repr=False) -class SourceCodeInfo(aristaproto.Message): - """ - Encapsulates information about the original source file from which a - FileDescriptorProto was generated. - """ - - location: List["SourceCodeInfoLocation"] = aristaproto.message_field(1) - """ - 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. - """ - - -@dataclass(eq=False, repr=False) -class SourceCodeInfoLocation(aristaproto.Message): - path: List[int] = aristaproto.int32_field(1) - """ - 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] = aristaproto.int32_field(2) - """ - 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 = aristaproto.string_field(3) - """ - If this SourceCodeInfo represents a complete declaration, these are any - comments appearing before and after the declaration which appear to be - attached to the declaration. A series of line comments appearing on - consecutive lines, with no other tokens appearing on those lines, will be - treated as a single comment. leading_detached_comments will keep paragraphs - of comments that appear before (but not connected to) the current element. - Each paragraph, separated by empty lines, will be one comment element in - the repeated field. Only the comment content is provided; comment markers - (e.g. //) are stripped out. For block comments, leading whitespace and an - asterisk will be stripped from the beginning of each line other than the - first. Newlines are included in the output. Examples: optional int32 foo - = 1; // Comment attached to foo. // Comment attached to bar. optional - int32 bar = 2; optional string baz = 3; // Comment attached to baz. - // Another line attached to baz. // Comment attached to qux. // // - Another line attached to qux. optional double qux = 4; // Detached - comment for corge. This is not leading or trailing comments // to qux or - corge because there are blank lines separating it from // both. // - Detached comment for corge paragraph 2. optional string corge = 5; /* - Block comment attached * to corge. Leading asterisks * will be - removed. */ /* Block comment attached to * grault. */ optional int32 - grault = 6; // ignored detached comments. - """ - - trailing_comments: str = aristaproto.string_field(4) - leading_detached_comments: List[str] = aristaproto.string_field(6) - - -@dataclass(eq=False, repr=False) -class GeneratedCodeInfo(aristaproto.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"] = aristaproto.message_field(1) - """ - An Annotation connects some span of text in generated code to an element of - its generating .proto file. - """ - - -@dataclass(eq=False, repr=False) -class GeneratedCodeInfoAnnotation(aristaproto.Message): - path: List[int] = aristaproto.int32_field(1) - """ - Identifies the element in the original source .proto file. This field is - formatted the same as SourceCodeInfo.Location.path. - """ - - source_file: str = aristaproto.string_field(2) - """Identifies the filesystem path to the original source .proto.""" - - begin: int = aristaproto.int32_field(3) - """ - Identifies the starting offset in bytes in the generated code that relates - to the identified object. - """ - - end: int = aristaproto.int32_field(4) - """ - Identifies the ending offset in bytes in the generated code that relates to - the identified offset. The end offset should be one past the last relevant - byte (so the length of the text = end - begin). - """ - - -@dataclass(eq=False, repr=False) -class Duration(aristaproto.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 = aristaproto.int64_field(1) - """ - 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 = aristaproto.int32_field(2) - """ - 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. - """ - - -@dataclass(eq=False, repr=False) -class Empty(aristaproto.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); } The - JSON representation for `Empty` is empty JSON object `{}`. - """ - - pass - - -@dataclass(eq=False, repr=False) -class FieldMask(aristaproto.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] = aristaproto.string_field(1) - """The set of field mask paths.""" - - -@dataclass(eq=False, repr=False) -class Struct(aristaproto.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"] = aristaproto.map_field( - 1, aristaproto.TYPE_STRING, aristaproto.TYPE_MESSAGE - ) - """Unordered map of dynamically typed values.""" - - -@dataclass(eq=False, repr=False) -class Value(aristaproto.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. - """ - - null_value: "NullValue" = aristaproto.enum_field(1, group="kind") - """Represents a null value.""" - - number_value: float = aristaproto.double_field(2, group="kind") - """Represents a double value.""" - - string_value: str = aristaproto.string_field(3, group="kind") - """Represents a string value.""" - - bool_value: bool = aristaproto.bool_field(4, group="kind") - """Represents a boolean value.""" - - struct_value: "Struct" = aristaproto.message_field(5, group="kind") - """Represents a structured value.""" - - list_value: "ListValue" = aristaproto.message_field(6, group="kind") - """Represents a repeated `Value`.""" - - -@dataclass(eq=False, repr=False) -class ListValue(aristaproto.Message): - """ - `ListValue` is a wrapper around a repeated field of values. The JSON - representation for `ListValue` is JSON array. - """ - - values: List["Value"] = aristaproto.message_field(1) - """Repeated field of dynamically typed values.""" - - -@dataclass(eq=False, repr=False) -class Timestamp(aristaproto.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://www.joda.org/joda- - time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D ) - to obtain a formatter capable of generating timestamps in this format. - """ - - seconds: int = aristaproto.int64_field(1) - """ - 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 = aristaproto.int32_field(2) - """ - 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. - """ - - -@dataclass(eq=False, repr=False) -class DoubleValue(aristaproto.Message): - """ - Wrapper message for `double`. The JSON representation for `DoubleValue` is - JSON number. - """ - - value: float = aristaproto.double_field(1) - """The double value.""" - - -@dataclass(eq=False, repr=False) -class FloatValue(aristaproto.Message): - """ - Wrapper message for `float`. The JSON representation for `FloatValue` is - JSON number. - """ - - value: float = aristaproto.float_field(1) - """The float value.""" - - -@dataclass(eq=False, repr=False) -class Int64Value(aristaproto.Message): - """ - Wrapper message for `int64`. The JSON representation for `Int64Value` is - JSON string. - """ - - value: int = aristaproto.int64_field(1) - """The int64 value.""" - - -@dataclass(eq=False, repr=False) -class UInt64Value(aristaproto.Message): - """ - Wrapper message for `uint64`. The JSON representation for `UInt64Value` is - JSON string. - """ - - value: int = aristaproto.uint64_field(1) - """The uint64 value.""" - - -@dataclass(eq=False, repr=False) -class Int32Value(aristaproto.Message): - """ - Wrapper message for `int32`. The JSON representation for `Int32Value` is - JSON number. - """ - - value: int = aristaproto.int32_field(1) - """The int32 value.""" - - -@dataclass(eq=False, repr=False) -class UInt32Value(aristaproto.Message): - """ - Wrapper message for `uint32`. The JSON representation for `UInt32Value` is - JSON number. - """ - - value: int = aristaproto.uint32_field(1) - """The uint32 value.""" - - -@dataclass(eq=False, repr=False) -class BoolValue(aristaproto.Message): - """ - Wrapper message for `bool`. The JSON representation for `BoolValue` is JSON - `true` and `false`. - """ - - value: bool = aristaproto.bool_field(1) - """The bool value.""" - - -@dataclass(eq=False, repr=False) -class StringValue(aristaproto.Message): - """ - Wrapper message for `string`. The JSON representation for `StringValue` is - JSON string. - """ - - value: str = aristaproto.string_field(1) - """The string value.""" - - -@dataclass(eq=False, repr=False) -class BytesValue(aristaproto.Message): - """ - Wrapper message for `bytes`. The JSON representation for `BytesValue` is - JSON string. - """ - - value: bytes = aristaproto.bytes_field(1) - """The bytes value.""" +from aristaproto.lib.std.google.protobuf import * diff --git a/src/aristaproto/lib/google/protobuf/compiler/__init__.py b/src/aristaproto/lib/google/protobuf/compiler/__init__.py index 6c08ef0..cfa3855 100644 --- a/src/aristaproto/lib/google/protobuf/compiler/__init__.py +++ b/src/aristaproto/lib/google/protobuf/compiler/__init__.py @@ -1,152 +1 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# sources: google/protobuf/compiler/plugin.proto -# plugin: python-aristaproto -# This file has been @generated -from dataclasses import dataclass -from typing import List - -import aristaproto -import aristaproto.lib.google.protobuf as aristaproto_lib_google_protobuf - - -class CodeGeneratorResponseFeature(aristaproto.Enum): - """Sync with code_generator.h.""" - - FEATURE_NONE = 0 - FEATURE_PROTO3_OPTIONAL = 1 - - -@dataclass(eq=False, repr=False) -class Version(aristaproto.Message): - """The version number of protocol compiler.""" - - major: int = aristaproto.int32_field(1) - minor: int = aristaproto.int32_field(2) - patch: int = aristaproto.int32_field(3) - suffix: str = aristaproto.string_field(4) - """ - A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should - be empty for mainline stable releases. - """ - - -@dataclass(eq=False, repr=False) -class CodeGeneratorRequest(aristaproto.Message): - """An encoded CodeGeneratorRequest is written to the plugin's stdin.""" - - file_to_generate: List[str] = aristaproto.string_field(1) - """ - The .proto files that were explicitly listed on the command-line. The code - generator should generate code only for these files. Each file's - descriptor will be included in proto_file, below. - """ - - parameter: str = aristaproto.string_field(2) - """The generator parameter passed on the command-line.""" - - proto_file: List[ - "aristaproto_lib_google_protobuf.FileDescriptorProto" - ] = aristaproto.message_field(15) - """ - FileDescriptorProtos for all files in files_to_generate and everything they - import. The files will appear in topological order, so each file appears - before any file that imports it. protoc guarantees that all proto_files - will be written after the fields above, even though this is not technically - guaranteed by the protobuf wire format. This theoretically could allow a - plugin to stream in the FileDescriptorProtos and handle them one by one - rather than read the entire set into memory at once. However, as of this - writing, this is not similarly optimized on protoc's end -- it will store - all fields in memory at once before sending them to the plugin. Type names - of fields and extensions in the FileDescriptorProto are always fully - qualified. - """ - - compiler_version: "Version" = aristaproto.message_field(3) - """The version number of protocol compiler.""" - - -@dataclass(eq=False, repr=False) -class CodeGeneratorResponse(aristaproto.Message): - """The plugin writes an encoded CodeGeneratorResponse to stdout.""" - - error: str = aristaproto.string_field(1) - """ - Error message. If non-empty, code generation failed. The plugin process - should exit with status code zero even if it reports an error in this way. - This should be used to indicate errors in .proto files which prevent the - code generator from generating correct code. Errors which indicate a - problem in protoc itself -- such as the input CodeGeneratorRequest being - unparseable -- should be reported by writing a message to stderr and - exiting with a non-zero status code. - """ - - supported_features: int = aristaproto.uint64_field(2) - """ - A bitmask of supported features that the code generator supports. This is a - bitwise "or" of values from the Feature enum. - """ - - file: List["CodeGeneratorResponseFile"] = aristaproto.message_field(15) - - -@dataclass(eq=False, repr=False) -class CodeGeneratorResponseFile(aristaproto.Message): - """Represents a single generated file.""" - - name: str = aristaproto.string_field(1) - """ - The file name, relative to the output directory. The name must not contain - "." or ".." components and must be relative, not be absolute (so, the file - cannot lie outside the output directory). "/" must be used as the path - separator, not "\". If the name is omitted, the content will be appended to - the previous file. This allows the generator to break large files into - small chunks, and allows the generated text to be streamed back to protoc - so that large files need not reside completely in memory at one time. Note - that as of this writing protoc does not optimize for this -- it will read - the entire CodeGeneratorResponse before writing files to disk. - """ - - insertion_point: str = aristaproto.string_field(2) - """ - If non-empty, indicates that the named file should already exist, and the - content here is to be inserted into that file at a defined insertion point. - This feature allows a code generator to extend the output produced by - another code generator. The original generator may provide insertion - points by placing special annotations in the file that look like: - @@protoc_insertion_point(NAME) The annotation can have arbitrary text - before and after it on the line, which allows it to be placed in a comment. - NAME should be replaced with an identifier naming the point -- this is what - other generators will use as the insertion_point. Code inserted at this - point will be placed immediately above the line containing the insertion - point (thus multiple insertions to the same point will come out in the - order they were added). The double-@ is intended to make it unlikely that - the generated code could contain things that look like insertion points by - accident. For example, the C++ code generator places the following line in - the .pb.h files that it generates: // - @@protoc_insertion_point(namespace_scope) This line appears within the - scope of the file's package namespace, but outside of any particular class. - Another plugin can then specify the insertion_point "namespace_scope" to - generate additional classes or other declarations that should be placed in - this scope. Note that if the line containing the insertion point begins - with whitespace, the same whitespace will be added to every line of the - inserted text. This is useful for languages like Python, where indentation - matters. In these languages, the insertion point comment should be - indented the same amount as any inserted code will need to be in order to - work correctly in that context. The code generator that generates the - initial file and the one which inserts into it must both run as part of a - single invocation of protoc. Code generators are executed in the order in - which they appear on the command line. If |insertion_point| is present, - |name| must also be present. - """ - - content: str = aristaproto.string_field(15) - """The file contents.""" - - generated_code_info: "aristaproto_lib_google_protobuf.GeneratedCodeInfo" = ( - aristaproto.message_field(16) - ) - """ - Information describing the file content being inserted. If an insertion - point is used, this information will be appropriately offset and inserted - into the code generation metadata for the generated files. - """ +from aristaproto.lib.std.google.protobuf.compiler import * diff --git a/src/aristaproto/lib/pydantic/__init__.py b/src/aristaproto/lib/pydantic/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/aristaproto/lib/pydantic/google/__init__.py b/src/aristaproto/lib/pydantic/google/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/aristaproto/lib/pydantic/google/protobuf/__init__.py b/src/aristaproto/lib/pydantic/google/protobuf/__init__.py new file mode 100644 index 0000000..3a7e8ac --- /dev/null +++ b/src/aristaproto/lib/pydantic/google/protobuf/__init__.py @@ -0,0 +1,2589 @@ +# 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-aristaproto + +import warnings +from typing import TYPE_CHECKING + + +if TYPE_CHECKING: + from dataclasses import dataclass +else: + from pydantic.dataclasses import dataclass + +from typing import ( + Dict, + List, + Mapping, + Optional, +) + +from pydantic import root_validator +from typing_extensions import Self + +import aristaproto +from aristaproto.utils import hybridmethod + + +class Syntax(aristaproto.Enum): + """The syntax in which a protocol buffer element is defined.""" + + PROTO2 = 0 + """Syntax `proto2`.""" + + PROTO3 = 1 + """Syntax `proto3`.""" + + EDITIONS = 2 + """Syntax `editions`.""" + + +class FieldKind(aristaproto.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 FieldCardinality(aristaproto.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 Edition(aristaproto.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. + """ + + _2024 = 1001 + _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 + MAX = 2147483647 + """ + Placeholder for specifying unbounded edition support. This should only + ever be used by plugins that can expect to never require any changes to + support a new edition. + """ + + +class ExtensionRangeOptionsVerificationState(aristaproto.Enum): + """The verification state of the extension range.""" + + DECLARATION = 0 + """All the extensions of the range must be declared.""" + + UNVERIFIED = 1 + + +class FieldDescriptorProtoType(aristaproto.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 + TYPE_BYTES = 12 + """New in version 2.""" + + TYPE_UINT32 = 13 + TYPE_ENUM = 14 + TYPE_SFIXED32 = 15 + TYPE_SFIXED64 = 16 + TYPE_SINT32 = 17 + TYPE_SINT64 = 18 + + +class FieldDescriptorProtoLabel(aristaproto.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 FileOptionsOptimizeMode(aristaproto.Enum): + """Generated classes can be optimized for speed or code size.""" + + SPEED = 1 + CODE_SIZE = 2 + """etc.""" + + LITE_RUNTIME = 3 + + +class FieldOptionsCType(aristaproto.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(aristaproto.Enum): + JS_NORMAL = 0 + """Use the default type.""" + + JS_STRING = 1 + """Use JavaScript strings.""" + + JS_NUMBER = 2 + """Use JavaScript numbers.""" + + +class FieldOptionsOptionRetention(aristaproto.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(aristaproto.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 MethodOptionsIdempotencyLevel(aristaproto.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 + IDEMPOTENT = 2 + + +class FeatureSetFieldPresence(aristaproto.Enum): + FIELD_PRESENCE_UNKNOWN = 0 + EXPLICIT = 1 + IMPLICIT = 2 + LEGACY_REQUIRED = 3 + + +class FeatureSetEnumType(aristaproto.Enum): + ENUM_TYPE_UNKNOWN = 0 + OPEN = 1 + CLOSED = 2 + + +class FeatureSetRepeatedFieldEncoding(aristaproto.Enum): + REPEATED_FIELD_ENCODING_UNKNOWN = 0 + PACKED = 1 + EXPANDED = 2 + + +class FeatureSetUtf8Validation(aristaproto.Enum): + UTF8_VALIDATION_UNKNOWN = 0 + VERIFY = 2 + NONE = 3 + + +class FeatureSetMessageEncoding(aristaproto.Enum): + MESSAGE_ENCODING_UNKNOWN = 0 + LENGTH_PREFIXED = 1 + DELIMITED = 2 + + +class FeatureSetJsonFormat(aristaproto.Enum): + JSON_FORMAT_UNKNOWN = 0 + ALLOW = 1 + LEGACY_BEST_EFFORT = 2 + + +class GeneratedCodeInfoAnnotationSemantic(aristaproto.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 NullValue(aristaproto.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.""" + + +@dataclass(eq=False, repr=False) +class Any(aristaproto.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 = aristaproto.string_field(1) + """ + 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 = aristaproto.bytes_field(2) + """ + Must be a valid serialized protocol buffer of the above specified type. + """ + + +@dataclass(eq=False, repr=False) +class SourceContext(aristaproto.Message): + """ + `SourceContext` represents information about the source of a + protobuf element, like the file in which it is defined. + """ + + file_name: str = aristaproto.string_field(1) + """ + The path-qualified name of the .proto file that contained the associated + protobuf element. For example: `"google/protobuf/source_context.proto"`. + """ + + +@dataclass(eq=False, repr=False) +class Type(aristaproto.Message): + """A protocol buffer message type.""" + + name: str = aristaproto.string_field(1) + """The fully qualified message name.""" + + fields: List["Field"] = aristaproto.message_field(2) + """The list of fields.""" + + oneofs: List[str] = aristaproto.string_field(3) + """The list of types appearing in `oneof` definitions in this type.""" + + options: List["Option"] = aristaproto.message_field(4) + """The protocol buffer options.""" + + source_context: "SourceContext" = aristaproto.message_field(5) + """The source context.""" + + syntax: "Syntax" = aristaproto.enum_field(6) + """The source syntax.""" + + edition: str = aristaproto.string_field(7) + """ + The source edition string, only valid when syntax is SYNTAX_EDITIONS. + """ + + +@dataclass(eq=False, repr=False) +class Field(aristaproto.Message): + """A single field of a message type.""" + + kind: "FieldKind" = aristaproto.enum_field(1) + """The field type.""" + + cardinality: "FieldCardinality" = aristaproto.enum_field(2) + """The field cardinality.""" + + number: int = aristaproto.int32_field(3) + """The field number.""" + + name: str = aristaproto.string_field(4) + """The field name.""" + + type_url: str = aristaproto.string_field(6) + """ + The field type URL, without the scheme, for message or enumeration + types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. + """ + + oneof_index: int = aristaproto.int32_field(7) + """ + 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 = aristaproto.bool_field(8) + """Whether to use alternative packed wire representation.""" + + options: List["Option"] = aristaproto.message_field(9) + """The protocol buffer options.""" + + json_name: str = aristaproto.string_field(10) + """The field JSON name.""" + + default_value: str = aristaproto.string_field(11) + """ + The string value of the default value of this field. Proto2 syntax only. + """ + + +@dataclass(eq=False, repr=False) +class Enum(aristaproto.Message): + """Enum type definition.""" + + name: str = aristaproto.string_field(1) + """Enum type name.""" + + enumvalue: List["EnumValue"] = aristaproto.message_field( + 2, wraps=aristaproto.TYPE_ENUM + ) + """Enum value definitions.""" + + options: List["Option"] = aristaproto.message_field(3) + """Protocol buffer options.""" + + source_context: "SourceContext" = aristaproto.message_field(4) + """The source context.""" + + syntax: "Syntax" = aristaproto.enum_field(5) + """The source syntax.""" + + edition: str = aristaproto.string_field(6) + """ + The source edition string, only valid when syntax is SYNTAX_EDITIONS. + """ + + +@dataclass(eq=False, repr=False) +class EnumValue(aristaproto.Message): + """Enum value definition.""" + + name: str = aristaproto.string_field(1) + """Enum value name.""" + + number: int = aristaproto.int32_field(2) + """Enum value number.""" + + options: List["Option"] = aristaproto.message_field(3) + """Protocol buffer options.""" + + +@dataclass(eq=False, repr=False) +class Option(aristaproto.Message): + """ + A protocol buffer option, which can be attached to a message, field, + enumeration, etc. + """ + + name: str = aristaproto.string_field(1) + """ + 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: "Any" = aristaproto.message_field(2) + """ + 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. + """ + + +@dataclass(eq=False, repr=False) +class Api(aristaproto.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 = aristaproto.string_field(1) + """ + The fully qualified name of this interface, including package name + followed by the interface's simple name. + """ + + methods: List["Method"] = aristaproto.message_field(2) + """The methods of this interface, in unspecified order.""" + + options: List["Option"] = aristaproto.message_field(3) + """Any metadata attached to the interface.""" + + version: str = aristaproto.string_field(4) + """ + 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: "SourceContext" = aristaproto.message_field(5) + """ + Source context for the protocol buffer service represented by this + message. + """ + + mixins: List["Mixin"] = aristaproto.message_field(6) + """Included interfaces. See [Mixin][].""" + + syntax: "Syntax" = aristaproto.enum_field(7) + """The source syntax of the service.""" + + +@dataclass(eq=False, repr=False) +class Method(aristaproto.Message): + """Method represents a method of an API interface.""" + + name: str = aristaproto.string_field(1) + """The simple name of this method.""" + + request_type_url: str = aristaproto.string_field(2) + """A URL of the input message type.""" + + request_streaming: bool = aristaproto.bool_field(3) + """If true, the request is streamed.""" + + response_type_url: str = aristaproto.string_field(4) + """The URL of the output message type.""" + + response_streaming: bool = aristaproto.bool_field(5) + """If true, the response is streamed.""" + + options: List["Option"] = aristaproto.message_field(6) + """Any metadata attached to the method.""" + + syntax: "Syntax" = aristaproto.enum_field(7) + """The source syntax of this method.""" + + +@dataclass(eq=False, repr=False) +class Mixin(aristaproto.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 = aristaproto.string_field(1) + """The fully qualified name of the interface which is included.""" + + root: str = aristaproto.string_field(2) + """ + If non-empty specifies a path under which inherited HTTP paths + are rooted. + """ + + +@dataclass(eq=False, repr=False) +class FileDescriptorSet(aristaproto.Message): + """ + The protocol compiler can output a FileDescriptorSet containing the .proto + files it parses. + """ + + file: List["FileDescriptorProto"] = aristaproto.message_field(1) + + +@dataclass(eq=False, repr=False) +class FileDescriptorProto(aristaproto.Message): + """Describes a complete .proto file.""" + + name: str = aristaproto.string_field(1) + package: str = aristaproto.string_field(2) + dependency: List[str] = aristaproto.string_field(3) + """Names of files imported by this file.""" + + public_dependency: List[int] = aristaproto.int32_field(10) + """Indexes of the public imported files in the dependency list above.""" + + weak_dependency: List[int] = aristaproto.int32_field(11) + """ + Indexes of the weak imported files in the dependency list. + For Google-internal migration only. Do not use. + """ + + message_type: List["DescriptorProto"] = aristaproto.message_field(4) + """All top-level definitions in this file.""" + + enum_type: List["EnumDescriptorProto"] = aristaproto.message_field(5) + service: List["ServiceDescriptorProto"] = aristaproto.message_field(6) + extension: List["FieldDescriptorProto"] = aristaproto.message_field(7) + options: "FileOptions" = aristaproto.message_field(8) + source_code_info: "SourceCodeInfo" = aristaproto.message_field(9) + """ + 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 = aristaproto.string_field(12) + """ + 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" = aristaproto.enum_field(14) + """The edition of the proto file.""" + + +@dataclass(eq=False, repr=False) +class DescriptorProto(aristaproto.Message): + """Describes a message type.""" + + name: str = aristaproto.string_field(1) + field: List["FieldDescriptorProto"] = aristaproto.message_field(2) + extension: List["FieldDescriptorProto"] = aristaproto.message_field(6) + nested_type: List["DescriptorProto"] = aristaproto.message_field(3) + enum_type: List["EnumDescriptorProto"] = aristaproto.message_field(4) + extension_range: List["DescriptorProtoExtensionRange"] = aristaproto.message_field( + 5 + ) + oneof_decl: List["OneofDescriptorProto"] = aristaproto.message_field(8) + options: "MessageOptions" = aristaproto.message_field(7) + reserved_range: List["DescriptorProtoReservedRange"] = aristaproto.message_field(9) + reserved_name: List[str] = aristaproto.string_field(10) + """ + Reserved field names, which may not be used by fields in the same message. + A given name may only be reserved once. + """ + + +@dataclass(eq=False, repr=False) +class DescriptorProtoExtensionRange(aristaproto.Message): + start: int = aristaproto.int32_field(1) + end: int = aristaproto.int32_field(2) + options: "ExtensionRangeOptions" = aristaproto.message_field(3) + + +@dataclass(eq=False, repr=False) +class DescriptorProtoReservedRange(aristaproto.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 = aristaproto.int32_field(1) + end: int = aristaproto.int32_field(2) + + +@dataclass(eq=False, repr=False) +class ExtensionRangeOptions(aristaproto.Message): + uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) + """The parser stores options it doesn't recognize here. See above.""" + + declaration: List["ExtensionRangeOptionsDeclaration"] = aristaproto.message_field(2) + """ + 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: "FeatureSet" = aristaproto.message_field(50) + """Any features defined in the specific edition.""" + + verification: "ExtensionRangeOptionsVerificationState" = aristaproto.enum_field(3) + """ + The verification state of the range. + TODO: flip the default to DECLARATION once all empty ranges + are marked as UNVERIFIED. + """ + + +@dataclass(eq=False, repr=False) +class ExtensionRangeOptionsDeclaration(aristaproto.Message): + number: int = aristaproto.int32_field(1) + """The extension number declared within the extension range.""" + + full_name: str = aristaproto.string_field(2) + """ + The fully-qualified name of the extension field. There must be a leading + dot in front of the full name. + """ + + type: str = aristaproto.string_field(3) + """ + 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 = aristaproto.bool_field(5) + """ + 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 = aristaproto.bool_field(6) + """ + If true, indicates that the extension must be defined as repeated. + Otherwise the extension must be defined as optional. + """ + + +@dataclass(eq=False, repr=False) +class FieldDescriptorProto(aristaproto.Message): + """Describes a field within a message.""" + + name: str = aristaproto.string_field(1) + number: int = aristaproto.int32_field(3) + label: "FieldDescriptorProtoLabel" = aristaproto.enum_field(4) + type: "FieldDescriptorProtoType" = aristaproto.enum_field(5) + """ + 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 = aristaproto.string_field(6) + """ + 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 = aristaproto.string_field(2) + """ + For extensions, this is the name of the type being extended. It is + resolved in the same manner as type_name. + """ + + default_value: str = aristaproto.string_field(7) + """ + 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 = aristaproto.int32_field(9) + """ + 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 = aristaproto.string_field(10) + """ + 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: "FieldOptions" = aristaproto.message_field(8) + proto3_optional: bool = aristaproto.bool_field(17) + """ + 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 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`. + """ + + +@dataclass(eq=False, repr=False) +class OneofDescriptorProto(aristaproto.Message): + """Describes a oneof.""" + + name: str = aristaproto.string_field(1) + options: "OneofOptions" = aristaproto.message_field(2) + + +@dataclass(eq=False, repr=False) +class EnumDescriptorProto(aristaproto.Message): + """Describes an enum type.""" + + name: str = aristaproto.string_field(1) + value: List["EnumValueDescriptorProto"] = aristaproto.message_field(2) + options: "EnumOptions" = aristaproto.message_field(3) + reserved_range: List[ + "EnumDescriptorProtoEnumReservedRange" + ] = aristaproto.message_field(4) + """ + 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] = aristaproto.string_field(5) + """ + Reserved enum value names, which may not be reused. A given name may only + be reserved once. + """ + + +@dataclass(eq=False, repr=False) +class EnumDescriptorProtoEnumReservedRange(aristaproto.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 = aristaproto.int32_field(1) + end: int = aristaproto.int32_field(2) + + +@dataclass(eq=False, repr=False) +class EnumValueDescriptorProto(aristaproto.Message): + """Describes a value within an enum.""" + + name: str = aristaproto.string_field(1) + number: int = aristaproto.int32_field(2) + options: "EnumValueOptions" = aristaproto.message_field(3) + + +@dataclass(eq=False, repr=False) +class ServiceDescriptorProto(aristaproto.Message): + """Describes a service.""" + + name: str = aristaproto.string_field(1) + method: List["MethodDescriptorProto"] = aristaproto.message_field(2) + options: "ServiceOptions" = aristaproto.message_field(3) + + +@dataclass(eq=False, repr=False) +class MethodDescriptorProto(aristaproto.Message): + """Describes a method of a service.""" + + name: str = aristaproto.string_field(1) + input_type: str = aristaproto.string_field(2) + """ + 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 = aristaproto.string_field(3) + options: "MethodOptions" = aristaproto.message_field(4) + client_streaming: bool = aristaproto.bool_field(5) + """Identifies if client streams multiple client messages""" + + server_streaming: bool = aristaproto.bool_field(6) + """Identifies if server streams multiple server messages""" + + +@dataclass(eq=False, repr=False) +class FileOptions(aristaproto.Message): + java_package: str = aristaproto.string_field(1) + """ + 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 = aristaproto.string_field(8) + """ + 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 = aristaproto.bool_field(10) + """ + 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 = aristaproto.bool_field(20) + """This option does nothing.""" + + java_string_check_utf8: bool = aristaproto.bool_field(27) + """ + A proto2 file can set this to true to opt in to UTF-8 checking for Java, + which will throw an exception if invalid UTF-8 is parsed from the wire or + assigned to a string field. + + TODO: clarify exactly what kinds of field types this option + applies to, and update these docs accordingly. + + Proto3 files already perform these checks. Setting the option explicitly to + false has no effect: it cannot be used to opt proto3 files out of UTF-8 + checks. + """ + + optimize_for: "FileOptionsOptimizeMode" = aristaproto.enum_field(9) + go_package: str = aristaproto.string_field(11) + """ + 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 = aristaproto.bool_field(16) + """ + 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 = aristaproto.bool_field(17) + py_generic_services: bool = aristaproto.bool_field(18) + deprecated: bool = aristaproto.bool_field(23) + """ + 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 = aristaproto.bool_field(31) + """ + Enables the use of arenas for the proto messages in this file. This applies + only to generated classes for C++. + """ + + objc_class_prefix: str = aristaproto.string_field(36) + """ + 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 = aristaproto.string_field(37) + """Namespace for generated classes; defaults to the package.""" + + swift_prefix: str = aristaproto.string_field(39) + """ + 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 = aristaproto.string_field(40) + """ + Sets the php class prefix which is prepended to all php generated classes + from this .proto. Default is empty. + """ + + php_namespace: str = aristaproto.string_field(41) + """ + 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 = aristaproto.string_field(44) + """ + 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 = aristaproto.string_field(45) + """ + 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: "FeatureSet" = aristaproto.message_field(50) + """Any features defined in the specific edition.""" + + uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) + """ + 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, + ) + + +@dataclass(eq=False, repr=False) +class MessageOptions(aristaproto.Message): + message_set_wire_format: bool = aristaproto.bool_field(1) + """ + 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 = aristaproto.bool_field(2) + """ + 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 = aristaproto.bool_field(3) + """ + 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 = aristaproto.bool_field(7) + """ + 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. + + 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. + """ + + deprecated_legacy_json_field_conflicts: bool = aristaproto.bool_field(11) + """ + 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: "FeatureSet" = aristaproto.message_field(12) + """Any features defined in the specific edition.""" + + uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) + """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, + ) + + +@dataclass(eq=False, repr=False) +class FieldOptions(aristaproto.Message): + ctype: "FieldOptionsCType" = aristaproto.enum_field(1) + """ + 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 = aristaproto.bool_field(2) + """ + The packed option can be enabled for repeated primitive fields to enable + a more efficient representation on the wire. Rather than repeatedly + writing the tag and type for each element, the entire array is encoded as + a single length-delimited blob. In proto3, only explicit setting it to + false will avoid using packed encoding. This option is prohibited in + Editions, but the `repeated_field_encoding` feature can be used to control + the behavior. + """ + + jstype: "FieldOptionsJsType" = aristaproto.enum_field(6) + """ + 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 = aristaproto.bool_field(5) + """ + 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 lazy message fields are still eagerly verified to check + ill-formed wireformat or missing required fields. Calling IsInitialized() + on the outer message would fail if the inner message has missing required + fields. Failed verification would result in parsing failure (except when + uninitialized messages are acceptable). + """ + + unverified_lazy: bool = aristaproto.bool_field(15) + """ + 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 = aristaproto.bool_field(3) + """ + 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 = aristaproto.bool_field(10) + """For Google-internal migration only. Do not use.""" + + debug_redact: bool = aristaproto.bool_field(16) + """ + Indicate that the field value should not be printed out when using debug + formats, e.g. when the field contains sensitive credentials. + """ + + retention: "FieldOptionsOptionRetention" = aristaproto.enum_field(17) + targets: List["FieldOptionsOptionTargetType"] = aristaproto.enum_field(19) + edition_defaults: List["FieldOptionsEditionDefault"] = aristaproto.message_field(20) + features: "FeatureSet" = aristaproto.message_field(21) + """Any features defined in the specific edition.""" + + feature_support: "FieldOptionsFeatureSupport" = aristaproto.message_field(22) + uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) + """The parser stores options it doesn't recognize here. See above.""" + + +@dataclass(eq=False, repr=False) +class FieldOptionsEditionDefault(aristaproto.Message): + edition: "Edition" = aristaproto.enum_field(3) + value: str = aristaproto.string_field(2) + + +@dataclass(eq=False, repr=False) +class FieldOptionsFeatureSupport(aristaproto.Message): + """Information about the support window of a feature.""" + + edition_introduced: "Edition" = aristaproto.enum_field(1) + """ + The edition that this feature was first available in. In editions + earlier than this one, the default assigned to EDITION_LEGACY will be + used, and proto files will not be able to override it. + """ + + edition_deprecated: "Edition" = aristaproto.enum_field(2) + """ + The edition this feature becomes deprecated in. Using this after this + edition may trigger warnings. + """ + + deprecation_warning: str = aristaproto.string_field(3) + """ + The deprecation warning text if this feature is used after the edition it + was marked deprecated in. + """ + + edition_removed: "Edition" = aristaproto.enum_field(4) + """ + The edition this feature is no longer available in. In editions after + this one, the last default assigned will be used, and proto files will + not be able to override it. + """ + + +@dataclass(eq=False, repr=False) +class OneofOptions(aristaproto.Message): + features: "FeatureSet" = aristaproto.message_field(1) + """Any features defined in the specific edition.""" + + uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) + """The parser stores options it doesn't recognize here. See above.""" + + +@dataclass(eq=False, repr=False) +class EnumOptions(aristaproto.Message): + allow_alias: bool = aristaproto.bool_field(2) + """ + Set this option to true to allow mapping different tag names to the same + value. + """ + + deprecated: bool = aristaproto.bool_field(3) + """ + 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 = aristaproto.bool_field(6) + """ + 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: "FeatureSet" = aristaproto.message_field(7) + """Any features defined in the specific edition.""" + + uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) + """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, + ) + + +@dataclass(eq=False, repr=False) +class EnumValueOptions(aristaproto.Message): + deprecated: bool = aristaproto.bool_field(1) + """ + 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: "FeatureSet" = aristaproto.message_field(2) + """Any features defined in the specific edition.""" + + debug_redact: bool = aristaproto.bool_field(3) + """ + 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"] = aristaproto.message_field(999) + """The parser stores options it doesn't recognize here. See above.""" + + +@dataclass(eq=False, repr=False) +class ServiceOptions(aristaproto.Message): + features: "FeatureSet" = aristaproto.message_field(34) + """Any features defined in the specific edition.""" + + deprecated: bool = aristaproto.bool_field(33) + """ + 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"] = aristaproto.message_field(999) + """The parser stores options it doesn't recognize here. See above.""" + + +@dataclass(eq=False, repr=False) +class MethodOptions(aristaproto.Message): + deprecated: bool = aristaproto.bool_field(33) + """ + 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" = aristaproto.enum_field(34) + features: "FeatureSet" = aristaproto.message_field(35) + """Any features defined in the specific edition.""" + + uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) + """The parser stores options it doesn't recognize here. See above.""" + + +@dataclass(eq=False, repr=False) +class UninterpretedOption(aristaproto.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"] = aristaproto.message_field(2) + identifier_value: str = aristaproto.string_field(3) + """ + 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 = aristaproto.uint64_field(4) + negative_int_value: int = aristaproto.int64_field(5) + double_value: float = aristaproto.double_field(6) + string_value: bytes = aristaproto.bytes_field(7) + aggregate_value: str = aristaproto.string_field(8) + + +@dataclass(eq=False, repr=False) +class UninterpretedOptionNamePart(aristaproto.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 = aristaproto.string_field(1) + is_extension: bool = aristaproto.bool_field(2) + + +@dataclass(eq=False, repr=False) +class FeatureSet(aristaproto.Message): + """ + 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" = aristaproto.enum_field(1) + enum_type: "FeatureSetEnumType" = aristaproto.enum_field(2) + repeated_field_encoding: "FeatureSetRepeatedFieldEncoding" = aristaproto.enum_field( + 3 + ) + utf8_validation: "FeatureSetUtf8Validation" = aristaproto.enum_field(4) + message_encoding: "FeatureSetMessageEncoding" = aristaproto.enum_field(5) + json_format: "FeatureSetJsonFormat" = aristaproto.enum_field(6) + + +@dataclass(eq=False, repr=False) +class FeatureSetDefaults(aristaproto.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" + ] = aristaproto.message_field(1) + minimum_edition: "Edition" = aristaproto.enum_field(4) + """ + The minimum supported edition (inclusive) when this was constructed. + Editions before this will not have defaults. + """ + + maximum_edition: "Edition" = aristaproto.enum_field(5) + """ + The maximum known edition (inclusive) when this was constructed. Editions + after this will not have reliable defaults. + """ + + +@dataclass(eq=False, repr=False) +class FeatureSetDefaultsFeatureSetEditionDefault(aristaproto.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" = aristaproto.enum_field(3) + overridable_features: "FeatureSet" = aristaproto.message_field(4) + """Defaults of features that can be overridden in this edition.""" + + fixed_features: "FeatureSet" = aristaproto.message_field(5) + """Defaults of features that can't be overridden in this edition.""" + + features: "FeatureSet" = aristaproto.message_field(2) + """ + TODO Deprecate and remove this field, which is just the + above two merged. + """ + + +@dataclass(eq=False, repr=False) +class SourceCodeInfo(aristaproto.Message): + """ + Encapsulates information about the original source file from which a + FileDescriptorProto was generated. + """ + + location: List["SourceCodeInfoLocation"] = aristaproto.message_field(1) + """ + 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. + """ + + +@dataclass(eq=False, repr=False) +class SourceCodeInfoLocation(aristaproto.Message): + path: List[int] = aristaproto.int32_field(1) + """ + 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 appears. + 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] = aristaproto.int32_field(2) + """ + 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 = aristaproto.string_field(3) + """ + 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 = aristaproto.string_field(4) + leading_detached_comments: List[str] = aristaproto.string_field(6) + + +@dataclass(eq=False, repr=False) +class GeneratedCodeInfo(aristaproto.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"] = aristaproto.message_field(1) + """ + An Annotation connects some span of text in generated code to an element + of its generating .proto file. + """ + + +@dataclass(eq=False, repr=False) +class GeneratedCodeInfoAnnotation(aristaproto.Message): + path: List[int] = aristaproto.int32_field(1) + """ + Identifies the element in the original source .proto file. This field + is formatted the same as SourceCodeInfo.Location.path. + """ + + source_file: str = aristaproto.string_field(2) + """Identifies the filesystem path to the original source .proto.""" + + begin: int = aristaproto.int32_field(3) + """ + Identifies the starting offset in bytes in the generated code + that relates to the identified object. + """ + + end: int = aristaproto.int32_field(4) + """ + 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" = aristaproto.enum_field(5) + + +@dataclass(eq=False, repr=False) +class Duration(aristaproto.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 = aristaproto.int64_field(1) + """ + 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 = aristaproto.int32_field(2) + """ + 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. + """ + + +@dataclass(eq=False, repr=False) +class Empty(aristaproto.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 + + +@dataclass(eq=False, repr=False) +class FieldMask(aristaproto.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] = aristaproto.string_field(1) + """The set of field mask paths.""" + + +@dataclass(eq=False, repr=False) +class Struct(aristaproto.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"] = aristaproto.map_field( + 1, aristaproto.TYPE_STRING, aristaproto.TYPE_MESSAGE + ) + """Unordered map of dynamically typed values.""" + + @hybridmethod + def from_dict(cls: "type[Self]", value: Mapping[str, Any]) -> Self: # type: ignore + self = cls() + return self.from_dict(value) + + @from_dict.instancemethod + def from_dict(self, value: Mapping[str, Any]) -> Self: + fields = {**value} + for k in fields: + if hasattr(fields[k], "from_dict"): + fields[k] = fields[k].from_dict() + + self.fields = fields + return self + + def to_dict( + self, + casing: aristaproto.Casing = aristaproto.Casing.CAMEL, + include_default_values: bool = False, + ) -> Dict[str, Any]: + output = {**self.fields} + for k in self.fields: + if hasattr(self.fields[k], "to_dict"): + output[k] = self.fields[k].to_dict(casing, include_default_values) + return output + + +@dataclass(eq=False, repr=False) +class Value(aristaproto.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. + """ + + null_value: Optional["NullValue"] = aristaproto.enum_field( + 1, optional=True, group="kind" + ) + """Represents a null value.""" + + number_value: Optional[float] = aristaproto.double_field( + 2, optional=True, group="kind" + ) + """Represents a double value.""" + + string_value: Optional[str] = aristaproto.string_field( + 3, optional=True, group="kind" + ) + """Represents a string value.""" + + bool_value: Optional[bool] = aristaproto.bool_field(4, optional=True, group="kind") + """Represents a boolean value.""" + + struct_value: Optional["Struct"] = aristaproto.message_field( + 5, optional=True, group="kind" + ) + """Represents a structured value.""" + + list_value: Optional["ListValue"] = aristaproto.message_field( + 6, optional=True, group="kind" + ) + """Represents a repeated `Value`.""" + + @root_validator() + def check_oneof(cls, values): + return cls._validate_field_groups(values) + + +@dataclass(eq=False, repr=False) +class ListValue(aristaproto.Message): + """ + `ListValue` is a wrapper around a repeated field of values. + + The JSON representation for `ListValue` is JSON array. + """ + + values: List["Value"] = aristaproto.message_field(1) + """Repeated field of dynamically typed values.""" + + +@dataclass(eq=False, repr=False) +class Timestamp(aristaproto.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 = aristaproto.int64_field(1) + """ + 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 = aristaproto.int32_field(2) + """ + 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. + """ + + +@dataclass(eq=False, repr=False) +class DoubleValue(aristaproto.Message): + """ + Wrapper message for `double`. + + The JSON representation for `DoubleValue` is JSON number. + """ + + value: float = aristaproto.double_field(1) + """The double value.""" + + +@dataclass(eq=False, repr=False) +class FloatValue(aristaproto.Message): + """ + Wrapper message for `float`. + + The JSON representation for `FloatValue` is JSON number. + """ + + value: float = aristaproto.float_field(1) + """The float value.""" + + +@dataclass(eq=False, repr=False) +class Int64Value(aristaproto.Message): + """ + Wrapper message for `int64`. + + The JSON representation for `Int64Value` is JSON string. + """ + + value: int = aristaproto.int64_field(1) + """The int64 value.""" + + +@dataclass(eq=False, repr=False) +class UInt64Value(aristaproto.Message): + """ + Wrapper message for `uint64`. + + The JSON representation for `UInt64Value` is JSON string. + """ + + value: int = aristaproto.uint64_field(1) + """The uint64 value.""" + + +@dataclass(eq=False, repr=False) +class Int32Value(aristaproto.Message): + """ + Wrapper message for `int32`. + + The JSON representation for `Int32Value` is JSON number. + """ + + value: int = aristaproto.int32_field(1) + """The int32 value.""" + + +@dataclass(eq=False, repr=False) +class UInt32Value(aristaproto.Message): + """ + Wrapper message for `uint32`. + + The JSON representation for `UInt32Value` is JSON number. + """ + + value: int = aristaproto.uint32_field(1) + """The uint32 value.""" + + +@dataclass(eq=False, repr=False) +class BoolValue(aristaproto.Message): + """ + Wrapper message for `bool`. + + The JSON representation for `BoolValue` is JSON `true` and `false`. + """ + + value: bool = aristaproto.bool_field(1) + """The bool value.""" + + +@dataclass(eq=False, repr=False) +class StringValue(aristaproto.Message): + """ + Wrapper message for `string`. + + The JSON representation for `StringValue` is JSON string. + """ + + value: str = aristaproto.string_field(1) + """The string value.""" + + +@dataclass(eq=False, repr=False) +class BytesValue(aristaproto.Message): + """ + Wrapper message for `bytes`. + + The JSON representation for `BytesValue` is JSON string. + """ + + value: bytes = aristaproto.bytes_field(1) + """The bytes value.""" + + +Type.__pydantic_model__.update_forward_refs() # type: ignore +Field.__pydantic_model__.update_forward_refs() # type: ignore +Enum.__pydantic_model__.update_forward_refs() # type: ignore +EnumValue.__pydantic_model__.update_forward_refs() # type: ignore +Option.__pydantic_model__.update_forward_refs() # type: ignore +Api.__pydantic_model__.update_forward_refs() # type: ignore +Method.__pydantic_model__.update_forward_refs() # type: ignore +FileDescriptorSet.__pydantic_model__.update_forward_refs() # type: ignore +FileDescriptorProto.__pydantic_model__.update_forward_refs() # type: ignore +DescriptorProto.__pydantic_model__.update_forward_refs() # type: ignore +DescriptorProtoExtensionRange.__pydantic_model__.update_forward_refs() # type: ignore +ExtensionRangeOptions.__pydantic_model__.update_forward_refs() # type: ignore +FieldDescriptorProto.__pydantic_model__.update_forward_refs() # type: ignore +OneofDescriptorProto.__pydantic_model__.update_forward_refs() # type: ignore +EnumDescriptorProto.__pydantic_model__.update_forward_refs() # type: ignore +EnumValueDescriptorProto.__pydantic_model__.update_forward_refs() # type: ignore +ServiceDescriptorProto.__pydantic_model__.update_forward_refs() # type: ignore +MethodDescriptorProto.__pydantic_model__.update_forward_refs() # type: ignore +FileOptions.__pydantic_model__.update_forward_refs() # type: ignore +MessageOptions.__pydantic_model__.update_forward_refs() # type: ignore +FieldOptions.__pydantic_model__.update_forward_refs() # type: ignore +FieldOptionsEditionDefault.__pydantic_model__.update_forward_refs() # type: ignore +FieldOptionsFeatureSupport.__pydantic_model__.update_forward_refs() # type: ignore +OneofOptions.__pydantic_model__.update_forward_refs() # type: ignore +EnumOptions.__pydantic_model__.update_forward_refs() # type: ignore +EnumValueOptions.__pydantic_model__.update_forward_refs() # type: ignore +ServiceOptions.__pydantic_model__.update_forward_refs() # type: ignore +MethodOptions.__pydantic_model__.update_forward_refs() # type: ignore +UninterpretedOption.__pydantic_model__.update_forward_refs() # type: ignore +FeatureSet.__pydantic_model__.update_forward_refs() # type: ignore +FeatureSetDefaults.__pydantic_model__.update_forward_refs() # type: ignore +FeatureSetDefaultsFeatureSetEditionDefault.__pydantic_model__.update_forward_refs() # type: ignore +SourceCodeInfo.__pydantic_model__.update_forward_refs() # type: ignore +GeneratedCodeInfo.__pydantic_model__.update_forward_refs() # type: ignore +GeneratedCodeInfoAnnotation.__pydantic_model__.update_forward_refs() # type: ignore +Struct.__pydantic_model__.update_forward_refs() # type: ignore +Value.__pydantic_model__.update_forward_refs() # type: ignore +ListValue.__pydantic_model__.update_forward_refs() # type: ignore diff --git a/src/aristaproto/lib/pydantic/google/protobuf/compiler/__init__.py b/src/aristaproto/lib/pydantic/google/protobuf/compiler/__init__.py new file mode 100644 index 0000000..495c555 --- /dev/null +++ b/src/aristaproto/lib/pydantic/google/protobuf/compiler/__init__.py @@ -0,0 +1,210 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# sources: google/protobuf/compiler/plugin.proto +# plugin: python-aristaproto +# This file has been @generated + +from typing import TYPE_CHECKING + + +if TYPE_CHECKING: + from dataclasses import dataclass +else: + from pydantic.dataclasses import dataclass + +from typing import List + +import aristaproto +import aristaproto.lib.pydantic.google.protobuf as aristaproto_lib_pydantic_google_protobuf + + +class CodeGeneratorResponseFeature(aristaproto.Enum): + """Sync with code_generator.h.""" + + FEATURE_NONE = 0 + FEATURE_PROTO3_OPTIONAL = 1 + FEATURE_SUPPORTS_EDITIONS = 2 + + +@dataclass(eq=False, repr=False) +class Version(aristaproto.Message): + """The version number of protocol compiler.""" + + major: int = aristaproto.int32_field(1) + minor: int = aristaproto.int32_field(2) + patch: int = aristaproto.int32_field(3) + suffix: str = aristaproto.string_field(4) + """ + A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should + be empty for mainline stable releases. + """ + + +@dataclass(eq=False, repr=False) +class CodeGeneratorRequest(aristaproto.Message): + """An encoded CodeGeneratorRequest is written to the plugin's stdin.""" + + file_to_generate: List[str] = aristaproto.string_field(1) + """ + The .proto files that were explicitly listed on the command-line. The + code generator should generate code only for these files. Each file's + descriptor will be included in proto_file, below. + """ + + parameter: str = aristaproto.string_field(2) + """The generator parameter passed on the command-line.""" + + proto_file: List[ + "aristaproto_lib_pydantic_google_protobuf.FileDescriptorProto" + ] = aristaproto.message_field(15) + """ + FileDescriptorProtos for all files in files_to_generate and everything + they import. The files will appear in topological order, so each file + appears before any file that imports it. + + Note: the files listed in files_to_generate will include runtime-retention + options only, but all other files will include source-retention options. + The source_file_descriptors field below is available in case you need + source-retention options for files_to_generate. + + protoc guarantees that all proto_files will be written after + the fields above, even though this is not technically guaranteed by the + protobuf wire format. This theoretically could allow a plugin to stream + in the FileDescriptorProtos and handle them one by one rather than read + the entire set into memory at once. However, as of this writing, this + is not similarly optimized on protoc's end -- it will store all fields in + memory at once before sending them to the plugin. + + Type names of fields and extensions in the FileDescriptorProto are always + fully qualified. + """ + + source_file_descriptors: List[ + "aristaproto_lib_pydantic_google_protobuf.FileDescriptorProto" + ] = aristaproto.message_field(17) + """ + File descriptors with all options, including source-retention options. + These descriptors are only provided for the files listed in + files_to_generate. + """ + + compiler_version: "Version" = aristaproto.message_field(3) + """The version number of protocol compiler.""" + + +@dataclass(eq=False, repr=False) +class CodeGeneratorResponse(aristaproto.Message): + """The plugin writes an encoded CodeGeneratorResponse to stdout.""" + + error: str = aristaproto.string_field(1) + """ + Error message. If non-empty, code generation failed. The plugin process + should exit with status code zero even if it reports an error in this way. + + This should be used to indicate errors in .proto files which prevent the + code generator from generating correct code. Errors which indicate a + problem in protoc itself -- such as the input CodeGeneratorRequest being + unparseable -- should be reported by writing a message to stderr and + exiting with a non-zero status code. + """ + + supported_features: int = aristaproto.uint64_field(2) + """ + A bitmask of supported features that the code generator supports. + This is a bitwise "or" of values from the Feature enum. + """ + + minimum_edition: int = aristaproto.int32_field(3) + """ + 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 = aristaproto.int32_field(4) + """ + 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"] = aristaproto.message_field(15) + + +@dataclass(eq=False, repr=False) +class CodeGeneratorResponseFile(aristaproto.Message): + """Represents a single generated file.""" + + name: str = aristaproto.string_field(1) + """ + The file name, relative to the output directory. The name must not + contain "." or ".." components and must be relative, not be absolute (so, + the file cannot lie outside the output directory). "/" must be used as + the path separator, not "\". + + If the name is omitted, the content will be appended to the previous + file. This allows the generator to break large files into small chunks, + and allows the generated text to be streamed back to protoc so that large + files need not reside completely in memory at one time. Note that as of + this writing protoc does not optimize for this -- it will read the entire + CodeGeneratorResponse before writing files to disk. + """ + + insertion_point: str = aristaproto.string_field(2) + """ + If non-empty, indicates that the named file should already exist, and the + content here is to be inserted into that file at a defined insertion + point. This feature allows a code generator to extend the output + produced by another code generator. The original generator may provide + insertion points by placing special annotations in the file that look + like: + @@protoc_insertion_point(NAME) + The annotation can have arbitrary text before and after it on the line, + which allows it to be placed in a comment. NAME should be replaced with + an identifier naming the point -- this is what other generators will use + as the insertion_point. Code inserted at this point will be placed + immediately above the line containing the insertion point (thus multiple + insertions to the same point will come out in the order they were added). + The double-@ is intended to make it unlikely that the generated code + could contain things that look like insertion points by accident. + + For example, the C++ code generator places the following line in the + .pb.h files that it generates: + // @@protoc_insertion_point(namespace_scope) + This line appears within the scope of the file's package namespace, but + outside of any particular class. Another plugin can then specify the + insertion_point "namespace_scope" to generate additional classes or + other declarations that should be placed in this scope. + + Note that if the line containing the insertion point begins with + whitespace, the same whitespace will be added to every line of the + inserted text. This is useful for languages like Python, where + indentation matters. In these languages, the insertion point comment + should be indented the same amount as any inserted code will need to be + in order to work correctly in that context. + + The code generator that generates the initial file and the one which + inserts into it must both run as part of a single invocation of protoc. + Code generators are executed in the order in which they appear on the + command line. + + If |insertion_point| is present, |name| must also be present. + """ + + content: str = aristaproto.string_field(15) + """The file contents.""" + + generated_code_info: ( + "aristaproto_lib_pydantic_google_protobuf.GeneratedCodeInfo" + ) = aristaproto.message_field(16) + """ + Information describing the file content being inserted. If an insertion + point is used, this information will be appropriately offset and inserted + into the code generation metadata for the generated files. + """ + + +CodeGeneratorRequest.__pydantic_model__.update_forward_refs() # type: ignore +CodeGeneratorResponse.__pydantic_model__.update_forward_refs() # type: ignore +CodeGeneratorResponseFile.__pydantic_model__.update_forward_refs() # type: ignore diff --git a/src/aristaproto/lib/std/__init__.py b/src/aristaproto/lib/std/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/aristaproto/lib/std/google/__init__.py b/src/aristaproto/lib/std/google/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/aristaproto/lib/std/google/protobuf/__init__.py b/src/aristaproto/lib/std/google/protobuf/__init__.py new file mode 100644 index 0000000..783676a --- /dev/null +++ b/src/aristaproto/lib/std/google/protobuf/__init__.py @@ -0,0 +1,2526 @@ +# 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-aristaproto + +import warnings +from dataclasses import dataclass +from typing import ( + Dict, + List, + Mapping, +) + +from typing_extensions import Self + +import aristaproto +from aristaproto.utils import hybridmethod + + +class Syntax(aristaproto.Enum): + """The syntax in which a protocol buffer element is defined.""" + + PROTO2 = 0 + """Syntax `proto2`.""" + + PROTO3 = 1 + """Syntax `proto3`.""" + + EDITIONS = 2 + """Syntax `editions`.""" + + +class FieldKind(aristaproto.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 FieldCardinality(aristaproto.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 Edition(aristaproto.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. + """ + + _2024 = 1001 + _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 + MAX = 2147483647 + """ + Placeholder for specifying unbounded edition support. This should only + ever be used by plugins that can expect to never require any changes to + support a new edition. + """ + + +class ExtensionRangeOptionsVerificationState(aristaproto.Enum): + """The verification state of the extension range.""" + + DECLARATION = 0 + """All the extensions of the range must be declared.""" + + UNVERIFIED = 1 + + +class FieldDescriptorProtoType(aristaproto.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 + TYPE_BYTES = 12 + """New in version 2.""" + + TYPE_UINT32 = 13 + TYPE_ENUM = 14 + TYPE_SFIXED32 = 15 + TYPE_SFIXED64 = 16 + TYPE_SINT32 = 17 + TYPE_SINT64 = 18 + + +class FieldDescriptorProtoLabel(aristaproto.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 FileOptionsOptimizeMode(aristaproto.Enum): + """Generated classes can be optimized for speed or code size.""" + + SPEED = 1 + CODE_SIZE = 2 + """etc.""" + + LITE_RUNTIME = 3 + + +class FieldOptionsCType(aristaproto.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(aristaproto.Enum): + JS_NORMAL = 0 + """Use the default type.""" + + JS_STRING = 1 + """Use JavaScript strings.""" + + JS_NUMBER = 2 + """Use JavaScript numbers.""" + + +class FieldOptionsOptionRetention(aristaproto.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(aristaproto.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 MethodOptionsIdempotencyLevel(aristaproto.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 + IDEMPOTENT = 2 + + +class FeatureSetFieldPresence(aristaproto.Enum): + FIELD_PRESENCE_UNKNOWN = 0 + EXPLICIT = 1 + IMPLICIT = 2 + LEGACY_REQUIRED = 3 + + +class FeatureSetEnumType(aristaproto.Enum): + ENUM_TYPE_UNKNOWN = 0 + OPEN = 1 + CLOSED = 2 + + +class FeatureSetRepeatedFieldEncoding(aristaproto.Enum): + REPEATED_FIELD_ENCODING_UNKNOWN = 0 + PACKED = 1 + EXPANDED = 2 + + +class FeatureSetUtf8Validation(aristaproto.Enum): + UTF8_VALIDATION_UNKNOWN = 0 + VERIFY = 2 + NONE = 3 + + +class FeatureSetMessageEncoding(aristaproto.Enum): + MESSAGE_ENCODING_UNKNOWN = 0 + LENGTH_PREFIXED = 1 + DELIMITED = 2 + + +class FeatureSetJsonFormat(aristaproto.Enum): + JSON_FORMAT_UNKNOWN = 0 + ALLOW = 1 + LEGACY_BEST_EFFORT = 2 + + +class GeneratedCodeInfoAnnotationSemantic(aristaproto.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 NullValue(aristaproto.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.""" + + +@dataclass(eq=False, repr=False) +class Any(aristaproto.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 = aristaproto.string_field(1) + """ + 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 = aristaproto.bytes_field(2) + """ + Must be a valid serialized protocol buffer of the above specified type. + """ + + +@dataclass(eq=False, repr=False) +class SourceContext(aristaproto.Message): + """ + `SourceContext` represents information about the source of a + protobuf element, like the file in which it is defined. + """ + + file_name: str = aristaproto.string_field(1) + """ + The path-qualified name of the .proto file that contained the associated + protobuf element. For example: `"google/protobuf/source_context.proto"`. + """ + + +@dataclass(eq=False, repr=False) +class Type(aristaproto.Message): + """A protocol buffer message type.""" + + name: str = aristaproto.string_field(1) + """The fully qualified message name.""" + + fields: List["Field"] = aristaproto.message_field(2) + """The list of fields.""" + + oneofs: List[str] = aristaproto.string_field(3) + """The list of types appearing in `oneof` definitions in this type.""" + + options: List["Option"] = aristaproto.message_field(4) + """The protocol buffer options.""" + + source_context: "SourceContext" = aristaproto.message_field(5) + """The source context.""" + + syntax: "Syntax" = aristaproto.enum_field(6) + """The source syntax.""" + + edition: str = aristaproto.string_field(7) + """ + The source edition string, only valid when syntax is SYNTAX_EDITIONS. + """ + + +@dataclass(eq=False, repr=False) +class Field(aristaproto.Message): + """A single field of a message type.""" + + kind: "FieldKind" = aristaproto.enum_field(1) + """The field type.""" + + cardinality: "FieldCardinality" = aristaproto.enum_field(2) + """The field cardinality.""" + + number: int = aristaproto.int32_field(3) + """The field number.""" + + name: str = aristaproto.string_field(4) + """The field name.""" + + type_url: str = aristaproto.string_field(6) + """ + The field type URL, without the scheme, for message or enumeration + types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. + """ + + oneof_index: int = aristaproto.int32_field(7) + """ + 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 = aristaproto.bool_field(8) + """Whether to use alternative packed wire representation.""" + + options: List["Option"] = aristaproto.message_field(9) + """The protocol buffer options.""" + + json_name: str = aristaproto.string_field(10) + """The field JSON name.""" + + default_value: str = aristaproto.string_field(11) + """ + The string value of the default value of this field. Proto2 syntax only. + """ + + +@dataclass(eq=False, repr=False) +class Enum(aristaproto.Message): + """Enum type definition.""" + + name: str = aristaproto.string_field(1) + """Enum type name.""" + + enumvalue: List["EnumValue"] = aristaproto.message_field( + 2, wraps=aristaproto.TYPE_ENUM + ) + """Enum value definitions.""" + + options: List["Option"] = aristaproto.message_field(3) + """Protocol buffer options.""" + + source_context: "SourceContext" = aristaproto.message_field(4) + """The source context.""" + + syntax: "Syntax" = aristaproto.enum_field(5) + """The source syntax.""" + + edition: str = aristaproto.string_field(6) + """ + The source edition string, only valid when syntax is SYNTAX_EDITIONS. + """ + + +@dataclass(eq=False, repr=False) +class EnumValue(aristaproto.Message): + """Enum value definition.""" + + name: str = aristaproto.string_field(1) + """Enum value name.""" + + number: int = aristaproto.int32_field(2) + """Enum value number.""" + + options: List["Option"] = aristaproto.message_field(3) + """Protocol buffer options.""" + + +@dataclass(eq=False, repr=False) +class Option(aristaproto.Message): + """ + A protocol buffer option, which can be attached to a message, field, + enumeration, etc. + """ + + name: str = aristaproto.string_field(1) + """ + 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: "Any" = aristaproto.message_field(2) + """ + 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. + """ + + +@dataclass(eq=False, repr=False) +class Api(aristaproto.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 = aristaproto.string_field(1) + """ + The fully qualified name of this interface, including package name + followed by the interface's simple name. + """ + + methods: List["Method"] = aristaproto.message_field(2) + """The methods of this interface, in unspecified order.""" + + options: List["Option"] = aristaproto.message_field(3) + """Any metadata attached to the interface.""" + + version: str = aristaproto.string_field(4) + """ + 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: "SourceContext" = aristaproto.message_field(5) + """ + Source context for the protocol buffer service represented by this + message. + """ + + mixins: List["Mixin"] = aristaproto.message_field(6) + """Included interfaces. See [Mixin][].""" + + syntax: "Syntax" = aristaproto.enum_field(7) + """The source syntax of the service.""" + + +@dataclass(eq=False, repr=False) +class Method(aristaproto.Message): + """Method represents a method of an API interface.""" + + name: str = aristaproto.string_field(1) + """The simple name of this method.""" + + request_type_url: str = aristaproto.string_field(2) + """A URL of the input message type.""" + + request_streaming: bool = aristaproto.bool_field(3) + """If true, the request is streamed.""" + + response_type_url: str = aristaproto.string_field(4) + """The URL of the output message type.""" + + response_streaming: bool = aristaproto.bool_field(5) + """If true, the response is streamed.""" + + options: List["Option"] = aristaproto.message_field(6) + """Any metadata attached to the method.""" + + syntax: "Syntax" = aristaproto.enum_field(7) + """The source syntax of this method.""" + + +@dataclass(eq=False, repr=False) +class Mixin(aristaproto.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 = aristaproto.string_field(1) + """The fully qualified name of the interface which is included.""" + + root: str = aristaproto.string_field(2) + """ + If non-empty specifies a path under which inherited HTTP paths + are rooted. + """ + + +@dataclass(eq=False, repr=False) +class FileDescriptorSet(aristaproto.Message): + """ + The protocol compiler can output a FileDescriptorSet containing the .proto + files it parses. + """ + + file: List["FileDescriptorProto"] = aristaproto.message_field(1) + + +@dataclass(eq=False, repr=False) +class FileDescriptorProto(aristaproto.Message): + """Describes a complete .proto file.""" + + name: str = aristaproto.string_field(1) + package: str = aristaproto.string_field(2) + dependency: List[str] = aristaproto.string_field(3) + """Names of files imported by this file.""" + + public_dependency: List[int] = aristaproto.int32_field(10) + """Indexes of the public imported files in the dependency list above.""" + + weak_dependency: List[int] = aristaproto.int32_field(11) + """ + Indexes of the weak imported files in the dependency list. + For Google-internal migration only. Do not use. + """ + + message_type: List["DescriptorProto"] = aristaproto.message_field(4) + """All top-level definitions in this file.""" + + enum_type: List["EnumDescriptorProto"] = aristaproto.message_field(5) + service: List["ServiceDescriptorProto"] = aristaproto.message_field(6) + extension: List["FieldDescriptorProto"] = aristaproto.message_field(7) + options: "FileOptions" = aristaproto.message_field(8) + source_code_info: "SourceCodeInfo" = aristaproto.message_field(9) + """ + 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 = aristaproto.string_field(12) + """ + 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" = aristaproto.enum_field(14) + """The edition of the proto file.""" + + +@dataclass(eq=False, repr=False) +class DescriptorProto(aristaproto.Message): + """Describes a message type.""" + + name: str = aristaproto.string_field(1) + field: List["FieldDescriptorProto"] = aristaproto.message_field(2) + extension: List["FieldDescriptorProto"] = aristaproto.message_field(6) + nested_type: List["DescriptorProto"] = aristaproto.message_field(3) + enum_type: List["EnumDescriptorProto"] = aristaproto.message_field(4) + extension_range: List["DescriptorProtoExtensionRange"] = aristaproto.message_field( + 5 + ) + oneof_decl: List["OneofDescriptorProto"] = aristaproto.message_field(8) + options: "MessageOptions" = aristaproto.message_field(7) + reserved_range: List["DescriptorProtoReservedRange"] = aristaproto.message_field(9) + reserved_name: List[str] = aristaproto.string_field(10) + """ + Reserved field names, which may not be used by fields in the same message. + A given name may only be reserved once. + """ + + +@dataclass(eq=False, repr=False) +class DescriptorProtoExtensionRange(aristaproto.Message): + start: int = aristaproto.int32_field(1) + end: int = aristaproto.int32_field(2) + options: "ExtensionRangeOptions" = aristaproto.message_field(3) + + +@dataclass(eq=False, repr=False) +class DescriptorProtoReservedRange(aristaproto.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 = aristaproto.int32_field(1) + end: int = aristaproto.int32_field(2) + + +@dataclass(eq=False, repr=False) +class ExtensionRangeOptions(aristaproto.Message): + uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) + """The parser stores options it doesn't recognize here. See above.""" + + declaration: List["ExtensionRangeOptionsDeclaration"] = aristaproto.message_field(2) + """ + 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: "FeatureSet" = aristaproto.message_field(50) + """Any features defined in the specific edition.""" + + verification: "ExtensionRangeOptionsVerificationState" = aristaproto.enum_field(3) + """ + The verification state of the range. + TODO: flip the default to DECLARATION once all empty ranges + are marked as UNVERIFIED. + """ + + +@dataclass(eq=False, repr=False) +class ExtensionRangeOptionsDeclaration(aristaproto.Message): + number: int = aristaproto.int32_field(1) + """The extension number declared within the extension range.""" + + full_name: str = aristaproto.string_field(2) + """ + The fully-qualified name of the extension field. There must be a leading + dot in front of the full name. + """ + + type: str = aristaproto.string_field(3) + """ + 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 = aristaproto.bool_field(5) + """ + 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 = aristaproto.bool_field(6) + """ + If true, indicates that the extension must be defined as repeated. + Otherwise the extension must be defined as optional. + """ + + +@dataclass(eq=False, repr=False) +class FieldDescriptorProto(aristaproto.Message): + """Describes a field within a message.""" + + name: str = aristaproto.string_field(1) + number: int = aristaproto.int32_field(3) + label: "FieldDescriptorProtoLabel" = aristaproto.enum_field(4) + type: "FieldDescriptorProtoType" = aristaproto.enum_field(5) + """ + 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 = aristaproto.string_field(6) + """ + 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 = aristaproto.string_field(2) + """ + For extensions, this is the name of the type being extended. It is + resolved in the same manner as type_name. + """ + + default_value: str = aristaproto.string_field(7) + """ + 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 = aristaproto.int32_field(9) + """ + 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 = aristaproto.string_field(10) + """ + 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: "FieldOptions" = aristaproto.message_field(8) + proto3_optional: bool = aristaproto.bool_field(17) + """ + 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 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`. + """ + + +@dataclass(eq=False, repr=False) +class OneofDescriptorProto(aristaproto.Message): + """Describes a oneof.""" + + name: str = aristaproto.string_field(1) + options: "OneofOptions" = aristaproto.message_field(2) + + +@dataclass(eq=False, repr=False) +class EnumDescriptorProto(aristaproto.Message): + """Describes an enum type.""" + + name: str = aristaproto.string_field(1) + value: List["EnumValueDescriptorProto"] = aristaproto.message_field(2) + options: "EnumOptions" = aristaproto.message_field(3) + reserved_range: List[ + "EnumDescriptorProtoEnumReservedRange" + ] = aristaproto.message_field(4) + """ + 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] = aristaproto.string_field(5) + """ + Reserved enum value names, which may not be reused. A given name may only + be reserved once. + """ + + +@dataclass(eq=False, repr=False) +class EnumDescriptorProtoEnumReservedRange(aristaproto.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 = aristaproto.int32_field(1) + end: int = aristaproto.int32_field(2) + + +@dataclass(eq=False, repr=False) +class EnumValueDescriptorProto(aristaproto.Message): + """Describes a value within an enum.""" + + name: str = aristaproto.string_field(1) + number: int = aristaproto.int32_field(2) + options: "EnumValueOptions" = aristaproto.message_field(3) + + +@dataclass(eq=False, repr=False) +class ServiceDescriptorProto(aristaproto.Message): + """Describes a service.""" + + name: str = aristaproto.string_field(1) + method: List["MethodDescriptorProto"] = aristaproto.message_field(2) + options: "ServiceOptions" = aristaproto.message_field(3) + + +@dataclass(eq=False, repr=False) +class MethodDescriptorProto(aristaproto.Message): + """Describes a method of a service.""" + + name: str = aristaproto.string_field(1) + input_type: str = aristaproto.string_field(2) + """ + 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 = aristaproto.string_field(3) + options: "MethodOptions" = aristaproto.message_field(4) + client_streaming: bool = aristaproto.bool_field(5) + """Identifies if client streams multiple client messages""" + + server_streaming: bool = aristaproto.bool_field(6) + """Identifies if server streams multiple server messages""" + + +@dataclass(eq=False, repr=False) +class FileOptions(aristaproto.Message): + java_package: str = aristaproto.string_field(1) + """ + 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 = aristaproto.string_field(8) + """ + 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 = aristaproto.bool_field(10) + """ + 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 = aristaproto.bool_field(20) + """This option does nothing.""" + + java_string_check_utf8: bool = aristaproto.bool_field(27) + """ + A proto2 file can set this to true to opt in to UTF-8 checking for Java, + which will throw an exception if invalid UTF-8 is parsed from the wire or + assigned to a string field. + + TODO: clarify exactly what kinds of field types this option + applies to, and update these docs accordingly. + + Proto3 files already perform these checks. Setting the option explicitly to + false has no effect: it cannot be used to opt proto3 files out of UTF-8 + checks. + """ + + optimize_for: "FileOptionsOptimizeMode" = aristaproto.enum_field(9) + go_package: str = aristaproto.string_field(11) + """ + 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 = aristaproto.bool_field(16) + """ + 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 = aristaproto.bool_field(17) + py_generic_services: bool = aristaproto.bool_field(18) + deprecated: bool = aristaproto.bool_field(23) + """ + 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 = aristaproto.bool_field(31) + """ + Enables the use of arenas for the proto messages in this file. This applies + only to generated classes for C++. + """ + + objc_class_prefix: str = aristaproto.string_field(36) + """ + 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 = aristaproto.string_field(37) + """Namespace for generated classes; defaults to the package.""" + + swift_prefix: str = aristaproto.string_field(39) + """ + 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 = aristaproto.string_field(40) + """ + Sets the php class prefix which is prepended to all php generated classes + from this .proto. Default is empty. + """ + + php_namespace: str = aristaproto.string_field(41) + """ + 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 = aristaproto.string_field(44) + """ + 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 = aristaproto.string_field(45) + """ + 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: "FeatureSet" = aristaproto.message_field(50) + """Any features defined in the specific edition.""" + + uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) + """ + 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, + ) + + +@dataclass(eq=False, repr=False) +class MessageOptions(aristaproto.Message): + message_set_wire_format: bool = aristaproto.bool_field(1) + """ + 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 = aristaproto.bool_field(2) + """ + 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 = aristaproto.bool_field(3) + """ + 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 = aristaproto.bool_field(7) + """ + 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. + + 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. + """ + + deprecated_legacy_json_field_conflicts: bool = aristaproto.bool_field(11) + """ + 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: "FeatureSet" = aristaproto.message_field(12) + """Any features defined in the specific edition.""" + + uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) + """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, + ) + + +@dataclass(eq=False, repr=False) +class FieldOptions(aristaproto.Message): + ctype: "FieldOptionsCType" = aristaproto.enum_field(1) + """ + 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 = aristaproto.bool_field(2) + """ + The packed option can be enabled for repeated primitive fields to enable + a more efficient representation on the wire. Rather than repeatedly + writing the tag and type for each element, the entire array is encoded as + a single length-delimited blob. In proto3, only explicit setting it to + false will avoid using packed encoding. This option is prohibited in + Editions, but the `repeated_field_encoding` feature can be used to control + the behavior. + """ + + jstype: "FieldOptionsJsType" = aristaproto.enum_field(6) + """ + 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 = aristaproto.bool_field(5) + """ + 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 lazy message fields are still eagerly verified to check + ill-formed wireformat or missing required fields. Calling IsInitialized() + on the outer message would fail if the inner message has missing required + fields. Failed verification would result in parsing failure (except when + uninitialized messages are acceptable). + """ + + unverified_lazy: bool = aristaproto.bool_field(15) + """ + 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 = aristaproto.bool_field(3) + """ + 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 = aristaproto.bool_field(10) + """For Google-internal migration only. Do not use.""" + + debug_redact: bool = aristaproto.bool_field(16) + """ + Indicate that the field value should not be printed out when using debug + formats, e.g. when the field contains sensitive credentials. + """ + + retention: "FieldOptionsOptionRetention" = aristaproto.enum_field(17) + targets: List["FieldOptionsOptionTargetType"] = aristaproto.enum_field(19) + edition_defaults: List["FieldOptionsEditionDefault"] = aristaproto.message_field(20) + features: "FeatureSet" = aristaproto.message_field(21) + """Any features defined in the specific edition.""" + + feature_support: "FieldOptionsFeatureSupport" = aristaproto.message_field(22) + uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) + """The parser stores options it doesn't recognize here. See above.""" + + +@dataclass(eq=False, repr=False) +class FieldOptionsEditionDefault(aristaproto.Message): + edition: "Edition" = aristaproto.enum_field(3) + value: str = aristaproto.string_field(2) + + +@dataclass(eq=False, repr=False) +class FieldOptionsFeatureSupport(aristaproto.Message): + """Information about the support window of a feature.""" + + edition_introduced: "Edition" = aristaproto.enum_field(1) + """ + The edition that this feature was first available in. In editions + earlier than this one, the default assigned to EDITION_LEGACY will be + used, and proto files will not be able to override it. + """ + + edition_deprecated: "Edition" = aristaproto.enum_field(2) + """ + The edition this feature becomes deprecated in. Using this after this + edition may trigger warnings. + """ + + deprecation_warning: str = aristaproto.string_field(3) + """ + The deprecation warning text if this feature is used after the edition it + was marked deprecated in. + """ + + edition_removed: "Edition" = aristaproto.enum_field(4) + """ + The edition this feature is no longer available in. In editions after + this one, the last default assigned will be used, and proto files will + not be able to override it. + """ + + +@dataclass(eq=False, repr=False) +class OneofOptions(aristaproto.Message): + features: "FeatureSet" = aristaproto.message_field(1) + """Any features defined in the specific edition.""" + + uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) + """The parser stores options it doesn't recognize here. See above.""" + + +@dataclass(eq=False, repr=False) +class EnumOptions(aristaproto.Message): + allow_alias: bool = aristaproto.bool_field(2) + """ + Set this option to true to allow mapping different tag names to the same + value. + """ + + deprecated: bool = aristaproto.bool_field(3) + """ + 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 = aristaproto.bool_field(6) + """ + 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: "FeatureSet" = aristaproto.message_field(7) + """Any features defined in the specific edition.""" + + uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) + """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, + ) + + +@dataclass(eq=False, repr=False) +class EnumValueOptions(aristaproto.Message): + deprecated: bool = aristaproto.bool_field(1) + """ + 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: "FeatureSet" = aristaproto.message_field(2) + """Any features defined in the specific edition.""" + + debug_redact: bool = aristaproto.bool_field(3) + """ + 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"] = aristaproto.message_field(999) + """The parser stores options it doesn't recognize here. See above.""" + + +@dataclass(eq=False, repr=False) +class ServiceOptions(aristaproto.Message): + features: "FeatureSet" = aristaproto.message_field(34) + """Any features defined in the specific edition.""" + + deprecated: bool = aristaproto.bool_field(33) + """ + 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"] = aristaproto.message_field(999) + """The parser stores options it doesn't recognize here. See above.""" + + +@dataclass(eq=False, repr=False) +class MethodOptions(aristaproto.Message): + deprecated: bool = aristaproto.bool_field(33) + """ + 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" = aristaproto.enum_field(34) + features: "FeatureSet" = aristaproto.message_field(35) + """Any features defined in the specific edition.""" + + uninterpreted_option: List["UninterpretedOption"] = aristaproto.message_field(999) + """The parser stores options it doesn't recognize here. See above.""" + + +@dataclass(eq=False, repr=False) +class UninterpretedOption(aristaproto.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"] = aristaproto.message_field(2) + identifier_value: str = aristaproto.string_field(3) + """ + 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 = aristaproto.uint64_field(4) + negative_int_value: int = aristaproto.int64_field(5) + double_value: float = aristaproto.double_field(6) + string_value: bytes = aristaproto.bytes_field(7) + aggregate_value: str = aristaproto.string_field(8) + + +@dataclass(eq=False, repr=False) +class UninterpretedOptionNamePart(aristaproto.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 = aristaproto.string_field(1) + is_extension: bool = aristaproto.bool_field(2) + + +@dataclass(eq=False, repr=False) +class FeatureSet(aristaproto.Message): + """ + 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" = aristaproto.enum_field(1) + enum_type: "FeatureSetEnumType" = aristaproto.enum_field(2) + repeated_field_encoding: "FeatureSetRepeatedFieldEncoding" = aristaproto.enum_field( + 3 + ) + utf8_validation: "FeatureSetUtf8Validation" = aristaproto.enum_field(4) + message_encoding: "FeatureSetMessageEncoding" = aristaproto.enum_field(5) + json_format: "FeatureSetJsonFormat" = aristaproto.enum_field(6) + + +@dataclass(eq=False, repr=False) +class FeatureSetDefaults(aristaproto.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" + ] = aristaproto.message_field(1) + minimum_edition: "Edition" = aristaproto.enum_field(4) + """ + The minimum supported edition (inclusive) when this was constructed. + Editions before this will not have defaults. + """ + + maximum_edition: "Edition" = aristaproto.enum_field(5) + """ + The maximum known edition (inclusive) when this was constructed. Editions + after this will not have reliable defaults. + """ + + +@dataclass(eq=False, repr=False) +class FeatureSetDefaultsFeatureSetEditionDefault(aristaproto.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" = aristaproto.enum_field(3) + overridable_features: "FeatureSet" = aristaproto.message_field(4) + """Defaults of features that can be overridden in this edition.""" + + fixed_features: "FeatureSet" = aristaproto.message_field(5) + """Defaults of features that can't be overridden in this edition.""" + + features: "FeatureSet" = aristaproto.message_field(2) + """ + TODO Deprecate and remove this field, which is just the + above two merged. + """ + + +@dataclass(eq=False, repr=False) +class SourceCodeInfo(aristaproto.Message): + """ + Encapsulates information about the original source file from which a + FileDescriptorProto was generated. + """ + + location: List["SourceCodeInfoLocation"] = aristaproto.message_field(1) + """ + 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. + """ + + +@dataclass(eq=False, repr=False) +class SourceCodeInfoLocation(aristaproto.Message): + path: List[int] = aristaproto.int32_field(1) + """ + 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 appears. + 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] = aristaproto.int32_field(2) + """ + 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 = aristaproto.string_field(3) + """ + 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 = aristaproto.string_field(4) + leading_detached_comments: List[str] = aristaproto.string_field(6) + + +@dataclass(eq=False, repr=False) +class GeneratedCodeInfo(aristaproto.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"] = aristaproto.message_field(1) + """ + An Annotation connects some span of text in generated code to an element + of its generating .proto file. + """ + + +@dataclass(eq=False, repr=False) +class GeneratedCodeInfoAnnotation(aristaproto.Message): + path: List[int] = aristaproto.int32_field(1) + """ + Identifies the element in the original source .proto file. This field + is formatted the same as SourceCodeInfo.Location.path. + """ + + source_file: str = aristaproto.string_field(2) + """Identifies the filesystem path to the original source .proto.""" + + begin: int = aristaproto.int32_field(3) + """ + Identifies the starting offset in bytes in the generated code + that relates to the identified object. + """ + + end: int = aristaproto.int32_field(4) + """ + 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" = aristaproto.enum_field(5) + + +@dataclass(eq=False, repr=False) +class Duration(aristaproto.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 = aristaproto.int64_field(1) + """ + 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 = aristaproto.int32_field(2) + """ + 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. + """ + + +@dataclass(eq=False, repr=False) +class Empty(aristaproto.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 + + +@dataclass(eq=False, repr=False) +class FieldMask(aristaproto.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] = aristaproto.string_field(1) + """The set of field mask paths.""" + + +@dataclass(eq=False, repr=False) +class Struct(aristaproto.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"] = aristaproto.map_field( + 1, aristaproto.TYPE_STRING, aristaproto.TYPE_MESSAGE + ) + """Unordered map of dynamically typed values.""" + + @hybridmethod + def from_dict(cls: "type[Self]", value: Mapping[str, Any]) -> Self: # type: ignore + self = cls() + return self.from_dict(value) + + @from_dict.instancemethod + def from_dict(self, value: Mapping[str, Any]) -> Self: + fields = {**value} + for k in fields: + if hasattr(fields[k], "from_dict"): + fields[k] = fields[k].from_dict() + + self.fields = fields + return self + + def to_dict( + self, + casing: aristaproto.Casing = aristaproto.Casing.CAMEL, + include_default_values: bool = False, + ) -> Dict[str, Any]: + output = {**self.fields} + for k in self.fields: + if hasattr(self.fields[k], "to_dict"): + output[k] = self.fields[k].to_dict(casing, include_default_values) + return output + + +@dataclass(eq=False, repr=False) +class Value(aristaproto.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. + """ + + null_value: "NullValue" = aristaproto.enum_field(1, group="kind") + """Represents a null value.""" + + number_value: float = aristaproto.double_field(2, group="kind") + """Represents a double value.""" + + string_value: str = aristaproto.string_field(3, group="kind") + """Represents a string value.""" + + bool_value: bool = aristaproto.bool_field(4, group="kind") + """Represents a boolean value.""" + + struct_value: "Struct" = aristaproto.message_field(5, group="kind") + """Represents a structured value.""" + + list_value: "ListValue" = aristaproto.message_field(6, group="kind") + """Represents a repeated `Value`.""" + + +@dataclass(eq=False, repr=False) +class ListValue(aristaproto.Message): + """ + `ListValue` is a wrapper around a repeated field of values. + + The JSON representation for `ListValue` is JSON array. + """ + + values: List["Value"] = aristaproto.message_field(1) + """Repeated field of dynamically typed values.""" + + +@dataclass(eq=False, repr=False) +class Timestamp(aristaproto.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 = aristaproto.int64_field(1) + """ + 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 = aristaproto.int32_field(2) + """ + 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. + """ + + +@dataclass(eq=False, repr=False) +class DoubleValue(aristaproto.Message): + """ + Wrapper message for `double`. + + The JSON representation for `DoubleValue` is JSON number. + """ + + value: float = aristaproto.double_field(1) + """The double value.""" + + +@dataclass(eq=False, repr=False) +class FloatValue(aristaproto.Message): + """ + Wrapper message for `float`. + + The JSON representation for `FloatValue` is JSON number. + """ + + value: float = aristaproto.float_field(1) + """The float value.""" + + +@dataclass(eq=False, repr=False) +class Int64Value(aristaproto.Message): + """ + Wrapper message for `int64`. + + The JSON representation for `Int64Value` is JSON string. + """ + + value: int = aristaproto.int64_field(1) + """The int64 value.""" + + +@dataclass(eq=False, repr=False) +class UInt64Value(aristaproto.Message): + """ + Wrapper message for `uint64`. + + The JSON representation for `UInt64Value` is JSON string. + """ + + value: int = aristaproto.uint64_field(1) + """The uint64 value.""" + + +@dataclass(eq=False, repr=False) +class Int32Value(aristaproto.Message): + """ + Wrapper message for `int32`. + + The JSON representation for `Int32Value` is JSON number. + """ + + value: int = aristaproto.int32_field(1) + """The int32 value.""" + + +@dataclass(eq=False, repr=False) +class UInt32Value(aristaproto.Message): + """ + Wrapper message for `uint32`. + + The JSON representation for `UInt32Value` is JSON number. + """ + + value: int = aristaproto.uint32_field(1) + """The uint32 value.""" + + +@dataclass(eq=False, repr=False) +class BoolValue(aristaproto.Message): + """ + Wrapper message for `bool`. + + The JSON representation for `BoolValue` is JSON `true` and `false`. + """ + + value: bool = aristaproto.bool_field(1) + """The bool value.""" + + +@dataclass(eq=False, repr=False) +class StringValue(aristaproto.Message): + """ + Wrapper message for `string`. + + The JSON representation for `StringValue` is JSON string. + """ + + value: str = aristaproto.string_field(1) + """The string value.""" + + +@dataclass(eq=False, repr=False) +class BytesValue(aristaproto.Message): + """ + Wrapper message for `bytes`. + + The JSON representation for `BytesValue` is JSON string. + """ + + value: bytes = aristaproto.bytes_field(1) + """The bytes value.""" diff --git a/src/aristaproto/lib/std/google/protobuf/compiler/__init__.py b/src/aristaproto/lib/std/google/protobuf/compiler/__init__.py new file mode 100644 index 0000000..a26dc86 --- /dev/null +++ b/src/aristaproto/lib/std/google/protobuf/compiler/__init__.py @@ -0,0 +1,198 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# sources: google/protobuf/compiler/plugin.proto +# plugin: python-aristaproto +# This file has been @generated + +from dataclasses import dataclass +from typing import List + +import aristaproto +import aristaproto.lib.google.protobuf as aristaproto_lib_google_protobuf + + +class CodeGeneratorResponseFeature(aristaproto.Enum): + """Sync with code_generator.h.""" + + FEATURE_NONE = 0 + FEATURE_PROTO3_OPTIONAL = 1 + FEATURE_SUPPORTS_EDITIONS = 2 + + +@dataclass(eq=False, repr=False) +class Version(aristaproto.Message): + """The version number of protocol compiler.""" + + major: int = aristaproto.int32_field(1) + minor: int = aristaproto.int32_field(2) + patch: int = aristaproto.int32_field(3) + suffix: str = aristaproto.string_field(4) + """ + A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should + be empty for mainline stable releases. + """ + + +@dataclass(eq=False, repr=False) +class CodeGeneratorRequest(aristaproto.Message): + """An encoded CodeGeneratorRequest is written to the plugin's stdin.""" + + file_to_generate: List[str] = aristaproto.string_field(1) + """ + The .proto files that were explicitly listed on the command-line. The + code generator should generate code only for these files. Each file's + descriptor will be included in proto_file, below. + """ + + parameter: str = aristaproto.string_field(2) + """The generator parameter passed on the command-line.""" + + proto_file: List[ + "aristaproto_lib_google_protobuf.FileDescriptorProto" + ] = aristaproto.message_field(15) + """ + FileDescriptorProtos for all files in files_to_generate and everything + they import. The files will appear in topological order, so each file + appears before any file that imports it. + + Note: the files listed in files_to_generate will include runtime-retention + options only, but all other files will include source-retention options. + The source_file_descriptors field below is available in case you need + source-retention options for files_to_generate. + + protoc guarantees that all proto_files will be written after + the fields above, even though this is not technically guaranteed by the + protobuf wire format. This theoretically could allow a plugin to stream + in the FileDescriptorProtos and handle them one by one rather than read + the entire set into memory at once. However, as of this writing, this + is not similarly optimized on protoc's end -- it will store all fields in + memory at once before sending them to the plugin. + + Type names of fields and extensions in the FileDescriptorProto are always + fully qualified. + """ + + source_file_descriptors: List[ + "aristaproto_lib_google_protobuf.FileDescriptorProto" + ] = aristaproto.message_field(17) + """ + File descriptors with all options, including source-retention options. + These descriptors are only provided for the files listed in + files_to_generate. + """ + + compiler_version: "Version" = aristaproto.message_field(3) + """The version number of protocol compiler.""" + + +@dataclass(eq=False, repr=False) +class CodeGeneratorResponse(aristaproto.Message): + """The plugin writes an encoded CodeGeneratorResponse to stdout.""" + + error: str = aristaproto.string_field(1) + """ + Error message. If non-empty, code generation failed. The plugin process + should exit with status code zero even if it reports an error in this way. + + This should be used to indicate errors in .proto files which prevent the + code generator from generating correct code. Errors which indicate a + problem in protoc itself -- such as the input CodeGeneratorRequest being + unparseable -- should be reported by writing a message to stderr and + exiting with a non-zero status code. + """ + + supported_features: int = aristaproto.uint64_field(2) + """ + A bitmask of supported features that the code generator supports. + This is a bitwise "or" of values from the Feature enum. + """ + + minimum_edition: int = aristaproto.int32_field(3) + """ + 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 = aristaproto.int32_field(4) + """ + 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"] = aristaproto.message_field(15) + + +@dataclass(eq=False, repr=False) +class CodeGeneratorResponseFile(aristaproto.Message): + """Represents a single generated file.""" + + name: str = aristaproto.string_field(1) + """ + The file name, relative to the output directory. The name must not + contain "." or ".." components and must be relative, not be absolute (so, + the file cannot lie outside the output directory). "/" must be used as + the path separator, not "\". + + If the name is omitted, the content will be appended to the previous + file. This allows the generator to break large files into small chunks, + and allows the generated text to be streamed back to protoc so that large + files need not reside completely in memory at one time. Note that as of + this writing protoc does not optimize for this -- it will read the entire + CodeGeneratorResponse before writing files to disk. + """ + + insertion_point: str = aristaproto.string_field(2) + """ + If non-empty, indicates that the named file should already exist, and the + content here is to be inserted into that file at a defined insertion + point. This feature allows a code generator to extend the output + produced by another code generator. The original generator may provide + insertion points by placing special annotations in the file that look + like: + @@protoc_insertion_point(NAME) + The annotation can have arbitrary text before and after it on the line, + which allows it to be placed in a comment. NAME should be replaced with + an identifier naming the point -- this is what other generators will use + as the insertion_point. Code inserted at this point will be placed + immediately above the line containing the insertion point (thus multiple + insertions to the same point will come out in the order they were added). + The double-@ is intended to make it unlikely that the generated code + could contain things that look like insertion points by accident. + + For example, the C++ code generator places the following line in the + .pb.h files that it generates: + // @@protoc_insertion_point(namespace_scope) + This line appears within the scope of the file's package namespace, but + outside of any particular class. Another plugin can then specify the + insertion_point "namespace_scope" to generate additional classes or + other declarations that should be placed in this scope. + + Note that if the line containing the insertion point begins with + whitespace, the same whitespace will be added to every line of the + inserted text. This is useful for languages like Python, where + indentation matters. In these languages, the insertion point comment + should be indented the same amount as any inserted code will need to be + in order to work correctly in that context. + + The code generator that generates the initial file and the one which + inserts into it must both run as part of a single invocation of protoc. + Code generators are executed in the order in which they appear on the + command line. + + If |insertion_point| is present, |name| must also be present. + """ + + content: str = aristaproto.string_field(15) + """The file contents.""" + + generated_code_info: "aristaproto_lib_google_protobuf.GeneratedCodeInfo" = ( + aristaproto.message_field(16) + ) + """ + Information describing the file content being inserted. If an insertion + point is used, this information will be appropriately offset and inserted + into the code generation metadata for the generated files. + """ diff --git a/src/aristaproto/plugin/models.py b/src/aristaproto/plugin/models.py index 693a2d4..484b40d 100644 --- a/src/aristaproto/plugin/models.py +++ b/src/aristaproto/plugin/models.py @@ -565,6 +565,7 @@ def py_type(self) -> str: package=self.output_file.package, imports=self.output_file.imports, source_type=self.proto_obj.type_name, + pydantic=self.output_file.pydantic_dataclasses, ) else: raise NotImplementedError(f"Unknown type {self.proto_obj.type}") @@ -809,6 +810,7 @@ def py_input_message_type(self) -> str: imports=self.output_file.imports, source_type=self.proto_obj.input_type, unwrap=False, + pydantic=self.output_file.pydantic_dataclasses, ).strip('"') @property @@ -837,6 +839,7 @@ def py_output_message_type(self) -> str: imports=self.output_file.imports, source_type=self.proto_obj.output_type, unwrap=False, + pydantic=self.output_file.pydantic_dataclasses, ).strip('"') @property diff --git a/tests/test_get_ref_type.py b/tests/test_get_ref_type.py index 1ff1fce..a4c6f76 100644 --- a/tests/test_get_ref_type.py +++ b/tests/test_get_ref_type.py @@ -35,7 +35,48 @@ def test_reference_google_wellknown_types_non_wrappers( google_type: str, expected_name: str, expected_import: str ): imports = set() - name = get_type_reference(package="", imports=imports, source_type=google_type) + name = get_type_reference( + package="", imports=imports, source_type=google_type, pydantic=False + ) + + assert name == expected_name + assert imports.__contains__( + expected_import + ), f"{expected_import} not found in {imports}" + + +@pytest.mark.parametrize( + ["google_type", "expected_name", "expected_import"], + [ + ( + ".google.protobuf.Empty", + '"aristaproto_lib_pydantic_google_protobuf.Empty"', + "import aristaproto.lib.pydantic.google.protobuf as aristaproto_lib_pydantic_google_protobuf", + ), + ( + ".google.protobuf.Struct", + '"aristaproto_lib_pydantic_google_protobuf.Struct"', + "import aristaproto.lib.pydantic.google.protobuf as aristaproto_lib_pydantic_google_protobuf", + ), + ( + ".google.protobuf.ListValue", + '"aristaproto_lib_pydantic_google_protobuf.ListValue"', + "import aristaproto.lib.pydantic.google.protobuf as aristaproto_lib_pydantic_google_protobuf", + ), + ( + ".google.protobuf.Value", + '"aristaproto_lib_pydantic_google_protobuf.Value"', + "import aristaproto.lib.pydantic.google.protobuf as aristaproto_lib_pydantic_google_protobuf", + ), + ], +) +def test_reference_google_wellknown_types_non_wrappers_pydantic( + google_type: str, expected_name: str, expected_import: str +): + imports = set() + name = get_type_reference( + package="", imports=imports, source_type=google_type, pydantic=True + ) assert name == expected_name assert imports.__contains__( diff --git a/tests/test_struct.py b/tests/test_struct.py new file mode 100644 index 0000000..c562763 --- /dev/null +++ b/tests/test_struct.py @@ -0,0 +1,36 @@ +import json + +from aristaproto.lib.google.protobuf import Struct +from aristaproto.lib.pydantic.google.protobuf import Struct as StructPydantic + + +def test_struct_roundtrip(): + data = { + "foo": "bar", + "baz": None, + "quux": 123, + "zap": [1, {"two": 3}, "four"], + } + data_json = json.dumps(data) + + struct_from_dict = Struct().from_dict(data) + assert struct_from_dict.fields == data + assert struct_from_dict.to_dict() == data + assert struct_from_dict.to_json() == data_json + + struct_from_json = Struct().from_json(data_json) + assert struct_from_json.fields == data + assert struct_from_json.to_dict() == data + assert struct_from_json == struct_from_dict + assert struct_from_json.to_json() == data_json + + struct_pyd_from_dict = StructPydantic(fields={}).from_dict(data) + assert struct_pyd_from_dict.fields == data + assert struct_pyd_from_dict.to_dict() == data + assert struct_pyd_from_dict.to_json() == data_json + + struct_pyd_from_dict = StructPydantic(fields={}).from_json(data_json) + assert struct_pyd_from_dict.fields == data + assert struct_pyd_from_dict.to_dict() == data + assert struct_pyd_from_dict == struct_pyd_from_dict + assert struct_pyd_from_dict.to_json() == data_json