Skip to main content

buffa_reflect/
error.rs

1//! Errors raised when constructing or querying a [`crate::DescriptorPool`].
2
3use buffa::DecodeError;
4
5/// All ways descriptor pool construction or lookup can fail.
6#[derive(Debug, thiserror::Error)]
7#[non_exhaustive]
8pub enum DescriptorError {
9    /// The serialized `FileDescriptorSet` bytes could not be parsed.
10    #[error("failed to decode FileDescriptorSet bytes: {0}")]
11    Decode(#[from] DecodeError),
12
13    /// A `FileDescriptorProto.name` field was missing.
14    #[error("file descriptor is missing the required `name` field")]
15    MissingFileName,
16
17    /// A nested type (message / enum / field / oneof) had no `name` set.
18    #[error("descriptor in `{location}` is missing the required `name` field")]
19    MissingName {
20        /// Containing context (file or fully-qualified message name) for the
21        /// offending descriptor.
22        location: String,
23    },
24
25    /// A field referenced a `type_name` that no descriptor in the pool
26    /// defines.
27    #[error("field `{field}` references unknown type `{type_name}`")]
28    UnresolvedType {
29        /// Fully-qualified name of the field whose `type_name` is dangling.
30        field: String,
31        /// The unresolved `type_name` value verbatim.
32        type_name: String,
33    },
34
35    /// Two descriptors share the same fully-qualified name within a single
36    /// pool.
37    #[error("duplicate type definition: `{0}`")]
38    DuplicateType(String),
39
40    /// Two `FileDescriptorProto`s carry the same `name`.
41    #[error("duplicate file descriptor: `{0}`")]
42    DuplicateFile(String),
43
44    /// proto3 forbids `LABEL_REQUIRED`. The descriptor declared one anyway.
45    #[error("field `{field}` uses `required` in a proto3 file")]
46    Proto3RequiredField {
47        /// Fully-qualified field name.
48        field: String,
49    },
50
51    /// A field declared a number outside the protobuf-permitted range or
52    /// inside the reserved internal range.
53    #[error(
54        "invalid field number {number} in `{message}`: must be in 1..={max} and outside \
55         19000..=19999"
56    )]
57    InvalidFieldNumber {
58        /// Fully-qualified message name owning the field.
59        message: String,
60        /// The offending number as it appeared on the descriptor.
61        number: i32,
62        /// Maximum permissible field number (`536_870_911`).
63        max: u32,
64    },
65
66    /// `FieldDescriptorProto.type` was unset and no `type_name` was supplied
67    /// — we cannot resolve the field's [`crate::Kind`].
68    #[error("field `{field}` is missing both `type` and `type_name`")]
69    MissingFieldType {
70        /// Fully-qualified field name.
71        field: String,
72    },
73
74    /// `FieldDescriptorProto.type` was
75    /// [`MESSAGE`](buffa_descriptor::generated::descriptor::field_descriptor_proto::Type)
76    /// or `GROUP`/`ENUM` but `type_name` was empty.
77    #[error("field `{field}` has type {kind:?} but no `type_name`")]
78    MissingTypeName {
79        /// Fully-qualified field name.
80        field: String,
81        /// The descriptor's declared `type` enum value.
82        kind: &'static str,
83    },
84
85    /// A `oneof_index` referenced a slot that does not exist in the
86    /// containing message's `oneof_decl` list.
87    #[error("field `{field}` references oneof index {index} but message has only {count} oneofs")]
88    InvalidOneofIndex {
89        /// Fully-qualified field name.
90        field: String,
91        /// The offending oneof index.
92        index: i32,
93        /// Number of `oneof_decl` entries in the containing message.
94        count: usize,
95    },
96
97    /// A proto3 enum is missing a variant with value `0` (required for
98    /// proto3 default semantics).
99    #[error("proto3 enum `{0}` is missing the required value-0 variant")]
100    Proto3EnumMissingZero(String),
101
102    /// `FieldDescriptorProto.default_value` could not be parsed against
103    /// the field's resolved kind.
104    #[error("invalid default value for field `{field}`: `{value}` ({message})")]
105    InvalidDefaultValue {
106        /// Fully-qualified field name.
107        field: String,
108        /// The literal string that failed to parse.
109        value: String,
110        /// Parser-level diagnostic.
111        message: String,
112    },
113
114    /// Generic descriptor-validation failure.
115    #[error("descriptor validation: {0}")]
116    Validation(String),
117}