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}