Skip to content

Oneof variant named self generates reserved keyword Self as enum variant #47

@varunbpatil

Description

@varunbpatil

Bug

When a proto oneof contains a field named self, buffa-codegen converts it to PascalCase Self when generating the Rust enum variant — which is a reserved keyword and produces invalid Rust code.

Reproducer: The upstream Temporal API proto contains this definition:

message SetWorkerDeploymentManagerRequest {
    oneof new_manager_identity {
      string manager_identity = 3;
      bool self = 4;  // <-- triggers the bug
    }
}

buffa-codegen emits:

pub enum NewManagerIdentity {
    ManagerIdentity(String),
    Self(bool),  // ERROR: `Self` is a reserved keyword
}

This causes buffa_codegen::generate() to fail with:

generated code failed to parse as Rust: expected identifier, found keyword `Self`

Root cause

In buffa-codegen, every place that converts a proto field name to a PascalCase enum variant identifier uses format_ident!("{}", to_pascal_case(proto_name)) without checking for reserved keywords. The affected files/lines (v0.3.0):

  • oneof.rscollect_variant_info (the enum definition itself)
  • impl_message.rs — encode/size codegen
  • message.rs — JSON deserialise codegen
  • impl_text.rs — text-format encode and decode codegen (two sites)
  • view.rs — view enum definition and merge codegen (three sites)

make_field_ident already handles this correctly for struct fields (selfself_), but the variant path has no equivalent guard.

Fix

Add a make_variant_ident(proto_name: &str) -> Ident helper (analogous to make_field_ident) that applies keyword escaping after PascalCase conversion:

  • self / super / Self / crate — append _ (can't be raw identifiers), e.g. Self_
  • other keywords — use r#name

Replace all eight format_ident!("{}", to_pascal_case(...)) call sites with this helper.

Secondary bug (same root cause exposure)

When run() in protoc-gen-buffa returns an error, the error response sets supported_features (which includes FEATURE_SUPPORTS_EDITIONS) but omits minimum_edition / maximum_edition. buf v1.47+ validates this and rejects the response with a misleading error:

plugin protoc-gen-buffa: CodeGeneratorResponse: supported_features: FEATURE_SUPPORTS_EDITIONS specified but no minimum_edition set

This masks the real codegen failure. The fix is to include minimum_edition and maximum_edition in the error-path response in protoc-gen-buffa/src/main.rs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions