From ea68537f0bbdd9bc1e6a5b0baee70e5dbfe6a315 Mon Sep 17 00:00:00 2001 From: charles Date: Mon, 4 May 2026 22:45:55 -0700 Subject: [PATCH] Refactor crate into multiple subcrates --- Cargo.lock | 21 +- Cargo.toml | 25 +- benches/.gitignore | 1 + benches/Cargo.toml | 18 + benches/{ => benches}/hackers_bench.rs | 2 +- {src => benches/src}/bin/gen_bench_data.rs | 11 +- {src => benches/src}/google/mod.rs | 0 .../src}/google/protobuf/compiler/mod.rs | 0 .../src}/google/protobuf/compiler/plugin.rs | 0 .../src}/google/protobuf/descriptor.rs | 0 {src => benches/src}/google/protobuf/mod.rs | 0 {src => benches/src}/hackers.rs | 692 +- benches/src/lib.rs | 1 + codegen/Cargo.toml | 10 + {data => codegen/data}/.gitignore | 0 {data => codegen/data}/descriptor.desc | Bin {data => codegen/data}/request.bin | Bin {data => codegen/data}/test_data.pb | Bin {data => codegen/data}/test_data.textproto | 0 {data => codegen/data}/test_types.desc | Bin {data => codegen/data}/test_types.proto | 0 .../google/protobuf/compiler/plugin.proto | 180 + .../proto/google/protobuf/descriptor.proto | 1507 ++++ codegen/proto/hackers.proto | 56 + {src => codegen/src}/bin/generator.rs | 12 +- {src => codegen/src}/bin/protoc-gen-roto.rs | 42 +- {src => codegen/src}/generator.rs | 42 +- codegen/src/google/mod.rs | 1 + codegen/src/google/protobuf/compiler/mod.rs | 1 + .../src/google/protobuf/compiler/plugin.rs | 679 ++ codegen/src/google/protobuf/descriptor.rs | 6711 +++++++++++++++++ codegen/src/google/protobuf/mod.rs | 2 + codegen/src/lib.rs | 2 + .../tests}/build_generated_code.rs | 34 +- .../tests}/test_nested_protos.rs | 29 +- {tests => codegen/tests}/test_with_method.rs | 8 +- protos/Cargo.toml | 6 + protos/src/lib.rs | 3 + runtime/Cargo.toml | 6 + runtime/data/.gitignore | 1 + runtime/data/descriptor.desc | Bin 0 -> 13915 bytes runtime/data/request.bin | Bin 0 -> 156932 bytes runtime/data/test_data.pb | Bin 0 -> 195 bytes runtime/data/test_data.textproto | 39 + runtime/data/test_types.desc | Bin 0 -> 876 bytes runtime/data/test_types.proto | 53 + {src => runtime/src}/lib.rs | 7 - src/main.rs | 3 - 48 files changed, 9839 insertions(+), 366 deletions(-) create mode 100644 benches/.gitignore create mode 100644 benches/Cargo.toml rename benches/{ => benches}/hackers_bench.rs (99%) rename {src => benches/src}/bin/gen_bench_data.rs (98%) rename {src => benches/src}/google/mod.rs (100%) rename {src => benches/src}/google/protobuf/compiler/mod.rs (100%) rename {src => benches/src}/google/protobuf/compiler/plugin.rs (100%) rename {src => benches/src}/google/protobuf/descriptor.rs (100%) rename {src => benches/src}/google/protobuf/mod.rs (100%) rename {src => benches/src}/hackers.rs (50%) create mode 100644 benches/src/lib.rs create mode 100644 codegen/Cargo.toml rename {data => codegen/data}/.gitignore (100%) rename {data => codegen/data}/descriptor.desc (100%) rename {data => codegen/data}/request.bin (100%) rename {data => codegen/data}/test_data.pb (100%) rename {data => codegen/data}/test_data.textproto (100%) rename {data => codegen/data}/test_types.desc (100%) rename {data => codegen/data}/test_types.proto (100%) create mode 100644 codegen/proto/google/protobuf/compiler/plugin.proto create mode 100644 codegen/proto/google/protobuf/descriptor.proto create mode 100644 codegen/proto/hackers.proto rename {src => codegen/src}/bin/generator.rs (79%) rename {src => codegen/src}/bin/protoc-gen-roto.rs (78%) rename {src => codegen/src}/generator.rs (89%) create mode 100644 codegen/src/google/mod.rs create mode 100644 codegen/src/google/protobuf/compiler/mod.rs create mode 100644 codegen/src/google/protobuf/compiler/plugin.rs create mode 100644 codegen/src/google/protobuf/descriptor.rs create mode 100644 codegen/src/google/protobuf/mod.rs create mode 100644 codegen/src/lib.rs rename {tests => codegen/tests}/build_generated_code.rs (71%) rename {tests => codegen/tests}/test_nested_protos.rs (66%) rename {tests => codegen/tests}/test_with_method.rs (89%) create mode 100644 protos/Cargo.toml create mode 100644 protos/src/lib.rs create mode 100644 runtime/Cargo.toml create mode 100644 runtime/data/.gitignore create mode 100644 runtime/data/descriptor.desc create mode 100644 runtime/data/request.bin create mode 100644 runtime/data/test_data.pb create mode 100644 runtime/data/test_data.textproto create mode 100644 runtime/data/test_types.desc create mode 100644 runtime/data/test_types.proto rename {src => runtime/src}/lib.rs (99%) delete mode 100644 src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 68048f5..f34f795 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -478,6 +478,10 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "protos" +version = "0.1.0" + [[package]] name = "quote" version = "1.0.45" @@ -537,15 +541,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] -name = "roto" +name = "roto-benches" version = "0.1.0" dependencies = [ "clap", "criterion", "env_logger", "log", + "roto-runtime", ] +[[package]] +name = "roto-codegen" +version = "0.1.0" +dependencies = [ + "clap", + "env_logger", + "log", + "roto-runtime", +] + +[[package]] +name = "roto-runtime" +version = "0.1.0" + [[package]] name = "rustversion" version = "1.0.22" diff --git a/Cargo.toml b/Cargo.toml index 97bd00c..44e1d9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,16 +1,11 @@ -[package] -name = "roto" -version = "0.1.0" -edition = "2024" +[workspace] +members = [ + "runtime", + "codegen", + "protos", + "benches", +] -[dependencies] -clap = { version = "4", features = ["derive"] } -log = "0.4" -env_logger = "0.11" - -[dev-dependencies] -criterion = { version = "0.5", features = ["html_reports"] } - -[[bench]] -name = "hackers_bench" -harness = false +exclude = [ + "test_gen_project" +] diff --git a/benches/.gitignore b/benches/.gitignore new file mode 100644 index 0000000..1269488 --- /dev/null +++ b/benches/.gitignore @@ -0,0 +1 @@ +data diff --git a/benches/Cargo.toml b/benches/Cargo.toml new file mode 100644 index 0000000..a8bbb74 --- /dev/null +++ b/benches/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "roto-benches" +version = "0.1.0" +edition = "2024" + +[dependencies] +roto-runtime = { path = "../runtime" } +clap = { version = "4", features = ["derive"] } +log = "0.4" +env_logger = "0.11" + + +[dev-dependencies] +criterion = { version = "0.5", features = ["html_reports"] } + +[[bench]] +name = "hackers_bench" +harness = false diff --git a/benches/hackers_bench.rs b/benches/benches/hackers_bench.rs similarity index 99% rename from benches/hackers_bench.rs rename to benches/benches/hackers_bench.rs index 34fe054..9f6509b 100644 --- a/benches/hackers_bench.rs +++ b/benches/benches/hackers_bench.rs @@ -27,7 +27,7 @@ //! - `iterate` — counting repeated fields at different nesting depths use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; -use roto::hackers::{Campaign, Hacker, Operation, Worm}; +use roto_benches::hackers::{Campaign, Hacker, Operation, Worm}; use std::hint::black_box; // ============================================================================= diff --git a/src/bin/gen_bench_data.rs b/benches/src/bin/gen_bench_data.rs similarity index 98% rename from src/bin/gen_bench_data.rs rename to benches/src/bin/gen_bench_data.rs index ad0d558..3273938 100644 --- a/src/bin/gen_bench_data.rs +++ b/benches/src/bin/gen_bench_data.rs @@ -17,7 +17,7 @@ //! Files land in `data/bench/` by default. use clap::Parser; -use roto::hackers::{ +use roto_benches::hackers::{ CampaignBuilder, ConnectionBuilder, HackerBuilder, OperationBuilder, ToolBuilder, WormBuilder, }; use std::io::{self, Write}; @@ -449,10 +449,11 @@ fn main() { ); // Default output: data/bench/.pb, or stdout if no output and no preset - let out_path = args - .output - .clone() - .or_else(|| args.preset.as_ref().map(|p| format!("data/bench/{}.pb", p))); + let out_path = args.output.clone().or_else(|| { + args.preset + .as_ref() + .map(|p| format!("benches/data/bench/{}.pb", p)) + }); match out_path { Some(ref path) => { diff --git a/src/google/mod.rs b/benches/src/google/mod.rs similarity index 100% rename from src/google/mod.rs rename to benches/src/google/mod.rs diff --git a/src/google/protobuf/compiler/mod.rs b/benches/src/google/protobuf/compiler/mod.rs similarity index 100% rename from src/google/protobuf/compiler/mod.rs rename to benches/src/google/protobuf/compiler/mod.rs diff --git a/src/google/protobuf/compiler/plugin.rs b/benches/src/google/protobuf/compiler/plugin.rs similarity index 100% rename from src/google/protobuf/compiler/plugin.rs rename to benches/src/google/protobuf/compiler/plugin.rs diff --git a/src/google/protobuf/descriptor.rs b/benches/src/google/protobuf/descriptor.rs similarity index 100% rename from src/google/protobuf/descriptor.rs rename to benches/src/google/protobuf/descriptor.rs diff --git a/src/google/protobuf/mod.rs b/benches/src/google/protobuf/mod.rs similarity index 100% rename from src/google/protobuf/mod.rs rename to benches/src/google/protobuf/mod.rs diff --git a/src/hackers.rs b/benches/src/hackers.rs similarity index 50% rename from src/hackers.rs rename to benches/src/hackers.rs index aadad46..e395e34 100644 --- a/src/hackers.rs +++ b/benches/src/hackers.rs @@ -1,12 +1,13 @@ // @generated by protoc-gen-roto — do not edit #![allow(unused_imports)] -use crate::{ProtoAccessor, ProtoBuilder, Result, RotoError, read_varint, RepeatedFieldIterator}; +use roto_runtime::{ + ProtoAccessor, ProtoBuilder, RepeatedFieldIterator, Result, RotoError, read_varint, +}; use std::str; - pub struct Tool<'a> { - accessor: crate::ProtoAccessor<'a>, + accessor: roto_runtime::ProtoAccessor<'a>, name_offset: Option, version_offset: Option, payload_offset: Option, @@ -15,8 +16,8 @@ pub struct Tool<'a> { } impl<'a> Tool<'a> { - pub fn new(data: &'a [u8]) -> crate::Result { - let accessor = crate::ProtoAccessor::new(data)?; + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; let mut name_offset = None; let mut version_offset = None; let mut payload_offset = None; @@ -24,61 +25,84 @@ impl<'a> Tool<'a> { let mut exploit_count_offset = None; for item in accessor.fields() { let (offset, tag, _) = item?; - if tag.field_number == 1 { name_offset = Some(offset); } - if tag.field_number == 2 { version_offset = Some(offset); } - if tag.field_number == 3 { payload_offset = Some(offset); } - if tag.field_number == 4 { is_active_offset = Some(offset); } - if tag.field_number == 5 { exploit_count_offset = Some(offset); } + if tag.field_number == 1 { + name_offset = Some(offset); + } + if tag.field_number == 2 { + version_offset = Some(offset); + } + if tag.field_number == 3 { + payload_offset = Some(offset); + } + if tag.field_number == 4 { + is_active_offset = Some(offset); + } + if tag.field_number == 5 { + exploit_count_offset = Some(offset); + } } Ok(Self { accessor, -name_offset, -version_offset, -payload_offset, -is_active_offset, -exploit_count_offset, + name_offset, + version_offset, + payload_offset, + is_active_offset, + exploit_count_offset, }) } - pub fn name(&self) -> crate::Result<&'a str> { - let offset = self.name_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn name(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .name_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - str::from_utf8(bytes).map_err(|_| crate::RotoError::WireFormatViolation) + str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } - pub fn version(&self) -> crate::Result<&'a str> { - let offset = self.version_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn version(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .version_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - str::from_utf8(bytes).map_err(|_| crate::RotoError::WireFormatViolation) + str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } - pub fn payload(&self) -> crate::Result<&'a [u8]> { - let offset = self.payload_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn payload(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .payload_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; Ok(bytes) } - pub fn is_active(&self) -> crate::Result { - let offset = self.is_active_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn is_active(&self) -> roto_runtime::Result { + let offset = self + .is_active_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - crate::read_varint(bytes).map(|(v, _)| v != 0).map_err(|_| crate::RotoError::WireFormatViolation) + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) } - pub fn exploit_count(&self) -> crate::Result { - let offset = self.exploit_count_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn exploit_count(&self) -> roto_runtime::Result { + let offset = self + .exploit_count_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - crate::read_varint(bytes).map(|(v, _)| v as i32).map_err(|_| crate::RotoError::WireFormatViolation) + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) } - pub fn raw_fields(&self) -> crate::RawFieldIterator<'a> { + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { self.accessor.raw_fields() } - } pub struct ToolBuilder<'b> { - builder: crate::ProtoBuilder<'b>, + builder: roto_runtime::ProtoBuilder<'b>, name_written: bool, version_written: bool, payload_written: bool, @@ -89,7 +113,7 @@ pub struct ToolBuilder<'b> { impl<'b> ToolBuilder<'b> { pub fn builder(buf: &mut [u8]) -> ToolBuilder<'_> { ToolBuilder { - builder: crate::ProtoBuilder::new(buf), + builder: roto_runtime::ProtoBuilder::new(buf), name_written: false, version_written: false, payload_written: false, @@ -98,37 +122,37 @@ impl<'b> ToolBuilder<'b> { } } - pub fn name(mut self, value: &str) -> crate::Result { + pub fn name(mut self, value: &str) -> roto_runtime::Result { self.builder.write_string(1, value)?; self.name_written = true; Ok(self) } - pub fn version(mut self, value: &str) -> crate::Result { + pub fn version(mut self, value: &str) -> roto_runtime::Result { self.builder.write_string(2, value)?; self.version_written = true; Ok(self) } - pub fn payload(mut self, value: &[u8]) -> crate::Result { + pub fn payload(mut self, value: &[u8]) -> roto_runtime::Result { self.builder.write_bytes(3, value)?; self.payload_written = true; Ok(self) } - pub fn is_active(mut self, value: u64) -> crate::Result { + pub fn is_active(mut self, value: u64) -> roto_runtime::Result { self.builder.write_varint(4, value)?; self.is_active_written = true; Ok(self) } - pub fn exploit_count(mut self, value: i32) -> crate::Result { + pub fn exploit_count(mut self, value: i32) -> roto_runtime::Result { self.builder.write_int32(5, value)?; self.exploit_count_written = true; Ok(self) } - pub fn with(mut self, msg: &Tool<'_>) -> crate::Result { + pub fn with(mut self, msg: &Tool<'_>) -> roto_runtime::Result { for item in msg.raw_fields() { let (field_number, raw_bytes) = item?; let is_written = match field_number { @@ -146,13 +170,13 @@ impl<'b> ToolBuilder<'b> { Ok(self) } - pub fn finish(self) -> crate::Result<&'b mut [u8]> { + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { self.builder.finish() } } pub struct Connection<'a> { - accessor: crate::ProtoAccessor<'a>, + accessor: roto_runtime::ProtoAccessor<'a>, host_offset: Option, port_offset: Option, encrypted_offset: Option, @@ -161,8 +185,8 @@ pub struct Connection<'a> { } impl<'a> Connection<'a> { - pub fn new(data: &'a [u8]) -> crate::Result { - let accessor = crate::ProtoAccessor::new(data)?; + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; let mut host_offset = None; let mut port_offset = None; let mut encrypted_offset = None; @@ -170,61 +194,86 @@ impl<'a> Connection<'a> { let mut session_key_offset = None; for item in accessor.fields() { let (offset, tag, _) = item?; - if tag.field_number == 1 { host_offset = Some(offset); } - if tag.field_number == 2 { port_offset = Some(offset); } - if tag.field_number == 3 { encrypted_offset = Some(offset); } - if tag.field_number == 4 { bandwidth_bps_offset = Some(offset); } - if tag.field_number == 5 { session_key_offset = Some(offset); } + if tag.field_number == 1 { + host_offset = Some(offset); + } + if tag.field_number == 2 { + port_offset = Some(offset); + } + if tag.field_number == 3 { + encrypted_offset = Some(offset); + } + if tag.field_number == 4 { + bandwidth_bps_offset = Some(offset); + } + if tag.field_number == 5 { + session_key_offset = Some(offset); + } } Ok(Self { accessor, -host_offset, -port_offset, -encrypted_offset, -bandwidth_bps_offset, -session_key_offset, + host_offset, + port_offset, + encrypted_offset, + bandwidth_bps_offset, + session_key_offset, }) } - pub fn host(&self) -> crate::Result<&'a str> { - let offset = self.host_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn host(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .host_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - str::from_utf8(bytes).map_err(|_| crate::RotoError::WireFormatViolation) + str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } - pub fn port(&self) -> crate::Result { - let offset = self.port_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn port(&self) -> roto_runtime::Result { + let offset = self + .port_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - crate::read_varint(bytes).map(|(v, _)| v as i32).map_err(|_| crate::RotoError::WireFormatViolation) + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) } - pub fn encrypted(&self) -> crate::Result { - let offset = self.encrypted_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn encrypted(&self) -> roto_runtime::Result { + let offset = self + .encrypted_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - crate::read_varint(bytes).map(|(v, _)| v != 0).map_err(|_| crate::RotoError::WireFormatViolation) + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) } - pub fn bandwidth_bps(&self) -> crate::Result { - let offset = self.bandwidth_bps_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn bandwidth_bps(&self) -> roto_runtime::Result { + let offset = self + .bandwidth_bps_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - crate::read_varint(bytes).map(|(v, _)| v as i32).map_err(|_| crate::RotoError::WireFormatViolation) + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) } - pub fn session_key(&self) -> crate::Result<&'a [u8]> { - let offset = self.session_key_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn session_key(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .session_key_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; Ok(bytes) } - pub fn raw_fields(&self) -> crate::RawFieldIterator<'a> { + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { self.accessor.raw_fields() } - } pub struct ConnectionBuilder<'b> { - builder: crate::ProtoBuilder<'b>, + builder: roto_runtime::ProtoBuilder<'b>, host_written: bool, port_written: bool, encrypted_written: bool, @@ -235,7 +284,7 @@ pub struct ConnectionBuilder<'b> { impl<'b> ConnectionBuilder<'b> { pub fn builder(buf: &mut [u8]) -> ConnectionBuilder<'_> { ConnectionBuilder { - builder: crate::ProtoBuilder::new(buf), + builder: roto_runtime::ProtoBuilder::new(buf), host_written: false, port_written: false, encrypted_written: false, @@ -244,37 +293,37 @@ impl<'b> ConnectionBuilder<'b> { } } - pub fn host(mut self, value: &str) -> crate::Result { + pub fn host(mut self, value: &str) -> roto_runtime::Result { self.builder.write_string(1, value)?; self.host_written = true; Ok(self) } - pub fn port(mut self, value: i32) -> crate::Result { + pub fn port(mut self, value: i32) -> roto_runtime::Result { self.builder.write_int32(2, value)?; self.port_written = true; Ok(self) } - pub fn encrypted(mut self, value: u64) -> crate::Result { + pub fn encrypted(mut self, value: u64) -> roto_runtime::Result { self.builder.write_varint(3, value)?; self.encrypted_written = true; Ok(self) } - pub fn bandwidth_bps(mut self, value: u64) -> crate::Result { + pub fn bandwidth_bps(mut self, value: u64) -> roto_runtime::Result { self.builder.write_varint(4, value)?; self.bandwidth_bps_written = true; Ok(self) } - pub fn session_key(mut self, value: &[u8]) -> crate::Result { + pub fn session_key(mut self, value: &[u8]) -> roto_runtime::Result { self.builder.write_bytes(5, value)?; self.session_key_written = true; Ok(self) } - pub fn with(mut self, msg: &Connection<'_>) -> crate::Result { + pub fn with(mut self, msg: &Connection<'_>) -> roto_runtime::Result { for item in msg.raw_fields() { let (field_number, raw_bytes) = item?; let is_written = match field_number { @@ -292,13 +341,13 @@ impl<'b> ConnectionBuilder<'b> { Ok(self) } - pub fn finish(self) -> crate::Result<&'b mut [u8]> { + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { self.builder.finish() } } pub struct Hacker<'a> { - accessor: crate::ProtoAccessor<'a>, + accessor: roto_runtime::ProtoAccessor<'a>, handle_offset: Option, real_name_offset: Option, age_offset: Option, @@ -313,8 +362,8 @@ pub struct Hacker<'a> { } impl<'a> Hacker<'a> { - pub fn new(data: &'a [u8]) -> crate::Result { - let accessor = crate::ProtoAccessor::new(data)?; + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; let mut handle_offset = None; let mut real_name_offset = None; let mut age_offset = None; @@ -328,101 +377,144 @@ impl<'a> Hacker<'a> { let mut active_connection_offset = None; for item in accessor.fields() { let (offset, tag, _) = item?; - if tag.field_number == 1 { handle_offset = Some(offset); } - if tag.field_number == 2 { real_name_offset = Some(offset); } - if tag.field_number == 3 { age_offset = Some(offset); } - if tag.field_number == 4 { skill_level_offset = Some(offset); } - if tag.field_number == 5 { is_elite_offset = Some(offset); } - if tag.field_number == 6 { crew_id_offset = Some(offset); } + if tag.field_number == 1 { + handle_offset = Some(offset); + } + if tag.field_number == 2 { + real_name_offset = Some(offset); + } + if tag.field_number == 3 { + age_offset = Some(offset); + } + if tag.field_number == 4 { + skill_level_offset = Some(offset); + } + if tag.field_number == 5 { + is_elite_offset = Some(offset); + } + if tag.field_number == 6 { + crew_id_offset = Some(offset); + } if tag.field_number == 7 { - if exploits_start.is_none() { exploits_start = Some(offset); } + if exploits_start.is_none() { + exploits_start = Some(offset); + } exploits_end = Some(offset); } if tag.field_number == 8 { - if tools_start.is_none() { tools_start = Some(offset); } + if tools_start.is_none() { + tools_start = Some(offset); + } tools_end = Some(offset); } - if tag.field_number == 9 { active_connection_offset = Some(offset); } + if tag.field_number == 9 { + active_connection_offset = Some(offset); + } } Ok(Self { accessor, -handle_offset, -real_name_offset, -age_offset, -skill_level_offset, -is_elite_offset, -crew_id_offset, -exploits_start, exploits_end, -tools_start, tools_end, -active_connection_offset, + handle_offset, + real_name_offset, + age_offset, + skill_level_offset, + is_elite_offset, + crew_id_offset, + exploits_start, + exploits_end, + tools_start, + tools_end, + active_connection_offset, }) } - pub fn handle(&self) -> crate::Result<&'a str> { - let offset = self.handle_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn handle(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .handle_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - str::from_utf8(bytes).map_err(|_| crate::RotoError::WireFormatViolation) + str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } - pub fn real_name(&self) -> crate::Result<&'a str> { - let offset = self.real_name_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn real_name(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .real_name_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - str::from_utf8(bytes).map_err(|_| crate::RotoError::WireFormatViolation) + str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } - pub fn age(&self) -> crate::Result { - let offset = self.age_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn age(&self) -> roto_runtime::Result { + let offset = self + .age_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - crate::read_varint(bytes).map(|(v, _)| v as i32).map_err(|_| crate::RotoError::WireFormatViolation) + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) } - pub fn skill_level(&self) -> crate::Result { - let offset = self.skill_level_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn skill_level(&self) -> roto_runtime::Result { + let offset = self + .skill_level_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - Ok(f32::from_le_bytes(bytes.try_into().map_err(|_| crate::RotoError::WireFormatViolation)?)) + Ok(f32::from_le_bytes( + bytes + .try_into() + .map_err(|_| RotoError::WireFormatViolation)?, + )) } - pub fn is_elite(&self) -> crate::Result { - let offset = self.is_elite_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn is_elite(&self) -> roto_runtime::Result { + let offset = self + .is_elite_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - crate::read_varint(bytes).map(|(v, _)| v != 0).map_err(|_| crate::RotoError::WireFormatViolation) + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) } - pub fn crew_id(&self) -> crate::Result { - let offset = self.crew_id_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn crew_id(&self) -> roto_runtime::Result { + let offset = self + .crew_id_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - crate::read_varint(bytes).map(|(v, _)| v as i32).map_err(|_| crate::RotoError::WireFormatViolation) + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) } - pub fn exploits(&self) -> crate::RepeatedFieldIterator<'a> { + pub fn exploits(&self) -> roto_runtime::RepeatedFieldIterator<'a> { match (self.exploits_start, self.exploits_end) { (Some(start), Some(end)) => self.accessor.iter_repeated_range(7, start, end), _ => self.accessor.iter_repeated(7), } } - pub fn tools(&self) -> crate::RepeatedFieldIterator<'a> { + pub fn tools(&self) -> roto_runtime::RepeatedFieldIterator<'a> { match (self.tools_start, self.tools_end) { (Some(start), Some(end)) => self.accessor.iter_repeated_range(8, start, end), _ => self.accessor.iter_repeated(8), } } - pub fn active_connection(&self) -> crate::Result<&'a [u8]> { - let offset = self.active_connection_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn active_connection(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .active_connection_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; Ok(bytes) } - pub fn raw_fields(&self) -> crate::RawFieldIterator<'a> { + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { self.accessor.raw_fields() } - } pub struct HackerBuilder<'b> { - builder: crate::ProtoBuilder<'b>, + builder: roto_runtime::ProtoBuilder<'b>, handle_written: bool, real_name_written: bool, age_written: bool, @@ -437,7 +529,7 @@ pub struct HackerBuilder<'b> { impl<'b> HackerBuilder<'b> { pub fn builder(buf: &mut [u8]) -> HackerBuilder<'_> { HackerBuilder { - builder: crate::ProtoBuilder::new(buf), + builder: roto_runtime::ProtoBuilder::new(buf), handle_written: false, real_name_written: false, age_written: false, @@ -450,61 +542,61 @@ impl<'b> HackerBuilder<'b> { } } - pub fn handle(mut self, value: &str) -> crate::Result { + pub fn handle(mut self, value: &str) -> roto_runtime::Result { self.builder.write_string(1, value)?; self.handle_written = true; Ok(self) } - pub fn real_name(mut self, value: &str) -> crate::Result { + pub fn real_name(mut self, value: &str) -> roto_runtime::Result { self.builder.write_string(2, value)?; self.real_name_written = true; Ok(self) } - pub fn age(mut self, value: i32) -> crate::Result { + pub fn age(mut self, value: i32) -> roto_runtime::Result { self.builder.write_int32(3, value)?; self.age_written = true; Ok(self) } - pub fn skill_level(mut self, value: &[u8]) -> crate::Result { + pub fn skill_level(mut self, value: &[u8]) -> roto_runtime::Result { self.builder.write_bytes(4, value)?; self.skill_level_written = true; Ok(self) } - pub fn is_elite(mut self, value: u64) -> crate::Result { + pub fn is_elite(mut self, value: u64) -> roto_runtime::Result { self.builder.write_varint(5, value)?; self.is_elite_written = true; Ok(self) } - pub fn crew_id(mut self, value: u64) -> crate::Result { + pub fn crew_id(mut self, value: u64) -> roto_runtime::Result { self.builder.write_varint(6, value)?; self.crew_id_written = true; Ok(self) } - pub fn exploits(mut self, value: &str) -> crate::Result { + pub fn exploits(mut self, value: &str) -> roto_runtime::Result { self.builder.write_string(7, value)?; self.exploits_written = true; Ok(self) } - pub fn tools(mut self, value: &[u8]) -> crate::Result { + pub fn tools(mut self, value: &[u8]) -> roto_runtime::Result { self.builder.write_bytes(8, value)?; self.tools_written = true; Ok(self) } - pub fn active_connection(mut self, value: &[u8]) -> crate::Result { + pub fn active_connection(mut self, value: &[u8]) -> roto_runtime::Result { self.builder.write_bytes(9, value)?; self.active_connection_written = true; Ok(self) } - pub fn with(mut self, msg: &Hacker<'_>) -> crate::Result { + pub fn with(mut self, msg: &Hacker<'_>) -> roto_runtime::Result { for item in msg.raw_fields() { let (field_number, raw_bytes) = item?; let is_written = match field_number { @@ -526,13 +618,13 @@ impl<'b> HackerBuilder<'b> { Ok(self) } - pub fn finish(self) -> crate::Result<&'b mut [u8]> { + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { self.builder.finish() } } pub struct Worm<'a> { - accessor: crate::ProtoAccessor<'a>, + accessor: roto_runtime::ProtoAccessor<'a>, name_offset: Option, variant_offset: Option, size_bytes_offset: Option, @@ -543,8 +635,8 @@ pub struct Worm<'a> { } impl<'a> Worm<'a> { - pub fn new(data: &'a [u8]) -> crate::Result { - let accessor = crate::ProtoAccessor::new(data)?; + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; let mut name_offset = None; let mut variant_offset = None; let mut size_bytes_offset = None; @@ -554,73 +646,101 @@ impl<'a> Worm<'a> { let mut targets_end = None; for item in accessor.fields() { let (offset, tag, _) = item?; - if tag.field_number == 1 { name_offset = Some(offset); } - if tag.field_number == 2 { variant_offset = Some(offset); } - if tag.field_number == 3 { size_bytes_offset = Some(offset); } - if tag.field_number == 4 { payload_offset = Some(offset); } - if tag.field_number == 5 { polymorphic_offset = Some(offset); } + if tag.field_number == 1 { + name_offset = Some(offset); + } + if tag.field_number == 2 { + variant_offset = Some(offset); + } + if tag.field_number == 3 { + size_bytes_offset = Some(offset); + } + if tag.field_number == 4 { + payload_offset = Some(offset); + } + if tag.field_number == 5 { + polymorphic_offset = Some(offset); + } if tag.field_number == 6 { - if targets_start.is_none() { targets_start = Some(offset); } + if targets_start.is_none() { + targets_start = Some(offset); + } targets_end = Some(offset); } } Ok(Self { accessor, -name_offset, -variant_offset, -size_bytes_offset, -payload_offset, -polymorphic_offset, -targets_start, targets_end, + name_offset, + variant_offset, + size_bytes_offset, + payload_offset, + polymorphic_offset, + targets_start, + targets_end, }) } - pub fn name(&self) -> crate::Result<&'a str> { - let offset = self.name_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn name(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .name_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - str::from_utf8(bytes).map_err(|_| crate::RotoError::WireFormatViolation) + str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } - pub fn variant(&self) -> crate::Result { - let offset = self.variant_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn variant(&self) -> roto_runtime::Result { + let offset = self + .variant_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - crate::read_varint(bytes).map(|(v, _)| v as i32).map_err(|_| crate::RotoError::WireFormatViolation) + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) } - pub fn size_bytes(&self) -> crate::Result { - let offset = self.size_bytes_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn size_bytes(&self) -> roto_runtime::Result { + let offset = self + .size_bytes_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - crate::read_varint(bytes).map(|(v, _)| v as i32).map_err(|_| crate::RotoError::WireFormatViolation) + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) } - pub fn payload(&self) -> crate::Result<&'a [u8]> { - let offset = self.payload_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn payload(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .payload_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; Ok(bytes) } - pub fn polymorphic(&self) -> crate::Result { - let offset = self.polymorphic_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn polymorphic(&self) -> roto_runtime::Result { + let offset = self + .polymorphic_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - crate::read_varint(bytes).map(|(v, _)| v != 0).map_err(|_| crate::RotoError::WireFormatViolation) + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) } - pub fn targets(&self) -> crate::RepeatedFieldIterator<'a> { + pub fn targets(&self) -> roto_runtime::RepeatedFieldIterator<'a> { match (self.targets_start, self.targets_end) { (Some(start), Some(end)) => self.accessor.iter_repeated_range(6, start, end), _ => self.accessor.iter_repeated(6), } } - pub fn raw_fields(&self) -> crate::RawFieldIterator<'a> { + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { self.accessor.raw_fields() } - } pub struct WormBuilder<'b> { - builder: crate::ProtoBuilder<'b>, + builder: roto_runtime::ProtoBuilder<'b>, name_written: bool, variant_written: bool, size_bytes_written: bool, @@ -632,7 +752,7 @@ pub struct WormBuilder<'b> { impl<'b> WormBuilder<'b> { pub fn builder(buf: &mut [u8]) -> WormBuilder<'_> { WormBuilder { - builder: crate::ProtoBuilder::new(buf), + builder: roto_runtime::ProtoBuilder::new(buf), name_written: false, variant_written: false, size_bytes_written: false, @@ -642,43 +762,43 @@ impl<'b> WormBuilder<'b> { } } - pub fn name(mut self, value: &str) -> crate::Result { + pub fn name(mut self, value: &str) -> roto_runtime::Result { self.builder.write_string(1, value)?; self.name_written = true; Ok(self) } - pub fn variant(mut self, value: i32) -> crate::Result { + pub fn variant(mut self, value: i32) -> roto_runtime::Result { self.builder.write_int32(2, value)?; self.variant_written = true; Ok(self) } - pub fn size_bytes(mut self, value: u64) -> crate::Result { + pub fn size_bytes(mut self, value: u64) -> roto_runtime::Result { self.builder.write_varint(3, value)?; self.size_bytes_written = true; Ok(self) } - pub fn payload(mut self, value: &[u8]) -> crate::Result { + pub fn payload(mut self, value: &[u8]) -> roto_runtime::Result { self.builder.write_bytes(4, value)?; self.payload_written = true; Ok(self) } - pub fn polymorphic(mut self, value: u64) -> crate::Result { + pub fn polymorphic(mut self, value: u64) -> roto_runtime::Result { self.builder.write_varint(5, value)?; self.polymorphic_written = true; Ok(self) } - pub fn targets(mut self, value: &str) -> crate::Result { + pub fn targets(mut self, value: &str) -> roto_runtime::Result { self.builder.write_string(6, value)?; self.targets_written = true; Ok(self) } - pub fn with(mut self, msg: &Worm<'_>) -> crate::Result { + pub fn with(mut self, msg: &Worm<'_>) -> roto_runtime::Result { for item in msg.raw_fields() { let (field_number, raw_bytes) = item?; let is_written = match field_number { @@ -697,13 +817,13 @@ impl<'b> WormBuilder<'b> { Ok(self) } - pub fn finish(self) -> crate::Result<&'b mut [u8]> { + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { self.builder.finish() } } pub struct Operation<'a> { - accessor: crate::ProtoAccessor<'a>, + accessor: roto_runtime::ProtoAccessor<'a>, codename_offset: Option, target_corp_offset: Option, timestamp_offset: Option, @@ -718,8 +838,8 @@ pub struct Operation<'a> { } impl<'a> Operation<'a> { - pub fn new(data: &'a [u8]) -> crate::Result { - let accessor = crate::ProtoAccessor::new(data)?; + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; let mut codename_offset = None; let mut target_corp_offset = None; let mut timestamp_offset = None; @@ -733,101 +853,140 @@ impl<'a> Operation<'a> { let mut severity_offset = None; for item in accessor.fields() { let (offset, tag, _) = item?; - if tag.field_number == 1 { codename_offset = Some(offset); } - if tag.field_number == 2 { target_corp_offset = Some(offset); } - if tag.field_number == 3 { timestamp_offset = Some(offset); } - if tag.field_number == 4 { successful_offset = Some(offset); } - if tag.field_number == 5 { stolen_data_offset = Some(offset); } + if tag.field_number == 1 { + codename_offset = Some(offset); + } + if tag.field_number == 2 { + target_corp_offset = Some(offset); + } + if tag.field_number == 3 { + timestamp_offset = Some(offset); + } + if tag.field_number == 4 { + successful_offset = Some(offset); + } + if tag.field_number == 5 { + stolen_data_offset = Some(offset); + } if tag.field_number == 6 { - if crew_start.is_none() { crew_start = Some(offset); } + if crew_start.is_none() { + crew_start = Some(offset); + } crew_end = Some(offset); } - if tag.field_number == 7 { worm_offset = Some(offset); } + if tag.field_number == 7 { + worm_offset = Some(offset); + } if tag.field_number == 8 { - if log_entries_start.is_none() { log_entries_start = Some(offset); } + if log_entries_start.is_none() { + log_entries_start = Some(offset); + } log_entries_end = Some(offset); } - if tag.field_number == 9 { severity_offset = Some(offset); } + if tag.field_number == 9 { + severity_offset = Some(offset); + } } Ok(Self { accessor, -codename_offset, -target_corp_offset, -timestamp_offset, -successful_offset, -stolen_data_offset, -crew_start, crew_end, -worm_offset, -log_entries_start, log_entries_end, -severity_offset, + codename_offset, + target_corp_offset, + timestamp_offset, + successful_offset, + stolen_data_offset, + crew_start, + crew_end, + worm_offset, + log_entries_start, + log_entries_end, + severity_offset, }) } - pub fn codename(&self) -> crate::Result<&'a str> { - let offset = self.codename_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn codename(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .codename_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - str::from_utf8(bytes).map_err(|_| crate::RotoError::WireFormatViolation) + str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } - pub fn target_corp(&self) -> crate::Result<&'a str> { - let offset = self.target_corp_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn target_corp(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .target_corp_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - str::from_utf8(bytes).map_err(|_| crate::RotoError::WireFormatViolation) + str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } - pub fn timestamp(&self) -> crate::Result { - let offset = self.timestamp_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn timestamp(&self) -> roto_runtime::Result { + let offset = self + .timestamp_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - crate::read_varint(bytes).map(|(v, _)| v as i32).map_err(|_| crate::RotoError::WireFormatViolation) + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) } - pub fn successful(&self) -> crate::Result { - let offset = self.successful_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn successful(&self) -> roto_runtime::Result { + let offset = self + .successful_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - crate::read_varint(bytes).map(|(v, _)| v != 0).map_err(|_| crate::RotoError::WireFormatViolation) + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) } - pub fn stolen_data(&self) -> crate::Result<&'a [u8]> { - let offset = self.stolen_data_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn stolen_data(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .stolen_data_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; Ok(bytes) } - pub fn crew(&self) -> crate::RepeatedFieldIterator<'a> { + pub fn crew(&self) -> roto_runtime::RepeatedFieldIterator<'a> { match (self.crew_start, self.crew_end) { (Some(start), Some(end)) => self.accessor.iter_repeated_range(6, start, end), _ => self.accessor.iter_repeated(6), } } - pub fn worm(&self) -> crate::Result<&'a [u8]> { - let offset = self.worm_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn worm(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .worm_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; Ok(bytes) } - pub fn log_entries(&self) -> crate::RepeatedFieldIterator<'a> { + pub fn log_entries(&self) -> roto_runtime::RepeatedFieldIterator<'a> { match (self.log_entries_start, self.log_entries_end) { (Some(start), Some(end)) => self.accessor.iter_repeated_range(8, start, end), _ => self.accessor.iter_repeated(8), } } - pub fn severity(&self) -> crate::Result { - let offset = self.severity_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn severity(&self) -> roto_runtime::Result { + let offset = self + .severity_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - crate::read_varint(bytes).map(|(v, _)| v as i32).map_err(|_| crate::RotoError::WireFormatViolation) + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) } - pub fn raw_fields(&self) -> crate::RawFieldIterator<'a> { + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { self.accessor.raw_fields() } - } pub struct OperationBuilder<'b> { - builder: crate::ProtoBuilder<'b>, + builder: roto_runtime::ProtoBuilder<'b>, codename_written: bool, target_corp_written: bool, timestamp_written: bool, @@ -842,7 +1001,7 @@ pub struct OperationBuilder<'b> { impl<'b> OperationBuilder<'b> { pub fn builder(buf: &mut [u8]) -> OperationBuilder<'_> { OperationBuilder { - builder: crate::ProtoBuilder::new(buf), + builder: roto_runtime::ProtoBuilder::new(buf), codename_written: false, target_corp_written: false, timestamp_written: false, @@ -855,61 +1014,61 @@ impl<'b> OperationBuilder<'b> { } } - pub fn codename(mut self, value: &str) -> crate::Result { + pub fn codename(mut self, value: &str) -> roto_runtime::Result { self.builder.write_string(1, value)?; self.codename_written = true; Ok(self) } - pub fn target_corp(mut self, value: &str) -> crate::Result { + pub fn target_corp(mut self, value: &str) -> roto_runtime::Result { self.builder.write_string(2, value)?; self.target_corp_written = true; Ok(self) } - pub fn timestamp(mut self, value: u64) -> crate::Result { + pub fn timestamp(mut self, value: u64) -> roto_runtime::Result { self.builder.write_varint(3, value)?; self.timestamp_written = true; Ok(self) } - pub fn successful(mut self, value: u64) -> crate::Result { + pub fn successful(mut self, value: u64) -> roto_runtime::Result { self.builder.write_varint(4, value)?; self.successful_written = true; Ok(self) } - pub fn stolen_data(mut self, value: &[u8]) -> crate::Result { + pub fn stolen_data(mut self, value: &[u8]) -> roto_runtime::Result { self.builder.write_bytes(5, value)?; self.stolen_data_written = true; Ok(self) } - pub fn crew(mut self, value: &[u8]) -> crate::Result { + pub fn crew(mut self, value: &[u8]) -> roto_runtime::Result { self.builder.write_bytes(6, value)?; self.crew_written = true; Ok(self) } - pub fn worm(mut self, value: &[u8]) -> crate::Result { + pub fn worm(mut self, value: &[u8]) -> roto_runtime::Result { self.builder.write_bytes(7, value)?; self.worm_written = true; Ok(self) } - pub fn log_entries(mut self, value: &str) -> crate::Result { + pub fn log_entries(mut self, value: &str) -> roto_runtime::Result { self.builder.write_string(8, value)?; self.log_entries_written = true; Ok(self) } - pub fn severity(mut self, value: i32) -> crate::Result { + pub fn severity(mut self, value: i32) -> roto_runtime::Result { self.builder.write_int32(9, value)?; self.severity_written = true; Ok(self) } - pub fn with(mut self, msg: &Operation<'_>) -> crate::Result { + pub fn with(mut self, msg: &Operation<'_>) -> roto_runtime::Result { for item in msg.raw_fields() { let (field_number, raw_bytes) = item?; let is_written = match field_number { @@ -931,13 +1090,13 @@ impl<'b> OperationBuilder<'b> { Ok(self) } - pub fn finish(self) -> crate::Result<&'b mut [u8]> { + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { self.builder.finish() } } pub struct Campaign<'a> { - accessor: crate::ProtoAccessor<'a>, + accessor: roto_runtime::ProtoAccessor<'a>, name_offset: Option, operations_start: Option, operations_end: Option, @@ -945,57 +1104,69 @@ pub struct Campaign<'a> { } impl<'a> Campaign<'a> { - pub fn new(data: &'a [u8]) -> crate::Result { - let accessor = crate::ProtoAccessor::new(data)?; + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; let mut name_offset = None; let mut operations_start = None; let mut operations_end = None; let mut total_bytes_stolen_offset = None; for item in accessor.fields() { let (offset, tag, _) = item?; - if tag.field_number == 1 { name_offset = Some(offset); } + if tag.field_number == 1 { + name_offset = Some(offset); + } if tag.field_number == 2 { - if operations_start.is_none() { operations_start = Some(offset); } + if operations_start.is_none() { + operations_start = Some(offset); + } operations_end = Some(offset); } - if tag.field_number == 3 { total_bytes_stolen_offset = Some(offset); } + if tag.field_number == 3 { + total_bytes_stolen_offset = Some(offset); + } } Ok(Self { accessor, -name_offset, -operations_start, operations_end, -total_bytes_stolen_offset, + name_offset, + operations_start, + operations_end, + total_bytes_stolen_offset, }) } - pub fn name(&self) -> crate::Result<&'a str> { - let offset = self.name_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn name(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .name_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - str::from_utf8(bytes).map_err(|_| crate::RotoError::WireFormatViolation) + str::from_utf8(bytes).map_err(|_| RotoError::WireFormatViolation) } - pub fn operations(&self) -> crate::RepeatedFieldIterator<'a> { + pub fn operations(&self) -> roto_runtime::RepeatedFieldIterator<'a> { match (self.operations_start, self.operations_end) { (Some(start), Some(end)) => self.accessor.iter_repeated_range(2, start, end), _ => self.accessor.iter_repeated(2), } } - pub fn total_bytes_stolen(&self) -> crate::Result { - let offset = self.total_bytes_stolen_offset.ok_or(crate::RotoError::FieldNotFound)?; + pub fn total_bytes_stolen(&self) -> roto_runtime::Result { + let offset = self + .total_bytes_stolen_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; let (bytes, _) = self.accessor.get_value_at(offset)?; - crate::read_varint(bytes).map(|(v, _)| v as i32).map_err(|_| crate::RotoError::WireFormatViolation) + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) } - pub fn raw_fields(&self) -> crate::RawFieldIterator<'a> { + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { self.accessor.raw_fields() } - } pub struct CampaignBuilder<'b> { - builder: crate::ProtoBuilder<'b>, + builder: roto_runtime::ProtoBuilder<'b>, name_written: bool, operations_written: bool, total_bytes_stolen_written: bool, @@ -1004,32 +1175,32 @@ pub struct CampaignBuilder<'b> { impl<'b> CampaignBuilder<'b> { pub fn builder(buf: &mut [u8]) -> CampaignBuilder<'_> { CampaignBuilder { - builder: crate::ProtoBuilder::new(buf), + builder: roto_runtime::ProtoBuilder::new(buf), name_written: false, operations_written: false, total_bytes_stolen_written: false, } } - pub fn name(mut self, value: &str) -> crate::Result { + pub fn name(mut self, value: &str) -> roto_runtime::Result { self.builder.write_string(1, value)?; self.name_written = true; Ok(self) } - pub fn operations(mut self, value: &[u8]) -> crate::Result { + pub fn operations(mut self, value: &[u8]) -> roto_runtime::Result { self.builder.write_bytes(2, value)?; self.operations_written = true; Ok(self) } - pub fn total_bytes_stolen(mut self, value: u64) -> crate::Result { + pub fn total_bytes_stolen(mut self, value: u64) -> roto_runtime::Result { self.builder.write_varint(3, value)?; self.total_bytes_stolen_written = true; Ok(self) } - pub fn with(mut self, msg: &Campaign<'_>) -> crate::Result { + pub fn with(mut self, msg: &Campaign<'_>) -> roto_runtime::Result { for item in msg.raw_fields() { let (field_number, raw_bytes) = item?; let is_written = match field_number { @@ -1045,8 +1216,7 @@ impl<'b> CampaignBuilder<'b> { Ok(self) } - pub fn finish(self) -> crate::Result<&'b mut [u8]> { + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { self.builder.finish() } } - diff --git a/benches/src/lib.rs b/benches/src/lib.rs new file mode 100644 index 0000000..45981ed --- /dev/null +++ b/benches/src/lib.rs @@ -0,0 +1 @@ +pub mod hackers; diff --git a/codegen/Cargo.toml b/codegen/Cargo.toml new file mode 100644 index 0000000..d7c36a7 --- /dev/null +++ b/codegen/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "roto-codegen" +version = "0.1.0" +edition = "2024" + +[dependencies] +roto-runtime = { path = "../runtime" } +clap = { version = "4", features = ["derive"] } +log = "0.4" +env_logger = "0.11" diff --git a/data/.gitignore b/codegen/data/.gitignore similarity index 100% rename from data/.gitignore rename to codegen/data/.gitignore diff --git a/data/descriptor.desc b/codegen/data/descriptor.desc similarity index 100% rename from data/descriptor.desc rename to codegen/data/descriptor.desc diff --git a/data/request.bin b/codegen/data/request.bin similarity index 100% rename from data/request.bin rename to codegen/data/request.bin diff --git a/data/test_data.pb b/codegen/data/test_data.pb similarity index 100% rename from data/test_data.pb rename to codegen/data/test_data.pb diff --git a/data/test_data.textproto b/codegen/data/test_data.textproto similarity index 100% rename from data/test_data.textproto rename to codegen/data/test_data.textproto diff --git a/data/test_types.desc b/codegen/data/test_types.desc similarity index 100% rename from data/test_types.desc rename to codegen/data/test_types.desc diff --git a/data/test_types.proto b/codegen/data/test_types.proto similarity index 100% rename from data/test_types.proto rename to codegen/data/test_types.proto diff --git a/codegen/proto/google/protobuf/compiler/plugin.proto b/codegen/proto/google/protobuf/compiler/plugin.proto new file mode 100644 index 0000000..10d285f --- /dev/null +++ b/codegen/proto/google/protobuf/compiler/plugin.proto @@ -0,0 +1,180 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// Author: kenton@google.com (Kenton Varda) +// +// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is +// just a program that reads a CodeGeneratorRequest from stdin and writes a +// CodeGeneratorResponse to stdout. +// +// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead +// of dealing with the raw protocol defined here. +// +// A plugin executable needs only to be placed somewhere in the path. The +// plugin should be named "protoc-gen-$NAME", and will then be used when the +// flag "--${NAME}_out" is passed to protoc. + +syntax = "proto2"; + +package google.protobuf.compiler; +option java_package = "com.google.protobuf.compiler"; +option java_outer_classname = "PluginProtos"; + +import "google/protobuf/descriptor.proto"; + +option csharp_namespace = "Google.Protobuf.Compiler"; +option go_package = "google.golang.org/protobuf/types/pluginpb"; + +// The version number of protocol compiler. +message Version { + optional int32 major = 1; + optional int32 minor = 2; + optional int32 patch = 3; + // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should + // be empty for mainline stable releases. + optional string suffix = 4; +} + +// An encoded CodeGeneratorRequest is written to the plugin's stdin. +message CodeGeneratorRequest { + // The .proto files that were explicitly listed on the command-line. The + // code generator should generate code only for these files. Each file's + // descriptor will be included in proto_file, below. + repeated string file_to_generate = 1; + + // The generator parameter passed on the command-line. + optional string parameter = 2; + + // FileDescriptorProtos for all files in files_to_generate and everything + // they import. The files will appear in topological order, so each file + // appears before any file that imports it. + // + // 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. + repeated FileDescriptorProto proto_file = 15; + + // File descriptors with all options, including source-retention options. + // These descriptors are only provided for the files listed in + // files_to_generate. + repeated FileDescriptorProto source_file_descriptors = 17; + + // The version number of protocol compiler. + optional Version compiler_version = 3; +} + +// The plugin writes an encoded CodeGeneratorResponse to stdout. +message CodeGeneratorResponse { + // Error message. If non-empty, code generation failed. The plugin process + // should exit with status code zero even if it reports an error in this way. + // + // This should be used to indicate errors in .proto files which prevent the + // code generator from generating correct code. Errors which indicate a + // problem in protoc itself -- such as the input CodeGeneratorRequest being + // unparseable -- should be reported by writing a message to stderr and + // exiting with a non-zero status code. + optional string error = 1; + + // A bitmask of supported features that the code generator supports. + // This is a bitwise "or" of values from the Feature enum. + optional uint64 supported_features = 2; + + // Sync with code_generator.h. + enum Feature { + FEATURE_NONE = 0; + FEATURE_PROTO3_OPTIONAL = 1; + FEATURE_SUPPORTS_EDITIONS = 2; + } + + // 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. + optional int32 minimum_edition = 3; + + // 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. + optional int32 maximum_edition = 4; + + // Represents a single generated file. + message File { + // The file name, relative to the output directory. The name must not + // contain "." or ".." components and must be relative, not be absolute (so, + // the file cannot lie outside the output directory). "/" must be used as + // the path separator, not "\". + // + // If the name is omitted, the content will be appended to the previous + // file. This allows the generator to break large files into small chunks, + // and allows the generated text to be streamed back to protoc so that large + // files need not reside completely in memory at one time. Note that as of + // this writing protoc does not optimize for this -- it will read the entire + // CodeGeneratorResponse before writing files to disk. + optional string name = 1; + + // If non-empty, indicates that the named file should already exist, and the + // content here is to be inserted into that file at a defined insertion + // point. This feature allows a code generator to extend the output + // produced by another code generator. The original generator may provide + // insertion points by placing special annotations in the file that look + // like: + // @@protoc_insertion_point(NAME) + // The annotation can have arbitrary text before and after it on the line, + // which allows it to be placed in a comment. NAME should be replaced with + // an identifier naming the point -- this is what other generators will use + // as the insertion_point. Code inserted at this point will be placed + // immediately above the line containing the insertion point (thus multiple + // insertions to the same point will come out in the order they were added). + // The double-@ is intended to make it unlikely that the generated code + // could contain things that look like insertion points by accident. + // + // For example, the C++ code generator places the following line in the + // .pb.h files that it generates: + // // @@protoc_insertion_point(namespace_scope) + // This line appears within the scope of the file's package namespace, but + // outside of any particular class. Another plugin can then specify the + // insertion_point "namespace_scope" to generate additional classes or + // other declarations that should be placed in this scope. + // + // Note that if the line containing the insertion point begins with + // whitespace, the same whitespace will be added to every line of the + // inserted text. This is useful for languages like Python, where + // indentation matters. In these languages, the insertion point comment + // should be indented the same amount as any inserted code will need to be + // in order to work correctly in that context. + // + // The code generator that generates the initial file and the one which + // inserts into it must both run as part of a single invocation of protoc. + // Code generators are executed in the order in which they appear on the + // command line. + // + // If |insertion_point| is present, |name| must also be present. + optional string insertion_point = 2; + + // The file contents. + optional string content = 15; + + // Information describing the file content being inserted. If an insertion + // point is used, this information will be appropriately offset and inserted + // into the code generation metadata for the generated files. + optional GeneratedCodeInfo generated_code_info = 16; + } + repeated File file = 15; +} diff --git a/codegen/proto/google/protobuf/descriptor.proto b/codegen/proto/google/protobuf/descriptor.proto new file mode 100644 index 0000000..89c4891 --- /dev/null +++ b/codegen/proto/google/protobuf/descriptor.proto @@ -0,0 +1,1507 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google LLC. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// The messages in this file describe the definitions found in .proto files. +// A valid .proto file can be translated directly to a FileDescriptorProto +// without any other information (e.g. without reading its imports). + +syntax = "proto2"; + +package google.protobuf; + +option go_package = "google.golang.org/protobuf/types/descriptorpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DescriptorProtos"; +option csharp_namespace = "Google.Protobuf.Reflection"; +option objc_class_prefix = "GPB"; +option cc_enable_arenas = true; + +// descriptor.proto must be optimized for speed because reflection-based +// algorithms don't work during bootstrapping. +option optimize_for = SPEED; + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +message FileDescriptorSet { + repeated FileDescriptorProto file = 1; + + // Extensions for tooling. + extensions 536000000 [declaration = { + number: 536000000 + type: ".buf.descriptor.v1.FileDescriptorSetExtension" + full_name: ".buf.descriptor.v1.buf_file_descriptor_set_extension" + }]; +} + +// The full set of known editions. +enum Edition { + // A placeholder for an unknown edition value. + EDITION_UNKNOWN = 0; + + // A placeholder edition for specifying default behaviors *before* a feature + // was first introduced. This is effectively an "infinite past". + EDITION_LEGACY = 900; + + // 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. + EDITION_PROTO2 = 998; + EDITION_PROTO3 = 999; + + // 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. + EDITION_2023 = 1000; + EDITION_2024 = 1001; + EDITION_2026 = 1002; + + // A placeholder edition for developing and testing unscheduled features. + EDITION_UNSTABLE = 9999; + + // Placeholder editions for testing feature resolution. These should not be + // used or relied on outside of tests. + EDITION_1_TEST_ONLY = 1; + EDITION_2_TEST_ONLY = 2; + EDITION_99997_TEST_ONLY = 99997; + EDITION_99998_TEST_ONLY = 99998; + EDITION_99999_TEST_ONLY = 99999; + + // 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. + EDITION_MAX = 0x7FFFFFFF; +} + +// Describes a complete .proto file. +message FileDescriptorProto { + optional string name = 1; // file name, relative to root of source tree + optional string package = 2; // e.g. "foo", "foo.bar", etc. + + // Names of files imported by this file. + repeated string dependency = 3; + // Indexes of the public imported files in the dependency list above. + repeated int32 public_dependency = 10; + // Indexes of the weak imported files in the dependency list. + // For Google-internal migration only. Do not use. + repeated int32 weak_dependency = 11; + + // Names of files imported by this file purely for the purpose of providing + // option extensions. These are excluded from the dependency list above. + repeated string option_dependency = 15; + + // All top-level definitions in this file. + repeated DescriptorProto message_type = 4; + repeated EnumDescriptorProto enum_type = 5; + repeated ServiceDescriptorProto service = 6; + repeated FieldDescriptorProto extension = 7; + + optional FileOptions options = 8; + + // This field contains optional information about the original source code. + // You may safely remove this entire field without harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + optional SourceCodeInfo source_code_info = 9; + + // The syntax of the proto file. + // The supported values are "proto2", "proto3", and "editions". + // + // If `edition` is present, this value must be "editions". + // WARNING: This field should only be used by protobuf plugins or special + // cases like the proto compiler. Other uses are discouraged and + // developers should rely on the protoreflect APIs for their client language. + optional string syntax = 12; + + // The edition of the proto file. + // WARNING: This field should only be used by protobuf plugins or special + // cases like the proto compiler. Other uses are discouraged and + // developers should rely on the protoreflect APIs for their client language. + optional Edition edition = 14; +} + +// Describes a message type. +message DescriptorProto { + optional string name = 1; + + repeated FieldDescriptorProto field = 2; + repeated FieldDescriptorProto extension = 6; + + repeated DescriptorProto nested_type = 3; + repeated EnumDescriptorProto enum_type = 4; + + message ExtensionRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + + optional ExtensionRangeOptions options = 3; + } + repeated ExtensionRange extension_range = 5; + + repeated OneofDescriptorProto oneof_decl = 8; + + optional MessageOptions options = 7; + + // Range of reserved tag numbers. Reserved tag numbers may not be used by + // fields or extension ranges in the same message. Reserved ranges may + // not overlap. + message ReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + } + repeated ReservedRange reserved_range = 9; + // Reserved field names, which may not be used by fields in the same message. + // A given name may only be reserved once. + repeated string reserved_name = 10; + + // Support for `export` and `local` keywords on enums. + optional SymbolVisibility visibility = 11; +} + +message ExtensionRangeOptions { + // Range reserved for first-class custom options defined by the Protobuf + // team. User custom options must use the 1000+ range instead. + extensions 990 to 998; + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + message Declaration { + // The extension number declared within the extension range. + optional int32 number = 1; + + // The fully-qualified name of the extension field. There must be a leading + // dot in front of the full name. + optional string full_name = 2; + + // The fully-qualified type name of the extension field. Unlike + // Metadata.type, Declaration.type must have a leading dot for messages + // and enums. + optional string type = 3; + + // 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. + optional bool reserved = 5; + + // If true, indicates that the extension must be defined as repeated. + // Otherwise the extension must be defined as optional. + optional bool repeated = 6; + + reserved 4; // removed is_repeated + } + + // 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. + repeated Declaration declaration = 2 [retention = RETENTION_SOURCE]; + + // Any features defined in the specific edition. + optional FeatureSet features = 50; + + // The verification state of the extension range. + enum VerificationState { + // All the extensions of the range must be declared. + DECLARATION = 0; + UNVERIFIED = 1; + } + + // The verification state of the range. + // TODO: flip the default to DECLARATION once all empty ranges + // are marked as UNVERIFIED. + optional VerificationState verification = 3 + [default = UNVERIFIED, retention = RETENTION_SOURCE]; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +// Describes a field within a message. +message FieldDescriptorProto { + enum Type { + // 0 is reserved for errors. + // Order is weird for historical reasons. + TYPE_DOUBLE = 1; + TYPE_FLOAT = 2; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + // negative values are likely. + TYPE_INT64 = 3; + TYPE_UINT64 = 4; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + // negative values are likely. + TYPE_INT32 = 5; + TYPE_FIXED64 = 6; + TYPE_FIXED32 = 7; + TYPE_BOOL = 8; + TYPE_STRING = 9; + // Tag-delimited aggregate. + // Group type is deprecated and not supported 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_GROUP = 10; + TYPE_MESSAGE = 11; // Length-delimited aggregate. + + // New in version 2. + TYPE_BYTES = 12; + TYPE_UINT32 = 13; + TYPE_ENUM = 14; + TYPE_SFIXED32 = 15; + TYPE_SFIXED64 = 16; + TYPE_SINT32 = 17; // Uses ZigZag encoding. + TYPE_SINT64 = 18; // Uses ZigZag encoding. + } + + enum Label { + // 0 is reserved for errors + LABEL_OPTIONAL = 1; + LABEL_REPEATED = 3; + // 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. + LABEL_REQUIRED = 2; + } + + optional string name = 1; + optional int32 number = 3; + optional Label label = 4; + + // If type_name is set, this need not be set. If both this and type_name + // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + optional Type type = 5; + + // For message and enum types, this is the name of the type. If the name + // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + // rules are used to find the type (i.e. first the nested types within this + // message are searched, then within the parent, on up to the root + // namespace). + optional string type_name = 6; + + // For extensions, this is the name of the type being extended. It is + // resolved in the same manner as type_name. + optional string extendee = 2; + + // For numeric types, contains the original text representation of the value. + // For booleans, "true" or "false". + // For strings, contains the default text contents (not escaped in any way). + // For bytes, contains the C escaped value. All bytes >= 128 are escaped. + optional string default_value = 7; + + // If set, gives the index of a oneof in the containing type's oneof_decl + // list. This field is a member of that oneof. + optional int32 oneof_index = 9; + + // JSON name of this field. The value is set by protocol compiler. If the + // user has set a "json_name" option on this field, that option's value + // will be used. Otherwise, it's deduced from the field's name by converting + // it to camelCase. + optional string json_name = 10; + + optional FieldOptions options = 8; + + // If true, this is a proto3 "optional". When a proto3 field is optional, it + // tracks presence regardless of field type. + // + // When proto3_optional is true, this field must belong to a oneof to signal + // to old proto3 clients that presence is tracked for this field. This oneof + // is known as a "synthetic" oneof, and this field must be its sole member + // (each proto3 optional field gets its own synthetic oneof). Synthetic oneofs + // exist in the descriptor only, and do not generate any API. Synthetic oneofs + // must be ordered after all "real" oneofs. + // + // For message fields, proto3_optional doesn't create any semantic change, + // since non-repeated message fields always track presence. However it still + // indicates the semantic detail of whether the user wrote "optional" or not. + // This can be useful for round-tripping the .proto file. For consistency we + // give message fields a synthetic oneof also, even though it is not required + // to track presence. This is especially important because the parser can't + // tell if a field is a message or an enum, so it must always create a + // synthetic oneof. + // + // Proto2 optional fields do not set this flag, because they already indicate + // optional with `LABEL_OPTIONAL`. + optional bool proto3_optional = 17; +} + +// Describes a oneof. +message OneofDescriptorProto { + optional string name = 1; + optional OneofOptions options = 2; +} + +// Describes an enum type. +message EnumDescriptorProto { + optional string name = 1; + + repeated EnumValueDescriptorProto value = 2; + + optional EnumOptions options = 3; + + // Range of reserved numeric values. Reserved values may not be used by + // entries in the same enum. Reserved ranges may not overlap. + // + // Note that this is distinct from DescriptorProto.ReservedRange in that it + // is inclusive such that it can appropriately represent the entire int32 + // domain. + message EnumReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Inclusive. + } + + // Range of reserved numeric values. Reserved numeric values may not be used + // by enum values in the same enum declaration. Reserved ranges may not + // overlap. + repeated EnumReservedRange reserved_range = 4; + + // Reserved enum value names, which may not be reused. A given name may only + // be reserved once. + repeated string reserved_name = 5; + + // Support for `export` and `local` keywords on enums. + optional SymbolVisibility visibility = 6; +} + +// Describes a value within an enum. +message EnumValueDescriptorProto { + optional string name = 1; + optional int32 number = 2; + + optional EnumValueOptions options = 3; +} + +// Describes a service. +message ServiceDescriptorProto { + optional string name = 1; + repeated MethodDescriptorProto method = 2; + + optional ServiceOptions options = 3; + + reserved 4; + reserved "stream"; +} + +// Describes a method of a service. +message MethodDescriptorProto { + optional string name = 1; + + // Input and output type names. These are resolved in the same way as + // FieldDescriptorProto.type_name, but must refer to a message type. + optional string input_type = 2; + optional string output_type = 3; + + optional MethodOptions options = 4; + + // Identifies if client streams multiple client messages + optional bool client_streaming = 5 [default = false]; + // Identifies if server streams multiple server messages + optional bool server_streaming = 6 [default = false]; +} + +// =================================================================== +// Options + +// Each of the definitions above may have "options" attached. These are +// just annotations which may cause code to be generated slightly differently +// or may contain hints for code that manipulates protocol messages. +// +// Clients may define custom options as extensions of the *Options messages. +// These extensions may not yet be known at parsing time, so the parser cannot +// store the values in them. Instead it stores them in a field in the *Options +// message called uninterpreted_option. This field must have the same name +// across all *Options messages. We then use this field to populate the +// extensions when we build a descriptor, at which point all protos have been +// parsed and so all extensions are known. +// +// Extension numbers for custom options may be chosen as follows: +// * For options which will only be used within a single application or +// organization, or for experimental options, use field numbers 50000 +// through 99999. It is up to you to ensure that you do not use the +// same number for multiple options. +// * For options which will be published and used publicly by multiple +// independent entities, e-mail protobuf-global-extension-registry@google.com +// to reserve extension numbers. Simply provide your project name (e.g. +// Objective-C plugin) and your project website (if available) -- there's no +// need to explain how you intend to use them. Usually you only need one +// extension number. You can declare multiple options with only one extension +// number by putting them in a sub-message. See the Custom Options section of +// the docs for examples: +// https://developers.google.com/protocol-buffers/docs/proto#options +// If this turns out to be popular, a web service will be set up +// to automatically assign option numbers. + +message FileOptions { + + // Sets the Java package where classes generated from this .proto will be + // placed. By default, the proto package is used, but this is often + // inappropriate because proto packages do not normally start with backwards + // domain names. + optional string java_package = 1; + + // Controls the name of the wrapper Java class generated for the .proto file. + // That class will always contain the .proto file's getDescriptor() method as + // well as any top-level extensions defined in the .proto file. + // If java_multiple_files is disabled, then all the other classes from the + // .proto file will be nested inside the single wrapper outer class. + optional string java_outer_classname = 8; + + // If enabled, then the Java code generator will generate a separate .java + // file for each top-level message, enum, and service defined in the .proto + // file. Thus, these types will *not* be nested inside the wrapper class + // named by java_outer_classname. However, the wrapper class will still be + // generated to contain the file's getDescriptor() method as well as any + // top-level extensions defined in the file. + optional bool java_multiple_files = 10 [ + default = false, + feature_support = { + edition_introduced: EDITION_PROTO2 + edition_removed: EDITION_2024 + removal_error: "This behavior is enabled by default in editions 2024 and above. " + "To disable it, you can set `features.(pb.java).nest_in_file_class = YES` " + "on individual messages, enums, or services." + + } + ]; + + // This option does nothing. + optional bool java_generate_equals_and_hash = 20 [deprecated=true]; + + // 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. + optional bool java_string_check_utf8 = 27 [default = false]; + + // Generated classes can be optimized for speed or code size. + enum OptimizeMode { + SPEED = 1; // Generate complete code for parsing, serialization, + // etc. + CODE_SIZE = 2; // Use ReflectionOps to implement these methods. + LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. + } + optional OptimizeMode optimize_for = 9 [default = SPEED]; + + // Sets the Go package where structs generated from this .proto will be + // placed. If omitted, the Go package will be derived from the following: + // - The basename of the package import path, if provided. + // - Otherwise, the package statement in the .proto file, if present. + // - Otherwise, the basename of the .proto file, without extension. + optional string go_package = 11; + + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of google.protobuf. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + optional bool cc_generic_services = 16 [default = false]; + optional bool java_generic_services = 17 [default = false]; + optional bool py_generic_services = 18 [default = false]; + reserved 42; // removed php_generic_services + reserved "php_generic_services"; + + // Is this file deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for everything in the file, or it will be completely ignored; in the very + // least, this is a formalization for deprecating files. + optional bool deprecated = 23 [default = false]; + + // Enables the use of arenas for the proto messages in this file. This applies + // only to generated classes for C++. + optional bool cc_enable_arenas = 31 [default = true]; + + // Sets the objective c class prefix which is prepended to all objective c + // generated classes from this .proto. There is no default. + optional string objc_class_prefix = 36; + + // Namespace for generated classes; defaults to the package. + optional string csharp_namespace = 37; + + // By default Swift generators will take the proto package and CamelCase it + // replacing '.' with underscore and use that to prefix the types/symbols + // defined. When this options is provided, they will use this value instead + // to prefix the types/symbols defined. + optional string swift_prefix = 39; + + // Sets the php class prefix which is prepended to all php generated classes + // from this .proto. Default is empty. + optional string php_class_prefix = 40; + + // Use this option to change the namespace of php generated classes. Default + // is empty. When this option is empty, the package name will be used for + // determining the namespace. + optional string php_namespace = 41; + + // Use this option to change the namespace of php generated metadata classes. + // Default is empty. When this option is empty, the proto file name will be + // used for determining the namespace. + optional string php_metadata_namespace = 44; + + // Use this option to change the package of ruby generated classes. Default + // is empty. When this option is not set, the package name will be used for + // determining the ruby package. + optional string ruby_package = 45; + + // Any features defined in the specific edition. + // WARNING: This field should only be used by protobuf plugins or special + // cases like the proto compiler. Other uses are discouraged and + // developers should rely on the protoreflect APIs for their client language. + optional FeatureSet features = 50; + + // Range reserved for first-class custom options defined by the Protobuf + // team. User custom options must use the 1000+ range instead. + extensions 990 to 998 [declaration = { + number: 990, + full_name: ".pb.file.cpp", + type: ".pb.file.CppFileOptions" + }]; + + // The parser stores options it doesn't recognize here. + // See the documentation for the "Options" section above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. + // See the documentation for the "Options" section above. + extensions 1000 to max; + + reserved 38; +} + +message MessageOptions { + // Set true to use the old proto1 MessageSet wire format for extensions. + // This is provided for backwards-compatibility with the MessageSet wire + // format. You should not use this for any other reason: It's less + // efficient, has fewer features, and is more complicated. + // + // The message must be defined exactly as follows: + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // Note that the message cannot have any defined fields; MessageSets only + // have extensions. + // + // All extensions of your type must be singular messages; e.g. they cannot + // be int32s, enums, or repeated messages. + // + // Because this is an option, the above two restrictions are not enforced by + // the protocol compiler. + optional bool message_set_wire_format = 1 [default = false]; + + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + optional bool no_standard_descriptor_accessor = 2 [default = false]; + + // Is this message deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the message, or it will be completely ignored; in the very least, + // this is a formalization for deprecating messages. + optional bool deprecated = 3 [default = false]; + + reserved 4, 5, 6; + + // Whether the message is an automatically generated map entry type for the + // maps field. + // + // For maps fields: + // map map_field = 1; + // The parsed descriptor looks like: + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; + // + // Implementations may choose not to generate the map_entry=true message, but + // use a native map in the target language to hold the keys and values. + // The reflection APIs in such implementations still need to work as + // if the field is a repeated message field. + // + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + optional bool map_entry = 7; + + reserved 8; // javalite_serializable + reserved 9; // javanano_as_lite + + // 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. + optional bool deprecated_legacy_json_field_conflicts = 11 [deprecated = true]; + + // Any features defined in the specific edition. + // WARNING: This field should only be used by protobuf plugins or special + // cases like the proto compiler. Other uses are discouraged and + // developers should rely on the protoreflect APIs for their client language. + optional FeatureSet features = 12; + + // Range reserved for first-class custom options defined by the Protobuf + // team. User custom options must use the 1000+ range instead. + extensions 990 to 998; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message FieldOptions { + // NOTE: ctype is deprecated. Use `features.(pb.cpp).string_type` instead. + // 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. + // TODO: make ctype actually deprecated. + optional CType ctype = 1 [/*deprecated = true,*/ default = STRING]; + enum CType { + // Default mode. + STRING = 0; + + // 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. + CORD = 1; + + STRING_PIECE = 2; + } + // The packed option can be enabled for repeated primitive fields to enable + // a more efficient representation on the wire. Rather than repeatedly + // writing the tag and type for each element, the entire array is encoded as + // a single length-delimited blob. In proto3, only explicit setting it to + // false will avoid using packed encoding. This option is prohibited in + // Editions, but the `repeated_field_encoding` feature can be used to control + // the behavior. + optional bool packed = 2; + + // The jstype option determines the JavaScript type used for values of the + // field. The option is permitted only for 64 bit integral and fixed types + // (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + // is represented as JavaScript string, which avoids loss of precision that + // can happen when a large value is converted to a floating point JavaScript. + // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + // use the JavaScript "number" type. The behavior of the default option + // JS_NORMAL is implementation dependent. + // + // This option is an enum to permit additional types to be added, e.g. + // goog.math.Integer. + optional JSType jstype = 6 [default = JS_NORMAL]; + enum JSType { + // Use the default type. + JS_NORMAL = 0; + + // Use JavaScript strings. + JS_STRING = 1; + + // Use JavaScript numbers. + JS_NUMBER = 2; + } + + // Should this field be parsed lazily? Lazy applies only to message-type + // fields. It means that when the outer message is initially parsed, the + // inner message's contents will not be parsed but instead stored in encoded + // form. The inner message will actually be parsed when it is first accessed. + // + // This is only a hint. Implementations are free to choose whether to use + // eager or lazy parsing regardless of the value of this option. However, + // setting this option true suggests that the protocol author believes that + // using lazy parsing on this field is worth the additional bookkeeping + // overhead typically needed to implement it. + // + // This option does not affect the public interface of any generated code; + // all method signatures remain the same. Furthermore, thread-safety of the + // interface is not affected by this option; const methods remain safe to + // call from multiple threads concurrently, while non-const methods continue + // to require exclusive access. + // + // Note that 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). + optional bool lazy = 5 [default = false]; + + // unverified_lazy does no correctness checks on the byte stream. This should + // only be used where lazy with verification is prohibitive for performance + // reasons. + optional bool unverified_lazy = 15 [default = false]; + + // Is this field deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for accessors, or it will be completely ignored; in the very least, this + // is a formalization for deprecating fields. + optional bool deprecated = 3 [default = false]; + + // DEPRECATED. DO NOT USE! + // For Google-internal migration only. Do not use. + optional bool weak = 10 [default = false, deprecated = true]; + + // Indicate that the field value should not be printed out when using debug + // formats, e.g. when the field contains sensitive credentials. + optional bool debug_redact = 16 [default = false]; + + // If set to RETENTION_SOURCE, the option will be omitted from the binary. + enum OptionRetention { + RETENTION_UNKNOWN = 0; + RETENTION_RUNTIME = 1; + RETENTION_SOURCE = 2; + } + + optional OptionRetention retention = 17; + + // 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. + enum OptionTargetType { + 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; + } + + repeated OptionTargetType targets = 19; + + message EditionDefault { + optional Edition edition = 3; + optional string value = 2; // Textproto value. + } + repeated EditionDefault edition_defaults = 20; + + // Any features defined in the specific edition. + // WARNING: This field should only be used by protobuf plugins or special + // cases like the proto compiler. Other uses are discouraged and + // developers should rely on the protoreflect APIs for their client language. + optional FeatureSet features = 21; + + // Information about the support window of a feature. + message FeatureSupport { + // 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. + optional Edition edition_introduced = 1; + + // The edition this feature becomes deprecated in. Using this after this + // edition may trigger warnings. + optional Edition edition_deprecated = 2; + + // The deprecation warning text if this feature is used after the edition it + // was marked deprecated in. + optional string deprecation_warning = 3; + + // 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. + optional Edition edition_removed = 4; + + // The removal error text if this feature is used after the edition it was + // removed in. + optional string removal_error = 5; + } + optional FeatureSupport feature_support = 22; + + // Range reserved for first-class custom options defined by the Protobuf + // team. User custom options must use the 1000+ range instead. + extensions 990 to 998; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; + + reserved 4; // removed jtype + reserved 18; // reserve target, target_obsolete_do_not_use +} + +message OneofOptions { + // Any features defined in the specific edition. + // WARNING: This field should only be used by protobuf plugins or special + // cases like the proto compiler. Other uses are discouraged and + // developers should rely on the protoreflect APIs for their client language. + optional FeatureSet features = 1; + + // Range reserved for first-class custom options defined by the Protobuf + // team. User custom options must use the 1000+ range instead. + extensions 990 to 998; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumOptions { + + // Set this option to true to allow mapping different tag names to the same + // value. + optional bool allow_alias = 2; + + // Is this enum deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum, or it will be completely ignored; in the very least, this + // is a formalization for deprecating enums. + optional bool deprecated = 3 [default = false]; + + reserved 5; // javanano_as_lite + + // 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. + optional bool deprecated_legacy_json_field_conflicts = 6 [deprecated = true]; + + // Any features defined in the specific edition. + // WARNING: This field should only be used by protobuf plugins or special + // cases like the proto compiler. Other uses are discouraged and + // developers should rely on the protoreflect APIs for their client language. + optional FeatureSet features = 7; + + // Range reserved for first-class custom options defined by the Protobuf + // team. User custom options must use the 1000+ range instead. + extensions 990 to 998; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumValueOptions { + // Is this enum value deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum value, or it will be completely ignored; in the very least, + // this is a formalization for deprecating enum values. + optional bool deprecated = 1 [default = false]; + + // Any features defined in the specific edition. + // WARNING: This field should only be used by protobuf plugins or special + // cases like the proto compiler. Other uses are discouraged and + // developers should rely on the protoreflect APIs for their client language. + optional FeatureSet features = 2; + + // 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. + optional bool debug_redact = 3 [default = false]; + + // Information about the support window of a feature value. + optional FieldOptions.FeatureSupport feature_support = 4; + + // Range reserved for first-class extension options defined by the Protobuf + // team. Custom options must use the 1000+ range instead. + extensions 990 to 998 [declaration = { + number: 998, + full_name: ".pb.enumvalue.json", + type: ".pb.enumvalue.JsonEnumValueOptions" + }]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message ServiceOptions { + + // Any features defined in the specific edition. + // WARNING: This field should only be used by protobuf plugins or special + // cases like the proto compiler. Other uses are discouraged and + // developers should rely on the protoreflect APIs for their client language. + optional FeatureSet features = 34; + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this service deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the service, or it will be completely ignored; in the very least, + // this is a formalization for deprecating services. + optional bool deprecated = 33 [default = false]; + + // Range reserved for first-class custom options defined by the Protobuf + // team. User custom options must use the 1000+ range instead. + extensions 990 to 998; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message MethodOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this method deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the method, or it will be completely ignored; in the very least, + // this is a formalization for deprecating methods. + optional bool deprecated = 33 [default = false]; + + // Is this method side-effect-free (or safe in HTTP parlance), or idempotent, + // or neither? HTTP based RPC implementation may choose GET verb for safe + // methods, and PUT verb for idempotent methods instead of the default POST. + enum IdempotencyLevel { + IDEMPOTENCY_UNKNOWN = 0; + NO_SIDE_EFFECTS = 1; // implies idempotent + IDEMPOTENT = 2; // idempotent, but may have side effects + } + optional IdempotencyLevel idempotency_level = 34 + [default = IDEMPOTENCY_UNKNOWN]; + + // Any features defined in the specific edition. + // WARNING: This field should only be used by protobuf plugins or special + // cases like the proto compiler. Other uses are discouraged and + // developers should rely on the protoreflect APIs for their client language. + optional FeatureSet features = 35; + + // Range reserved for first-class custom options defined by the Protobuf + // team. User custom options must use the 1000+ range instead. + extensions 990 to 998; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +message UninterpretedOption { + // The name of the uninterpreted option. Each string represents a segment in + // a dot-separated name. is_extension is true iff a segment represents an + // extension (denoted with parentheses in options specs in .proto files). + // E.g.,{ ["foo", false], ["bar.baz", true], ["moo", false] } represents + // "foo.(bar.baz).moo". + message NamePart { + required string name_part = 1; + required bool is_extension = 2; + } + repeated NamePart name = 2; + + // The value of the uninterpreted option, in whatever type the tokenizer + // identified it as during parsing. Exactly one of these should be set. + optional string identifier_value = 3; + optional uint64 positive_int_value = 4; + optional int64 negative_int_value = 5; + optional double double_value = 6; + optional bytes string_value = 7; + optional string aggregate_value = 8; +} + +// =================================================================== +// Features + +// TODO Enums in C++ gencode (and potentially other languages) are +// not well scoped. This means that each of the feature enums below can clash +// with each other. The short names we've chosen maximize call-site +// readability, but leave us very open to this scenario. A future feature will +// be designed and implemented to handle this, hopefully before we ever hit a +// conflict here. +message FeatureSet { + enum FieldPresence { + FIELD_PRESENCE_UNKNOWN = 0; + EXPLICIT = 1; + IMPLICIT = 2; + LEGACY_REQUIRED = 3; + } + optional FieldPresence field_presence = 1 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_FIELD, + targets = TARGET_TYPE_FILE, + feature_support = { + edition_introduced: EDITION_2023, + }, + edition_defaults = { edition: EDITION_LEGACY, value: "EXPLICIT" }, + edition_defaults = { edition: EDITION_PROTO3, value: "IMPLICIT" }, + edition_defaults = { edition: EDITION_2023, value: "EXPLICIT" } + ]; + + enum EnumType { + ENUM_TYPE_UNKNOWN = 0; + OPEN = 1; + CLOSED = 2; + } + optional EnumType enum_type = 2 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_ENUM, + targets = TARGET_TYPE_FILE, + feature_support = { + edition_introduced: EDITION_2023, + }, + edition_defaults = { edition: EDITION_LEGACY, value: "CLOSED" }, + edition_defaults = { edition: EDITION_PROTO3, value: "OPEN" } + ]; + + enum RepeatedFieldEncoding { + REPEATED_FIELD_ENCODING_UNKNOWN = 0; + PACKED = 1; + EXPANDED = 2; + } + optional RepeatedFieldEncoding repeated_field_encoding = 3 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_FIELD, + targets = TARGET_TYPE_FILE, + feature_support = { + edition_introduced: EDITION_2023, + }, + edition_defaults = { edition: EDITION_LEGACY, value: "EXPANDED" }, + edition_defaults = { edition: EDITION_PROTO3, value: "PACKED" } + ]; + + enum Utf8Validation { + UTF8_VALIDATION_UNKNOWN = 0; + VERIFY = 2; + NONE = 3; + reserved 1; + } + optional Utf8Validation utf8_validation = 4 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_FIELD, + targets = TARGET_TYPE_FILE, + feature_support = { + edition_introduced: EDITION_2023, + }, + edition_defaults = { edition: EDITION_LEGACY, value: "NONE" }, + edition_defaults = { edition: EDITION_PROTO3, value: "VERIFY" } + ]; + + enum MessageEncoding { + MESSAGE_ENCODING_UNKNOWN = 0; + LENGTH_PREFIXED = 1; + DELIMITED = 2; + } + optional MessageEncoding message_encoding = 5 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_FIELD, + targets = TARGET_TYPE_FILE, + feature_support = { + edition_introduced: EDITION_2023, + }, + edition_defaults = { edition: EDITION_LEGACY, value: "LENGTH_PREFIXED" } + ]; + + enum JsonFormat { + JSON_FORMAT_UNKNOWN = 0; + ALLOW = 1; + LEGACY_BEST_EFFORT = 2; + } + optional JsonFormat json_format = 6 [ + retention = RETENTION_RUNTIME, + targets = TARGET_TYPE_MESSAGE, + targets = TARGET_TYPE_ENUM, + targets = TARGET_TYPE_FILE, + feature_support = { + edition_introduced: EDITION_2023, + }, + edition_defaults = { edition: EDITION_LEGACY, value: "LEGACY_BEST_EFFORT" }, + edition_defaults = { edition: EDITION_PROTO3, value: "ALLOW" } + ]; + + enum EnforceNamingStyle { + ENFORCE_NAMING_STYLE_UNKNOWN = 0; + STYLE2024 = 1; + STYLE_LEGACY = 2; + STYLE2026 = 3; + } + optional EnforceNamingStyle enforce_naming_style = 7 [ + retention = RETENTION_SOURCE, + targets = TARGET_TYPE_FILE, + targets = TARGET_TYPE_EXTENSION_RANGE, + targets = TARGET_TYPE_MESSAGE, + targets = TARGET_TYPE_FIELD, + targets = TARGET_TYPE_ONEOF, + targets = TARGET_TYPE_ENUM, + targets = TARGET_TYPE_ENUM_ENTRY, + targets = TARGET_TYPE_SERVICE, + targets = TARGET_TYPE_METHOD, + feature_support = { + edition_introduced: EDITION_2024, + }, + edition_defaults = { edition: EDITION_LEGACY, value: "STYLE_LEGACY" }, + edition_defaults = { edition: EDITION_2024, value: "STYLE2024" }, + edition_defaults = { edition: EDITION_2026, value: "STYLE2026" } + ]; + + message VisibilityFeature { + enum DefaultSymbolVisibility { + DEFAULT_SYMBOL_VISIBILITY_UNKNOWN = 0; + + // Default pre-EDITION_2024, all UNSET visibility are export. + EXPORT_ALL = 1; + + // All top-level symbols default to export, nested default to local. + EXPORT_TOP_LEVEL = 2; + + // All symbols default to local. + LOCAL_ALL = 3; + + // All symbols local by default. Nested types cannot be exported. + // With special case caveat for message { enum {} reserved 1 to max; } + // This is the recommended setting for new protos. + STRICT = 4; + } + reserved 1 to max; + } + optional VisibilityFeature.DefaultSymbolVisibility default_symbol_visibility = + 8 [ + retention = RETENTION_SOURCE, + targets = TARGET_TYPE_FILE, + feature_support = { + edition_introduced: EDITION_2024, + }, + edition_defaults = { edition: EDITION_LEGACY, value: "EXPORT_ALL" }, + edition_defaults = { edition: EDITION_2024, value: "EXPORT_TOP_LEVEL" } + ]; + + message ProtoLimitsFeature { + enum EnforceProtoLimits { + PROTO_LIMITS_UNKNOWN = 0; + + // Default pre-EDITION_2026: there are no limit enforcement at the protoc + // level. Practical limits still exist, but they will tend to fail while + // compiling protoc-generated code, and these limits tend to be language + // or toolchain specific. + LEGACY_NO_EXPLICIT_LIMITS = 1; + + // A set of limits enforced by Edition 2026 by default. For a detailed + // list of all the limits please consult the Edition 2026 documentation. + PROTO_LIMITS2026 = 2; + } + } + optional ProtoLimitsFeature.EnforceProtoLimits enforce_proto_limits = 9 [ + retention = RETENTION_SOURCE, + targets = TARGET_TYPE_ENUM, + targets = TARGET_TYPE_MESSAGE, + targets = TARGET_TYPE_FIELD, + targets = TARGET_TYPE_ONEOF, + feature_support = { + edition_introduced: EDITION_2026, + }, + edition_defaults = { + edition: EDITION_LEGACY, + value: "LEGACY_NO_EXPLICIT_LIMITS" + }, + edition_defaults = { edition: EDITION_2026, value: "PROTO_LIMITS2026" } + ]; + + reserved 999; + + extensions 1000 to 9994 [ + declaration = { + number: 1000, + full_name: ".pb.cpp", + type: ".pb.CppFeatures" + }, + declaration = { + number: 1001, + full_name: ".pb.java", + type: ".pb.JavaFeatures" + }, + declaration = { number: 1002, full_name: ".pb.go", type: ".pb.GoFeatures" }, + declaration = { + number: 1003, + full_name: ".pb.python", + type: ".pb.PythonFeatures" + }, + declaration = { + number: 1004, + full_name: ".pb.csharp", + type: ".pb.CSharpFeatures" + }, + declaration = { + number: 1100, + full_name: ".imp.impress_feature_set", + type: ".imp.ImpressFeatureSet" + }, + declaration = { + number: 9989, + full_name: ".pb.java_mutable", + type: ".pb.JavaMutableFeatures" + }, + declaration = { + number: 9990, + full_name: ".pb.proto1", + type: ".pb.Proto1Features" + } + ]; + + extensions 9995 to 9999; // For internal testing + extensions 10000; // for https://github.com/bufbuild/protobuf-es +} + +// 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. +message FeatureSetDefaults { + // 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. + message FeatureSetEditionDefault { + optional Edition edition = 3; + + // Defaults of features that can be overridden in this edition. + optional FeatureSet overridable_features = 4; + + // Defaults of features that can't be overridden in this edition. + optional FeatureSet fixed_features = 5; + + reserved 1, 2; + reserved "features"; + } + repeated FeatureSetEditionDefault defaults = 1; + + // The minimum supported edition (inclusive) when this was constructed. + // Editions before this will not have defaults. + optional Edition minimum_edition = 4; + + // The maximum known edition (inclusive) when this was constructed. Editions + // after this will not have reliable defaults. + optional Edition maximum_edition = 5; +} + +// =================================================================== +// Optional source code info + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +message SourceCodeInfo { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendant. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + repeated Location location = 1; + message Location { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition 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). + repeated int32 path = 1 [packed = true]; + + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + repeated int32 span = 2 [packed = true]; + + // If this SourceCodeInfo represents a complete declaration, these are any + // comments appearing before and after the declaration which appear to be + // attached to the declaration. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // leading_detached_comments will keep paragraphs of comments that appear + // before (but not connected to) the current element. Each paragraph, + // separated by empty lines, will be one comment element in the repeated + // field. + // + // Only the comment content is provided; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk + // will be stripped from the beginning of each line other than the first. + // Newlines are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to 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. + optional string leading_comments = 3; + optional string trailing_comments = 4; + repeated string leading_detached_comments = 6; + } + + // Extensions for tooling. + extensions 536000000 [declaration = { + number: 536000000 + type: ".buf.descriptor.v1.SourceCodeInfoExtension" + full_name: ".buf.descriptor.v1.buf_source_code_info_extension" + }]; +} + +// Describes the relationship between generated code and its original source +// file. A GeneratedCodeInfo message is associated with only one generated +// source file, but may contain references to different source .proto files. +message GeneratedCodeInfo { + // An Annotation connects some span of text in generated code to an element + // of its generating .proto file. + repeated Annotation annotation = 1; + message Annotation { + // Identifies the element in the original source .proto file. This field + // is formatted the same as SourceCodeInfo.Location.path. + repeated int32 path = 1 [packed = true]; + + // Identifies the filesystem path to the original source .proto. + optional string source_file = 2; + + // Identifies the starting offset in bytes in the generated code + // that relates to the identified object. + optional int32 begin = 3; + + // Identifies the ending offset in bytes in the generated code that + // relates to the identified object. The end offset should be one past + // the last relevant byte (so the length of the text = end - begin). + optional int32 end = 4; + + // Represents the identified object's effect on the element in the original + // .proto file. + enum Semantic { + // There is no effect or the effect is indescribable. + NONE = 0; + // The element is set or otherwise mutated. + SET = 1; + // An alias to the element is returned. + ALIAS = 2; + } + optional Semantic semantic = 5; + } +} + +// Describes the 'visibility' of a symbol with respect to the proto import +// system. Symbols can only be imported when the visibility rules do not prevent +// it (ex: local symbols cannot be imported). Visibility modifiers can only set +// on `message` and `enum` as they are the only types available to be referenced +// from other files. +enum SymbolVisibility { + VISIBILITY_UNSET = 0; + VISIBILITY_LOCAL = 1; + VISIBILITY_EXPORT = 2; +} diff --git a/codegen/proto/hackers.proto b/codegen/proto/hackers.proto new file mode 100644 index 0000000..f456b9c --- /dev/null +++ b/codegen/proto/hackers.proto @@ -0,0 +1,56 @@ +syntax = "proto3"; + +message Tool { + string name = 1; + string version = 2; + bytes payload = 3; + bool is_active = 4; + int32 exploit_count = 5; +} + +message Connection { + string host = 1; + int32 port = 2; + bool encrypted = 3; + int64 bandwidth_bps = 4; + bytes session_key = 5; +} + +message Hacker { + string handle = 1; + string real_name = 2; + int32 age = 3; + float skill_level = 4; // Fixed32 + bool is_elite = 5; + int64 crew_id = 6; + repeated string exploits = 7; + repeated Tool tools = 8; + Connection active_connection = 9; +} + +message Worm { + string name = 1; + int32 variant = 2; + int64 size_bytes = 3; + bytes payload = 4; + bool polymorphic = 5; + repeated string targets = 6; +} + +message Operation { + string codename = 1; + string target_corp = 2; + int64 timestamp = 3; + bool successful = 4; + bytes stolen_data = 5; + repeated Hacker crew = 6; + Worm worm = 7; + repeated string log_entries = 8; + int32 severity = 9; +} + +message Campaign { + string name = 1; + repeated Operation operations = 2; + int64 total_bytes_stolen = 3; +} diff --git a/src/bin/generator.rs b/codegen/src/bin/generator.rs similarity index 79% rename from src/bin/generator.rs rename to codegen/src/bin/generator.rs index 97f2607..fe0f0de 100644 --- a/src/bin/generator.rs +++ b/codegen/src/bin/generator.rs @@ -1,13 +1,15 @@ use clap::Parser; -use roto::google::protobuf::descriptor::{ - FileDescriptorSet -}; -use roto::generator::generate_rust_code; +use roto_codegen::generator::generate_rust_code; +use roto_codegen::google::protobuf::descriptor::FileDescriptorSet; use std::fs; use std::path::PathBuf; #[derive(Parser)] -#[command(author, version, about = "Generates Rust accessor and builder code from a protobuf descriptor set")] +#[command( + author, + version, + about = "Generates Rust accessor and builder code from a protobuf descriptor set" +)] struct Args { /// Path to the descriptor set file (.desc) #[arg(short, long)] diff --git a/src/bin/protoc-gen-roto.rs b/codegen/src/bin/protoc-gen-roto.rs similarity index 78% rename from src/bin/protoc-gen-roto.rs rename to codegen/src/bin/protoc-gen-roto.rs index d5608ad..444aedf 100644 --- a/src/bin/protoc-gen-roto.rs +++ b/codegen/src/bin/protoc-gen-roto.rs @@ -1,13 +1,11 @@ use env_logger::init; use log::{error, info}; -use roto::generator::generate_rust_code; -use roto::google::protobuf::descriptor::{ - FileDescriptorSet -}; -use roto::google::protobuf::compiler::plugin::{ +use roto_codegen::generator::generate_rust_code; +use roto_codegen::google::protobuf::compiler::plugin::{ CodeGeneratorRequest, CodeGeneratorResponseBuilder, code_generator_response::FileBuilder, }; -// use roto::ProtoBuilder; +use roto_codegen::google::protobuf::descriptor::FileDescriptorSet; +// use roto_runtime::ProtoBuilder; use std::io::{self, Read, Write}; fn main() { @@ -43,7 +41,9 @@ fn run() -> std::result::Result<(), Box> { } /// Core logic that transforms a CodeGeneratorRequest into a serialized CodeGeneratorResponse. -fn handle_request(request: &CodeGeneratorRequest) -> std::result::Result, Box> { +fn handle_request( + request: &CodeGeneratorRequest, +) -> std::result::Result, Box> { // 2. Construct a FileDescriptorSet from the request's proto_files let mut set_buf = Vec::new(); for file_res in request.proto_file() { @@ -58,7 +58,7 @@ fn handle_request(request: &CodeGeneratorRequest) -> std::result::Result // Write length as varint let len = file_data.len() as u64; let mut len_buf = [0u8; 10]; - let len_size = roto::write_varint(len, &mut len_buf).map_err(|e| { + let len_size = roto_runtime::write_varint(len, &mut len_buf).map_err(|e| { error!("Failed to write varint length: {:?}", e); e })?; @@ -70,7 +70,8 @@ fn handle_request(request: &CodeGeneratorRequest) -> std::result::Result let set = FileDescriptorSet::new(&set_buf)?; - let files_to_generate: Vec = request.file_to_generate() + let files_to_generate: Vec = request + .file_to_generate() .filter_map(|res| { let (bytes, _) = res.ok()?; std::str::from_utf8(bytes).ok().map(|s| s.to_string()) @@ -98,12 +99,10 @@ fn handle_request(request: &CodeGeneratorRequest) -> std::result::Result resp_builder = resp_builder.file(final_file)?; } - let final_response_slice = resp_builder - .finish() - .map_err(|e| { - error!("Failed to finish CodeGeneratorResponse: {:?}", e); - e - })?; + let final_response_slice = resp_builder.finish().map_err(|e| { + error!("Failed to finish CodeGeneratorResponse: {:?}", e); + e + })?; // The finish() method returns a reference to the buffer. // We convert it to a Vec to return it from this function. @@ -125,12 +124,19 @@ mod tests { } let data = fs::read(request_path).expect("Failed to read request.bin"); - let request = CodeGeneratorRequest::new(&data).expect("Failed to parse CodeGeneratorRequest"); + let request = + CodeGeneratorRequest::new(&data).expect("Failed to parse CodeGeneratorRequest"); let result = handle_request(&request); - assert!(result.is_ok(), "handle_request should succeed with request.bin"); + assert!( + result.is_ok(), + "handle_request should succeed with request.bin" + ); let response = result.unwrap(); - assert!(!response.is_empty(), "The generated response should not be empty"); + assert!( + !response.is_empty(), + "The generated response should not be empty" + ); } } diff --git a/src/generator.rs b/codegen/src/generator.rs similarity index 89% rename from src/generator.rs rename to codegen/src/generator.rs index 9aeab92..72dfae6 100644 --- a/src/generator.rs +++ b/codegen/src/generator.rs @@ -1,8 +1,8 @@ -use crate::ProtoAccessor; use crate::google::protobuf::descriptor::{ DescriptorProto, EnumDescriptorProto, FieldDescriptorProto, FileDescriptorProto, FileDescriptorSet, }; +use roto_runtime::ProtoAccessor; use std::collections::{HashMap, HashSet}; use std::str; @@ -37,7 +37,7 @@ fn map_type_to_rust_accessor(field_type: i32, label: i32) -> (String, String) { if label == 3 { // LABEL_REPEATED return ( - "crate::RepeatedFieldIterator<'a>".to_string(), + "roto_runtime::RepeatedFieldIterator<'a>".to_string(), "".to_string(), // Not used for repeated fields in the same way ); } @@ -57,23 +57,23 @@ fn map_type_to_rust_accessor(field_type: i32, label: i32) -> (String, String) { ), // TYPE_FLOAT 3 | 5 | 15 | 17 => ( "i32".to_string(), - "crate::read_varint(bytes).map(|(v, _)| v as i32).map_err(|_| crate::RotoError::WireFormatViolation)".to_string(), + "roto_runtime::read_varint(bytes).map(|(v, _)| v as i32).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(), ), // INT/SINT/SFIXED 32 4 | 6 | 13 => ( "u32".to_string(), - "crate::read_varint(bytes).map(|(v, _)| v as u32).map_err(|_| crate::RotoError::WireFormatViolation)".to_string(), + "roto_runtime::read_varint(bytes).map(|(v, _)| v as u32).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(), ), // UINT/FIXED 32 16 | 18 => ( "i64".to_string(), - "crate::read_varint(bytes).map(|(v, _)| v as i64).map_err(|_| crate::RotoError::WireFormatViolation)".to_string(), + "roto_runtime::read_varint(bytes).map(|(v, _)| v as i64).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(), ), // SINT/SFIXED 64 7 | 14 => ( "u64".to_string(), - "crate::read_varint(bytes).map(|(v, _)| v as u64).map_err(|_| crate::RotoError::WireFormatViolation)".to_string(), + "roto_runtime::read_varint(bytes).map(|(v, _)| v as u64).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(), ), // UINT/FIXED 64 8 => ( "bool".to_string(), - "crate::read_varint(bytes).map(|(v, _)| v != 0).map_err(|_| crate::RotoError::WireFormatViolation)".to_string(), + "roto_runtime::read_varint(bytes).map(|(v, _)| v != 0).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(), ), // TYPE_BOOL 11 | 12 => ("&'a [u8]".to_string(), "Ok(bytes)".to_string()), // MESSAGE/BYTES _ => ("&'a [u8]".to_string(), "Ok(bytes)".to_string()), @@ -97,7 +97,8 @@ fn write_enum(enum_proto: &EnumDescriptorProto, output: &mut String) { let (name_bytes, _) = accessor.get_value(1).expect("Enum value name missing"); let name = str::from_utf8(name_bytes).expect("Enum value name invalid utf8"); let (num_bytes, _) = accessor.get_value(2).expect("Enum value number missing"); - let (num, _) = crate::read_varint(num_bytes).expect("Enum value number invalid varint"); + let (num, _) = + roto_runtime::read_varint(num_bytes).expect("Enum value number invalid varint"); let pascal_name = to_pascal_case(name); if num == 0 { @@ -126,7 +127,8 @@ fn write_enum(enum_proto: &EnumDescriptorProto, output: &mut String) { let (name_bytes, _) = accessor.get_value(1).expect("Enum value name missing"); let name = str::from_utf8(name_bytes).expect("Enum value name invalid utf8"); let (num_bytes, _) = accessor.get_value(2).expect("Enum value number missing"); - let (num, _) = crate::read_varint(num_bytes).expect("Enum value number invalid varint"); + let (num, _) = + roto_runtime::read_varint(num_bytes).expect("Enum value number invalid varint"); output.push_str(&format!( " {} => {}::{},\n", @@ -162,7 +164,7 @@ fn write_message(msg_proto: &DescriptorProto, output: &mut String) { } output.push_str(&format!("pub struct {}<'a> {{\n", msg_name)); - output.push_str(" accessor: crate::ProtoAccessor<'a>,\n"); + output.push_str(" accessor: roto_runtime::ProtoAccessor<'a>,\n"); for (field_name, _tag, _f_type, f_label) in &fields_info { if *f_label == 3 { @@ -175,8 +177,8 @@ fn write_message(msg_proto: &DescriptorProto, output: &mut String) { output.push_str("}\n\n"); output.push_str(&format!("impl<'a> {}<'a> {{\n", msg_name)); - output.push_str(" pub fn new(data: &'a [u8]) -> crate::Result {\n"); - output.push_str(" let accessor = crate::ProtoAccessor::new(data)?;\n"); + output.push_str(" pub fn new(data: &'a [u8]) -> roto_runtime::Result {\n"); + output.push_str(" let accessor = roto_runtime::ProtoAccessor::new(data)?;\n"); if !fields_info.is_empty() { for (name, _, _, label) in &fields_info { if *label == 3 { @@ -245,11 +247,11 @@ fn write_message(msg_proto: &DescriptorProto, output: &mut String) { output.push_str(" }\n }\n\n"); } else { output.push_str(&format!( - " pub fn {}(&self) -> crate::Result<{}> {{\n", + " pub fn {}(&self) -> roto_runtime::Result<{}> {{\n", safe_name, rust_type )); output.push_str(&format!( - " let offset = self.{}_offset.ok_or(crate::RotoError::FieldNotFound)?;\n", + " let offset = self.{}_offset.ok_or(roto_runtime::RotoError::FieldNotFound)?;\n", field_name )); output.push_str(" let (bytes, _) = self.accessor.get_value_at(offset)?;\n"); @@ -284,7 +286,7 @@ fn write_message(msg_proto: &DescriptorProto, output: &mut String) { // Builder struct — one `_written: bool` flag per field output.push_str(&format!("pub struct {}Builder<'b> {{\n", msg_name)); - output.push_str(" builder: crate::ProtoBuilder<'b>,\n"); + output.push_str(" builder: roto_runtime::ProtoBuilder<'b>,\n"); for (field_name, _, _, _, _) in &builder_fields { output.push_str(&format!(" {}_written: bool,\n", field_name)); } @@ -295,7 +297,7 @@ fn write_message(msg_proto: &DescriptorProto, output: &mut String) { " pub fn builder(buf: &mut [u8]) -> {}Builder<'_> {{\n {}Builder {{\n", msg_name, msg_name )); - output.push_str(" builder: crate::ProtoBuilder::new(buf),\n"); + output.push_str(" builder: roto_runtime::ProtoBuilder::new(buf),\n"); for (field_name, _, _, _, _) in &builder_fields { output.push_str(&format!(" {}_written: false,\n", field_name)); } @@ -304,14 +306,14 @@ fn write_message(msg_proto: &DescriptorProto, output: &mut String) { // Per-field setters — mark field as written for (field_name, safe_name, tag, rust_type, method) in &builder_fields { output.push_str(&format!( - " pub fn {}(mut self, value: {}) -> crate::Result {{\n self.builder.{}({}, value)?;\n self.{}_written = true;\n Ok(self)\n }}\n\n", + " pub fn {}(mut self, value: {}) -> roto_runtime::Result {{\n self.builder.{}({}, value)?;\n self.{}_written = true;\n Ok(self)\n }}\n\n", safe_name, rust_type, method, tag, field_name )); } // with() — copies unseen fields from an existing message output.push_str(&format!( - " pub fn with(mut self, msg: &{}<'_>) -> crate::Result {{\n", + " pub fn with(mut self, msg: &{}<'_>) -> roto_runtime::Result {{\n", msg_name )); output.push_str(" for item in msg.raw_fields() {\n"); @@ -332,7 +334,7 @@ fn write_message(msg_proto: &DescriptorProto, output: &mut String) { output.push_str(" Ok(self)\n"); output.push_str(" }\n\n"); - output.push_str(&format!(" pub fn finish(self) -> crate::Result<&'b mut [u8]> {{\n self.builder.finish()\n }}\n}}\n\n")); + output.push_str(&format!(" pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> {{\n self.builder.finish()\n }}\n}}\n\n")); let mut nested_enums = Vec::new(); for e_res in msg_proto.enum_type() { @@ -403,7 +405,7 @@ pub fn generate_rust_code( let mut output = String::new(); output.push_str("// @generated by protoc-gen-roto — do not edit\n"); output.push_str("#![allow(unused_imports)]\n\n"); - output.push_str("use crate::{ProtoAccessor, ProtoBuilder, Result, RotoError, read_varint, RepeatedFieldIterator};\n"); + output.push_str("use roto_runtime::{ProtoAccessor, ProtoBuilder, Result, RotoError, read_varint, RepeatedFieldIterator};\n"); output.push_str("use std::str;\n\n"); for dep_res in file_proto.dependency() { diff --git a/codegen/src/google/mod.rs b/codegen/src/google/mod.rs new file mode 100644 index 0000000..91e4166 --- /dev/null +++ b/codegen/src/google/mod.rs @@ -0,0 +1 @@ +pub mod protobuf; diff --git a/codegen/src/google/protobuf/compiler/mod.rs b/codegen/src/google/protobuf/compiler/mod.rs new file mode 100644 index 0000000..962cb1b --- /dev/null +++ b/codegen/src/google/protobuf/compiler/mod.rs @@ -0,0 +1 @@ +pub mod plugin; diff --git a/codegen/src/google/protobuf/compiler/plugin.rs b/codegen/src/google/protobuf/compiler/plugin.rs new file mode 100644 index 0000000..c6421ec --- /dev/null +++ b/codegen/src/google/protobuf/compiler/plugin.rs @@ -0,0 +1,679 @@ +// @generated by protoc-gen-roto — do not edit +#![allow(unused_imports)] + +use roto_runtime::{ + ProtoAccessor, ProtoBuilder, RepeatedFieldIterator, Result, RotoError, read_varint, +}; +use std::str; + +use crate::google::protobuf::descriptor; + +pub struct Version<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + major_offset: Option, + minor_offset: Option, + patch_offset: Option, + suffix_offset: Option, +} + +impl<'a> Version<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut major_offset = None; + let mut minor_offset = None; + let mut patch_offset = None; + let mut suffix_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + major_offset = Some(offset); + } + if tag.field_number == 2 { + minor_offset = Some(offset); + } + if tag.field_number == 3 { + patch_offset = Some(offset); + } + if tag.field_number == 4 { + suffix_offset = Some(offset); + } + } + + Ok(Self { + accessor, + major_offset, + minor_offset, + patch_offset, + suffix_offset, + }) + } + + pub fn major(&self) -> roto_runtime::Result { + let offset = self + .major_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn minor(&self) -> roto_runtime::Result { + let offset = self + .minor_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn patch(&self) -> roto_runtime::Result { + let offset = self + .patch_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn suffix(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .suffix_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct VersionBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + major_written: bool, + minor_written: bool, + patch_written: bool, + suffix_written: bool, +} + +impl<'b> VersionBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> VersionBuilder<'_> { + VersionBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + major_written: false, + minor_written: false, + patch_written: false, + suffix_written: false, + } + } + + pub fn major(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(1, value)?; + self.major_written = true; + Ok(self) + } + + pub fn minor(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(2, value)?; + self.minor_written = true; + Ok(self) + } + + pub fn patch(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(3, value)?; + self.patch_written = true; + Ok(self) + } + + pub fn suffix(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(4, value)?; + self.suffix_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &Version<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.major_written, + 2 => self.minor_written, + 3 => self.patch_written, + 4 => self.suffix_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub struct CodeGeneratorRequest<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + file_to_generate_start: Option, + file_to_generate_end: Option, + parameter_offset: Option, + proto_file_start: Option, + proto_file_end: Option, + source_file_descriptors_start: Option, + source_file_descriptors_end: Option, + compiler_version_offset: Option, +} + +impl<'a> CodeGeneratorRequest<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut file_to_generate_start = None; + let mut file_to_generate_end = None; + let mut parameter_offset = None; + let mut proto_file_start = None; + let mut proto_file_end = None; + let mut source_file_descriptors_start = None; + let mut source_file_descriptors_end = None; + let mut compiler_version_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + if file_to_generate_start.is_none() { + file_to_generate_start = Some(offset); + } + file_to_generate_end = Some(offset); + } + if tag.field_number == 2 { + parameter_offset = Some(offset); + } + if tag.field_number == 15 { + if proto_file_start.is_none() { + proto_file_start = Some(offset); + } + proto_file_end = Some(offset); + } + if tag.field_number == 17 { + if source_file_descriptors_start.is_none() { + source_file_descriptors_start = Some(offset); + } + source_file_descriptors_end = Some(offset); + } + if tag.field_number == 3 { + compiler_version_offset = Some(offset); + } + } + + Ok(Self { + accessor, + file_to_generate_start, + file_to_generate_end, + parameter_offset, + proto_file_start, + proto_file_end, + source_file_descriptors_start, + source_file_descriptors_end, + compiler_version_offset, + }) + } + + pub fn file_to_generate(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.file_to_generate_start, self.file_to_generate_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(1, start, end), + _ => self.accessor.iter_repeated(1), + } + } + + pub fn parameter(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .parameter_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn proto_file(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.proto_file_start, self.proto_file_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(15, start, end), + _ => self.accessor.iter_repeated(15), + } + } + + pub fn source_file_descriptors(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match ( + self.source_file_descriptors_start, + self.source_file_descriptors_end, + ) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(17, start, end), + _ => self.accessor.iter_repeated(17), + } + } + + pub fn compiler_version(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .compiler_version_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct CodeGeneratorRequestBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + file_to_generate_written: bool, + parameter_written: bool, + proto_file_written: bool, + source_file_descriptors_written: bool, + compiler_version_written: bool, +} + +impl<'b> CodeGeneratorRequestBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> CodeGeneratorRequestBuilder<'_> { + CodeGeneratorRequestBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + file_to_generate_written: false, + parameter_written: false, + proto_file_written: false, + source_file_descriptors_written: false, + compiler_version_written: false, + } + } + + pub fn file_to_generate(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(1, value)?; + self.file_to_generate_written = true; + Ok(self) + } + + pub fn parameter(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(2, value)?; + self.parameter_written = true; + Ok(self) + } + + pub fn proto_file(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(15, value)?; + self.proto_file_written = true; + Ok(self) + } + + pub fn source_file_descriptors(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(17, value)?; + self.source_file_descriptors_written = true; + Ok(self) + } + + pub fn compiler_version(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(3, value)?; + self.compiler_version_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &CodeGeneratorRequest<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.file_to_generate_written, + 2 => self.parameter_written, + 15 => self.proto_file_written, + 17 => self.source_file_descriptors_written, + 3 => self.compiler_version_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub struct CodeGeneratorResponse<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + error_offset: Option, + supported_features_offset: Option, + minimum_edition_offset: Option, + maximum_edition_offset: Option, + file_start: Option, + file_end: Option, +} + +impl<'a> CodeGeneratorResponse<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut error_offset = None; + let mut supported_features_offset = None; + let mut minimum_edition_offset = None; + let mut maximum_edition_offset = None; + let mut file_start = None; + let mut file_end = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + error_offset = Some(offset); + } + if tag.field_number == 2 { + supported_features_offset = Some(offset); + } + if tag.field_number == 3 { + minimum_edition_offset = Some(offset); + } + if tag.field_number == 4 { + maximum_edition_offset = Some(offset); + } + if tag.field_number == 15 { + if file_start.is_none() { + file_start = Some(offset); + } + file_end = Some(offset); + } + } + + Ok(Self { + accessor, + error_offset, + supported_features_offset, + minimum_edition_offset, + maximum_edition_offset, + file_start, + file_end, + }) + } + + pub fn error(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .error_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn supported_features(&self) -> roto_runtime::Result { + let offset = self + .supported_features_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn minimum_edition(&self) -> roto_runtime::Result { + let offset = self + .minimum_edition_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn maximum_edition(&self) -> roto_runtime::Result { + let offset = self + .maximum_edition_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn file(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.file_start, self.file_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(15, start, end), + _ => self.accessor.iter_repeated(15), + } + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct CodeGeneratorResponseBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + error_written: bool, + supported_features_written: bool, + minimum_edition_written: bool, + maximum_edition_written: bool, + file_written: bool, +} + +impl<'b> CodeGeneratorResponseBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> CodeGeneratorResponseBuilder<'_> { + CodeGeneratorResponseBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + error_written: false, + supported_features_written: false, + minimum_edition_written: false, + maximum_edition_written: false, + file_written: false, + } + } + + pub fn error(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(1, value)?; + self.error_written = true; + Ok(self) + } + + pub fn supported_features(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(2, value)?; + self.supported_features_written = true; + Ok(self) + } + + pub fn minimum_edition(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(3, value)?; + self.minimum_edition_written = true; + Ok(self) + } + + pub fn maximum_edition(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(4, value)?; + self.maximum_edition_written = true; + Ok(self) + } + + pub fn file(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(15, value)?; + self.file_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &CodeGeneratorResponse<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.error_written, + 2 => self.supported_features_written, + 3 => self.minimum_edition_written, + 4 => self.maximum_edition_written, + 15 => self.file_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub mod code_generator_response { + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum Feature { + FEATURENONE = 0, + FEATUREPROTO3OPTIONAL = 1, + FEATURESUPPORTSEDITIONS = 2, + } + + impl Feature { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => Feature::FEATURENONE, + 1 => Feature::FEATUREPROTO3OPTIONAL, + 2 => Feature::FEATURESUPPORTSEDITIONS, + _ => Feature::FEATURENONE, + } + } + } + + pub struct File<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + name_offset: Option, + insertion_point_offset: Option, + content_offset: Option, + generated_code_info_offset: Option, + } + + impl<'a> File<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut name_offset = None; + let mut insertion_point_offset = None; + let mut content_offset = None; + let mut generated_code_info_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + name_offset = Some(offset); + } + if tag.field_number == 2 { + insertion_point_offset = Some(offset); + } + if tag.field_number == 15 { + content_offset = Some(offset); + } + if tag.field_number == 16 { + generated_code_info_offset = Some(offset); + } + } + + Ok(Self { + accessor, + name_offset, + insertion_point_offset, + content_offset, + generated_code_info_offset, + }) + } + + pub fn name(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .name_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn insertion_point(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .insertion_point_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn content(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .content_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn generated_code_info(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .generated_code_info_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } + } + + pub struct FileBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + name_written: bool, + insertion_point_written: bool, + content_written: bool, + generated_code_info_written: bool, + } + + impl<'b> FileBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> FileBuilder<'_> { + FileBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + name_written: false, + insertion_point_written: false, + content_written: false, + generated_code_info_written: false, + } + } + + pub fn name(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(1, value)?; + self.name_written = true; + Ok(self) + } + + pub fn insertion_point(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(2, value)?; + self.insertion_point_written = true; + Ok(self) + } + + pub fn content(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(15, value)?; + self.content_written = true; + Ok(self) + } + + pub fn generated_code_info(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(16, value)?; + self.generated_code_info_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &File<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.name_written, + 2 => self.insertion_point_written, + 15 => self.content_written, + 16 => self.generated_code_info_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } + } +} diff --git a/codegen/src/google/protobuf/descriptor.rs b/codegen/src/google/protobuf/descriptor.rs new file mode 100644 index 0000000..24ff708 --- /dev/null +++ b/codegen/src/google/protobuf/descriptor.rs @@ -0,0 +1,6711 @@ +// @generated by protoc-gen-roto — do not edit +#![allow(unused_imports)] + +use roto_runtime::{ + ProtoAccessor, ProtoBuilder, RepeatedFieldIterator, Result, RotoError, read_varint, +}; +use std::str; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(i32)] +pub enum Edition { + EDITIONUNKNOWN = 0, + EDITIONLEGACY = 900, + EDITIONPROTO2 = 998, + EDITIONPROTO3 = 999, + EDITION2023 = 1000, + EDITION2024 = 1001, + EDITION2026 = 1002, + EDITIONUNSTABLE = 9999, + EDITION1TESTONLY = 1, + EDITION2TESTONLY = 2, + EDITION99997TESTONLY = 99997, + EDITION99998TESTONLY = 99998, + EDITION99999TESTONLY = 99999, + EDITIONMAX = 2147483647, +} + +impl Edition { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => Edition::EDITIONUNKNOWN, + 900 => Edition::EDITIONLEGACY, + 998 => Edition::EDITIONPROTO2, + 999 => Edition::EDITIONPROTO3, + 1000 => Edition::EDITION2023, + 1001 => Edition::EDITION2024, + 1002 => Edition::EDITION2026, + 9999 => Edition::EDITIONUNSTABLE, + 1 => Edition::EDITION1TESTONLY, + 2 => Edition::EDITION2TESTONLY, + 99997 => Edition::EDITION99997TESTONLY, + 99998 => Edition::EDITION99998TESTONLY, + 99999 => Edition::EDITION99999TESTONLY, + 2147483647 => Edition::EDITIONMAX, + _ => Edition::EDITIONUNKNOWN, + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(i32)] +pub enum SymbolVisibility { + VISIBILITYUNSET = 0, + VISIBILITYLOCAL = 1, + VISIBILITYEXPORT = 2, +} + +impl SymbolVisibility { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => SymbolVisibility::VISIBILITYUNSET, + 1 => SymbolVisibility::VISIBILITYLOCAL, + 2 => SymbolVisibility::VISIBILITYEXPORT, + _ => SymbolVisibility::VISIBILITYUNSET, + } + } +} + +pub struct FileDescriptorSet<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + file_start: Option, + file_end: Option, +} + +impl<'a> FileDescriptorSet<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut file_start = None; + let mut file_end = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + if file_start.is_none() { + file_start = Some(offset); + } + file_end = Some(offset); + } + } + + Ok(Self { + accessor, + file_start, + file_end, + }) + } + + pub fn file(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.file_start, self.file_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(1, start, end), + _ => self.accessor.iter_repeated(1), + } + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct FileDescriptorSetBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + file_written: bool, +} + +impl<'b> FileDescriptorSetBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> FileDescriptorSetBuilder<'_> { + FileDescriptorSetBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + file_written: false, + } + } + + pub fn file(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(1, value)?; + self.file_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &FileDescriptorSet<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.file_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub struct FileDescriptorProto<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + name_offset: Option, + package_offset: Option, + dependency_start: Option, + dependency_end: Option, + public_dependency_start: Option, + public_dependency_end: Option, + weak_dependency_start: Option, + weak_dependency_end: Option, + option_dependency_start: Option, + option_dependency_end: Option, + message_type_start: Option, + message_type_end: Option, + enum_type_start: Option, + enum_type_end: Option, + service_start: Option, + service_end: Option, + extension_start: Option, + extension_end: Option, + options_offset: Option, + source_code_info_offset: Option, + syntax_offset: Option, + edition_offset: Option, +} + +impl<'a> FileDescriptorProto<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut name_offset = None; + let mut package_offset = None; + let mut dependency_start = None; + let mut dependency_end = None; + let mut public_dependency_start = None; + let mut public_dependency_end = None; + let mut weak_dependency_start = None; + let mut weak_dependency_end = None; + let mut option_dependency_start = None; + let mut option_dependency_end = None; + let mut message_type_start = None; + let mut message_type_end = None; + let mut enum_type_start = None; + let mut enum_type_end = None; + let mut service_start = None; + let mut service_end = None; + let mut extension_start = None; + let mut extension_end = None; + let mut options_offset = None; + let mut source_code_info_offset = None; + let mut syntax_offset = None; + let mut edition_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + name_offset = Some(offset); + } + if tag.field_number == 2 { + package_offset = Some(offset); + } + if tag.field_number == 3 { + if dependency_start.is_none() { + dependency_start = Some(offset); + } + dependency_end = Some(offset); + } + if tag.field_number == 10 { + if public_dependency_start.is_none() { + public_dependency_start = Some(offset); + } + public_dependency_end = Some(offset); + } + if tag.field_number == 11 { + if weak_dependency_start.is_none() { + weak_dependency_start = Some(offset); + } + weak_dependency_end = Some(offset); + } + if tag.field_number == 15 { + if option_dependency_start.is_none() { + option_dependency_start = Some(offset); + } + option_dependency_end = Some(offset); + } + if tag.field_number == 4 { + if message_type_start.is_none() { + message_type_start = Some(offset); + } + message_type_end = Some(offset); + } + if tag.field_number == 5 { + if enum_type_start.is_none() { + enum_type_start = Some(offset); + } + enum_type_end = Some(offset); + } + if tag.field_number == 6 { + if service_start.is_none() { + service_start = Some(offset); + } + service_end = Some(offset); + } + if tag.field_number == 7 { + if extension_start.is_none() { + extension_start = Some(offset); + } + extension_end = Some(offset); + } + if tag.field_number == 8 { + options_offset = Some(offset); + } + if tag.field_number == 9 { + source_code_info_offset = Some(offset); + } + if tag.field_number == 12 { + syntax_offset = Some(offset); + } + if tag.field_number == 14 { + edition_offset = Some(offset); + } + } + + Ok(Self { + accessor, + name_offset, + package_offset, + dependency_start, + dependency_end, + public_dependency_start, + public_dependency_end, + weak_dependency_start, + weak_dependency_end, + option_dependency_start, + option_dependency_end, + message_type_start, + message_type_end, + enum_type_start, + enum_type_end, + service_start, + service_end, + extension_start, + extension_end, + options_offset, + source_code_info_offset, + syntax_offset, + edition_offset, + }) + } + + pub fn name(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .name_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn package(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .package_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn dependency(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.dependency_start, self.dependency_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(3, start, end), + _ => self.accessor.iter_repeated(3), + } + } + + pub fn public_dependency(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.public_dependency_start, self.public_dependency_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(10, start, end), + _ => self.accessor.iter_repeated(10), + } + } + + pub fn weak_dependency(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.weak_dependency_start, self.weak_dependency_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(11, start, end), + _ => self.accessor.iter_repeated(11), + } + } + + pub fn option_dependency(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.option_dependency_start, self.option_dependency_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(15, start, end), + _ => self.accessor.iter_repeated(15), + } + } + + pub fn message_type(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.message_type_start, self.message_type_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(4, start, end), + _ => self.accessor.iter_repeated(4), + } + } + + pub fn enum_type(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.enum_type_start, self.enum_type_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(5, start, end), + _ => self.accessor.iter_repeated(5), + } + } + + pub fn service(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.service_start, self.service_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(6, start, end), + _ => self.accessor.iter_repeated(6), + } + } + + pub fn extension(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.extension_start, self.extension_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(7, start, end), + _ => self.accessor.iter_repeated(7), + } + } + + pub fn options(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .options_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn source_code_info(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .source_code_info_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn syntax(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .syntax_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn edition(&self) -> roto_runtime::Result { + let offset = self + .edition_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct FileDescriptorProtoBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + name_written: bool, + package_written: bool, + dependency_written: bool, + public_dependency_written: bool, + weak_dependency_written: bool, + option_dependency_written: bool, + message_type_written: bool, + enum_type_written: bool, + service_written: bool, + extension_written: bool, + options_written: bool, + source_code_info_written: bool, + syntax_written: bool, + edition_written: bool, +} + +impl<'b> FileDescriptorProtoBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> FileDescriptorProtoBuilder<'_> { + FileDescriptorProtoBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + name_written: false, + package_written: false, + dependency_written: false, + public_dependency_written: false, + weak_dependency_written: false, + option_dependency_written: false, + message_type_written: false, + enum_type_written: false, + service_written: false, + extension_written: false, + options_written: false, + source_code_info_written: false, + syntax_written: false, + edition_written: false, + } + } + + pub fn name(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(1, value)?; + self.name_written = true; + Ok(self) + } + + pub fn package(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(2, value)?; + self.package_written = true; + Ok(self) + } + + pub fn dependency(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(3, value)?; + self.dependency_written = true; + Ok(self) + } + + pub fn public_dependency(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(10, value)?; + self.public_dependency_written = true; + Ok(self) + } + + pub fn weak_dependency(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(11, value)?; + self.weak_dependency_written = true; + Ok(self) + } + + pub fn option_dependency(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(15, value)?; + self.option_dependency_written = true; + Ok(self) + } + + pub fn message_type(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(4, value)?; + self.message_type_written = true; + Ok(self) + } + + pub fn enum_type(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(5, value)?; + self.enum_type_written = true; + Ok(self) + } + + pub fn service(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(6, value)?; + self.service_written = true; + Ok(self) + } + + pub fn extension(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(7, value)?; + self.extension_written = true; + Ok(self) + } + + pub fn options(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(8, value)?; + self.options_written = true; + Ok(self) + } + + pub fn source_code_info(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(9, value)?; + self.source_code_info_written = true; + Ok(self) + } + + pub fn syntax(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(12, value)?; + self.syntax_written = true; + Ok(self) + } + + pub fn edition(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(14, value)?; + self.edition_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &FileDescriptorProto<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.name_written, + 2 => self.package_written, + 3 => self.dependency_written, + 10 => self.public_dependency_written, + 11 => self.weak_dependency_written, + 15 => self.option_dependency_written, + 4 => self.message_type_written, + 5 => self.enum_type_written, + 6 => self.service_written, + 7 => self.extension_written, + 8 => self.options_written, + 9 => self.source_code_info_written, + 12 => self.syntax_written, + 14 => self.edition_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub struct DescriptorProto<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + name_offset: Option, + field_start: Option, + field_end: Option, + extension_start: Option, + extension_end: Option, + nested_type_start: Option, + nested_type_end: Option, + enum_type_start: Option, + enum_type_end: Option, + extension_range_start: Option, + extension_range_end: Option, + oneof_decl_start: Option, + oneof_decl_end: Option, + options_offset: Option, + reserved_range_start: Option, + reserved_range_end: Option, + reserved_name_start: Option, + reserved_name_end: Option, + visibility_offset: Option, +} + +impl<'a> DescriptorProto<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut name_offset = None; + let mut field_start = None; + let mut field_end = None; + let mut extension_start = None; + let mut extension_end = None; + let mut nested_type_start = None; + let mut nested_type_end = None; + let mut enum_type_start = None; + let mut enum_type_end = None; + let mut extension_range_start = None; + let mut extension_range_end = None; + let mut oneof_decl_start = None; + let mut oneof_decl_end = None; + let mut options_offset = None; + let mut reserved_range_start = None; + let mut reserved_range_end = None; + let mut reserved_name_start = None; + let mut reserved_name_end = None; + let mut visibility_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + name_offset = Some(offset); + } + if tag.field_number == 2 { + if field_start.is_none() { + field_start = Some(offset); + } + field_end = Some(offset); + } + if tag.field_number == 6 { + if extension_start.is_none() { + extension_start = Some(offset); + } + extension_end = Some(offset); + } + if tag.field_number == 3 { + if nested_type_start.is_none() { + nested_type_start = Some(offset); + } + nested_type_end = Some(offset); + } + if tag.field_number == 4 { + if enum_type_start.is_none() { + enum_type_start = Some(offset); + } + enum_type_end = Some(offset); + } + if tag.field_number == 5 { + if extension_range_start.is_none() { + extension_range_start = Some(offset); + } + extension_range_end = Some(offset); + } + if tag.field_number == 8 { + if oneof_decl_start.is_none() { + oneof_decl_start = Some(offset); + } + oneof_decl_end = Some(offset); + } + if tag.field_number == 7 { + options_offset = Some(offset); + } + if tag.field_number == 9 { + if reserved_range_start.is_none() { + reserved_range_start = Some(offset); + } + reserved_range_end = Some(offset); + } + if tag.field_number == 10 { + if reserved_name_start.is_none() { + reserved_name_start = Some(offset); + } + reserved_name_end = Some(offset); + } + if tag.field_number == 11 { + visibility_offset = Some(offset); + } + } + + Ok(Self { + accessor, + name_offset, + field_start, + field_end, + extension_start, + extension_end, + nested_type_start, + nested_type_end, + enum_type_start, + enum_type_end, + extension_range_start, + extension_range_end, + oneof_decl_start, + oneof_decl_end, + options_offset, + reserved_range_start, + reserved_range_end, + reserved_name_start, + reserved_name_end, + visibility_offset, + }) + } + + pub fn name(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .name_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn field(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.field_start, self.field_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(2, start, end), + _ => self.accessor.iter_repeated(2), + } + } + + pub fn extension(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.extension_start, self.extension_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(6, start, end), + _ => self.accessor.iter_repeated(6), + } + } + + pub fn nested_type(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.nested_type_start, self.nested_type_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(3, start, end), + _ => self.accessor.iter_repeated(3), + } + } + + pub fn enum_type(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.enum_type_start, self.enum_type_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(4, start, end), + _ => self.accessor.iter_repeated(4), + } + } + + pub fn extension_range(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.extension_range_start, self.extension_range_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(5, start, end), + _ => self.accessor.iter_repeated(5), + } + } + + pub fn oneof_decl(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.oneof_decl_start, self.oneof_decl_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(8, start, end), + _ => self.accessor.iter_repeated(8), + } + } + + pub fn options(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .options_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn reserved_range(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.reserved_range_start, self.reserved_range_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(9, start, end), + _ => self.accessor.iter_repeated(9), + } + } + + pub fn reserved_name(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.reserved_name_start, self.reserved_name_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(10, start, end), + _ => self.accessor.iter_repeated(10), + } + } + + pub fn visibility(&self) -> roto_runtime::Result { + let offset = self + .visibility_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct DescriptorProtoBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + name_written: bool, + field_written: bool, + extension_written: bool, + nested_type_written: bool, + enum_type_written: bool, + extension_range_written: bool, + oneof_decl_written: bool, + options_written: bool, + reserved_range_written: bool, + reserved_name_written: bool, + visibility_written: bool, +} + +impl<'b> DescriptorProtoBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> DescriptorProtoBuilder<'_> { + DescriptorProtoBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + name_written: false, + field_written: false, + extension_written: false, + nested_type_written: false, + enum_type_written: false, + extension_range_written: false, + oneof_decl_written: false, + options_written: false, + reserved_range_written: false, + reserved_name_written: false, + visibility_written: false, + } + } + + pub fn name(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(1, value)?; + self.name_written = true; + Ok(self) + } + + pub fn field(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(2, value)?; + self.field_written = true; + Ok(self) + } + + pub fn extension(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(6, value)?; + self.extension_written = true; + Ok(self) + } + + pub fn nested_type(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(3, value)?; + self.nested_type_written = true; + Ok(self) + } + + pub fn enum_type(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(4, value)?; + self.enum_type_written = true; + Ok(self) + } + + pub fn extension_range(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(5, value)?; + self.extension_range_written = true; + Ok(self) + } + + pub fn oneof_decl(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(8, value)?; + self.oneof_decl_written = true; + Ok(self) + } + + pub fn options(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(7, value)?; + self.options_written = true; + Ok(self) + } + + pub fn reserved_range(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(9, value)?; + self.reserved_range_written = true; + Ok(self) + } + + pub fn reserved_name(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(10, value)?; + self.reserved_name_written = true; + Ok(self) + } + + pub fn visibility(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(11, value)?; + self.visibility_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &DescriptorProto<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.name_written, + 2 => self.field_written, + 6 => self.extension_written, + 3 => self.nested_type_written, + 4 => self.enum_type_written, + 5 => self.extension_range_written, + 8 => self.oneof_decl_written, + 7 => self.options_written, + 9 => self.reserved_range_written, + 10 => self.reserved_name_written, + 11 => self.visibility_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub mod descriptor_proto { + pub struct ExtensionRange<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + start_offset: Option, + end_offset: Option, + options_offset: Option, + } + + impl<'a> ExtensionRange<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut start_offset = None; + let mut end_offset = None; + let mut options_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + start_offset = Some(offset); + } + if tag.field_number == 2 { + end_offset = Some(offset); + } + if tag.field_number == 3 { + options_offset = Some(offset); + } + } + + Ok(Self { + accessor, + start_offset, + end_offset, + options_offset, + }) + } + + pub fn start(&self) -> roto_runtime::Result { + let offset = self + .start_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn end(&self) -> roto_runtime::Result { + let offset = self + .end_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn options(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .options_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } + } + + pub struct ExtensionRangeBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + start_written: bool, + end_written: bool, + options_written: bool, + } + + impl<'b> ExtensionRangeBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> ExtensionRangeBuilder<'_> { + ExtensionRangeBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + start_written: false, + end_written: false, + options_written: false, + } + } + + pub fn start(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(1, value)?; + self.start_written = true; + Ok(self) + } + + pub fn end(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(2, value)?; + self.end_written = true; + Ok(self) + } + + pub fn options(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(3, value)?; + self.options_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &ExtensionRange<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.start_written, + 2 => self.end_written, + 3 => self.options_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } + } + + pub struct ReservedRange<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + start_offset: Option, + end_offset: Option, + } + + impl<'a> ReservedRange<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut start_offset = None; + let mut end_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + start_offset = Some(offset); + } + if tag.field_number == 2 { + end_offset = Some(offset); + } + } + + Ok(Self { + accessor, + start_offset, + end_offset, + }) + } + + pub fn start(&self) -> roto_runtime::Result { + let offset = self + .start_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn end(&self) -> roto_runtime::Result { + let offset = self + .end_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } + } + + pub struct ReservedRangeBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + start_written: bool, + end_written: bool, + } + + impl<'b> ReservedRangeBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> ReservedRangeBuilder<'_> { + ReservedRangeBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + start_written: false, + end_written: false, + } + } + + pub fn start(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(1, value)?; + self.start_written = true; + Ok(self) + } + + pub fn end(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(2, value)?; + self.end_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &ReservedRange<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.start_written, + 2 => self.end_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } + } +} + +pub struct ExtensionRangeOptions<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + uninterpreted_option_start: Option, + uninterpreted_option_end: Option, + declaration_start: Option, + declaration_end: Option, + features_offset: Option, + verification_offset: Option, +} + +impl<'a> ExtensionRangeOptions<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut uninterpreted_option_start = None; + let mut uninterpreted_option_end = None; + let mut declaration_start = None; + let mut declaration_end = None; + let mut features_offset = None; + let mut verification_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 999 { + if uninterpreted_option_start.is_none() { + uninterpreted_option_start = Some(offset); + } + uninterpreted_option_end = Some(offset); + } + if tag.field_number == 2 { + if declaration_start.is_none() { + declaration_start = Some(offset); + } + declaration_end = Some(offset); + } + if tag.field_number == 50 { + features_offset = Some(offset); + } + if tag.field_number == 3 { + verification_offset = Some(offset); + } + } + + Ok(Self { + accessor, + uninterpreted_option_start, + uninterpreted_option_end, + declaration_start, + declaration_end, + features_offset, + verification_offset, + }) + } + + pub fn uninterpreted_option(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match ( + self.uninterpreted_option_start, + self.uninterpreted_option_end, + ) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(999, start, end), + _ => self.accessor.iter_repeated(999), + } + } + + pub fn declaration(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.declaration_start, self.declaration_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(2, start, end), + _ => self.accessor.iter_repeated(2), + } + } + + pub fn features(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .features_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn verification(&self) -> roto_runtime::Result { + let offset = self + .verification_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct ExtensionRangeOptionsBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + uninterpreted_option_written: bool, + declaration_written: bool, + features_written: bool, + verification_written: bool, +} + +impl<'b> ExtensionRangeOptionsBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> ExtensionRangeOptionsBuilder<'_> { + ExtensionRangeOptionsBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + uninterpreted_option_written: false, + declaration_written: false, + features_written: false, + verification_written: false, + } + } + + pub fn uninterpreted_option(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(999, value)?; + self.uninterpreted_option_written = true; + Ok(self) + } + + pub fn declaration(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(2, value)?; + self.declaration_written = true; + Ok(self) + } + + pub fn features(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(50, value)?; + self.features_written = true; + Ok(self) + } + + pub fn verification(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(3, value)?; + self.verification_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &ExtensionRangeOptions<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 999 => self.uninterpreted_option_written, + 2 => self.declaration_written, + 50 => self.features_written, + 3 => self.verification_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub mod extension_range_options { + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum VerificationState { + DECLARATION = 0, + UNVERIFIED = 1, + } + + impl VerificationState { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => VerificationState::DECLARATION, + 1 => VerificationState::UNVERIFIED, + _ => VerificationState::DECLARATION, + } + } + } + + pub struct Declaration<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + number_offset: Option, + full_name_offset: Option, + type_offset: Option, + reserved_offset: Option, + repeated_offset: Option, + } + + impl<'a> Declaration<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut number_offset = None; + let mut full_name_offset = None; + let mut type_offset = None; + let mut reserved_offset = None; + let mut repeated_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + number_offset = Some(offset); + } + if tag.field_number == 2 { + full_name_offset = Some(offset); + } + if tag.field_number == 3 { + type_offset = Some(offset); + } + if tag.field_number == 5 { + reserved_offset = Some(offset); + } + if tag.field_number == 6 { + repeated_offset = Some(offset); + } + } + + Ok(Self { + accessor, + number_offset, + full_name_offset, + type_offset, + reserved_offset, + repeated_offset, + }) + } + + pub fn number(&self) -> roto_runtime::Result { + let offset = self + .number_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn full_name(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .full_name_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn r#type(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .type_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn reserved(&self) -> roto_runtime::Result { + let offset = self + .reserved_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn repeated(&self) -> roto_runtime::Result { + let offset = self + .repeated_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } + } + + pub struct DeclarationBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + number_written: bool, + full_name_written: bool, + type_written: bool, + reserved_written: bool, + repeated_written: bool, + } + + impl<'b> DeclarationBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> DeclarationBuilder<'_> { + DeclarationBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + number_written: false, + full_name_written: false, + type_written: false, + reserved_written: false, + repeated_written: false, + } + } + + pub fn number(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(1, value)?; + self.number_written = true; + Ok(self) + } + + pub fn full_name(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(2, value)?; + self.full_name_written = true; + Ok(self) + } + + pub fn r#type(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(3, value)?; + self.type_written = true; + Ok(self) + } + + pub fn reserved(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(5, value)?; + self.reserved_written = true; + Ok(self) + } + + pub fn repeated(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(6, value)?; + self.repeated_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &Declaration<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.number_written, + 2 => self.full_name_written, + 3 => self.type_written, + 5 => self.reserved_written, + 6 => self.repeated_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } + } +} + +pub struct FieldDescriptorProto<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + name_offset: Option, + number_offset: Option, + label_offset: Option, + type_offset: Option, + type_name_offset: Option, + extendee_offset: Option, + default_value_offset: Option, + oneof_index_offset: Option, + json_name_offset: Option, + options_offset: Option, + proto3_optional_offset: Option, +} + +impl<'a> FieldDescriptorProto<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut name_offset = None; + let mut number_offset = None; + let mut label_offset = None; + let mut type_offset = None; + let mut type_name_offset = None; + let mut extendee_offset = None; + let mut default_value_offset = None; + let mut oneof_index_offset = None; + let mut json_name_offset = None; + let mut options_offset = None; + let mut proto3_optional_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + name_offset = Some(offset); + } + if tag.field_number == 3 { + number_offset = Some(offset); + } + if tag.field_number == 4 { + label_offset = Some(offset); + } + if tag.field_number == 5 { + type_offset = Some(offset); + } + if tag.field_number == 6 { + type_name_offset = Some(offset); + } + if tag.field_number == 2 { + extendee_offset = Some(offset); + } + if tag.field_number == 7 { + default_value_offset = Some(offset); + } + if tag.field_number == 9 { + oneof_index_offset = Some(offset); + } + if tag.field_number == 10 { + json_name_offset = Some(offset); + } + if tag.field_number == 8 { + options_offset = Some(offset); + } + if tag.field_number == 17 { + proto3_optional_offset = Some(offset); + } + } + + Ok(Self { + accessor, + name_offset, + number_offset, + label_offset, + type_offset, + type_name_offset, + extendee_offset, + default_value_offset, + oneof_index_offset, + json_name_offset, + options_offset, + proto3_optional_offset, + }) + } + + pub fn name(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .name_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn number(&self) -> roto_runtime::Result { + let offset = self + .number_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn label(&self) -> roto_runtime::Result { + let offset = self + .label_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn r#type(&self) -> roto_runtime::Result { + let offset = self + .type_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn type_name(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .type_name_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn extendee(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .extendee_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn default_value(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .default_value_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn oneof_index(&self) -> roto_runtime::Result { + let offset = self + .oneof_index_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn json_name(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .json_name_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn options(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .options_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn proto3_optional(&self) -> roto_runtime::Result { + let offset = self + .proto3_optional_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct FieldDescriptorProtoBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + name_written: bool, + number_written: bool, + label_written: bool, + type_written: bool, + type_name_written: bool, + extendee_written: bool, + default_value_written: bool, + oneof_index_written: bool, + json_name_written: bool, + options_written: bool, + proto3_optional_written: bool, +} + +impl<'b> FieldDescriptorProtoBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> FieldDescriptorProtoBuilder<'_> { + FieldDescriptorProtoBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + name_written: false, + number_written: false, + label_written: false, + type_written: false, + type_name_written: false, + extendee_written: false, + default_value_written: false, + oneof_index_written: false, + json_name_written: false, + options_written: false, + proto3_optional_written: false, + } + } + + pub fn name(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(1, value)?; + self.name_written = true; + Ok(self) + } + + pub fn number(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(3, value)?; + self.number_written = true; + Ok(self) + } + + pub fn label(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(4, value)?; + self.label_written = true; + Ok(self) + } + + pub fn r#type(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(5, value)?; + self.type_written = true; + Ok(self) + } + + pub fn type_name(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(6, value)?; + self.type_name_written = true; + Ok(self) + } + + pub fn extendee(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(2, value)?; + self.extendee_written = true; + Ok(self) + } + + pub fn default_value(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(7, value)?; + self.default_value_written = true; + Ok(self) + } + + pub fn oneof_index(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(9, value)?; + self.oneof_index_written = true; + Ok(self) + } + + pub fn json_name(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(10, value)?; + self.json_name_written = true; + Ok(self) + } + + pub fn options(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(8, value)?; + self.options_written = true; + Ok(self) + } + + pub fn proto3_optional(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(17, value)?; + self.proto3_optional_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &FieldDescriptorProto<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.name_written, + 3 => self.number_written, + 4 => self.label_written, + 5 => self.type_written, + 6 => self.type_name_written, + 2 => self.extendee_written, + 7 => self.default_value_written, + 9 => self.oneof_index_written, + 10 => self.json_name_written, + 8 => self.options_written, + 17 => self.proto3_optional_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub mod field_descriptor_proto { + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum Type { + TYPEDOUBLE = 1, + TYPEFLOAT = 2, + TYPEINT64 = 3, + TYPEUINT64 = 4, + TYPEINT32 = 5, + TYPEFIXED64 = 6, + TYPEFIXED32 = 7, + TYPEBOOL = 8, + TYPESTRING = 9, + TYPEGROUP = 10, + TYPEMESSAGE = 11, + TYPEBYTES = 12, + TYPEUINT32 = 13, + TYPEENUM = 14, + TYPESFIXED32 = 15, + TYPESFIXED64 = 16, + TYPESINT32 = 17, + TYPESINT64 = 18, + Unknown = 0, + } + + impl Type { + pub fn from_i32(value: i32) -> Self { + match value { + 1 => Type::TYPEDOUBLE, + 2 => Type::TYPEFLOAT, + 3 => Type::TYPEINT64, + 4 => Type::TYPEUINT64, + 5 => Type::TYPEINT32, + 6 => Type::TYPEFIXED64, + 7 => Type::TYPEFIXED32, + 8 => Type::TYPEBOOL, + 9 => Type::TYPESTRING, + 10 => Type::TYPEGROUP, + 11 => Type::TYPEMESSAGE, + 12 => Type::TYPEBYTES, + 13 => Type::TYPEUINT32, + 14 => Type::TYPEENUM, + 15 => Type::TYPESFIXED32, + 16 => Type::TYPESFIXED64, + 17 => Type::TYPESINT32, + 18 => Type::TYPESINT64, + _ => Type::Unknown, + } + } + } + + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum Label { + LABELOPTIONAL = 1, + LABELREPEATED = 3, + LABELREQUIRED = 2, + Unknown = 0, + } + + impl Label { + pub fn from_i32(value: i32) -> Self { + match value { + 1 => Label::LABELOPTIONAL, + 3 => Label::LABELREPEATED, + 2 => Label::LABELREQUIRED, + _ => Label::Unknown, + } + } + } +} + +pub struct OneofDescriptorProto<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + name_offset: Option, + options_offset: Option, +} + +impl<'a> OneofDescriptorProto<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut name_offset = None; + let mut options_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + name_offset = Some(offset); + } + if tag.field_number == 2 { + options_offset = Some(offset); + } + } + + Ok(Self { + accessor, + name_offset, + options_offset, + }) + } + + pub fn name(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .name_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn options(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .options_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct OneofDescriptorProtoBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + name_written: bool, + options_written: bool, +} + +impl<'b> OneofDescriptorProtoBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> OneofDescriptorProtoBuilder<'_> { + OneofDescriptorProtoBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + name_written: false, + options_written: false, + } + } + + pub fn name(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(1, value)?; + self.name_written = true; + Ok(self) + } + + pub fn options(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(2, value)?; + self.options_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &OneofDescriptorProto<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.name_written, + 2 => self.options_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub struct EnumDescriptorProto<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + name_offset: Option, + value_start: Option, + value_end: Option, + options_offset: Option, + reserved_range_start: Option, + reserved_range_end: Option, + reserved_name_start: Option, + reserved_name_end: Option, + visibility_offset: Option, +} + +impl<'a> EnumDescriptorProto<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut name_offset = None; + let mut value_start = None; + let mut value_end = None; + let mut options_offset = None; + let mut reserved_range_start = None; + let mut reserved_range_end = None; + let mut reserved_name_start = None; + let mut reserved_name_end = None; + let mut visibility_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + name_offset = Some(offset); + } + if tag.field_number == 2 { + if value_start.is_none() { + value_start = Some(offset); + } + value_end = Some(offset); + } + if tag.field_number == 3 { + options_offset = Some(offset); + } + if tag.field_number == 4 { + if reserved_range_start.is_none() { + reserved_range_start = Some(offset); + } + reserved_range_end = Some(offset); + } + if tag.field_number == 5 { + if reserved_name_start.is_none() { + reserved_name_start = Some(offset); + } + reserved_name_end = Some(offset); + } + if tag.field_number == 6 { + visibility_offset = Some(offset); + } + } + + Ok(Self { + accessor, + name_offset, + value_start, + value_end, + options_offset, + reserved_range_start, + reserved_range_end, + reserved_name_start, + reserved_name_end, + visibility_offset, + }) + } + + pub fn name(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .name_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn value(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.value_start, self.value_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(2, start, end), + _ => self.accessor.iter_repeated(2), + } + } + + pub fn options(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .options_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn reserved_range(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.reserved_range_start, self.reserved_range_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(4, start, end), + _ => self.accessor.iter_repeated(4), + } + } + + pub fn reserved_name(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.reserved_name_start, self.reserved_name_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(5, start, end), + _ => self.accessor.iter_repeated(5), + } + } + + pub fn visibility(&self) -> roto_runtime::Result { + let offset = self + .visibility_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct EnumDescriptorProtoBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + name_written: bool, + value_written: bool, + options_written: bool, + reserved_range_written: bool, + reserved_name_written: bool, + visibility_written: bool, +} + +impl<'b> EnumDescriptorProtoBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> EnumDescriptorProtoBuilder<'_> { + EnumDescriptorProtoBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + name_written: false, + value_written: false, + options_written: false, + reserved_range_written: false, + reserved_name_written: false, + visibility_written: false, + } + } + + pub fn name(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(1, value)?; + self.name_written = true; + Ok(self) + } + + pub fn value(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(2, value)?; + self.value_written = true; + Ok(self) + } + + pub fn options(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(3, value)?; + self.options_written = true; + Ok(self) + } + + pub fn reserved_range(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(4, value)?; + self.reserved_range_written = true; + Ok(self) + } + + pub fn reserved_name(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(5, value)?; + self.reserved_name_written = true; + Ok(self) + } + + pub fn visibility(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(6, value)?; + self.visibility_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &EnumDescriptorProto<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.name_written, + 2 => self.value_written, + 3 => self.options_written, + 4 => self.reserved_range_written, + 5 => self.reserved_name_written, + 6 => self.visibility_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub mod enum_descriptor_proto { + pub struct EnumReservedRange<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + start_offset: Option, + end_offset: Option, + } + + impl<'a> EnumReservedRange<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut start_offset = None; + let mut end_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + start_offset = Some(offset); + } + if tag.field_number == 2 { + end_offset = Some(offset); + } + } + + Ok(Self { + accessor, + start_offset, + end_offset, + }) + } + + pub fn start(&self) -> roto_runtime::Result { + let offset = self + .start_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn end(&self) -> roto_runtime::Result { + let offset = self + .end_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } + } + + pub struct EnumReservedRangeBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + start_written: bool, + end_written: bool, + } + + impl<'b> EnumReservedRangeBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> EnumReservedRangeBuilder<'_> { + EnumReservedRangeBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + start_written: false, + end_written: false, + } + } + + pub fn start(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(1, value)?; + self.start_written = true; + Ok(self) + } + + pub fn end(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(2, value)?; + self.end_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &EnumReservedRange<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.start_written, + 2 => self.end_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } + } +} + +pub struct EnumValueDescriptorProto<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + name_offset: Option, + number_offset: Option, + options_offset: Option, +} + +impl<'a> EnumValueDescriptorProto<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut name_offset = None; + let mut number_offset = None; + let mut options_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + name_offset = Some(offset); + } + if tag.field_number == 2 { + number_offset = Some(offset); + } + if tag.field_number == 3 { + options_offset = Some(offset); + } + } + + Ok(Self { + accessor, + name_offset, + number_offset, + options_offset, + }) + } + + pub fn name(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .name_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn number(&self) -> roto_runtime::Result { + let offset = self + .number_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn options(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .options_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct EnumValueDescriptorProtoBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + name_written: bool, + number_written: bool, + options_written: bool, +} + +impl<'b> EnumValueDescriptorProtoBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> EnumValueDescriptorProtoBuilder<'_> { + EnumValueDescriptorProtoBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + name_written: false, + number_written: false, + options_written: false, + } + } + + pub fn name(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(1, value)?; + self.name_written = true; + Ok(self) + } + + pub fn number(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(2, value)?; + self.number_written = true; + Ok(self) + } + + pub fn options(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(3, value)?; + self.options_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &EnumValueDescriptorProto<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.name_written, + 2 => self.number_written, + 3 => self.options_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub struct ServiceDescriptorProto<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + name_offset: Option, + method_start: Option, + method_end: Option, + options_offset: Option, +} + +impl<'a> ServiceDescriptorProto<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut name_offset = None; + let mut method_start = None; + let mut method_end = None; + let mut options_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + name_offset = Some(offset); + } + if tag.field_number == 2 { + if method_start.is_none() { + method_start = Some(offset); + } + method_end = Some(offset); + } + if tag.field_number == 3 { + options_offset = Some(offset); + } + } + + Ok(Self { + accessor, + name_offset, + method_start, + method_end, + options_offset, + }) + } + + pub fn name(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .name_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn method(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.method_start, self.method_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(2, start, end), + _ => self.accessor.iter_repeated(2), + } + } + + pub fn options(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .options_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct ServiceDescriptorProtoBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + name_written: bool, + method_written: bool, + options_written: bool, +} + +impl<'b> ServiceDescriptorProtoBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> ServiceDescriptorProtoBuilder<'_> { + ServiceDescriptorProtoBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + name_written: false, + method_written: false, + options_written: false, + } + } + + pub fn name(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(1, value)?; + self.name_written = true; + Ok(self) + } + + pub fn method(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(2, value)?; + self.method_written = true; + Ok(self) + } + + pub fn options(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(3, value)?; + self.options_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &ServiceDescriptorProto<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.name_written, + 2 => self.method_written, + 3 => self.options_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub struct MethodDescriptorProto<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + name_offset: Option, + input_type_offset: Option, + output_type_offset: Option, + options_offset: Option, + client_streaming_offset: Option, + server_streaming_offset: Option, +} + +impl<'a> MethodDescriptorProto<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut name_offset = None; + let mut input_type_offset = None; + let mut output_type_offset = None; + let mut options_offset = None; + let mut client_streaming_offset = None; + let mut server_streaming_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + name_offset = Some(offset); + } + if tag.field_number == 2 { + input_type_offset = Some(offset); + } + if tag.field_number == 3 { + output_type_offset = Some(offset); + } + if tag.field_number == 4 { + options_offset = Some(offset); + } + if tag.field_number == 5 { + client_streaming_offset = Some(offset); + } + if tag.field_number == 6 { + server_streaming_offset = Some(offset); + } + } + + Ok(Self { + accessor, + name_offset, + input_type_offset, + output_type_offset, + options_offset, + client_streaming_offset, + server_streaming_offset, + }) + } + + pub fn name(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .name_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn input_type(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .input_type_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn output_type(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .output_type_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn options(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .options_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn client_streaming(&self) -> roto_runtime::Result { + let offset = self + .client_streaming_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn server_streaming(&self) -> roto_runtime::Result { + let offset = self + .server_streaming_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct MethodDescriptorProtoBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + name_written: bool, + input_type_written: bool, + output_type_written: bool, + options_written: bool, + client_streaming_written: bool, + server_streaming_written: bool, +} + +impl<'b> MethodDescriptorProtoBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> MethodDescriptorProtoBuilder<'_> { + MethodDescriptorProtoBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + name_written: false, + input_type_written: false, + output_type_written: false, + options_written: false, + client_streaming_written: false, + server_streaming_written: false, + } + } + + pub fn name(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(1, value)?; + self.name_written = true; + Ok(self) + } + + pub fn input_type(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(2, value)?; + self.input_type_written = true; + Ok(self) + } + + pub fn output_type(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(3, value)?; + self.output_type_written = true; + Ok(self) + } + + pub fn options(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(4, value)?; + self.options_written = true; + Ok(self) + } + + pub fn client_streaming(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(5, value)?; + self.client_streaming_written = true; + Ok(self) + } + + pub fn server_streaming(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(6, value)?; + self.server_streaming_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &MethodDescriptorProto<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.name_written, + 2 => self.input_type_written, + 3 => self.output_type_written, + 4 => self.options_written, + 5 => self.client_streaming_written, + 6 => self.server_streaming_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub struct FileOptions<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + java_package_offset: Option, + java_outer_classname_offset: Option, + java_multiple_files_offset: Option, + java_generate_equals_and_hash_offset: Option, + java_string_check_utf8_offset: Option, + optimize_for_offset: Option, + go_package_offset: Option, + cc_generic_services_offset: Option, + java_generic_services_offset: Option, + py_generic_services_offset: Option, + deprecated_offset: Option, + cc_enable_arenas_offset: Option, + objc_class_prefix_offset: Option, + csharp_namespace_offset: Option, + swift_prefix_offset: Option, + php_class_prefix_offset: Option, + php_namespace_offset: Option, + php_metadata_namespace_offset: Option, + ruby_package_offset: Option, + features_offset: Option, + uninterpreted_option_start: Option, + uninterpreted_option_end: Option, +} + +impl<'a> FileOptions<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut java_package_offset = None; + let mut java_outer_classname_offset = None; + let mut java_multiple_files_offset = None; + let mut java_generate_equals_and_hash_offset = None; + let mut java_string_check_utf8_offset = None; + let mut optimize_for_offset = None; + let mut go_package_offset = None; + let mut cc_generic_services_offset = None; + let mut java_generic_services_offset = None; + let mut py_generic_services_offset = None; + let mut deprecated_offset = None; + let mut cc_enable_arenas_offset = None; + let mut objc_class_prefix_offset = None; + let mut csharp_namespace_offset = None; + let mut swift_prefix_offset = None; + let mut php_class_prefix_offset = None; + let mut php_namespace_offset = None; + let mut php_metadata_namespace_offset = None; + let mut ruby_package_offset = None; + let mut features_offset = None; + let mut uninterpreted_option_start = None; + let mut uninterpreted_option_end = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + java_package_offset = Some(offset); + } + if tag.field_number == 8 { + java_outer_classname_offset = Some(offset); + } + if tag.field_number == 10 { + java_multiple_files_offset = Some(offset); + } + if tag.field_number == 20 { + java_generate_equals_and_hash_offset = Some(offset); + } + if tag.field_number == 27 { + java_string_check_utf8_offset = Some(offset); + } + if tag.field_number == 9 { + optimize_for_offset = Some(offset); + } + if tag.field_number == 11 { + go_package_offset = Some(offset); + } + if tag.field_number == 16 { + cc_generic_services_offset = Some(offset); + } + if tag.field_number == 17 { + java_generic_services_offset = Some(offset); + } + if tag.field_number == 18 { + py_generic_services_offset = Some(offset); + } + if tag.field_number == 23 { + deprecated_offset = Some(offset); + } + if tag.field_number == 31 { + cc_enable_arenas_offset = Some(offset); + } + if tag.field_number == 36 { + objc_class_prefix_offset = Some(offset); + } + if tag.field_number == 37 { + csharp_namespace_offset = Some(offset); + } + if tag.field_number == 39 { + swift_prefix_offset = Some(offset); + } + if tag.field_number == 40 { + php_class_prefix_offset = Some(offset); + } + if tag.field_number == 41 { + php_namespace_offset = Some(offset); + } + if tag.field_number == 44 { + php_metadata_namespace_offset = Some(offset); + } + if tag.field_number == 45 { + ruby_package_offset = Some(offset); + } + if tag.field_number == 50 { + features_offset = Some(offset); + } + if tag.field_number == 999 { + if uninterpreted_option_start.is_none() { + uninterpreted_option_start = Some(offset); + } + uninterpreted_option_end = Some(offset); + } + } + + Ok(Self { + accessor, + java_package_offset, + java_outer_classname_offset, + java_multiple_files_offset, + java_generate_equals_and_hash_offset, + java_string_check_utf8_offset, + optimize_for_offset, + go_package_offset, + cc_generic_services_offset, + java_generic_services_offset, + py_generic_services_offset, + deprecated_offset, + cc_enable_arenas_offset, + objc_class_prefix_offset, + csharp_namespace_offset, + swift_prefix_offset, + php_class_prefix_offset, + php_namespace_offset, + php_metadata_namespace_offset, + ruby_package_offset, + features_offset, + uninterpreted_option_start, + uninterpreted_option_end, + }) + } + + pub fn java_package(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .java_package_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn java_outer_classname(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .java_outer_classname_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn java_multiple_files(&self) -> roto_runtime::Result { + let offset = self + .java_multiple_files_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn java_generate_equals_and_hash(&self) -> roto_runtime::Result { + let offset = self + .java_generate_equals_and_hash_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn java_string_check_utf8(&self) -> roto_runtime::Result { + let offset = self + .java_string_check_utf8_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn optimize_for(&self) -> roto_runtime::Result { + let offset = self + .optimize_for_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn go_package(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .go_package_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn cc_generic_services(&self) -> roto_runtime::Result { + let offset = self + .cc_generic_services_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn java_generic_services(&self) -> roto_runtime::Result { + let offset = self + .java_generic_services_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn py_generic_services(&self) -> roto_runtime::Result { + let offset = self + .py_generic_services_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn deprecated(&self) -> roto_runtime::Result { + let offset = self + .deprecated_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn cc_enable_arenas(&self) -> roto_runtime::Result { + let offset = self + .cc_enable_arenas_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn objc_class_prefix(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .objc_class_prefix_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn csharp_namespace(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .csharp_namespace_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn swift_prefix(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .swift_prefix_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn php_class_prefix(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .php_class_prefix_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn php_namespace(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .php_namespace_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn php_metadata_namespace(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .php_metadata_namespace_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn ruby_package(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .ruby_package_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn features(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .features_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn uninterpreted_option(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match ( + self.uninterpreted_option_start, + self.uninterpreted_option_end, + ) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(999, start, end), + _ => self.accessor.iter_repeated(999), + } + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct FileOptionsBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + java_package_written: bool, + java_outer_classname_written: bool, + java_multiple_files_written: bool, + java_generate_equals_and_hash_written: bool, + java_string_check_utf8_written: bool, + optimize_for_written: bool, + go_package_written: bool, + cc_generic_services_written: bool, + java_generic_services_written: bool, + py_generic_services_written: bool, + deprecated_written: bool, + cc_enable_arenas_written: bool, + objc_class_prefix_written: bool, + csharp_namespace_written: bool, + swift_prefix_written: bool, + php_class_prefix_written: bool, + php_namespace_written: bool, + php_metadata_namespace_written: bool, + ruby_package_written: bool, + features_written: bool, + uninterpreted_option_written: bool, +} + +impl<'b> FileOptionsBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> FileOptionsBuilder<'_> { + FileOptionsBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + java_package_written: false, + java_outer_classname_written: false, + java_multiple_files_written: false, + java_generate_equals_and_hash_written: false, + java_string_check_utf8_written: false, + optimize_for_written: false, + go_package_written: false, + cc_generic_services_written: false, + java_generic_services_written: false, + py_generic_services_written: false, + deprecated_written: false, + cc_enable_arenas_written: false, + objc_class_prefix_written: false, + csharp_namespace_written: false, + swift_prefix_written: false, + php_class_prefix_written: false, + php_namespace_written: false, + php_metadata_namespace_written: false, + ruby_package_written: false, + features_written: false, + uninterpreted_option_written: false, + } + } + + pub fn java_package(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(1, value)?; + self.java_package_written = true; + Ok(self) + } + + pub fn java_outer_classname(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(8, value)?; + self.java_outer_classname_written = true; + Ok(self) + } + + pub fn java_multiple_files(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(10, value)?; + self.java_multiple_files_written = true; + Ok(self) + } + + pub fn java_generate_equals_and_hash(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(20, value)?; + self.java_generate_equals_and_hash_written = true; + Ok(self) + } + + pub fn java_string_check_utf8(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(27, value)?; + self.java_string_check_utf8_written = true; + Ok(self) + } + + pub fn optimize_for(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(9, value)?; + self.optimize_for_written = true; + Ok(self) + } + + pub fn go_package(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(11, value)?; + self.go_package_written = true; + Ok(self) + } + + pub fn cc_generic_services(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(16, value)?; + self.cc_generic_services_written = true; + Ok(self) + } + + pub fn java_generic_services(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(17, value)?; + self.java_generic_services_written = true; + Ok(self) + } + + pub fn py_generic_services(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(18, value)?; + self.py_generic_services_written = true; + Ok(self) + } + + pub fn deprecated(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(23, value)?; + self.deprecated_written = true; + Ok(self) + } + + pub fn cc_enable_arenas(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(31, value)?; + self.cc_enable_arenas_written = true; + Ok(self) + } + + pub fn objc_class_prefix(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(36, value)?; + self.objc_class_prefix_written = true; + Ok(self) + } + + pub fn csharp_namespace(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(37, value)?; + self.csharp_namespace_written = true; + Ok(self) + } + + pub fn swift_prefix(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(39, value)?; + self.swift_prefix_written = true; + Ok(self) + } + + pub fn php_class_prefix(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(40, value)?; + self.php_class_prefix_written = true; + Ok(self) + } + + pub fn php_namespace(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(41, value)?; + self.php_namespace_written = true; + Ok(self) + } + + pub fn php_metadata_namespace(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(44, value)?; + self.php_metadata_namespace_written = true; + Ok(self) + } + + pub fn ruby_package(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(45, value)?; + self.ruby_package_written = true; + Ok(self) + } + + pub fn features(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(50, value)?; + self.features_written = true; + Ok(self) + } + + pub fn uninterpreted_option(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(999, value)?; + self.uninterpreted_option_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &FileOptions<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.java_package_written, + 8 => self.java_outer_classname_written, + 10 => self.java_multiple_files_written, + 20 => self.java_generate_equals_and_hash_written, + 27 => self.java_string_check_utf8_written, + 9 => self.optimize_for_written, + 11 => self.go_package_written, + 16 => self.cc_generic_services_written, + 17 => self.java_generic_services_written, + 18 => self.py_generic_services_written, + 23 => self.deprecated_written, + 31 => self.cc_enable_arenas_written, + 36 => self.objc_class_prefix_written, + 37 => self.csharp_namespace_written, + 39 => self.swift_prefix_written, + 40 => self.php_class_prefix_written, + 41 => self.php_namespace_written, + 44 => self.php_metadata_namespace_written, + 45 => self.ruby_package_written, + 50 => self.features_written, + 999 => self.uninterpreted_option_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub mod file_options { + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum OptimizeMode { + SPEED = 1, + CODESIZE = 2, + LITERUNTIME = 3, + Unknown = 0, + } + + impl OptimizeMode { + pub fn from_i32(value: i32) -> Self { + match value { + 1 => OptimizeMode::SPEED, + 2 => OptimizeMode::CODESIZE, + 3 => OptimizeMode::LITERUNTIME, + _ => OptimizeMode::Unknown, + } + } + } +} + +pub struct MessageOptions<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + message_set_wire_format_offset: Option, + no_standard_descriptor_accessor_offset: Option, + deprecated_offset: Option, + map_entry_offset: Option, + deprecated_legacy_json_field_conflicts_offset: Option, + features_offset: Option, + uninterpreted_option_start: Option, + uninterpreted_option_end: Option, +} + +impl<'a> MessageOptions<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut message_set_wire_format_offset = None; + let mut no_standard_descriptor_accessor_offset = None; + let mut deprecated_offset = None; + let mut map_entry_offset = None; + let mut deprecated_legacy_json_field_conflicts_offset = None; + let mut features_offset = None; + let mut uninterpreted_option_start = None; + let mut uninterpreted_option_end = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + message_set_wire_format_offset = Some(offset); + } + if tag.field_number == 2 { + no_standard_descriptor_accessor_offset = Some(offset); + } + if tag.field_number == 3 { + deprecated_offset = Some(offset); + } + if tag.field_number == 7 { + map_entry_offset = Some(offset); + } + if tag.field_number == 11 { + deprecated_legacy_json_field_conflicts_offset = Some(offset); + } + if tag.field_number == 12 { + features_offset = Some(offset); + } + if tag.field_number == 999 { + if uninterpreted_option_start.is_none() { + uninterpreted_option_start = Some(offset); + } + uninterpreted_option_end = Some(offset); + } + } + + Ok(Self { + accessor, + message_set_wire_format_offset, + no_standard_descriptor_accessor_offset, + deprecated_offset, + map_entry_offset, + deprecated_legacy_json_field_conflicts_offset, + features_offset, + uninterpreted_option_start, + uninterpreted_option_end, + }) + } + + pub fn message_set_wire_format(&self) -> roto_runtime::Result { + let offset = self + .message_set_wire_format_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn no_standard_descriptor_accessor(&self) -> roto_runtime::Result { + let offset = self + .no_standard_descriptor_accessor_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn deprecated(&self) -> roto_runtime::Result { + let offset = self + .deprecated_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn map_entry(&self) -> roto_runtime::Result { + let offset = self + .map_entry_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn deprecated_legacy_json_field_conflicts(&self) -> roto_runtime::Result { + let offset = self + .deprecated_legacy_json_field_conflicts_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn features(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .features_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn uninterpreted_option(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match ( + self.uninterpreted_option_start, + self.uninterpreted_option_end, + ) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(999, start, end), + _ => self.accessor.iter_repeated(999), + } + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct MessageOptionsBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + message_set_wire_format_written: bool, + no_standard_descriptor_accessor_written: bool, + deprecated_written: bool, + map_entry_written: bool, + deprecated_legacy_json_field_conflicts_written: bool, + features_written: bool, + uninterpreted_option_written: bool, +} + +impl<'b> MessageOptionsBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> MessageOptionsBuilder<'_> { + MessageOptionsBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + message_set_wire_format_written: false, + no_standard_descriptor_accessor_written: false, + deprecated_written: false, + map_entry_written: false, + deprecated_legacy_json_field_conflicts_written: false, + features_written: false, + uninterpreted_option_written: false, + } + } + + pub fn message_set_wire_format(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(1, value)?; + self.message_set_wire_format_written = true; + Ok(self) + } + + pub fn no_standard_descriptor_accessor(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(2, value)?; + self.no_standard_descriptor_accessor_written = true; + Ok(self) + } + + pub fn deprecated(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(3, value)?; + self.deprecated_written = true; + Ok(self) + } + + pub fn map_entry(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(7, value)?; + self.map_entry_written = true; + Ok(self) + } + + pub fn deprecated_legacy_json_field_conflicts( + mut self, + value: u64, + ) -> roto_runtime::Result { + self.builder.write_varint(11, value)?; + self.deprecated_legacy_json_field_conflicts_written = true; + Ok(self) + } + + pub fn features(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(12, value)?; + self.features_written = true; + Ok(self) + } + + pub fn uninterpreted_option(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(999, value)?; + self.uninterpreted_option_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &MessageOptions<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.message_set_wire_format_written, + 2 => self.no_standard_descriptor_accessor_written, + 3 => self.deprecated_written, + 7 => self.map_entry_written, + 11 => self.deprecated_legacy_json_field_conflicts_written, + 12 => self.features_written, + 999 => self.uninterpreted_option_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub struct FieldOptions<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + ctype_offset: Option, + packed_offset: Option, + jstype_offset: Option, + lazy_offset: Option, + unverified_lazy_offset: Option, + deprecated_offset: Option, + weak_offset: Option, + debug_redact_offset: Option, + retention_offset: Option, + targets_start: Option, + targets_end: Option, + edition_defaults_start: Option, + edition_defaults_end: Option, + features_offset: Option, + feature_support_offset: Option, + uninterpreted_option_start: Option, + uninterpreted_option_end: Option, +} + +impl<'a> FieldOptions<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut ctype_offset = None; + let mut packed_offset = None; + let mut jstype_offset = None; + let mut lazy_offset = None; + let mut unverified_lazy_offset = None; + let mut deprecated_offset = None; + let mut weak_offset = None; + let mut debug_redact_offset = None; + let mut retention_offset = None; + let mut targets_start = None; + let mut targets_end = None; + let mut edition_defaults_start = None; + let mut edition_defaults_end = None; + let mut features_offset = None; + let mut feature_support_offset = None; + let mut uninterpreted_option_start = None; + let mut uninterpreted_option_end = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + ctype_offset = Some(offset); + } + if tag.field_number == 2 { + packed_offset = Some(offset); + } + if tag.field_number == 6 { + jstype_offset = Some(offset); + } + if tag.field_number == 5 { + lazy_offset = Some(offset); + } + if tag.field_number == 15 { + unverified_lazy_offset = Some(offset); + } + if tag.field_number == 3 { + deprecated_offset = Some(offset); + } + if tag.field_number == 10 { + weak_offset = Some(offset); + } + if tag.field_number == 16 { + debug_redact_offset = Some(offset); + } + if tag.field_number == 17 { + retention_offset = Some(offset); + } + if tag.field_number == 19 { + if targets_start.is_none() { + targets_start = Some(offset); + } + targets_end = Some(offset); + } + if tag.field_number == 20 { + if edition_defaults_start.is_none() { + edition_defaults_start = Some(offset); + } + edition_defaults_end = Some(offset); + } + if tag.field_number == 21 { + features_offset = Some(offset); + } + if tag.field_number == 22 { + feature_support_offset = Some(offset); + } + if tag.field_number == 999 { + if uninterpreted_option_start.is_none() { + uninterpreted_option_start = Some(offset); + } + uninterpreted_option_end = Some(offset); + } + } + + Ok(Self { + accessor, + ctype_offset, + packed_offset, + jstype_offset, + lazy_offset, + unverified_lazy_offset, + deprecated_offset, + weak_offset, + debug_redact_offset, + retention_offset, + targets_start, + targets_end, + edition_defaults_start, + edition_defaults_end, + features_offset, + feature_support_offset, + uninterpreted_option_start, + uninterpreted_option_end, + }) + } + + pub fn ctype(&self) -> roto_runtime::Result { + let offset = self + .ctype_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn packed(&self) -> roto_runtime::Result { + let offset = self + .packed_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn jstype(&self) -> roto_runtime::Result { + let offset = self + .jstype_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn lazy(&self) -> roto_runtime::Result { + let offset = self + .lazy_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn unverified_lazy(&self) -> roto_runtime::Result { + let offset = self + .unverified_lazy_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn deprecated(&self) -> roto_runtime::Result { + let offset = self + .deprecated_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn weak(&self) -> roto_runtime::Result { + let offset = self + .weak_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn debug_redact(&self) -> roto_runtime::Result { + let offset = self + .debug_redact_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn retention(&self) -> roto_runtime::Result { + let offset = self + .retention_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn targets(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.targets_start, self.targets_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(19, start, end), + _ => self.accessor.iter_repeated(19), + } + } + + pub fn edition_defaults(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.edition_defaults_start, self.edition_defaults_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(20, start, end), + _ => self.accessor.iter_repeated(20), + } + } + + pub fn features(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .features_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn feature_support(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .feature_support_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn uninterpreted_option(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match ( + self.uninterpreted_option_start, + self.uninterpreted_option_end, + ) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(999, start, end), + _ => self.accessor.iter_repeated(999), + } + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct FieldOptionsBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + ctype_written: bool, + packed_written: bool, + jstype_written: bool, + lazy_written: bool, + unverified_lazy_written: bool, + deprecated_written: bool, + weak_written: bool, + debug_redact_written: bool, + retention_written: bool, + targets_written: bool, + edition_defaults_written: bool, + features_written: bool, + feature_support_written: bool, + uninterpreted_option_written: bool, +} + +impl<'b> FieldOptionsBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> FieldOptionsBuilder<'_> { + FieldOptionsBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + ctype_written: false, + packed_written: false, + jstype_written: false, + lazy_written: false, + unverified_lazy_written: false, + deprecated_written: false, + weak_written: false, + debug_redact_written: false, + retention_written: false, + targets_written: false, + edition_defaults_written: false, + features_written: false, + feature_support_written: false, + uninterpreted_option_written: false, + } + } + + pub fn ctype(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(1, value)?; + self.ctype_written = true; + Ok(self) + } + + pub fn packed(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(2, value)?; + self.packed_written = true; + Ok(self) + } + + pub fn jstype(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(6, value)?; + self.jstype_written = true; + Ok(self) + } + + pub fn lazy(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(5, value)?; + self.lazy_written = true; + Ok(self) + } + + pub fn unverified_lazy(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(15, value)?; + self.unverified_lazy_written = true; + Ok(self) + } + + pub fn deprecated(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(3, value)?; + self.deprecated_written = true; + Ok(self) + } + + pub fn weak(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(10, value)?; + self.weak_written = true; + Ok(self) + } + + pub fn debug_redact(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(16, value)?; + self.debug_redact_written = true; + Ok(self) + } + + pub fn retention(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(17, value)?; + self.retention_written = true; + Ok(self) + } + + pub fn targets(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(19, value)?; + self.targets_written = true; + Ok(self) + } + + pub fn edition_defaults(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(20, value)?; + self.edition_defaults_written = true; + Ok(self) + } + + pub fn features(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(21, value)?; + self.features_written = true; + Ok(self) + } + + pub fn feature_support(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(22, value)?; + self.feature_support_written = true; + Ok(self) + } + + pub fn uninterpreted_option(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(999, value)?; + self.uninterpreted_option_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &FieldOptions<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.ctype_written, + 2 => self.packed_written, + 6 => self.jstype_written, + 5 => self.lazy_written, + 15 => self.unverified_lazy_written, + 3 => self.deprecated_written, + 10 => self.weak_written, + 16 => self.debug_redact_written, + 17 => self.retention_written, + 19 => self.targets_written, + 20 => self.edition_defaults_written, + 21 => self.features_written, + 22 => self.feature_support_written, + 999 => self.uninterpreted_option_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub mod field_options { + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum CType { + STRING = 0, + CORD = 1, + STRINGPIECE = 2, + } + + impl CType { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => CType::STRING, + 1 => CType::CORD, + 2 => CType::STRINGPIECE, + _ => CType::STRING, + } + } + } + + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum JSType { + JSNORMAL = 0, + JSSTRING = 1, + JSNUMBER = 2, + } + + impl JSType { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => JSType::JSNORMAL, + 1 => JSType::JSSTRING, + 2 => JSType::JSNUMBER, + _ => JSType::JSNORMAL, + } + } + } + + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum OptionRetention { + RETENTIONUNKNOWN = 0, + RETENTIONRUNTIME = 1, + RETENTIONSOURCE = 2, + } + + impl OptionRetention { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => OptionRetention::RETENTIONUNKNOWN, + 1 => OptionRetention::RETENTIONRUNTIME, + 2 => OptionRetention::RETENTIONSOURCE, + _ => OptionRetention::RETENTIONUNKNOWN, + } + } + } + + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum OptionTargetType { + TARGETTYPEUNKNOWN = 0, + TARGETTYPEFILE = 1, + TARGETTYPEEXTENSIONRANGE = 2, + TARGETTYPEMESSAGE = 3, + TARGETTYPEFIELD = 4, + TARGETTYPEONEOF = 5, + TARGETTYPEENUM = 6, + TARGETTYPEENUMENTRY = 7, + TARGETTYPESERVICE = 8, + TARGETTYPEMETHOD = 9, + } + + impl OptionTargetType { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => OptionTargetType::TARGETTYPEUNKNOWN, + 1 => OptionTargetType::TARGETTYPEFILE, + 2 => OptionTargetType::TARGETTYPEEXTENSIONRANGE, + 3 => OptionTargetType::TARGETTYPEMESSAGE, + 4 => OptionTargetType::TARGETTYPEFIELD, + 5 => OptionTargetType::TARGETTYPEONEOF, + 6 => OptionTargetType::TARGETTYPEENUM, + 7 => OptionTargetType::TARGETTYPEENUMENTRY, + 8 => OptionTargetType::TARGETTYPESERVICE, + 9 => OptionTargetType::TARGETTYPEMETHOD, + _ => OptionTargetType::TARGETTYPEUNKNOWN, + } + } + } + + pub struct EditionDefault<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + edition_offset: Option, + value_offset: Option, + } + + impl<'a> EditionDefault<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut edition_offset = None; + let mut value_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 3 { + edition_offset = Some(offset); + } + if tag.field_number == 2 { + value_offset = Some(offset); + } + } + + Ok(Self { + accessor, + edition_offset, + value_offset, + }) + } + + pub fn edition(&self) -> roto_runtime::Result { + let offset = self + .edition_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn value(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .value_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } + } + + pub struct EditionDefaultBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + edition_written: bool, + value_written: bool, + } + + impl<'b> EditionDefaultBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> EditionDefaultBuilder<'_> { + EditionDefaultBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + edition_written: false, + value_written: false, + } + } + + pub fn edition(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(3, value)?; + self.edition_written = true; + Ok(self) + } + + pub fn value(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(2, value)?; + self.value_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &EditionDefault<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 3 => self.edition_written, + 2 => self.value_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } + } + + pub struct FeatureSupport<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + edition_introduced_offset: Option, + edition_deprecated_offset: Option, + deprecation_warning_offset: Option, + edition_removed_offset: Option, + removal_error_offset: Option, + } + + impl<'a> FeatureSupport<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut edition_introduced_offset = None; + let mut edition_deprecated_offset = None; + let mut deprecation_warning_offset = None; + let mut edition_removed_offset = None; + let mut removal_error_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + edition_introduced_offset = Some(offset); + } + if tag.field_number == 2 { + edition_deprecated_offset = Some(offset); + } + if tag.field_number == 3 { + deprecation_warning_offset = Some(offset); + } + if tag.field_number == 4 { + edition_removed_offset = Some(offset); + } + if tag.field_number == 5 { + removal_error_offset = Some(offset); + } + } + + Ok(Self { + accessor, + edition_introduced_offset, + edition_deprecated_offset, + deprecation_warning_offset, + edition_removed_offset, + removal_error_offset, + }) + } + + pub fn edition_introduced(&self) -> roto_runtime::Result { + let offset = self + .edition_introduced_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn edition_deprecated(&self) -> roto_runtime::Result { + let offset = self + .edition_deprecated_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn deprecation_warning(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .deprecation_warning_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn edition_removed(&self) -> roto_runtime::Result { + let offset = self + .edition_removed_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn removal_error(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .removal_error_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } + } + + pub struct FeatureSupportBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + edition_introduced_written: bool, + edition_deprecated_written: bool, + deprecation_warning_written: bool, + edition_removed_written: bool, + removal_error_written: bool, + } + + impl<'b> FeatureSupportBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> FeatureSupportBuilder<'_> { + FeatureSupportBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + edition_introduced_written: false, + edition_deprecated_written: false, + deprecation_warning_written: false, + edition_removed_written: false, + removal_error_written: false, + } + } + + pub fn edition_introduced(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(1, value)?; + self.edition_introduced_written = true; + Ok(self) + } + + pub fn edition_deprecated(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(2, value)?; + self.edition_deprecated_written = true; + Ok(self) + } + + pub fn deprecation_warning(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(3, value)?; + self.deprecation_warning_written = true; + Ok(self) + } + + pub fn edition_removed(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(4, value)?; + self.edition_removed_written = true; + Ok(self) + } + + pub fn removal_error(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(5, value)?; + self.removal_error_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &FeatureSupport<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.edition_introduced_written, + 2 => self.edition_deprecated_written, + 3 => self.deprecation_warning_written, + 4 => self.edition_removed_written, + 5 => self.removal_error_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } + } +} + +pub struct OneofOptions<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + features_offset: Option, + uninterpreted_option_start: Option, + uninterpreted_option_end: Option, +} + +impl<'a> OneofOptions<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut features_offset = None; + let mut uninterpreted_option_start = None; + let mut uninterpreted_option_end = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + features_offset = Some(offset); + } + if tag.field_number == 999 { + if uninterpreted_option_start.is_none() { + uninterpreted_option_start = Some(offset); + } + uninterpreted_option_end = Some(offset); + } + } + + Ok(Self { + accessor, + features_offset, + uninterpreted_option_start, + uninterpreted_option_end, + }) + } + + pub fn features(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .features_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn uninterpreted_option(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match ( + self.uninterpreted_option_start, + self.uninterpreted_option_end, + ) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(999, start, end), + _ => self.accessor.iter_repeated(999), + } + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct OneofOptionsBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + features_written: bool, + uninterpreted_option_written: bool, +} + +impl<'b> OneofOptionsBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> OneofOptionsBuilder<'_> { + OneofOptionsBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + features_written: false, + uninterpreted_option_written: false, + } + } + + pub fn features(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(1, value)?; + self.features_written = true; + Ok(self) + } + + pub fn uninterpreted_option(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(999, value)?; + self.uninterpreted_option_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &OneofOptions<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.features_written, + 999 => self.uninterpreted_option_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub struct EnumOptions<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + allow_alias_offset: Option, + deprecated_offset: Option, + deprecated_legacy_json_field_conflicts_offset: Option, + features_offset: Option, + uninterpreted_option_start: Option, + uninterpreted_option_end: Option, +} + +impl<'a> EnumOptions<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut allow_alias_offset = None; + let mut deprecated_offset = None; + let mut deprecated_legacy_json_field_conflicts_offset = None; + let mut features_offset = None; + let mut uninterpreted_option_start = None; + let mut uninterpreted_option_end = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 2 { + allow_alias_offset = Some(offset); + } + if tag.field_number == 3 { + deprecated_offset = Some(offset); + } + if tag.field_number == 6 { + deprecated_legacy_json_field_conflicts_offset = Some(offset); + } + if tag.field_number == 7 { + features_offset = Some(offset); + } + if tag.field_number == 999 { + if uninterpreted_option_start.is_none() { + uninterpreted_option_start = Some(offset); + } + uninterpreted_option_end = Some(offset); + } + } + + Ok(Self { + accessor, + allow_alias_offset, + deprecated_offset, + deprecated_legacy_json_field_conflicts_offset, + features_offset, + uninterpreted_option_start, + uninterpreted_option_end, + }) + } + + pub fn allow_alias(&self) -> roto_runtime::Result { + let offset = self + .allow_alias_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn deprecated(&self) -> roto_runtime::Result { + let offset = self + .deprecated_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn deprecated_legacy_json_field_conflicts(&self) -> roto_runtime::Result { + let offset = self + .deprecated_legacy_json_field_conflicts_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn features(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .features_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn uninterpreted_option(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match ( + self.uninterpreted_option_start, + self.uninterpreted_option_end, + ) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(999, start, end), + _ => self.accessor.iter_repeated(999), + } + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct EnumOptionsBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + allow_alias_written: bool, + deprecated_written: bool, + deprecated_legacy_json_field_conflicts_written: bool, + features_written: bool, + uninterpreted_option_written: bool, +} + +impl<'b> EnumOptionsBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> EnumOptionsBuilder<'_> { + EnumOptionsBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + allow_alias_written: false, + deprecated_written: false, + deprecated_legacy_json_field_conflicts_written: false, + features_written: false, + uninterpreted_option_written: false, + } + } + + pub fn allow_alias(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(2, value)?; + self.allow_alias_written = true; + Ok(self) + } + + pub fn deprecated(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(3, value)?; + self.deprecated_written = true; + Ok(self) + } + + pub fn deprecated_legacy_json_field_conflicts( + mut self, + value: u64, + ) -> roto_runtime::Result { + self.builder.write_varint(6, value)?; + self.deprecated_legacy_json_field_conflicts_written = true; + Ok(self) + } + + pub fn features(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(7, value)?; + self.features_written = true; + Ok(self) + } + + pub fn uninterpreted_option(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(999, value)?; + self.uninterpreted_option_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &EnumOptions<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 2 => self.allow_alias_written, + 3 => self.deprecated_written, + 6 => self.deprecated_legacy_json_field_conflicts_written, + 7 => self.features_written, + 999 => self.uninterpreted_option_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub struct EnumValueOptions<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + deprecated_offset: Option, + features_offset: Option, + debug_redact_offset: Option, + feature_support_offset: Option, + uninterpreted_option_start: Option, + uninterpreted_option_end: Option, +} + +impl<'a> EnumValueOptions<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut deprecated_offset = None; + let mut features_offset = None; + let mut debug_redact_offset = None; + let mut feature_support_offset = None; + let mut uninterpreted_option_start = None; + let mut uninterpreted_option_end = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + deprecated_offset = Some(offset); + } + if tag.field_number == 2 { + features_offset = Some(offset); + } + if tag.field_number == 3 { + debug_redact_offset = Some(offset); + } + if tag.field_number == 4 { + feature_support_offset = Some(offset); + } + if tag.field_number == 999 { + if uninterpreted_option_start.is_none() { + uninterpreted_option_start = Some(offset); + } + uninterpreted_option_end = Some(offset); + } + } + + Ok(Self { + accessor, + deprecated_offset, + features_offset, + debug_redact_offset, + feature_support_offset, + uninterpreted_option_start, + uninterpreted_option_end, + }) + } + + pub fn deprecated(&self) -> roto_runtime::Result { + let offset = self + .deprecated_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn features(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .features_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn debug_redact(&self) -> roto_runtime::Result { + let offset = self + .debug_redact_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn feature_support(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .feature_support_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn uninterpreted_option(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match ( + self.uninterpreted_option_start, + self.uninterpreted_option_end, + ) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(999, start, end), + _ => self.accessor.iter_repeated(999), + } + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct EnumValueOptionsBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + deprecated_written: bool, + features_written: bool, + debug_redact_written: bool, + feature_support_written: bool, + uninterpreted_option_written: bool, +} + +impl<'b> EnumValueOptionsBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> EnumValueOptionsBuilder<'_> { + EnumValueOptionsBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + deprecated_written: false, + features_written: false, + debug_redact_written: false, + feature_support_written: false, + uninterpreted_option_written: false, + } + } + + pub fn deprecated(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(1, value)?; + self.deprecated_written = true; + Ok(self) + } + + pub fn features(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(2, value)?; + self.features_written = true; + Ok(self) + } + + pub fn debug_redact(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(3, value)?; + self.debug_redact_written = true; + Ok(self) + } + + pub fn feature_support(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(4, value)?; + self.feature_support_written = true; + Ok(self) + } + + pub fn uninterpreted_option(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(999, value)?; + self.uninterpreted_option_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &EnumValueOptions<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.deprecated_written, + 2 => self.features_written, + 3 => self.debug_redact_written, + 4 => self.feature_support_written, + 999 => self.uninterpreted_option_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub struct ServiceOptions<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + features_offset: Option, + deprecated_offset: Option, + uninterpreted_option_start: Option, + uninterpreted_option_end: Option, +} + +impl<'a> ServiceOptions<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut features_offset = None; + let mut deprecated_offset = None; + let mut uninterpreted_option_start = None; + let mut uninterpreted_option_end = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 34 { + features_offset = Some(offset); + } + if tag.field_number == 33 { + deprecated_offset = Some(offset); + } + if tag.field_number == 999 { + if uninterpreted_option_start.is_none() { + uninterpreted_option_start = Some(offset); + } + uninterpreted_option_end = Some(offset); + } + } + + Ok(Self { + accessor, + features_offset, + deprecated_offset, + uninterpreted_option_start, + uninterpreted_option_end, + }) + } + + pub fn features(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .features_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn deprecated(&self) -> roto_runtime::Result { + let offset = self + .deprecated_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn uninterpreted_option(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match ( + self.uninterpreted_option_start, + self.uninterpreted_option_end, + ) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(999, start, end), + _ => self.accessor.iter_repeated(999), + } + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct ServiceOptionsBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + features_written: bool, + deprecated_written: bool, + uninterpreted_option_written: bool, +} + +impl<'b> ServiceOptionsBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> ServiceOptionsBuilder<'_> { + ServiceOptionsBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + features_written: false, + deprecated_written: false, + uninterpreted_option_written: false, + } + } + + pub fn features(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(34, value)?; + self.features_written = true; + Ok(self) + } + + pub fn deprecated(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(33, value)?; + self.deprecated_written = true; + Ok(self) + } + + pub fn uninterpreted_option(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(999, value)?; + self.uninterpreted_option_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &ServiceOptions<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 34 => self.features_written, + 33 => self.deprecated_written, + 999 => self.uninterpreted_option_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub struct MethodOptions<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + deprecated_offset: Option, + idempotency_level_offset: Option, + features_offset: Option, + uninterpreted_option_start: Option, + uninterpreted_option_end: Option, +} + +impl<'a> MethodOptions<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut deprecated_offset = None; + let mut idempotency_level_offset = None; + let mut features_offset = None; + let mut uninterpreted_option_start = None; + let mut uninterpreted_option_end = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 33 { + deprecated_offset = Some(offset); + } + if tag.field_number == 34 { + idempotency_level_offset = Some(offset); + } + if tag.field_number == 35 { + features_offset = Some(offset); + } + if tag.field_number == 999 { + if uninterpreted_option_start.is_none() { + uninterpreted_option_start = Some(offset); + } + uninterpreted_option_end = Some(offset); + } + } + + Ok(Self { + accessor, + deprecated_offset, + idempotency_level_offset, + features_offset, + uninterpreted_option_start, + uninterpreted_option_end, + }) + } + + pub fn deprecated(&self) -> roto_runtime::Result { + let offset = self + .deprecated_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn idempotency_level(&self) -> roto_runtime::Result { + let offset = self + .idempotency_level_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn features(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .features_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn uninterpreted_option(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match ( + self.uninterpreted_option_start, + self.uninterpreted_option_end, + ) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(999, start, end), + _ => self.accessor.iter_repeated(999), + } + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct MethodOptionsBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + deprecated_written: bool, + idempotency_level_written: bool, + features_written: bool, + uninterpreted_option_written: bool, +} + +impl<'b> MethodOptionsBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> MethodOptionsBuilder<'_> { + MethodOptionsBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + deprecated_written: false, + idempotency_level_written: false, + features_written: false, + uninterpreted_option_written: false, + } + } + + pub fn deprecated(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(33, value)?; + self.deprecated_written = true; + Ok(self) + } + + pub fn idempotency_level(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(34, value)?; + self.idempotency_level_written = true; + Ok(self) + } + + pub fn features(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(35, value)?; + self.features_written = true; + Ok(self) + } + + pub fn uninterpreted_option(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(999, value)?; + self.uninterpreted_option_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &MethodOptions<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 33 => self.deprecated_written, + 34 => self.idempotency_level_written, + 35 => self.features_written, + 999 => self.uninterpreted_option_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub mod method_options { + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum IdempotencyLevel { + IDEMPOTENCYUNKNOWN = 0, + NOSIDEEFFECTS = 1, + IDEMPOTENT = 2, + } + + impl IdempotencyLevel { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => IdempotencyLevel::IDEMPOTENCYUNKNOWN, + 1 => IdempotencyLevel::NOSIDEEFFECTS, + 2 => IdempotencyLevel::IDEMPOTENT, + _ => IdempotencyLevel::IDEMPOTENCYUNKNOWN, + } + } + } +} + +pub struct UninterpretedOption<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + name_start: Option, + name_end: Option, + identifier_value_offset: Option, + positive_int_value_offset: Option, + negative_int_value_offset: Option, + double_value_offset: Option, + string_value_offset: Option, + aggregate_value_offset: Option, +} + +impl<'a> UninterpretedOption<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut name_start = None; + let mut name_end = None; + let mut identifier_value_offset = None; + let mut positive_int_value_offset = None; + let mut negative_int_value_offset = None; + let mut double_value_offset = None; + let mut string_value_offset = None; + let mut aggregate_value_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 2 { + if name_start.is_none() { + name_start = Some(offset); + } + name_end = Some(offset); + } + if tag.field_number == 3 { + identifier_value_offset = Some(offset); + } + if tag.field_number == 4 { + positive_int_value_offset = Some(offset); + } + if tag.field_number == 5 { + negative_int_value_offset = Some(offset); + } + if tag.field_number == 6 { + double_value_offset = Some(offset); + } + if tag.field_number == 7 { + string_value_offset = Some(offset); + } + if tag.field_number == 8 { + aggregate_value_offset = Some(offset); + } + } + + Ok(Self { + accessor, + name_start, + name_end, + identifier_value_offset, + positive_int_value_offset, + negative_int_value_offset, + double_value_offset, + string_value_offset, + aggregate_value_offset, + }) + } + + pub fn name(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.name_start, self.name_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(2, start, end), + _ => self.accessor.iter_repeated(2), + } + } + + pub fn identifier_value(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .identifier_value_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn positive_int_value(&self) -> roto_runtime::Result { + let offset = self + .positive_int_value_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn negative_int_value(&self) -> roto_runtime::Result { + let offset = self + .negative_int_value_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn double_value(&self) -> roto_runtime::Result { + let offset = self + .double_value_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(f64::from_le_bytes(bytes.try_into().map_err(|_| { + roto_runtime::RotoError::WireFormatViolation + })?)) + } + + pub fn string_value(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .string_value_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn aggregate_value(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .aggregate_value_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct UninterpretedOptionBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + name_written: bool, + identifier_value_written: bool, + positive_int_value_written: bool, + negative_int_value_written: bool, + double_value_written: bool, + string_value_written: bool, + aggregate_value_written: bool, +} + +impl<'b> UninterpretedOptionBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> UninterpretedOptionBuilder<'_> { + UninterpretedOptionBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + name_written: false, + identifier_value_written: false, + positive_int_value_written: false, + negative_int_value_written: false, + double_value_written: false, + string_value_written: false, + aggregate_value_written: false, + } + } + + pub fn name(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(2, value)?; + self.name_written = true; + Ok(self) + } + + pub fn identifier_value(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(3, value)?; + self.identifier_value_written = true; + Ok(self) + } + + pub fn positive_int_value(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(4, value)?; + self.positive_int_value_written = true; + Ok(self) + } + + pub fn negative_int_value(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(5, value)?; + self.negative_int_value_written = true; + Ok(self) + } + + pub fn double_value(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(6, value)?; + self.double_value_written = true; + Ok(self) + } + + pub fn string_value(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(7, value)?; + self.string_value_written = true; + Ok(self) + } + + pub fn aggregate_value(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(8, value)?; + self.aggregate_value_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &UninterpretedOption<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 2 => self.name_written, + 3 => self.identifier_value_written, + 4 => self.positive_int_value_written, + 5 => self.negative_int_value_written, + 6 => self.double_value_written, + 7 => self.string_value_written, + 8 => self.aggregate_value_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub mod uninterpreted_option { + pub struct NamePart<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + name_part_offset: Option, + is_extension_offset: Option, + } + + impl<'a> NamePart<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut name_part_offset = None; + let mut is_extension_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + name_part_offset = Some(offset); + } + if tag.field_number == 2 { + is_extension_offset = Some(offset); + } + } + + Ok(Self { + accessor, + name_part_offset, + is_extension_offset, + }) + } + + pub fn name_part(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .name_part_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn is_extension(&self) -> roto_runtime::Result { + let offset = self + .is_extension_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v != 0) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } + } + + pub struct NamePartBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + name_part_written: bool, + is_extension_written: bool, + } + + impl<'b> NamePartBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> NamePartBuilder<'_> { + NamePartBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + name_part_written: false, + is_extension_written: false, + } + } + + pub fn name_part(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(1, value)?; + self.name_part_written = true; + Ok(self) + } + + pub fn is_extension(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(2, value)?; + self.is_extension_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &NamePart<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.name_part_written, + 2 => self.is_extension_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } + } +} + +pub struct FeatureSet<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + field_presence_offset: Option, + enum_type_offset: Option, + repeated_field_encoding_offset: Option, + utf8_validation_offset: Option, + message_encoding_offset: Option, + json_format_offset: Option, + enforce_naming_style_offset: Option, + default_symbol_visibility_offset: Option, + enforce_proto_limits_offset: Option, +} + +impl<'a> FeatureSet<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut field_presence_offset = None; + let mut enum_type_offset = None; + let mut repeated_field_encoding_offset = None; + let mut utf8_validation_offset = None; + let mut message_encoding_offset = None; + let mut json_format_offset = None; + let mut enforce_naming_style_offset = None; + let mut default_symbol_visibility_offset = None; + let mut enforce_proto_limits_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + field_presence_offset = Some(offset); + } + if tag.field_number == 2 { + enum_type_offset = Some(offset); + } + if tag.field_number == 3 { + repeated_field_encoding_offset = Some(offset); + } + if tag.field_number == 4 { + utf8_validation_offset = Some(offset); + } + if tag.field_number == 5 { + message_encoding_offset = Some(offset); + } + if tag.field_number == 6 { + json_format_offset = Some(offset); + } + if tag.field_number == 7 { + enforce_naming_style_offset = Some(offset); + } + if tag.field_number == 8 { + default_symbol_visibility_offset = Some(offset); + } + if tag.field_number == 9 { + enforce_proto_limits_offset = Some(offset); + } + } + + Ok(Self { + accessor, + field_presence_offset, + enum_type_offset, + repeated_field_encoding_offset, + utf8_validation_offset, + message_encoding_offset, + json_format_offset, + enforce_naming_style_offset, + default_symbol_visibility_offset, + enforce_proto_limits_offset, + }) + } + + pub fn field_presence(&self) -> roto_runtime::Result { + let offset = self + .field_presence_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn enum_type(&self) -> roto_runtime::Result { + let offset = self + .enum_type_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn repeated_field_encoding(&self) -> roto_runtime::Result { + let offset = self + .repeated_field_encoding_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn utf8_validation(&self) -> roto_runtime::Result { + let offset = self + .utf8_validation_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn message_encoding(&self) -> roto_runtime::Result { + let offset = self + .message_encoding_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn json_format(&self) -> roto_runtime::Result { + let offset = self + .json_format_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn enforce_naming_style(&self) -> roto_runtime::Result { + let offset = self + .enforce_naming_style_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn default_symbol_visibility(&self) -> roto_runtime::Result { + let offset = self + .default_symbol_visibility_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn enforce_proto_limits(&self) -> roto_runtime::Result { + let offset = self + .enforce_proto_limits_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct FeatureSetBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + field_presence_written: bool, + enum_type_written: bool, + repeated_field_encoding_written: bool, + utf8_validation_written: bool, + message_encoding_written: bool, + json_format_written: bool, + enforce_naming_style_written: bool, + default_symbol_visibility_written: bool, + enforce_proto_limits_written: bool, +} + +impl<'b> FeatureSetBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> FeatureSetBuilder<'_> { + FeatureSetBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + field_presence_written: false, + enum_type_written: false, + repeated_field_encoding_written: false, + utf8_validation_written: false, + message_encoding_written: false, + json_format_written: false, + enforce_naming_style_written: false, + default_symbol_visibility_written: false, + enforce_proto_limits_written: false, + } + } + + pub fn field_presence(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(1, value)?; + self.field_presence_written = true; + Ok(self) + } + + pub fn enum_type(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(2, value)?; + self.enum_type_written = true; + Ok(self) + } + + pub fn repeated_field_encoding(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(3, value)?; + self.repeated_field_encoding_written = true; + Ok(self) + } + + pub fn utf8_validation(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(4, value)?; + self.utf8_validation_written = true; + Ok(self) + } + + pub fn message_encoding(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(5, value)?; + self.message_encoding_written = true; + Ok(self) + } + + pub fn json_format(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(6, value)?; + self.json_format_written = true; + Ok(self) + } + + pub fn enforce_naming_style(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(7, value)?; + self.enforce_naming_style_written = true; + Ok(self) + } + + pub fn default_symbol_visibility(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(8, value)?; + self.default_symbol_visibility_written = true; + Ok(self) + } + + pub fn enforce_proto_limits(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(9, value)?; + self.enforce_proto_limits_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &FeatureSet<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.field_presence_written, + 2 => self.enum_type_written, + 3 => self.repeated_field_encoding_written, + 4 => self.utf8_validation_written, + 5 => self.message_encoding_written, + 6 => self.json_format_written, + 7 => self.enforce_naming_style_written, + 8 => self.default_symbol_visibility_written, + 9 => self.enforce_proto_limits_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub mod feature_set { + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum FieldPresence { + FIELDPRESENCEUNKNOWN = 0, + EXPLICIT = 1, + IMPLICIT = 2, + LEGACYREQUIRED = 3, + } + + impl FieldPresence { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => FieldPresence::FIELDPRESENCEUNKNOWN, + 1 => FieldPresence::EXPLICIT, + 2 => FieldPresence::IMPLICIT, + 3 => FieldPresence::LEGACYREQUIRED, + _ => FieldPresence::FIELDPRESENCEUNKNOWN, + } + } + } + + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum EnumType { + ENUMTYPEUNKNOWN = 0, + OPEN = 1, + CLOSED = 2, + } + + impl EnumType { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => EnumType::ENUMTYPEUNKNOWN, + 1 => EnumType::OPEN, + 2 => EnumType::CLOSED, + _ => EnumType::ENUMTYPEUNKNOWN, + } + } + } + + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum RepeatedFieldEncoding { + REPEATEDFIELDENCODINGUNKNOWN = 0, + PACKED = 1, + EXPANDED = 2, + } + + impl RepeatedFieldEncoding { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => RepeatedFieldEncoding::REPEATEDFIELDENCODINGUNKNOWN, + 1 => RepeatedFieldEncoding::PACKED, + 2 => RepeatedFieldEncoding::EXPANDED, + _ => RepeatedFieldEncoding::REPEATEDFIELDENCODINGUNKNOWN, + } + } + } + + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum Utf8Validation { + UTF8VALIDATIONUNKNOWN = 0, + VERIFY = 2, + NONE = 3, + } + + impl Utf8Validation { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => Utf8Validation::UTF8VALIDATIONUNKNOWN, + 2 => Utf8Validation::VERIFY, + 3 => Utf8Validation::NONE, + _ => Utf8Validation::UTF8VALIDATIONUNKNOWN, + } + } + } + + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum MessageEncoding { + MESSAGEENCODINGUNKNOWN = 0, + LENGTHPREFIXED = 1, + DELIMITED = 2, + } + + impl MessageEncoding { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => MessageEncoding::MESSAGEENCODINGUNKNOWN, + 1 => MessageEncoding::LENGTHPREFIXED, + 2 => MessageEncoding::DELIMITED, + _ => MessageEncoding::MESSAGEENCODINGUNKNOWN, + } + } + } + + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum JsonFormat { + JSONFORMATUNKNOWN = 0, + ALLOW = 1, + LEGACYBESTEFFORT = 2, + } + + impl JsonFormat { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => JsonFormat::JSONFORMATUNKNOWN, + 1 => JsonFormat::ALLOW, + 2 => JsonFormat::LEGACYBESTEFFORT, + _ => JsonFormat::JSONFORMATUNKNOWN, + } + } + } + + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum EnforceNamingStyle { + ENFORCENAMINGSTYLEUNKNOWN = 0, + STYLE2024 = 1, + STYLELEGACY = 2, + STYLE2026 = 3, + } + + impl EnforceNamingStyle { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => EnforceNamingStyle::ENFORCENAMINGSTYLEUNKNOWN, + 1 => EnforceNamingStyle::STYLE2024, + 2 => EnforceNamingStyle::STYLELEGACY, + 3 => EnforceNamingStyle::STYLE2026, + _ => EnforceNamingStyle::ENFORCENAMINGSTYLEUNKNOWN, + } + } + } + + pub struct VisibilityFeature<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + } + + impl<'a> VisibilityFeature<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + Ok(Self { accessor }) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } + } + + pub struct VisibilityFeatureBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + } + + impl<'b> VisibilityFeatureBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> VisibilityFeatureBuilder<'_> { + VisibilityFeatureBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + } + } + + pub fn with(mut self, msg: &VisibilityFeature<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } + } + + pub mod visibility_feature { + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum DefaultSymbolVisibility { + DEFAULTSYMBOLVISIBILITYUNKNOWN = 0, + EXPORTALL = 1, + EXPORTTOPLEVEL = 2, + LOCALALL = 3, + STRICT = 4, + } + + impl DefaultSymbolVisibility { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => DefaultSymbolVisibility::DEFAULTSYMBOLVISIBILITYUNKNOWN, + 1 => DefaultSymbolVisibility::EXPORTALL, + 2 => DefaultSymbolVisibility::EXPORTTOPLEVEL, + 3 => DefaultSymbolVisibility::LOCALALL, + 4 => DefaultSymbolVisibility::STRICT, + _ => DefaultSymbolVisibility::DEFAULTSYMBOLVISIBILITYUNKNOWN, + } + } + } + } + + pub struct ProtoLimitsFeature<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + } + + impl<'a> ProtoLimitsFeature<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + Ok(Self { accessor }) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } + } + + pub struct ProtoLimitsFeatureBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + } + + impl<'b> ProtoLimitsFeatureBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> ProtoLimitsFeatureBuilder<'_> { + ProtoLimitsFeatureBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + } + } + + pub fn with(mut self, msg: &ProtoLimitsFeature<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } + } + + pub mod proto_limits_feature { + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum EnforceProtoLimits { + PROTOLIMITSUNKNOWN = 0, + LEGACYNOEXPLICITLIMITS = 1, + PROTOLIMITS2026 = 2, + } + + impl EnforceProtoLimits { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => EnforceProtoLimits::PROTOLIMITSUNKNOWN, + 1 => EnforceProtoLimits::LEGACYNOEXPLICITLIMITS, + 2 => EnforceProtoLimits::PROTOLIMITS2026, + _ => EnforceProtoLimits::PROTOLIMITSUNKNOWN, + } + } + } + } +} + +pub struct FeatureSetDefaults<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + defaults_start: Option, + defaults_end: Option, + minimum_edition_offset: Option, + maximum_edition_offset: Option, +} + +impl<'a> FeatureSetDefaults<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut defaults_start = None; + let mut defaults_end = None; + let mut minimum_edition_offset = None; + let mut maximum_edition_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + if defaults_start.is_none() { + defaults_start = Some(offset); + } + defaults_end = Some(offset); + } + if tag.field_number == 4 { + minimum_edition_offset = Some(offset); + } + if tag.field_number == 5 { + maximum_edition_offset = Some(offset); + } + } + + Ok(Self { + accessor, + defaults_start, + defaults_end, + minimum_edition_offset, + maximum_edition_offset, + }) + } + + pub fn defaults(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.defaults_start, self.defaults_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(1, start, end), + _ => self.accessor.iter_repeated(1), + } + } + + pub fn minimum_edition(&self) -> roto_runtime::Result { + let offset = self + .minimum_edition_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn maximum_edition(&self) -> roto_runtime::Result { + let offset = self + .maximum_edition_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct FeatureSetDefaultsBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + defaults_written: bool, + minimum_edition_written: bool, + maximum_edition_written: bool, +} + +impl<'b> FeatureSetDefaultsBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> FeatureSetDefaultsBuilder<'_> { + FeatureSetDefaultsBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + defaults_written: false, + minimum_edition_written: false, + maximum_edition_written: false, + } + } + + pub fn defaults(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(1, value)?; + self.defaults_written = true; + Ok(self) + } + + pub fn minimum_edition(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(4, value)?; + self.minimum_edition_written = true; + Ok(self) + } + + pub fn maximum_edition(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(5, value)?; + self.maximum_edition_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &FeatureSetDefaults<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.defaults_written, + 4 => self.minimum_edition_written, + 5 => self.maximum_edition_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub mod feature_set_defaults { + pub struct FeatureSetEditionDefault<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + edition_offset: Option, + overridable_features_offset: Option, + fixed_features_offset: Option, + } + + impl<'a> FeatureSetEditionDefault<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut edition_offset = None; + let mut overridable_features_offset = None; + let mut fixed_features_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 3 { + edition_offset = Some(offset); + } + if tag.field_number == 4 { + overridable_features_offset = Some(offset); + } + if tag.field_number == 5 { + fixed_features_offset = Some(offset); + } + } + + Ok(Self { + accessor, + edition_offset, + overridable_features_offset, + fixed_features_offset, + }) + } + + pub fn edition(&self) -> roto_runtime::Result { + let offset = self + .edition_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn overridable_features(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .overridable_features_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn fixed_features(&self) -> roto_runtime::Result<&'a [u8]> { + let offset = self + .fixed_features_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + Ok(bytes) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } + } + + pub struct FeatureSetEditionDefaultBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + edition_written: bool, + overridable_features_written: bool, + fixed_features_written: bool, + } + + impl<'b> FeatureSetEditionDefaultBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> FeatureSetEditionDefaultBuilder<'_> { + FeatureSetEditionDefaultBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + edition_written: false, + overridable_features_written: false, + fixed_features_written: false, + } + } + + pub fn edition(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(3, value)?; + self.edition_written = true; + Ok(self) + } + + pub fn overridable_features(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(4, value)?; + self.overridable_features_written = true; + Ok(self) + } + + pub fn fixed_features(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(5, value)?; + self.fixed_features_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &FeatureSetEditionDefault<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 3 => self.edition_written, + 4 => self.overridable_features_written, + 5 => self.fixed_features_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } + } +} + +pub struct SourceCodeInfo<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + location_start: Option, + location_end: Option, +} + +impl<'a> SourceCodeInfo<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut location_start = None; + let mut location_end = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + if location_start.is_none() { + location_start = Some(offset); + } + location_end = Some(offset); + } + } + + Ok(Self { + accessor, + location_start, + location_end, + }) + } + + pub fn location(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.location_start, self.location_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(1, start, end), + _ => self.accessor.iter_repeated(1), + } + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct SourceCodeInfoBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + location_written: bool, +} + +impl<'b> SourceCodeInfoBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> SourceCodeInfoBuilder<'_> { + SourceCodeInfoBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + location_written: false, + } + } + + pub fn location(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(1, value)?; + self.location_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &SourceCodeInfo<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.location_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub mod source_code_info { + pub struct Location<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + path_start: Option, + path_end: Option, + span_start: Option, + span_end: Option, + leading_comments_offset: Option, + trailing_comments_offset: Option, + leading_detached_comments_start: Option, + leading_detached_comments_end: Option, + } + + impl<'a> Location<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut path_start = None; + let mut path_end = None; + let mut span_start = None; + let mut span_end = None; + let mut leading_comments_offset = None; + let mut trailing_comments_offset = None; + let mut leading_detached_comments_start = None; + let mut leading_detached_comments_end = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + if path_start.is_none() { + path_start = Some(offset); + } + path_end = Some(offset); + } + if tag.field_number == 2 { + if span_start.is_none() { + span_start = Some(offset); + } + span_end = Some(offset); + } + if tag.field_number == 3 { + leading_comments_offset = Some(offset); + } + if tag.field_number == 4 { + trailing_comments_offset = Some(offset); + } + if tag.field_number == 6 { + if leading_detached_comments_start.is_none() { + leading_detached_comments_start = Some(offset); + } + leading_detached_comments_end = Some(offset); + } + } + + Ok(Self { + accessor, + path_start, + path_end, + span_start, + span_end, + leading_comments_offset, + trailing_comments_offset, + leading_detached_comments_start, + leading_detached_comments_end, + }) + } + + pub fn path(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.path_start, self.path_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(1, start, end), + _ => self.accessor.iter_repeated(1), + } + } + + pub fn span(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.span_start, self.span_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(2, start, end), + _ => self.accessor.iter_repeated(2), + } + } + + pub fn leading_comments(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .leading_comments_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn trailing_comments(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .trailing_comments_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn leading_detached_comments(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match ( + self.leading_detached_comments_start, + self.leading_detached_comments_end, + ) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(6, start, end), + _ => self.accessor.iter_repeated(6), + } + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } + } + + pub struct LocationBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + path_written: bool, + span_written: bool, + leading_comments_written: bool, + trailing_comments_written: bool, + leading_detached_comments_written: bool, + } + + impl<'b> LocationBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> LocationBuilder<'_> { + LocationBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + path_written: false, + span_written: false, + leading_comments_written: false, + trailing_comments_written: false, + leading_detached_comments_written: false, + } + } + + pub fn path(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(1, value)?; + self.path_written = true; + Ok(self) + } + + pub fn span(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(2, value)?; + self.span_written = true; + Ok(self) + } + + pub fn leading_comments(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(3, value)?; + self.leading_comments_written = true; + Ok(self) + } + + pub fn trailing_comments(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(4, value)?; + self.trailing_comments_written = true; + Ok(self) + } + + pub fn leading_detached_comments(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(6, value)?; + self.leading_detached_comments_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &Location<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.path_written, + 2 => self.span_written, + 3 => self.leading_comments_written, + 4 => self.trailing_comments_written, + 6 => self.leading_detached_comments_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } + } +} + +pub struct GeneratedCodeInfo<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + annotation_start: Option, + annotation_end: Option, +} + +impl<'a> GeneratedCodeInfo<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut annotation_start = None; + let mut annotation_end = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + if annotation_start.is_none() { + annotation_start = Some(offset); + } + annotation_end = Some(offset); + } + } + + Ok(Self { + accessor, + annotation_start, + annotation_end, + }) + } + + pub fn annotation(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.annotation_start, self.annotation_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(1, start, end), + _ => self.accessor.iter_repeated(1), + } + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } +} + +pub struct GeneratedCodeInfoBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + annotation_written: bool, +} + +impl<'b> GeneratedCodeInfoBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> GeneratedCodeInfoBuilder<'_> { + GeneratedCodeInfoBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + annotation_written: false, + } + } + + pub fn annotation(mut self, value: &[u8]) -> roto_runtime::Result { + self.builder.write_bytes(1, value)?; + self.annotation_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &GeneratedCodeInfo<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.annotation_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } +} + +pub mod generated_code_info { + pub struct Annotation<'a> { + accessor: roto_runtime::ProtoAccessor<'a>, + path_start: Option, + path_end: Option, + source_file_offset: Option, + begin_offset: Option, + end_offset: Option, + semantic_offset: Option, + } + + impl<'a> Annotation<'a> { + pub fn new(data: &'a [u8]) -> roto_runtime::Result { + let accessor = roto_runtime::ProtoAccessor::new(data)?; + let mut path_start = None; + let mut path_end = None; + let mut source_file_offset = None; + let mut begin_offset = None; + let mut end_offset = None; + let mut semantic_offset = None; + for item in accessor.fields() { + let (offset, tag, _) = item?; + if tag.field_number == 1 { + if path_start.is_none() { + path_start = Some(offset); + } + path_end = Some(offset); + } + if tag.field_number == 2 { + source_file_offset = Some(offset); + } + if tag.field_number == 3 { + begin_offset = Some(offset); + } + if tag.field_number == 4 { + end_offset = Some(offset); + } + if tag.field_number == 5 { + semantic_offset = Some(offset); + } + } + + Ok(Self { + accessor, + path_start, + path_end, + source_file_offset, + begin_offset, + end_offset, + semantic_offset, + }) + } + + pub fn path(&self) -> roto_runtime::RepeatedFieldIterator<'a> { + match (self.path_start, self.path_end) { + (Some(start), Some(end)) => self.accessor.iter_repeated_range(1, start, end), + _ => self.accessor.iter_repeated(1), + } + } + + pub fn source_file(&self) -> roto_runtime::Result<&'a str> { + let offset = self + .source_file_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn begin(&self) -> roto_runtime::Result { + let offset = self + .begin_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn end(&self) -> roto_runtime::Result { + let offset = self + .end_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as i32) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn semantic(&self) -> roto_runtime::Result { + let offset = self + .semantic_offset + .ok_or(roto_runtime::RotoError::FieldNotFound)?; + let (bytes, _) = self.accessor.get_value_at(offset)?; + roto_runtime::read_varint(bytes) + .map(|(v, _)| v as u64) + .map_err(|_| roto_runtime::RotoError::WireFormatViolation) + } + + pub fn raw_fields(&self) -> roto_runtime::RawFieldIterator<'a> { + self.accessor.raw_fields() + } + } + + pub struct AnnotationBuilder<'b> { + builder: roto_runtime::ProtoBuilder<'b>, + path_written: bool, + source_file_written: bool, + begin_written: bool, + end_written: bool, + semantic_written: bool, + } + + impl<'b> AnnotationBuilder<'b> { + pub fn builder(buf: &mut [u8]) -> AnnotationBuilder<'_> { + AnnotationBuilder { + builder: roto_runtime::ProtoBuilder::new(buf), + path_written: false, + source_file_written: false, + begin_written: false, + end_written: false, + semantic_written: false, + } + } + + pub fn path(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(1, value)?; + self.path_written = true; + Ok(self) + } + + pub fn source_file(mut self, value: &str) -> roto_runtime::Result { + self.builder.write_string(2, value)?; + self.source_file_written = true; + Ok(self) + } + + pub fn begin(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(3, value)?; + self.begin_written = true; + Ok(self) + } + + pub fn end(mut self, value: i32) -> roto_runtime::Result { + self.builder.write_int32(4, value)?; + self.end_written = true; + Ok(self) + } + + pub fn semantic(mut self, value: u64) -> roto_runtime::Result { + self.builder.write_varint(5, value)?; + self.semantic_written = true; + Ok(self) + } + + pub fn with(mut self, msg: &Annotation<'_>) -> roto_runtime::Result { + for item in msg.raw_fields() { + let (field_number, raw_bytes) = item?; + let is_written = match field_number { + 1 => self.path_written, + 2 => self.source_file_written, + 3 => self.begin_written, + 4 => self.end_written, + 5 => self.semantic_written, + _ => false, + }; + if !is_written { + self.builder.write_raw(raw_bytes)?; + } + } + Ok(self) + } + + pub fn finish(self) -> roto_runtime::Result<&'b mut [u8]> { + self.builder.finish() + } + } + + pub mod annotation { + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(i32)] + pub enum Semantic { + NONE = 0, + SET = 1, + ALIAS = 2, + } + + impl Semantic { + pub fn from_i32(value: i32) -> Self { + match value { + 0 => Semantic::NONE, + 1 => Semantic::SET, + 2 => Semantic::ALIAS, + _ => Semantic::NONE, + } + } + } + } +} diff --git a/codegen/src/google/protobuf/mod.rs b/codegen/src/google/protobuf/mod.rs new file mode 100644 index 0000000..e4b3346 --- /dev/null +++ b/codegen/src/google/protobuf/mod.rs @@ -0,0 +1,2 @@ +pub mod compiler; +pub mod descriptor; diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs new file mode 100644 index 0000000..8038813 --- /dev/null +++ b/codegen/src/lib.rs @@ -0,0 +1,2 @@ +pub mod generator; +pub mod google; diff --git a/tests/build_generated_code.rs b/codegen/tests/build_generated_code.rs similarity index 71% rename from tests/build_generated_code.rs rename to codegen/tests/build_generated_code.rs index ddffc63..814d91d 100644 --- a/tests/build_generated_code.rs +++ b/codegen/tests/build_generated_code.rs @@ -1,19 +1,14 @@ +use roto_codegen::google::protobuf::compiler::plugin::CodeGeneratorRequest; +use roto_codegen::google::protobuf::descriptor::FileDescriptorSet; use std::fs; use std::process::Command; -use roto::google::protobuf::descriptor::{ - FileDescriptorSet -}; -use roto::google::protobuf::compiler::plugin::{ - CodeGeneratorRequest, -}; #[test] fn test_generated_code_builds() { // 1. Generate Rust code from data/request.bin let request_path = "data/request.bin"; let data = fs::read(request_path).expect("Failed to read request.bin"); - let request = CodeGeneratorRequest::new(&data) - .expect("Failed to parse CodeGeneratorRequest"); + let request = CodeGeneratorRequest::new(&data).expect("Failed to parse CodeGeneratorRequest"); // Mimic the logic from protoc-gen-roto to build a FileDescriptorSet let mut set_buf = Vec::new(); @@ -26,17 +21,20 @@ fn test_generated_code_builds() { // Write length as varint let len = file_data.len() as u64; let mut len_buf = [0u8; 10]; - let len_size = roto::write_varint(len, &mut len_buf).expect("Failed to write varint length"); + let len_size = + roto_runtime::write_varint(len, &mut len_buf).expect("Failed to write varint length"); set_buf.extend_from_slice(&len_buf[..len_size]); // Write data set_buf.extend_from_slice(file_data); } - let set = FileDescriptorSet::new(&set_buf) - .expect("Failed to create FileDescriptorSet"); + let set = FileDescriptorSet::new(&set_buf).expect("Failed to create FileDescriptorSet"); - let generated_files = roto::generator::generate_rust_code(&set, None, false); - assert!(!generated_files.is_empty(), "Generated code should not be empty"); + let generated_files = roto_codegen::generator::generate_rust_code(&set, None, false); + assert!( + !generated_files.is_empty(), + "Generated code should not be empty" + ); // 2. Setup a temporary Cargo project to verify the code builds let root = std::env::current_dir().expect("Failed to get current directory"); @@ -57,9 +55,10 @@ fn test_generated_code_builds() { // 3. Configure the project to depend on the current roto crate let cargo_toml_path = temp_project_dir.join("Cargo.toml"); - let cargo_toml_content = fs::read_to_string(&cargo_toml_path).expect("Failed to read Cargo.toml"); + let cargo_toml_content = + fs::read_to_string(&cargo_toml_path).expect("Failed to read Cargo.toml"); let updated_cargo_toml = format!( - "{}\n\nroto = {{ path = \"..\" }}", + "{}\n\nroto-codegen = {{ path = \"..\" }}\nroto-runtime = {{ path = \"../../runtime\" }}\n\n[workspace]\n", cargo_toml_content ); fs::write(cargo_toml_path, updated_cargo_toml).expect("Failed to write Cargo.toml"); @@ -83,5 +82,8 @@ fn test_generated_code_builds() { .status() .expect("Failed to run cargo build"); - assert!(build_status.success(), "The generated Rust code failed to build in a standalone project!"); + assert!( + build_status.success(), + "The generated Rust code failed to build in a standalone project!" + ); } diff --git a/tests/test_nested_protos.rs b/codegen/tests/test_nested_protos.rs similarity index 66% rename from tests/test_nested_protos.rs rename to codegen/tests/test_nested_protos.rs index 78aefa3..53688ab 100644 --- a/tests/test_nested_protos.rs +++ b/codegen/tests/test_nested_protos.rs @@ -1,7 +1,5 @@ -use roto::generator::generate_rust_code; -use roto::google::protobuf::descriptor::{ - FileDescriptorSet -}; +use roto_codegen::generator::generate_rust_code; +use roto_codegen::google::protobuf::descriptor::FileDescriptorSet; use std::fs; #[test] @@ -18,8 +16,9 @@ fn test_nested_proto_generation_contains_modules() { // but request.bin is usually a CodeGeneratorRequest. // Let's use the same logic as build_generated_code.rs to get a FileDescriptorSet - let request = roto::google::protobuf::compiler::plugin::CodeGeneratorRequest::new(&data) - .expect("Failed to parse CodeGeneratorRequest"); + let request = + roto_codegen::google::protobuf::compiler::plugin::CodeGeneratorRequest::new(&data) + .expect("Failed to parse CodeGeneratorRequest"); let mut set_buf = Vec::new(); for file_res in request.proto_file() { @@ -27,7 +26,8 @@ fn test_nested_proto_generation_contains_modules() { set_buf.push(10); let len = file_data.len() as u64; let mut len_buf = [0u8; 10]; - let len_size = roto::write_varint(len, &mut len_buf).expect("Failed to write varint length"); + let len_size = + roto_runtime::write_varint(len, &mut len_buf).expect("Failed to write varint length"); set_buf.extend_from_slice(&len_buf[..len_size]); set_buf.extend_from_slice(file_data); } @@ -35,12 +35,21 @@ fn test_nested_proto_generation_contains_modules() { let generated_files = generate_rust_code(&set, None, false); - let all_code: String = generated_files.into_iter().map(|(_, content)| content).collect(); + let all_code: String = generated_files + .into_iter() + .map(|(_, content)| content) + .collect(); println!("Generated Code:\n{}", all_code); // We want to see if any message has a nested module. // Since we don't know exactly what's in request.bin, we'll look for ANY 'pub mod' inside the generated code // that isn't at the top level (though the generator puts them inside the message definition). - assert!(all_code.contains("pub mod "), "Generated code should contain at least one nested module for nested types"); - assert!(all_code.contains("pub struct "), "Generated code should contain structs"); + assert!( + all_code.contains("pub mod "), + "Generated code should contain at least one nested module for nested types" + ); + assert!( + all_code.contains("pub struct "), + "Generated code should contain structs" + ); } diff --git a/tests/test_with_method.rs b/codegen/tests/test_with_method.rs similarity index 89% rename from tests/test_with_method.rs rename to codegen/tests/test_with_method.rs index 7c8dfd9..d211387 100644 --- a/tests/test_with_method.rs +++ b/codegen/tests/test_with_method.rs @@ -1,6 +1,6 @@ -use roto::generator::generate_rust_code; -use roto::google::protobuf::compiler::plugin::CodeGeneratorRequest; -use roto::google::protobuf::descriptor::FileDescriptorSet; +use roto_codegen::generator::generate_rust_code; +use roto_codegen::google::protobuf::compiler::plugin::CodeGeneratorRequest; +use roto_codegen::google::protobuf::descriptor::FileDescriptorSet; use std::fs; fn load_generated_code() -> String { @@ -13,7 +13,7 @@ fn load_generated_code() -> String { set_buf.push(10u8); let len = file_data.len() as u64; let mut len_buf = [0u8; 10]; - let len_size = roto::write_varint(len, &mut len_buf).unwrap(); + let len_size = roto_runtime::write_varint(len, &mut len_buf).unwrap(); set_buf.extend_from_slice(&len_buf[..len_size]); set_buf.extend_from_slice(file_data); } diff --git a/protos/Cargo.toml b/protos/Cargo.toml new file mode 100644 index 0000000..e416ccf --- /dev/null +++ b/protos/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "protos" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/protos/src/lib.rs b/protos/src/lib.rs new file mode 100644 index 0000000..98dd882 --- /dev/null +++ b/protos/src/lib.rs @@ -0,0 +1,3 @@ +pub fn hello() { + println!("Hello from protos!"); +} diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml new file mode 100644 index 0000000..29c59cd --- /dev/null +++ b/runtime/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "roto-runtime" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/runtime/data/.gitignore b/runtime/data/.gitignore new file mode 100644 index 0000000..f2e59b9 --- /dev/null +++ b/runtime/data/.gitignore @@ -0,0 +1 @@ +bench/ diff --git a/runtime/data/descriptor.desc b/runtime/data/descriptor.desc new file mode 100644 index 0000000000000000000000000000000000000000..8378d0bce7d6117f241e32695bde325bc0859406 GIT binary patch literal 13915 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 O!V0Fd-*eh@vi=VSi2cL> literal 0 HcmV?d00001 diff --git a/runtime/data/request.bin b/runtime/data/request.bin new file mode 100644 index 0000000000000000000000000000000000000000..7afcaaa3296fea27b242d2cb0edeb483ccd085ad GIT binary patch literal 156932 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

