From 7221683e91aa750b1c8b5ceb656a7ebed3845656 Mon Sep 17 00:00:00 2001 From: Yordis Prieto Date: Fri, 8 May 2026 17:37:08 -0400 Subject: [PATCH 1/2] fix(buffa-codegen): omit empty ancillary content files The crate doc already promised that empty ancillary kinds are not emitted in default split mode, but the generator was writing header-only `.__oneof.rs`, `.__view_oneof.rs`, and `.__ext.rs` files for every input proto. In schemas with one message per file, the generated tree triples in size with placeholder files that surface in editors, search results, and review diffs while carrying no code. Signed-off-by: Yordis Prieto --- DESIGN.md | 8 +- buffa-codegen/src/lib.rs | 123 ++++++++++-------- buffa-codegen/src/tests/generation.rs | 79 ++++++++++- buffa-codegen/src/tests/mod.rs | 5 +- .../generated/google.protobuf.compiler.mod.rs | 2 - .../google.protobuf.compiler.plugin.__ext.rs | 3 - ...google.protobuf.compiler.plugin.__oneof.rs | 3 - .../google.protobuf.compiler.plugin.__view.rs | 3 - ...e.protobuf.compiler.plugin.__view_oneof.rs | 3 - .../google.protobuf.descriptor.__ext.rs | 3 - .../google.protobuf.descriptor.__oneof.rs | 3 - .../google.protobuf.descriptor.__view.rs | 3 - ...google.protobuf.descriptor.__view_oneof.rs | 3 - .../src/generated/google.protobuf.mod.rs | 2 - .../generated/google.protobuf.any.__ext.rs | 3 - .../generated/google.protobuf.any.__oneof.rs | 3 - .../google.protobuf.any.__view_oneof.rs | 3 - .../google.protobuf.duration.__ext.rs | 3 - .../google.protobuf.duration.__oneof.rs | 3 - .../google.protobuf.duration.__view_oneof.rs | 3 - .../generated/google.protobuf.empty.__ext.rs | 3 - .../google.protobuf.empty.__oneof.rs | 3 - .../google.protobuf.empty.__view_oneof.rs | 3 - .../google.protobuf.field_mask.__ext.rs | 3 - .../google.protobuf.field_mask.__oneof.rs | 3 - ...google.protobuf.field_mask.__view_oneof.rs | 3 - .../src/generated/google.protobuf.mod.rs | 19 --- .../generated/google.protobuf.struct.__ext.rs | 3 - .../google.protobuf.timestamp.__ext.rs | 3 - .../google.protobuf.timestamp.__oneof.rs | 3 - .../google.protobuf.timestamp.__view_oneof.rs | 3 - .../google.protobuf.wrappers.__ext.rs | 3 - .../google.protobuf.wrappers.__oneof.rs | 3 - .../google.protobuf.wrappers.__view_oneof.rs | 3 - 34 files changed, 155 insertions(+), 164 deletions(-) delete mode 100644 buffa-descriptor/src/generated/google.protobuf.compiler.plugin.__ext.rs delete mode 100644 buffa-descriptor/src/generated/google.protobuf.compiler.plugin.__oneof.rs delete mode 100644 buffa-descriptor/src/generated/google.protobuf.compiler.plugin.__view.rs delete mode 100644 buffa-descriptor/src/generated/google.protobuf.compiler.plugin.__view_oneof.rs delete mode 100644 buffa-descriptor/src/generated/google.protobuf.descriptor.__ext.rs delete mode 100644 buffa-descriptor/src/generated/google.protobuf.descriptor.__oneof.rs delete mode 100644 buffa-descriptor/src/generated/google.protobuf.descriptor.__view.rs delete mode 100644 buffa-descriptor/src/generated/google.protobuf.descriptor.__view_oneof.rs delete mode 100644 buffa-types/src/generated/google.protobuf.any.__ext.rs delete mode 100644 buffa-types/src/generated/google.protobuf.any.__oneof.rs delete mode 100644 buffa-types/src/generated/google.protobuf.any.__view_oneof.rs delete mode 100644 buffa-types/src/generated/google.protobuf.duration.__ext.rs delete mode 100644 buffa-types/src/generated/google.protobuf.duration.__oneof.rs delete mode 100644 buffa-types/src/generated/google.protobuf.duration.__view_oneof.rs delete mode 100644 buffa-types/src/generated/google.protobuf.empty.__ext.rs delete mode 100644 buffa-types/src/generated/google.protobuf.empty.__oneof.rs delete mode 100644 buffa-types/src/generated/google.protobuf.empty.__view_oneof.rs delete mode 100644 buffa-types/src/generated/google.protobuf.field_mask.__ext.rs delete mode 100644 buffa-types/src/generated/google.protobuf.field_mask.__oneof.rs delete mode 100644 buffa-types/src/generated/google.protobuf.field_mask.__view_oneof.rs delete mode 100644 buffa-types/src/generated/google.protobuf.struct.__ext.rs delete mode 100644 buffa-types/src/generated/google.protobuf.timestamp.__ext.rs delete mode 100644 buffa-types/src/generated/google.protobuf.timestamp.__oneof.rs delete mode 100644 buffa-types/src/generated/google.protobuf.timestamp.__view_oneof.rs delete mode 100644 buffa-types/src/generated/google.protobuf.wrappers.__ext.rs delete mode 100644 buffa-types/src/generated/google.protobuf.wrappers.__oneof.rs delete mode 100644 buffa-types/src/generated/google.protobuf.wrappers.__view_oneof.rs diff --git a/DESIGN.md b/DESIGN.md index a5dce91..5b332ae 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -243,9 +243,9 @@ Oneof and view-oneof enums drop the `Oneof`/`View` suffix — the tree position This makes name collisions **structurally impossible**: a oneof `kind` and a nested message `Kind` can coexist because they land in different trees. There is no suffix-escalation or rename escape hatch; codegen emits proto names verbatim. -**File layout — five content files + one stitcher:** +**File layout — up to five content files + one stitcher:** -Each `.proto` emits five sibling content files into `OUT_DIR`: +Each `.proto` emits up to five sibling content files into `OUT_DIR`: | File | Contents | |---------------------------|-------------------------------------------| @@ -255,6 +255,8 @@ Each `.proto` emits five sibling content files into `OUT_DIR`: | `.__view_oneof.rs` | View oneof enums | | `.__ext.rs` | File-level extension consts | +A content file is emitted only when its kind has real content for that input — a proto with no oneofs emits no `__oneof.rs` / `__view_oneof.rs`, a proto with no `extend` blocks emits no `__ext.rs`, and so on. The stitcher's `include!` set is filtered to match. + Each proto **package** additionally emits one `.mod.rs` stitcher that `include!`s the content files and authors the `pub mod __buffa { … }` wrapper. Consumers wire up only the stitcher: ```rust,ignore @@ -265,7 +267,7 @@ pub mod my_pkg { `buffa::include_proto_relative!("dir", "my.pkg")` does the same for checked-in generated code (no `OUT_DIR`). `buffa-build`'s `_include.rs` and `protoc-gen-buffa-packaging` both emit module trees that reference only the stitchers. -The per-proto content files mean editing one `.proto` regenerates only its five siblings (incremental friendly); the per-package stitcher means `register_types` is naturally one fn per package, so multi-file packages (e.g. seven WKT files in `google.protobuf`) no longer collide. +The per-proto content files mean editing one `.proto` regenerates only its siblings (incremental friendly); the per-package stitcher means `register_types` is naturally one fn per package, so multi-file packages (e.g. seven WKT files in `google.protobuf`) no longer collide. **Natural-path re-exports.** The canonical `__buffa::` path is unconditional — generated method signatures, field types, and downstream codegen always use it. As an ergonomic convenience codegen *also* emits a `pub use` for each ancillary item at the path a Rust user would reach for first, mirroring the pre-`__buffa` (and prost) layout: diff --git a/buffa-codegen/src/lib.rs b/buffa-codegen/src/lib.rs index fc6af88..59cc766 100644 --- a/buffa-codegen/src/lib.rs +++ b/buffa-codegen/src/lib.rs @@ -75,15 +75,18 @@ pub fn allow_lints_attr() -> TokenStream { /// One generated output file. /// -/// Each `.proto` produces five **content files** (`.rs`, +/// Each `.proto` produces up to five **content files** (`.rs`, /// `.__view.rs`, `.__oneof.rs`, `.__view_oneof.rs`, /// `.__ext.rs`) and each proto package produces one /// `.mod.rs` **stitcher** that `include!`s the content files /// and authors the `pub mod __buffa { … }` ancillary tree. +/// Ancillary kinds with no content for that input file (e.g. a message +/// with no oneofs and no extensions) are omitted, and the stitcher's +/// `include!` set is filtered to match. /// See `DESIGN.md` → "Generated code layout". /// /// Consumers normally only need to wire up the -/// [`GeneratedFileKind::PackageMod`] entries (one per package); the five +/// [`GeneratedFileKind::PackageMod`] entries (one per package); the /// per-proto content kinds are reached transitively via `include!` from /// the stitcher. Write all files to disk; build a module tree from only /// the `PackageMod` ones. @@ -107,13 +110,16 @@ pub struct GeneratedFile { /// Kind of [`GeneratedFile`]. /// -/// [`generate`] produces five per-proto content kinds — one each of -/// [`Owned`](Self::Owned), [`View`](Self::View), [`Oneof`](Self::Oneof), +/// [`generate`] produces up to five per-proto content kinds — one each +/// of [`Owned`](Self::Owned), [`View`](Self::View), [`Oneof`](Self::Oneof), /// [`ViewOneof`](Self::ViewOneof), and [`Ext`](Self::Ext) per input /// `.proto` file — plus one [`PackageMod`](Self::PackageMod) stitcher per -/// package. Build integrations only need to wire up `PackageMod` entries; -/// the per-proto content kinds are reached via `include!` from the stitcher -/// and need only be written to disk alongside it. Under +/// package. Kinds with no content for the input (a proto with no oneofs +/// emits no [`Oneof`](Self::Oneof) / [`ViewOneof`](Self::ViewOneof); +/// no extensions, no [`Ext`](Self::Ext); etc.) are omitted. Build +/// integrations only need to wire up `PackageMod` entries; the per-proto +/// content kinds are reached via `include!` from the stitcher and need +/// only be written to disk alongside it. Under /// [`CodeGenConfig::file_per_package`] only `PackageMod` is emitted. /// /// [`Companion`](Self::Companion) is the one kind *not* produced by @@ -375,9 +381,10 @@ pub(crate) fn effective_extern_paths( /// dependencies may be present in `file_descriptors` but won't produce output /// files unless they appear in `files_to_generate`. /// -/// Each `.proto` emits five content files; each distinct package emits one -/// `.mod.rs` stitcher. Packages are processed in sorted order for -/// deterministic output. +/// Each `.proto` emits up to five content files (kinds with no content +/// are omitted); each distinct package emits one `.mod.rs` +/// stitcher. Packages are processed in sorted order for deterministic +/// output. pub fn generate( file_descriptors: &[FileDescriptorProto], files_to_generate: &[String], @@ -609,7 +616,9 @@ struct ProtoContent { root_reexports: Vec, } -/// Generate the five per-`.proto` content files for one input file. +/// Generate the per-`.proto` content token streams for one input file. +/// Each ancillary kind that has no content yields an empty stream and +/// is dropped at the file-emission stage. fn generate_proto_content( ctx: &context::CodeGenContext, current_package: &str, @@ -773,30 +782,6 @@ struct PackageSections { } impl PackageSections { - /// Build sections of `include!` calls referencing per-file content. - /// - /// Paths are bare-sibling (no `OUT_DIR` prefix) so the same stitcher - /// works for both `OUT_DIR` builds (where the consumer's - /// `include_proto!` already prepended `OUT_DIR`) and checked-in code. - fn from_stems(stems: &[String]) -> Self { - let includes = |suffix: &str| -> Vec { - stems - .iter() - .map(|stem| { - let path = format!("{stem}{suffix}.rs"); - quote! { include!(#path); } - }) - .collect() - }; - Self { - owned: includes(""), - view: includes(".__view"), - oneof: includes(".__oneof"), - view_oneof: includes(".__view_oneof"), - ext: includes(".__ext"), - } - } - /// Append one proto file's generated items in-line. fn push_inline(&mut self, pc: ProtoContent) { self.owned.push(pc.owned); @@ -807,8 +792,9 @@ impl PackageSections { } } -/// Generate all output files for one proto package: five content files per -/// `.proto` plus one `.mod.rs` stitcher, or a single `.rs` when +/// Generate all output files for one proto package: up to five content +/// files per `.proto` (empty ancillary kinds are skipped) plus one +/// `.mod.rs` stitcher, or a single `.rs` when /// [`CodeGenConfig::file_per_package`] is set. fn generate_package( ctx: &context::CodeGenContext, @@ -831,37 +817,71 @@ fn generate_package( } sections } else { - let mut stems: Vec = Vec::new(); + let mut sections = PackageSections::default(); for file in files { let mut pc = generate_proto_content(ctx, current_package, file, &mut reg)?; root_reexports.append(&mut pc.root_reexports); let source = file.name.as_deref().unwrap_or(""); - let push = |out: &mut Vec, - suffix: &str, + let stem = pc.stem; + + // Empty ancillary token streams are skipped — neither the + // content file nor the stitcher's `include!` is emitted. + let emit = |suffix: &str, kind: GeneratedFileKind, - tokens: TokenStream| + tokens: TokenStream, + section: &mut Vec, + out: &mut Vec| -> Result<(), CodeGenError> { + if tokens.is_empty() { + return Ok(()); + } + let name = format!("{stem}{suffix}.rs"); + section.push(quote! { include!(#name); }); out.push(GeneratedFile { - name: format!("{}{suffix}.rs", pc.stem), + name, package: current_package.to_string(), kind, content: format_tokens(tokens, source)?, }); Ok(()) }; - push(out, "", GeneratedFileKind::Owned, pc.owned)?; - push(out, ".__view", GeneratedFileKind::View, pc.view)?; - push(out, ".__oneof", GeneratedFileKind::Oneof, pc.oneof)?; - push( + emit( + "", + GeneratedFileKind::Owned, + pc.owned, + &mut sections.owned, out, + )?; + emit( + ".__view", + GeneratedFileKind::View, + pc.view, + &mut sections.view, + out, + )?; + emit( + ".__oneof", + GeneratedFileKind::Oneof, + pc.oneof, + &mut sections.oneof, + out, + )?; + emit( ".__view_oneof", GeneratedFileKind::ViewOneof, pc.view_oneof, + &mut sections.view_oneof, + out, + )?; + emit( + ".__ext", + GeneratedFileKind::Ext, + pc.ext, + &mut sections.ext, + out, )?; - push(out, ".__ext", GeneratedFileKind::Ext, pc.ext)?; - stems.push(pc.stem); } - PackageSections::from_stems(&stems) + sections }; let reexport_block = surviving_root_reexports(ctx, files, ®, root_reexports); @@ -1060,8 +1080,9 @@ pub fn package_to_filename(package: &str) -> String { /// Convert a `.proto` file path to its content-file stem. /// /// e.g., `"google/protobuf/timestamp.proto"` → `"google.protobuf.timestamp"`. -/// The five content files append `""`, `".__view"`, `".__oneof"`, -/// `".__view_oneof"`, `".__ext"` plus `".rs"`. +/// Content files append `""`, `".__view"`, `".__oneof"`, +/// `".__view_oneof"`, or `".__ext"` plus `".rs"` — emitted only for +/// kinds with non-empty content. pub fn proto_path_to_stem(proto_path: &str) -> String { let without_ext = proto_path.strip_suffix(".proto").unwrap_or(proto_path); without_ext.replace('/', ".") diff --git a/buffa-codegen/src/tests/generation.rs b/buffa-codegen/src/tests/generation.rs index d78a3fe..612d8b7 100644 --- a/buffa-codegen/src/tests/generation.rs +++ b/buffa-codegen/src/tests/generation.rs @@ -55,8 +55,8 @@ fn test_empty_file() { &CodeGenConfig::default(), ); let files = result.expect("empty file should generate without error"); - // 5 content files + 1 .mod.rs. - assert_eq!(files.len(), 6); + // No content files (all empty) + 1 .mod.rs. + assert_eq!(files.len(), 1); let stitcher = files .iter() .find(|f| f.kind == GeneratedFileKind::PackageMod) @@ -68,6 +68,75 @@ fn test_empty_file() { ); } +#[test] +fn test_empty_message_omits_empty_ancillary_files() { + // Regression: a proto file with only an empty message should not emit + // empty `.__oneof.rs`, `.__view_oneof.rs`, or `.__ext.rs` companion files. + let mut file = proto3_file("example/v1/empty.proto"); + file.package = Some("example.v1".to_string()); + file.message_type.push(DescriptorProto { + name: Some("Empty".to_string()), + ..Default::default() + }); + + let files = generate( + &[file], + &["example/v1/empty.proto".to_string()], + &CodeGenConfig::default(), + ) + .expect("empty-message file should generate"); + + let names: Vec<&str> = files.iter().map(|f| f.name.as_str()).collect(); + + assert!( + files + .iter() + .any(|f| f.name == "example.v1.empty.rs" && f.kind == GeneratedFileKind::Owned), + "owned file with the empty message should still be emitted; got {names:?}" + ); + assert!( + files + .iter() + .any(|f| f.kind == GeneratedFileKind::PackageMod), + "package mod should be generated; got {names:?}" + ); + + assert!( + !files.iter().any(|f| f.name.ends_with(".__oneof.rs")), + "empty oneof companion file should not be emitted; got {names:?}" + ); + assert!( + !files.iter().any(|f| f.name.ends_with(".__view_oneof.rs")), + "empty view-oneof companion file should not be emitted; got {names:?}" + ); + assert!( + !files.iter().any(|f| f.name.ends_with(".__ext.rs")), + "empty extension companion file should not be emitted; got {names:?}" + ); + + let package_mod = files + .iter() + .find(|f| f.kind == GeneratedFileKind::PackageMod) + .expect("package mod should be generated"); + assert!( + !package_mod.content.contains("example.v1.empty.__oneof.rs"), + "package mod should not include omitted oneof companion:\n{}", + package_mod.content + ); + assert!( + !package_mod + .content + .contains("example.v1.empty.__view_oneof.rs"), + "package mod should not include omitted view-oneof companion:\n{}", + package_mod.content + ); + assert!( + !package_mod.content.contains("example.v1.empty.__ext.rs"), + "package mod should not include omitted ext companion:\n{}", + package_mod.content + ); +} + #[test] fn test_package_to_mod_filename() { assert_eq!( @@ -103,8 +172,10 @@ fn test_multi_file_same_package_merged() { &CodeGenConfig::default(), ) .expect("multi-file package should merge"); - // 2 protos × 5 content files + 1 stitcher = 11. - assert_eq!(files.len(), 11); + // 2 protos × 2 content kinds (owned + view; oneof / view_oneof / + // ext omitted because the messages have no oneofs and no extensions) + // + 1 stitcher = 5. + assert_eq!(files.len(), 5); let stitcher = files .iter() .find(|f| f.kind == GeneratedFileKind::PackageMod) diff --git a/buffa-codegen/src/tests/mod.rs b/buffa-codegen/src/tests/mod.rs index ad51767..18e3341 100644 --- a/buffa-codegen/src/tests/mod.rs +++ b/buffa-codegen/src/tests/mod.rs @@ -38,8 +38,9 @@ pub(super) fn make_field(name: &str, number: i32, label: Label, ty: Type) -> Fie /// Concatenate all generated-file contents for snapshot-style assertions. /// -/// Each proto now emits 5 content files + 1 `.mod.rs`; tests that assert -/// "the output contains substring X" don't care which file it lands in. +/// Each proto emits up to 5 content files + 1 `.mod.rs`; tests that +/// assert "the output contains substring X" don't care which file it +/// lands in. pub(super) fn joined(files: &[GeneratedFile]) -> String { files .iter() diff --git a/buffa-descriptor/src/generated/google.protobuf.compiler.mod.rs b/buffa-descriptor/src/generated/google.protobuf.compiler.mod.rs index 0e4186e..eeb6680 100644 --- a/buffa-descriptor/src/generated/google.protobuf.compiler.mod.rs +++ b/buffa-descriptor/src/generated/google.protobuf.compiler.mod.rs @@ -18,11 +18,9 @@ pub mod __buffa { pub mod oneof { #[allow(unused_imports)] use super::*; - include!("google.protobuf.compiler.plugin.__oneof.rs"); } pub mod ext { #[allow(unused_imports)] use super::*; - include!("google.protobuf.compiler.plugin.__ext.rs"); } } diff --git a/buffa-descriptor/src/generated/google.protobuf.compiler.plugin.__ext.rs b/buffa-descriptor/src/generated/google.protobuf.compiler.plugin.__ext.rs deleted file mode 100644 index 7e3d491..0000000 --- a/buffa-descriptor/src/generated/google.protobuf.compiler.plugin.__ext.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/compiler/plugin.proto - diff --git a/buffa-descriptor/src/generated/google.protobuf.compiler.plugin.__oneof.rs b/buffa-descriptor/src/generated/google.protobuf.compiler.plugin.__oneof.rs deleted file mode 100644 index 7e3d491..0000000 --- a/buffa-descriptor/src/generated/google.protobuf.compiler.plugin.__oneof.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/compiler/plugin.proto - diff --git a/buffa-descriptor/src/generated/google.protobuf.compiler.plugin.__view.rs b/buffa-descriptor/src/generated/google.protobuf.compiler.plugin.__view.rs deleted file mode 100644 index 7e3d491..0000000 --- a/buffa-descriptor/src/generated/google.protobuf.compiler.plugin.__view.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/compiler/plugin.proto - diff --git a/buffa-descriptor/src/generated/google.protobuf.compiler.plugin.__view_oneof.rs b/buffa-descriptor/src/generated/google.protobuf.compiler.plugin.__view_oneof.rs deleted file mode 100644 index 7e3d491..0000000 --- a/buffa-descriptor/src/generated/google.protobuf.compiler.plugin.__view_oneof.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/compiler/plugin.proto - diff --git a/buffa-descriptor/src/generated/google.protobuf.descriptor.__ext.rs b/buffa-descriptor/src/generated/google.protobuf.descriptor.__ext.rs deleted file mode 100644 index 6b0ab31..0000000 --- a/buffa-descriptor/src/generated/google.protobuf.descriptor.__ext.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/descriptor.proto - diff --git a/buffa-descriptor/src/generated/google.protobuf.descriptor.__oneof.rs b/buffa-descriptor/src/generated/google.protobuf.descriptor.__oneof.rs deleted file mode 100644 index 6b0ab31..0000000 --- a/buffa-descriptor/src/generated/google.protobuf.descriptor.__oneof.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/descriptor.proto - diff --git a/buffa-descriptor/src/generated/google.protobuf.descriptor.__view.rs b/buffa-descriptor/src/generated/google.protobuf.descriptor.__view.rs deleted file mode 100644 index 6b0ab31..0000000 --- a/buffa-descriptor/src/generated/google.protobuf.descriptor.__view.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/descriptor.proto - diff --git a/buffa-descriptor/src/generated/google.protobuf.descriptor.__view_oneof.rs b/buffa-descriptor/src/generated/google.protobuf.descriptor.__view_oneof.rs deleted file mode 100644 index 6b0ab31..0000000 --- a/buffa-descriptor/src/generated/google.protobuf.descriptor.__view_oneof.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/descriptor.proto - diff --git a/buffa-descriptor/src/generated/google.protobuf.mod.rs b/buffa-descriptor/src/generated/google.protobuf.mod.rs index fee39ec..88c5619 100644 --- a/buffa-descriptor/src/generated/google.protobuf.mod.rs +++ b/buffa-descriptor/src/generated/google.protobuf.mod.rs @@ -18,11 +18,9 @@ pub mod __buffa { pub mod oneof { #[allow(unused_imports)] use super::*; - include!("google.protobuf.descriptor.__oneof.rs"); } pub mod ext { #[allow(unused_imports)] use super::*; - include!("google.protobuf.descriptor.__ext.rs"); } } diff --git a/buffa-types/src/generated/google.protobuf.any.__ext.rs b/buffa-types/src/generated/google.protobuf.any.__ext.rs deleted file mode 100644 index 53a39a9..0000000 --- a/buffa-types/src/generated/google.protobuf.any.__ext.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/any.proto - diff --git a/buffa-types/src/generated/google.protobuf.any.__oneof.rs b/buffa-types/src/generated/google.protobuf.any.__oneof.rs deleted file mode 100644 index 53a39a9..0000000 --- a/buffa-types/src/generated/google.protobuf.any.__oneof.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/any.proto - diff --git a/buffa-types/src/generated/google.protobuf.any.__view_oneof.rs b/buffa-types/src/generated/google.protobuf.any.__view_oneof.rs deleted file mode 100644 index 53a39a9..0000000 --- a/buffa-types/src/generated/google.protobuf.any.__view_oneof.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/any.proto - diff --git a/buffa-types/src/generated/google.protobuf.duration.__ext.rs b/buffa-types/src/generated/google.protobuf.duration.__ext.rs deleted file mode 100644 index 5665aee..0000000 --- a/buffa-types/src/generated/google.protobuf.duration.__ext.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/duration.proto - diff --git a/buffa-types/src/generated/google.protobuf.duration.__oneof.rs b/buffa-types/src/generated/google.protobuf.duration.__oneof.rs deleted file mode 100644 index 5665aee..0000000 --- a/buffa-types/src/generated/google.protobuf.duration.__oneof.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/duration.proto - diff --git a/buffa-types/src/generated/google.protobuf.duration.__view_oneof.rs b/buffa-types/src/generated/google.protobuf.duration.__view_oneof.rs deleted file mode 100644 index 5665aee..0000000 --- a/buffa-types/src/generated/google.protobuf.duration.__view_oneof.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/duration.proto - diff --git a/buffa-types/src/generated/google.protobuf.empty.__ext.rs b/buffa-types/src/generated/google.protobuf.empty.__ext.rs deleted file mode 100644 index 36cded0..0000000 --- a/buffa-types/src/generated/google.protobuf.empty.__ext.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/empty.proto - diff --git a/buffa-types/src/generated/google.protobuf.empty.__oneof.rs b/buffa-types/src/generated/google.protobuf.empty.__oneof.rs deleted file mode 100644 index 36cded0..0000000 --- a/buffa-types/src/generated/google.protobuf.empty.__oneof.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/empty.proto - diff --git a/buffa-types/src/generated/google.protobuf.empty.__view_oneof.rs b/buffa-types/src/generated/google.protobuf.empty.__view_oneof.rs deleted file mode 100644 index 36cded0..0000000 --- a/buffa-types/src/generated/google.protobuf.empty.__view_oneof.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/empty.proto - diff --git a/buffa-types/src/generated/google.protobuf.field_mask.__ext.rs b/buffa-types/src/generated/google.protobuf.field_mask.__ext.rs deleted file mode 100644 index ded36e5..0000000 --- a/buffa-types/src/generated/google.protobuf.field_mask.__ext.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/field_mask.proto - diff --git a/buffa-types/src/generated/google.protobuf.field_mask.__oneof.rs b/buffa-types/src/generated/google.protobuf.field_mask.__oneof.rs deleted file mode 100644 index ded36e5..0000000 --- a/buffa-types/src/generated/google.protobuf.field_mask.__oneof.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/field_mask.proto - diff --git a/buffa-types/src/generated/google.protobuf.field_mask.__view_oneof.rs b/buffa-types/src/generated/google.protobuf.field_mask.__view_oneof.rs deleted file mode 100644 index ded36e5..0000000 --- a/buffa-types/src/generated/google.protobuf.field_mask.__view_oneof.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/field_mask.proto - diff --git a/buffa-types/src/generated/google.protobuf.mod.rs b/buffa-types/src/generated/google.protobuf.mod.rs index 410821c..1da5a01 100644 --- a/buffa-types/src/generated/google.protobuf.mod.rs +++ b/buffa-types/src/generated/google.protobuf.mod.rs @@ -34,36 +34,17 @@ pub mod __buffa { pub mod oneof { #[allow(unused_imports)] use super::*; - include!("google.protobuf.any.__view_oneof.rs"); - include!("google.protobuf.duration.__view_oneof.rs"); - include!("google.protobuf.empty.__view_oneof.rs"); - include!("google.protobuf.field_mask.__view_oneof.rs"); include!("google.protobuf.struct.__view_oneof.rs"); - include!("google.protobuf.timestamp.__view_oneof.rs"); - include!("google.protobuf.wrappers.__view_oneof.rs"); } } pub mod oneof { #[allow(unused_imports)] use super::*; - include!("google.protobuf.any.__oneof.rs"); - include!("google.protobuf.duration.__oneof.rs"); - include!("google.protobuf.empty.__oneof.rs"); - include!("google.protobuf.field_mask.__oneof.rs"); include!("google.protobuf.struct.__oneof.rs"); - include!("google.protobuf.timestamp.__oneof.rs"); - include!("google.protobuf.wrappers.__oneof.rs"); } pub mod ext { #[allow(unused_imports)] use super::*; - include!("google.protobuf.any.__ext.rs"); - include!("google.protobuf.duration.__ext.rs"); - include!("google.protobuf.empty.__ext.rs"); - include!("google.protobuf.field_mask.__ext.rs"); - include!("google.protobuf.struct.__ext.rs"); - include!("google.protobuf.timestamp.__ext.rs"); - include!("google.protobuf.wrappers.__ext.rs"); } } #[doc(inline)] diff --git a/buffa-types/src/generated/google.protobuf.struct.__ext.rs b/buffa-types/src/generated/google.protobuf.struct.__ext.rs deleted file mode 100644 index 4449756..0000000 --- a/buffa-types/src/generated/google.protobuf.struct.__ext.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/struct.proto - diff --git a/buffa-types/src/generated/google.protobuf.timestamp.__ext.rs b/buffa-types/src/generated/google.protobuf.timestamp.__ext.rs deleted file mode 100644 index cb0ed2d..0000000 --- a/buffa-types/src/generated/google.protobuf.timestamp.__ext.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/timestamp.proto - diff --git a/buffa-types/src/generated/google.protobuf.timestamp.__oneof.rs b/buffa-types/src/generated/google.protobuf.timestamp.__oneof.rs deleted file mode 100644 index cb0ed2d..0000000 --- a/buffa-types/src/generated/google.protobuf.timestamp.__oneof.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/timestamp.proto - diff --git a/buffa-types/src/generated/google.protobuf.timestamp.__view_oneof.rs b/buffa-types/src/generated/google.protobuf.timestamp.__view_oneof.rs deleted file mode 100644 index cb0ed2d..0000000 --- a/buffa-types/src/generated/google.protobuf.timestamp.__view_oneof.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/timestamp.proto - diff --git a/buffa-types/src/generated/google.protobuf.wrappers.__ext.rs b/buffa-types/src/generated/google.protobuf.wrappers.__ext.rs deleted file mode 100644 index 47c2c1a..0000000 --- a/buffa-types/src/generated/google.protobuf.wrappers.__ext.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/wrappers.proto - diff --git a/buffa-types/src/generated/google.protobuf.wrappers.__oneof.rs b/buffa-types/src/generated/google.protobuf.wrappers.__oneof.rs deleted file mode 100644 index 47c2c1a..0000000 --- a/buffa-types/src/generated/google.protobuf.wrappers.__oneof.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/wrappers.proto - diff --git a/buffa-types/src/generated/google.protobuf.wrappers.__view_oneof.rs b/buffa-types/src/generated/google.protobuf.wrappers.__view_oneof.rs deleted file mode 100644 index 47c2c1a..0000000 --- a/buffa-types/src/generated/google.protobuf.wrappers.__view_oneof.rs +++ /dev/null @@ -1,3 +0,0 @@ -// @generated by buffa-codegen. DO NOT EDIT. -// source: google/protobuf/wrappers.proto - From 3901d9adfdc12fb4419e53d70594ee700b54a5d1 Mon Sep 17 00:00:00 2001 From: Yordis Prieto Date: Fri, 8 May 2026 18:42:47 -0400 Subject: [PATCH 2/2] fix(buffa-codegen): omit empty ancillary modules from stitcher Empty `pub mod view`/`oneof`/`ext` blocks (and the outer `__buffa` wrapper when none would have items) were still emitted, leaving dead namespace nodes in the generated tree. Signed-off-by: Yordis Prieto --- DESIGN.md | 2 +- buffa-codegen/src/lib.rs | 115 ++++++++--- buffa-codegen/src/tests/generation.rs | 184 +++++++++++++++++- .../generated/google.protobuf.compiler.mod.rs | 23 --- .../src/generated/google.protobuf.mod.rs | 23 --- .../src/generated/google.protobuf.mod.rs | 4 - 6 files changed, 271 insertions(+), 80 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index 5b332ae..ac5082d 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -257,7 +257,7 @@ Each `.proto` emits up to five sibling content files into `OUT_DIR`: A content file is emitted only when its kind has real content for that input — a proto with no oneofs emits no `__oneof.rs` / `__view_oneof.rs`, a proto with no `extend` blocks emits no `__ext.rs`, and so on. The stitcher's `include!` set is filtered to match. -Each proto **package** additionally emits one `.mod.rs` stitcher that `include!`s the content files and authors the `pub mod __buffa { … }` wrapper. Consumers wire up only the stitcher: +Each proto **package** additionally emits one `.mod.rs` stitcher that `include!`s the content files and authors the `pub mod __buffa { … }` wrapper. The wrapper — and each `view` / `oneof` / `ext` submodule inside it — is omitted when it would have no items, so packages that contain only owned messages don't carry an empty `__buffa` block. Consumers wire up only the stitcher: ```rust,ignore pub mod my_pkg { diff --git a/buffa-codegen/src/lib.rs b/buffa-codegen/src/lib.rs index 59cc766..ba674c0 100644 --- a/buffa-codegen/src/lib.rs +++ b/buffa-codegen/src/lib.rs @@ -82,7 +82,10 @@ pub fn allow_lints_attr() -> TokenStream { /// and authors the `pub mod __buffa { … }` ancillary tree. /// Ancillary kinds with no content for that input file (e.g. a message /// with no oneofs and no extensions) are omitted, and the stitcher's -/// `include!` set is filtered to match. +/// `include!` set is filtered to match. The `__buffa` wrapper (and each +/// `view` / `oneof` / `ext` submodule inside it) is itself omitted when +/// it would be empty, so packages with only owned messages emit no +/// `__buffa` block at all. /// See `DESIGN.md` → "Generated code layout". /// /// Consumers normally only need to wire up the @@ -783,12 +786,21 @@ struct PackageSections { impl PackageSections { /// Append one proto file's generated items in-line. + /// + /// Empty streams are skipped so each section's emptiness reflects + /// "the package has no content of this kind" — symmetric with the + /// per-file branch that filters at file-emission time. fn push_inline(&mut self, pc: ProtoContent) { - self.owned.push(pc.owned); - self.view.push(pc.view); - self.oneof.push(pc.oneof); - self.view_oneof.push(pc.view_oneof); - self.ext.push(pc.ext); + let push_if_nonempty = |dst: &mut Vec, ts: TokenStream| { + if !ts.is_empty() { + dst.push(ts); + } + }; + push_if_nonempty(&mut self.owned, pc.owned); + push_if_nonempty(&mut self.view, pc.view); + push_if_nonempty(&mut self.oneof, pc.oneof); + push_if_nonempty(&mut self.view_oneof, pc.view_oneof); + push_if_nonempty(&mut self.ext, pc.ext); } } @@ -969,17 +981,58 @@ fn generate_package_mod( let oneof = §ions.oneof; let ext = §ions.ext; - let view_mod = if ctx.config.generate_views { + // Each ancillary module is emitted only when its section has + // content. The natural-path re-exports outside `__buffa` target + // these modules — they are emitted only when their target items + // exist, so the conditions align and re-exports never reference + // a missing module. + let view_oneof_mod = if !view_oneof.is_empty() { + quote! { + pub mod oneof { + #[allow(unused_imports)] + use super::*; + #(#view_oneof)* + } + } + } else { + TokenStream::new() + }; + + // `view_oneof` is only populated for messages that have oneofs, and + // every message also contributes to `view`, so `!view.is_empty()` is + // sufficient — `view_oneof` non-empty implies `view` non-empty. + debug_assert!(view_oneof.is_empty() || !view.is_empty()); + let view_mod = if ctx.config.generate_views && !view.is_empty() { quote! { pub mod view { #[allow(unused_imports)] use super::*; #(#view)* - pub mod oneof { - #[allow(unused_imports)] - use super::*; - #(#view_oneof)* - } + #view_oneof_mod + } + } + } else { + TokenStream::new() + }; + + let oneof_mod = if !oneof.is_empty() { + quote! { + pub mod oneof { + #[allow(unused_imports)] + use super::*; + #(#oneof)* + } + } + } else { + TokenStream::new() + }; + + let ext_mod = if !ext.is_empty() { + quote! { + pub mod ext { + #[allow(unused_imports)] + use super::*; + #(#ext)* } } } else { @@ -1004,27 +1057,33 @@ fn generate_package_mod( TokenStream::new() }; - let allow = allow_lints_attr(); let sentinel = make_field_ident(context::SENTINEL_MOD); - let tokens = quote! { - #(#owned)* - #allow - pub mod #sentinel { - #[allow(unused_imports)] - use super::*; - #view_mod - pub mod oneof { - #[allow(unused_imports)] - use super::*; - #(#oneof)* - } - pub mod ext { + // The whole `pub mod __buffa { ... }` wrapper is itself omitted + // when none of its inner modules or `register_types` exist. + let buffa_mod = if view_mod.is_empty() + && oneof_mod.is_empty() + && ext_mod.is_empty() + && register_fn.is_empty() + { + TokenStream::new() + } else { + let allow = allow_lints_attr(); + quote! { + #allow + pub mod #sentinel { #[allow(unused_imports)] use super::*; - #(#ext)* + #view_mod + #oneof_mod + #ext_mod + #register_fn } - #register_fn } + }; + + let tokens = quote! { + #(#owned)* + #buffa_mod #root_reexports }; diff --git a/buffa-codegen/src/tests/generation.rs b/buffa-codegen/src/tests/generation.rs index 612d8b7..bf973bd 100644 --- a/buffa-codegen/src/tests/generation.rs +++ b/buffa-codegen/src/tests/generation.rs @@ -66,6 +66,12 @@ fn test_empty_file() { stitcher.content.contains("@generated"), "missing header comment" ); + // No content of any kind → no `__buffa` wrapper at all. + assert!( + !stitcher.content.contains("pub mod __buffa"), + "empty file should not emit a `pub mod __buffa` wrapper:\n{}", + stitcher.content + ); } #[test] @@ -137,6 +143,171 @@ fn test_empty_message_omits_empty_ancillary_files() { ); } +#[test] +fn stitcher_omits_empty_inner_modules_for_empty_message() { + // A proto containing only an empty message (default config: views on, + // no JSON, no register_fn-relevant content) should produce only + // `pub mod view { … }` inside `__buffa` — no inner `view::oneof`, + // no `oneof`, no `ext`. + let mut file = proto3_file("only_msg.proto"); + file.package = Some("p".to_string()); + file.message_type.push(DescriptorProto { + name: Some("Empty".to_string()), + ..Default::default() + }); + let files = generate( + &[file], + &["only_msg.proto".to_string()], + &CodeGenConfig::default(), + ) + .expect("should generate"); + let stitcher = files + .iter() + .find(|f| f.kind == GeneratedFileKind::PackageMod) + .expect("stitcher present"); + assert!( + stitcher.content.contains("pub mod __buffa"), + "expected `__buffa` wrapper (view module is non-empty):\n{}", + stitcher.content + ); + assert!( + stitcher.content.contains("pub mod view"), + "expected `pub mod view`:\n{}", + stitcher.content + ); + assert!( + !stitcher.content.contains("pub mod oneof"), + "should not emit empty `pub mod oneof` (covers both top-level \ + and nested view::oneof):\n{}", + stitcher.content + ); + assert!( + !stitcher.content.contains("pub mod ext"), + "should not emit empty `pub mod ext`:\n{}", + stitcher.content + ); +} + +#[test] +fn stitcher_omits_view_module_when_views_disabled_and_only_oneof_present() { + // Views off + a message with a oneof: only `pub mod oneof` survives; + // `view` and `ext` are omitted. + let mut file = proto3_file("only_oneof.proto"); + file.package = Some("p".to_string()); + file.message_type.push(DescriptorProto { + name: Some("M".to_string()), + field: vec![ + FieldDescriptorProto { + name: Some("x".to_string()), + number: Some(1), + label: Some(Label::LABEL_OPTIONAL), + r#type: Some(Type::TYPE_INT32), + oneof_index: Some(0), + ..Default::default() + }, + FieldDescriptorProto { + name: Some("y".to_string()), + number: Some(2), + label: Some(Label::LABEL_OPTIONAL), + r#type: Some(Type::TYPE_STRING), + oneof_index: Some(0), + ..Default::default() + }, + ], + oneof_decl: vec![OneofDescriptorProto { + name: Some("kind".to_string()), + ..Default::default() + }], + ..Default::default() + }); + let config = CodeGenConfig { + generate_views: false, + ..Default::default() + }; + let files = + generate(&[file], &["only_oneof.proto".to_string()], &config).expect("should generate"); + let stitcher = files + .iter() + .find(|f| f.kind == GeneratedFileKind::PackageMod) + .expect("stitcher present"); + assert!( + stitcher.content.contains("pub mod __buffa"), + "expected `__buffa` wrapper (oneof module is non-empty):\n{}", + stitcher.content + ); + assert!( + stitcher.content.contains("pub mod oneof"), + "expected `pub mod oneof`:\n{}", + stitcher.content + ); + assert!( + !stitcher.content.contains("pub mod view"), + "should not emit `pub mod view` when views are disabled:\n{}", + stitcher.content + ); + assert!( + !stitcher.content.contains("pub mod ext"), + "should not emit empty `pub mod ext`:\n{}", + stitcher.content + ); +} + +#[test] +fn stitcher_emits_only_ext_module_for_extension_only_proto() { + // A proto carrying only a file-level `extend` block (no own + // messages) emits only `pub mod ext` inside `__buffa`. + let mut file = proto3_file("ext_only.proto"); + file.package = Some("p".to_string()); + file.message_type = vec![DescriptorProto { + name: Some("Target".to_string()), + extension_range: vec![ + crate::generated::descriptor::descriptor_proto::ExtensionRange { + start: Some(100), + end: Some(200), + ..Default::default() + }, + ], + ..Default::default() + }]; + file.extension = vec![{ + let mut f = make_field("my_opt", 100, Label::LABEL_OPTIONAL, Type::TYPE_STRING); + f.extendee = Some(".p.Target".to_string()); + f + }]; + let files = generate( + &[file], + &["ext_only.proto".to_string()], + &CodeGenConfig::default(), + ) + .expect("should generate"); + let stitcher = files + .iter() + .find(|f| f.kind == GeneratedFileKind::PackageMod) + .expect("stitcher present"); + assert!( + stitcher.content.contains("pub mod __buffa"), + "expected `__buffa` wrapper (ext module is non-empty):\n{}", + stitcher.content + ); + assert!( + stitcher.content.contains("pub mod ext"), + "expected `pub mod ext`:\n{}", + stitcher.content + ); + // `Target` has an extension range but no oneofs and no fields, so + // no view oneof / oneof content. View module exists for `TargetView`. + assert!( + stitcher.content.contains("pub mod view"), + "expected `pub mod view` for `TargetView`:\n{}", + stitcher.content + ); + assert!( + !stitcher.content.contains("pub mod oneof"), + "should not emit empty `pub mod oneof`:\n{}", + stitcher.content + ); +} + #[test] fn test_package_to_mod_filename() { assert_eq!( @@ -265,10 +436,15 @@ fn test_file_per_package_multi_file() { "per-package file must inline content, not include! per-file outputs" ); // Same `__buffa` module wrappers as the per-file stitcher. + // The fixture has views and a oneof but no extensions, so `view` + // and `oneof` are emitted but `ext` is omitted as empty. assert_eq!(pkg.content.matches("pub mod __buffa {").count(), 1); assert!(pkg.content.contains("pub mod view {")); assert!(pkg.content.contains("pub mod oneof {")); - assert!(pkg.content.contains("pub mod ext {")); + assert!( + !pkg.content.contains("pub mod ext {"), + "no extensions in fixture → empty `pub mod ext` should be omitted" + ); } #[test] @@ -384,6 +560,12 @@ fn test_file_per_package_unnamed_package() { .expect("unnamed package should generate"); assert_eq!(files.len(), 1); assert_eq!(files[0].name, "__buffa.rs"); + // No messages → no view/oneof/ext content → no `__buffa` wrapper. + assert!( + !files[0].content.contains("pub mod __buffa"), + "empty package should not emit `__buffa` wrapper:\n{}", + files[0].content + ); } #[test] diff --git a/buffa-descriptor/src/generated/google.protobuf.compiler.mod.rs b/buffa-descriptor/src/generated/google.protobuf.compiler.mod.rs index eeb6680..d5ac6b4 100644 --- a/buffa-descriptor/src/generated/google.protobuf.compiler.mod.rs +++ b/buffa-descriptor/src/generated/google.protobuf.compiler.mod.rs @@ -1,26 +1,3 @@ // @generated by buffa-codegen. DO NOT EDIT. include!("google.protobuf.compiler.plugin.rs"); -#[allow( - non_camel_case_types, - dead_code, - unused_imports, - unused_qualifications, - clippy::derivable_impls, - clippy::match_single_binding, - clippy::uninlined_format_args, - clippy::doc_lazy_continuation, - clippy::module_inception -)] -pub mod __buffa { - #[allow(unused_imports)] - use super::*; - pub mod oneof { - #[allow(unused_imports)] - use super::*; - } - pub mod ext { - #[allow(unused_imports)] - use super::*; - } -} diff --git a/buffa-descriptor/src/generated/google.protobuf.mod.rs b/buffa-descriptor/src/generated/google.protobuf.mod.rs index 88c5619..a689836 100644 --- a/buffa-descriptor/src/generated/google.protobuf.mod.rs +++ b/buffa-descriptor/src/generated/google.protobuf.mod.rs @@ -1,26 +1,3 @@ // @generated by buffa-codegen. DO NOT EDIT. include!("google.protobuf.descriptor.rs"); -#[allow( - non_camel_case_types, - dead_code, - unused_imports, - unused_qualifications, - clippy::derivable_impls, - clippy::match_single_binding, - clippy::uninlined_format_args, - clippy::doc_lazy_continuation, - clippy::module_inception -)] -pub mod __buffa { - #[allow(unused_imports)] - use super::*; - pub mod oneof { - #[allow(unused_imports)] - use super::*; - } - pub mod ext { - #[allow(unused_imports)] - use super::*; - } -} diff --git a/buffa-types/src/generated/google.protobuf.mod.rs b/buffa-types/src/generated/google.protobuf.mod.rs index 1da5a01..c94798e 100644 --- a/buffa-types/src/generated/google.protobuf.mod.rs +++ b/buffa-types/src/generated/google.protobuf.mod.rs @@ -42,10 +42,6 @@ pub mod __buffa { use super::*; include!("google.protobuf.struct.__oneof.rs"); } - pub mod ext { - #[allow(unused_imports)] - use super::*; - } } #[doc(inline)] pub use self::__buffa::view::AnyView;