Fl2DJQLwB5W^J2S?VKF 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 literal 0 HcmV?d00001 diff --git a/runtime/data/test_data.textproto b/runtime/data/test_data.textproto new file mode 100644 index 0000000..5dc54ba --- /dev/null +++ b/runtime/data/test_data.textproto @@ -0,0 +1,39 @@ +d_val: 3.1415926535 +f_val: 2.71828 +i32_val: 42 +i64_val: 123456789012345 +u32_val: 1000 +u64_val: 18446744073709551615 +si32_val: -42 +si64_val: -123456789012345 +fx32_val: 123456 +fx64_val: 1234567890123456789 +sfx32_val: -123456 +sfx64_val: -1234567890123456789 +b_val: true +s_val: "Hello Roto!" +bytes_val: "SGVsbG8gUm90byE=" +status: ACTIVE +repeated_i32: 1 +repeated_i32: 2 +repeated_i32: 3 +repeated_i32: 4 +repeated_i32: 5 +repeated_string: "one" +repeated_string: "two" +repeated_string: "three" +repeated_nested { + id: 101 + name: "Nested 1" + active: true +} +repeated_nested { + id: 102 + name: "Nested 2" + active: false +} +single_nested { + id: 200 + name: "Single Nested" + active: true +} diff --git a/runtime/data/test_types.desc b/runtime/data/test_types.desc new file mode 100644 index 0000000000000000000000000000000000000000..6ff3fb19ce104f0dd6d88b8551a6df81fe29a7ed GIT binary patch literal 876 zcmb7@&u-d45XK9bwLKW)Y|_?kE;N_qh zyhUf%Yf=t5))*j+3@n^Dp0PP@6M@H^v38&+jToZnGe_Do<7XVb z0WAap^NgV3B@n5&TFW>>5_a0j?xvFcTS{(C9<%xM8w4w{6kLfs!|}ui?Hb-kqtu4o z4n2id8D>(grt`;`VwTUsQoc1Rz4j;{A?Pv(qX>QiF&hU*=aOV6;#Clh8?)sg60>b~O=|;qQRXt{- zlOI5eQPKvu_vtA8^*fC|Pylk(yBj_Xq6!Vb8>Tj@>a_mgdT=-BN3}6AKUDW0e}wMD literal 0 HcmV?d00001 diff --git a/runtime/data/test_types.proto b/runtime/data/test_types.proto new file mode 100644 index 0000000..c4b4a9a --- /dev/null +++ b/runtime/data/test_types.proto @@ -0,0 +1,53 @@ +syntax = "proto3"; + +package roto.test; + +// A comprehensive message containing all primitive types and complex structures +// to test the proto-to-rust codegen and runtime accessors. +message ComplexMessage { + // --- Floating Point --- + double d_val = 1; + float f_val = 2; + + // --- Integers (Variable Length) --- + int32 i32_val = 3; + int64 i64_val = 4; + uint32 u32_val = 5; + uint64 u64_val = 6; + sint32 si32_val = 7; + sint64 si64_val = 8; + + // --- Integers (Fixed Length) --- + fixed32 fx32_val = 9; + fixed64 fx64_val = 10; + sfixed32 sfx32_val = 11; + sfixed64 sfx64_val = 12; + + // --- Other Primitives --- + bool b_val = 13; + string s_val = 14; + bytes bytes_val = 15; + + // --- Enumerations --- + enum Status { + UNKNOWN = 0; + ACTIVE = 1; + INACTIVE = 2; + DELETED = 3; + } + Status status = 16; + + // --- Repeated Fields --- + // Testing packed primitives and non-packed types + repeated int32 repeated_i32 = 17; + repeated string repeated_string = 18; + repeated NestedMessage repeated_nested = 19; + + // --- Nested Messages --- + message NestedMessage { + int32 id = 1; + string name = 2; + bool active = 3; + } + NestedMessage single_nested = 20; +} diff --git a/src/lib.rs b/runtime/src/lib.rs similarity index 99% rename from src/lib.rs rename to runtime/src/lib.rs index e289ddf..0c71a0f 100644 --- a/src/lib.rs +++ b/runtime/src/lib.rs @@ -1,10 +1,3 @@ -pub mod generator; -pub mod google; -pub mod hackers; -// Uncomment this to check if the code compiles -// #[path = "../proto/google/protobuf/descriptor.rs"] -// pub mod descriptor; - use std::fmt; #[derive(Debug, PartialEq, Eq)] diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -}