1use protobuf::descriptor::DescriptorProto;
2use protobuf::descriptor::EnumDescriptorProto;
3use protobuf::descriptor::EnumValueDescriptorProto;
4use protobuf::descriptor::FieldDescriptorProto;
5use protobuf::descriptor::FileDescriptorProto;
6use protobuf::descriptor::MethodDescriptorProto;
7use protobuf::descriptor::OneofDescriptorProto;
8use protobuf::descriptor::ServiceDescriptorProto;
9use protobuf::reflect::FieldDescriptor;
10use protobuf::reflect::FileDescriptor;
11use protobuf::reflect::MessageDescriptor;
12use protobuf::MessageFull;
13use protobuf::UnknownFields;
14use protobuf::UnknownValue;
15use protobuf_support::lexer::str_lit::StrLitDecodeError;
16
17use crate::model;
18use crate::model::ProtobufConstant;
19use crate::model::ProtobufConstantMessage;
20use crate::model::ProtobufConstantMessageFieldName;
21use crate::model::ProtobufOptionName;
22use crate::model::ProtobufOptionNameExt;
23use crate::model::ProtobufOptionNamePart;
24use crate::model::WithLoc;
25use crate::protobuf_path::ProtobufPath;
26use crate::pure::convert::Resolver;
27use crate::pure::convert::TypeResolved;
28use crate::ProtobufAbsPath;
29use crate::ProtobufAbsPathRef;
30use crate::ProtobufIdent;
31use crate::ProtobufIdentRef;
32use crate::ProtobufRelPath;
33use crate::ProtobufRelPathRef;
34
35#[derive(Debug, thiserror::Error)]
36enum OptionResolverError {
37 #[error(transparent)]
38 OtherError(anyhow::Error),
39 #[error("extension is not a message: {0}")]
40 ExtensionIsNotMessage(String),
41 #[error("unknown field name: {0}")]
42 UnknownFieldName(String),
43 #[error("wrong extension type: option {0} extendee {1} expected extendee {2}")]
44 WrongExtensionType(String, String, String),
45 #[error("extension not found: {0}")]
46 ExtensionNotFound(String),
47 #[error("unknown enum value: {0}")]
48 UnknownEnumValue(String),
49 #[error("unsupported extension type: {0} {1} {2}")]
50 UnsupportedExtensionType(String, String, model::ProtobufConstant),
51 #[error("builtin option {0} not found for options {1}")]
52 BuiltinOptionNotFound(String, String),
53 #[error("builtin option {0} points to a non-singular field of {1}")]
54 BuiltinOptionPointsToNonSingularField(String, String),
55 #[error("incorrect string literal: {0}")]
56 StrLitDecodeError(#[source] StrLitDecodeError),
57 #[error("wrong option type, expecting {0}, got `{1}`")]
58 WrongOptionType(&'static str, String),
59 #[error("Message field requires a message constant")]
60 MessageFieldRequiresMessageConstant,
61 #[error("message not found by name {0}")]
62 MessageNotFound(ProtobufAbsPath),
63 #[error("message not found by name {0}")]
64 MessageFoundMoreThanOnce(ProtobufAbsPath),
65}
66
67#[derive(Clone)]
68enum LookupScope2 {
69 File(FileDescriptor),
70 Message(MessageDescriptor, ProtobufAbsPath),
71}
72
73impl LookupScope2 {
74 fn current_path(&self) -> ProtobufAbsPath {
75 match self {
76 LookupScope2::File(f) => ProtobufAbsPath::package_from_file_descriptor(f),
77 LookupScope2::Message(_, p) => p.clone(),
78 }
79 }
80
81 fn messages(&self) -> Vec<MessageDescriptor> {
82 match self {
83 LookupScope2::File(file) => file.messages().collect(),
84 LookupScope2::Message(message, _) => message.nested_messages().collect(),
85 }
86 }
87
88 fn down(&self, name: &ProtobufIdentRef) -> Option<LookupScope2> {
89 match self.messages().iter().find(|m| m.name() == name.as_str()) {
90 Some(m) => {
91 let mut path = self.current_path();
92 path.push_simple(name);
93 Some(LookupScope2::Message(m.clone(), path))
94 }
95 None => None,
96 }
97 }
98
99 fn extensions(&self) -> Vec<FieldDescriptor> {
100 match self {
101 LookupScope2::File(f) => f.extensions().collect(),
102 LookupScope2::Message(m, _) => m.extensions().collect(),
103 }
104 }
105}
106
107#[derive(Clone)]
108pub(crate) struct LookupScopeUnion2 {
109 path: ProtobufAbsPath,
110 scopes: Vec<LookupScope2>,
111 partial_scopes: Vec<FileDescriptor>,
112}
113
114impl LookupScopeUnion2 {
115 fn down(&self, name: &ProtobufIdentRef) -> LookupScopeUnion2 {
116 let mut path: ProtobufAbsPath = self.path.clone();
117 path.push_simple(name);
118
119 let mut scopes: Vec<_> = self.scopes.iter().flat_map(|f| f.down(name)).collect();
120 let mut partial_scopes = Vec::new();
121
122 for partial_scope in &self.partial_scopes {
123 let package = ProtobufAbsPath::package_from_file_descriptor(partial_scope);
124 if package.as_ref() == path.as_ref() {
125 scopes.push(LookupScope2::File(partial_scope.clone()));
126 } else if package.starts_with(&path) {
127 partial_scopes.push(partial_scope.clone());
128 }
129 }
130 LookupScopeUnion2 {
131 path,
132 scopes,
133 partial_scopes,
134 }
135 }
136
137 fn lookup(&self, path: &ProtobufRelPath) -> LookupScopeUnion2 {
138 let mut scope = self.clone();
139 for c in path.components() {
140 scope = scope.down(c);
141 }
142 scope
143 }
144
145 fn extensions(&self) -> Vec<FieldDescriptor> {
146 self.scopes.iter().flat_map(|s| s.extensions()).collect()
147 }
148
149 fn as_message(&self) -> anyhow::Result<MessageDescriptor> {
150 let mut messages: Vec<MessageDescriptor> = self
151 .scopes
152 .iter()
153 .filter_map(|s| match s {
154 LookupScope2::Message(m, _) => Some(m.clone()),
155 _ => None,
156 })
157 .collect();
158 let message = match messages.pop() {
159 Some(m) => m,
160 None => return Err(OptionResolverError::MessageNotFound(self.path.clone()).into()),
161 };
162 if !messages.is_empty() {
163 return Err(OptionResolverError::MessageFoundMoreThanOnce(self.path.clone()).into());
164 }
165 Ok(message)
166 }
167}
168
169pub(crate) trait ProtobufOptions {
170 fn by_name(&self, name: &str) -> Option<&model::ProtobufConstant>;
171
172 fn _by_name_bool(&self, name: &str) -> anyhow::Result<Option<bool>> {
173 match self.by_name(name) {
174 Some(model::ProtobufConstant::Bool(b)) => Ok(Some(*b)),
175 Some(c) => Err(OptionResolverError::WrongOptionType("bool", c.to_string()).into()),
176 None => Ok(None),
177 }
178 }
179
180 fn by_name_string(&self, name: &str) -> anyhow::Result<Option<String>> {
181 match self.by_name(name) {
182 Some(model::ProtobufConstant::String(s)) => s
183 .decode_utf8()
184 .map(Some)
185 .map_err(|e| OptionResolverError::StrLitDecodeError(e).into()),
186 Some(c) => Err(OptionResolverError::WrongOptionType("string", c.to_string()).into()),
187 None => Ok(None),
188 }
189 }
190}
191
192impl<'a> ProtobufOptions for &'a [model::ProtobufOption] {
193 fn by_name(&self, name: &str) -> Option<&model::ProtobufConstant> {
194 let option_name = ProtobufOptionName::simple(name);
195 for model::ProtobufOption { name, value } in *self {
196 if name == &option_name {
197 return Some(&value);
198 }
199 }
200 None
201 }
202}
203
204pub(crate) struct OptionResoler<'a> {
205 pub(crate) resolver: &'a Resolver<'a>,
206 pub(crate) descriptor_without_options: FileDescriptor,
207}
208
209impl<'a> OptionResoler<'a> {
210 fn all_files(&self) -> Vec<FileDescriptor> {
211 let mut files = Vec::new();
212 files.push(self.descriptor_without_options.clone());
213 files.extend(
214 self.resolver
215 .type_resolver
216 .deps
217 .iter()
218 .map(|p| p.descriptor.clone()),
219 );
220 files
221 }
222
223 fn root_scope(&self) -> LookupScopeUnion2 {
224 let (scopes, partial_scopes) = self
225 .all_files()
226 .into_iter()
227 .partition::<Vec<_>, _>(|f| ProtobufAbsPath::package_from_file_descriptor(f).is_root());
228 LookupScopeUnion2 {
229 path: ProtobufAbsPath::root(),
230 scopes: scopes.into_iter().map(LookupScope2::File).collect(),
231 partial_scopes,
232 }
233 }
234
235 fn lookup(&self, path: &ProtobufAbsPath) -> LookupScopeUnion2 {
236 self.root_scope().lookup(&path.to_root_rel())
237 }
238
239 fn find_message_by_abs_name(
240 &self,
241 path: &ProtobufAbsPath,
242 ) -> anyhow::Result<MessageDescriptor> {
243 let scope = self.lookup(path);
244 scope.as_message()
245 }
246
247 fn scope_resolved_candidates_rel(
248 scope: &ProtobufAbsPathRef,
249 rel: &ProtobufRelPathRef,
250 ) -> Vec<ProtobufAbsPath> {
251 scope
252 .self_and_parents()
253 .into_iter()
254 .map(|a| {
255 let mut a = a.to_owned();
256 a.push_relative(rel);
257 a
258 })
259 .collect()
260 }
261
262 fn scope_resolved_candidates(
263 scope: &ProtobufAbsPathRef,
264 path: &ProtobufPath,
265 ) -> Vec<ProtobufAbsPath> {
266 match path {
267 ProtobufPath::Abs(p) => vec![p.clone()],
268 ProtobufPath::Rel(p) => Self::scope_resolved_candidates_rel(scope, p),
269 }
270 }
271
272 fn find_extension_by_abs_path(
273 &self,
274 path: &ProtobufAbsPathRef,
275 ) -> anyhow::Result<Option<FieldDescriptor>> {
276 let mut path = path.to_owned();
277 let extension = path.pop().unwrap();
278
279 let scope = self.lookup(&path);
280
281 for ext in scope.extensions() {
282 if ext.name() == extension.get() {
283 return Ok(Some(ext.clone()));
284 }
285 }
286
287 Ok(None)
288 }
289
290 fn find_extension_by_path(
291 &self,
292 scope: &ProtobufAbsPathRef,
293 path: &ProtobufPath,
294 ) -> anyhow::Result<FieldDescriptor> {
295 for candidate in Self::scope_resolved_candidates(scope, path) {
296 if let Some(e) = self.find_extension_by_abs_path(&candidate)? {
297 return Ok(e);
298 }
299 }
300
301 Err(OptionResolverError::ExtensionNotFound(path.to_string()).into())
302 }
303
304 fn ext_resolve_field_ext(
305 &self,
306 scope: &ProtobufAbsPathRef,
307 message: &MessageDescriptor,
308 field_name: &ProtobufPath,
309 ) -> anyhow::Result<FieldDescriptor> {
310 let expected_extendee = ProtobufAbsPath::from_message(message);
311 let field = self.find_extension_by_path(scope, field_name)?;
312 if ProtobufAbsPath::new(field.proto().extendee()) != expected_extendee {
313 return Err(OptionResolverError::WrongExtensionType(
314 format!("{}", field_name),
315 format!("{}", field.proto().extendee()),
316 format!("{}", expected_extendee),
317 )
318 .into());
319 }
320
321 Ok(field)
322 }
323
324 fn ext_resolve_field(
325 &self,
326 scope: &ProtobufAbsPathRef,
327 message: &MessageDescriptor,
328 field: &ProtobufOptionNamePart,
329 ) -> anyhow::Result<FieldDescriptor> {
330 match field {
331 ProtobufOptionNamePart::Direct(field) => match message.field_by_name(field.get()) {
332 Some(field) => Ok(field),
333 None => Err(OptionResolverError::UnknownFieldName(field.to_string()).into()),
334 },
335 ProtobufOptionNamePart::Ext(field) => {
336 Ok(self.ext_resolve_field_ext(scope, message, field)?)
337 }
338 }
339 }
340
341 fn custom_option_ext_step(
342 &self,
343 scope: &ProtobufAbsPathRef,
344 options_type: &MessageDescriptor,
345 unknown_fields: &mut UnknownFields,
346 option_name: &ProtobufOptionNamePart,
347 option_name_rem: &[ProtobufOptionNamePart],
348 option_value: &ProtobufConstant,
349 ) -> anyhow::Result<()> {
350 let field = self.ext_resolve_field(scope, options_type, option_name)?;
351
352 let field_type = TypeResolved::from_field(field.proto());
353
354 match option_name_rem.split_first() {
355 Some((first, rem)) => {
356 match field_type {
357 TypeResolved::Message(message_name) => {
358 let m = self.find_message_by_abs_name(&message_name)?;
359 let mut message_unknown_fields = UnknownFields::new();
360 self.custom_option_ext_step(
361 scope,
362 &m,
363 &mut message_unknown_fields,
364 first,
365 rem,
366 option_value,
367 )?;
368 unknown_fields.add_length_delimited(
369 field.proto().number() as u32,
370 message_unknown_fields.write_to_bytes(),
371 );
372 Ok(())
373 }
374 TypeResolved::Group(..) => {
375 Ok(())
377 }
378 _ => Err(OptionResolverError::ExtensionIsNotMessage(format!(
379 "scope: {}, option name: {}",
380 scope, option_name
381 ))
382 .into()),
383 }
384 }
385 None => self
386 .add_option_value_to_unknown_fields(
387 &field_type,
388 field.number() as u32,
389 unknown_fields,
390 option_value,
391 &format!("{}", option_name),
392 )
393 .map_err(|err| {
394 err.context(format!(
395 "parsing custom option `{}` value `{}` at `{}`",
396 option_name, option_value, scope
397 ))
398 }),
399 }
400 }
401
402 fn add_option_value_to_unknown_fields(
403 &self,
404 field_type: &TypeResolved,
405 field_num: u32,
406 unknown_fields: &mut UnknownFields,
407 option_value: &ProtobufConstant,
408 option_name_for_diag: &str,
409 ) -> anyhow::Result<()> {
410 let error = || {
411 OptionResolverError::UnsupportedExtensionType(
412 option_name_for_diag.to_owned(),
413 format!("{:?}", field_type),
414 option_value.clone(),
415 )
416 };
417
418 match option_value {
419 ProtobufConstant::U64(v) => match field_type {
420 TypeResolved::Fixed64 => unknown_fields.add_value(field_num, Self::fixed64(*v)?),
421 TypeResolved::Sfixed64 => unknown_fields.add_value(field_num, Self::sfixed64(*v)?),
422 TypeResolved::Fixed32 => unknown_fields.add_value(field_num, Self::fixed32(*v)?),
423 TypeResolved::Sfixed32 => unknown_fields.add_value(field_num, Self::sfixed32(*v)?),
424 TypeResolved::Int32 => unknown_fields.add_value(field_num, Self::int32(*v)?),
425 TypeResolved::Int64 => unknown_fields.add_value(field_num, Self::int64(*v)?),
426 TypeResolved::Uint64 => unknown_fields.add_value(field_num, Self::uint64(*v)?),
427 TypeResolved::Uint32 => unknown_fields.add_value(field_num, Self::uint32(*v)?),
428 TypeResolved::Sint64 => unknown_fields.add_value(field_num, Self::sint64(*v)?),
429 TypeResolved::Sint32 => unknown_fields.add_value(field_num, Self::sint32(*v)?),
430 TypeResolved::Float => {
431 unknown_fields.add_value(field_num, UnknownValue::float(*v as f32))
432 }
433 TypeResolved::Double => {
434 unknown_fields.add_value(field_num, UnknownValue::double(*v as f64))
435 }
436 _ => return Err(error().into()),
437 },
438 ProtobufConstant::I64(v) => match field_type {
439 TypeResolved::Fixed64 => unknown_fields.add_value(field_num, Self::fixed64(*v)?),
440 TypeResolved::Sfixed64 => unknown_fields.add_value(field_num, Self::sfixed64(*v)?),
441 TypeResolved::Fixed32 => unknown_fields.add_value(field_num, Self::fixed32(*v)?),
442 TypeResolved::Sfixed32 => unknown_fields.add_value(field_num, Self::sfixed32(*v)?),
443 TypeResolved::Int32 => unknown_fields.add_value(field_num, Self::int32(*v)?),
444 TypeResolved::Int64 => unknown_fields.add_value(field_num, Self::int64(*v)?),
445 TypeResolved::Uint64 => unknown_fields.add_value(field_num, Self::uint64(*v)?),
446 TypeResolved::Uint32 => unknown_fields.add_value(field_num, Self::uint32(*v)?),
447 TypeResolved::Sint64 => unknown_fields.add_value(field_num, Self::sint64(*v)?),
448 TypeResolved::Sint32 => unknown_fields.add_value(field_num, Self::sint32(*v)?),
449 TypeResolved::Float => {
450 unknown_fields.add_value(field_num, UnknownValue::float(*v as f32))
451 }
452 TypeResolved::Double => {
453 unknown_fields.add_value(field_num, UnknownValue::double(*v as f64))
454 }
455 _ => return Err(error().into()),
456 },
457 ProtobufConstant::F64(f) => match field_type {
458 TypeResolved::Float => {
459 unknown_fields.add_value(field_num, UnknownValue::float(*f as f32))
460 }
461 TypeResolved::Double => {
462 unknown_fields.add_value(field_num, UnknownValue::double(*f))
463 }
464 TypeResolved::Fixed32 => {
465 unknown_fields.add_value(field_num, UnknownValue::Fixed32(*f as u32))
466 }
467 TypeResolved::Fixed64 => {
468 unknown_fields.add_value(field_num, UnknownValue::Fixed64(*f as u64))
469 }
470 TypeResolved::Sfixed32 => {
471 unknown_fields.add_value(field_num, UnknownValue::sfixed32(*f as i32))
472 }
473 TypeResolved::Sfixed64 => {
474 unknown_fields.add_value(field_num, UnknownValue::sfixed64(*f as i64))
475 }
476 TypeResolved::Sint64 => {
477 unknown_fields.add_value(field_num, UnknownValue::sint64(*f as i64))
478 }
479 TypeResolved::Sint32 => {
480 unknown_fields.add_value(field_num, UnknownValue::sint32(*f as i32))
481 }
482 TypeResolved::Int32 | TypeResolved::Int64 => {
483 unknown_fields.add_value(field_num, UnknownValue::int64(*f as i64))
484 }
485 TypeResolved::Uint32 | TypeResolved::Uint64 => {
486 unknown_fields.add_value(field_num, UnknownValue::Varint(*f as u64))
487 }
488 _ => return Err(error().into()),
489 },
490 ProtobufConstant::Bool(b) => match field_type {
491 TypeResolved::Bool => unknown_fields
492 .add_value(field_num, UnknownValue::Varint(if *b { 1 } else { 0 })),
493 _ => return Err(error().into()),
494 },
495 ProtobufConstant::Ident(ident) => match field_type {
496 TypeResolved::Enum(abs_path) => {
497 let n = self
498 .resolver
499 .find_enum_by_abs_name(abs_path)
500 .map_err(OptionResolverError::OtherError)?
501 .values
502 .iter()
503 .find(|v| v.name == ident.to_string())
504 .map(|v| v.number)
505 .ok_or_else(|| OptionResolverError::UnknownEnumValue(ident.to_string()))?;
506
507 unknown_fields.add_value(field_num, UnknownValue::int32(n));
508 }
509 _ => return Err(error().into()),
510 },
511 ProtobufConstant::String(s) => match field_type {
512 TypeResolved::String => unknown_fields.add_value(
513 field_num,
514 UnknownValue::LengthDelimited(s.decode_utf8()?.into_bytes()),
515 ),
516 TypeResolved::Bytes => unknown_fields
517 .add_value(field_num, UnknownValue::LengthDelimited(s.decode_bytes()?)),
518 _ => return Err(error().into()),
519 },
520 ProtobufConstant::Message(message) => self.add_option_value_message_to_unknown_fields(
521 field_type,
522 field_num,
523 unknown_fields,
524 message,
525 &option_name_for_diag,
526 )?,
527 ProtobufConstant::Repeated(list) => {
528 for v in list {
529 self.add_option_value_to_unknown_fields(
530 field_type,
531 field_num,
532 unknown_fields,
533 v,
534 option_name_for_diag,
535 )?
536 }
537 }
538 }
539
540 Ok(())
541 }
542
543 fn custom_option_ext<M>(
544 &self,
545 scope: &ProtobufAbsPathRef,
546 options: &mut M,
547 option_name: &ProtobufOptionNameExt,
548 option_value: &ProtobufConstant,
549 ) -> anyhow::Result<()>
550 where
551 M: MessageFull,
552 {
553 self.custom_option_ext_step(
554 scope,
555 &M::descriptor(),
556 options.mut_unknown_fields(),
557 &option_name.0[0],
558 &option_name.0[1..],
559 option_value,
560 )
561 }
562
563 fn fixed32(
564 v: impl TryInto<u32, Error = impl std::error::Error + Send + Sync + 'static>,
565 ) -> anyhow::Result<UnknownValue> {
566 Ok(UnknownValue::Fixed32(v.try_into()?))
567 }
568
569 fn sfixed32(
570 v: impl TryInto<i32, Error = impl std::error::Error + Send + Sync + 'static>,
571 ) -> anyhow::Result<UnknownValue> {
572 Ok(UnknownValue::sfixed32(v.try_into()?))
573 }
574
575 fn fixed64(
576 v: impl TryInto<u64, Error = impl std::error::Error + Send + Sync + 'static>,
577 ) -> anyhow::Result<UnknownValue> {
578 Ok(UnknownValue::Fixed64(v.try_into()?))
579 }
580
581 fn sfixed64(
582 v: impl TryInto<i64, Error = impl std::error::Error + Send + Sync + 'static>,
583 ) -> anyhow::Result<UnknownValue> {
584 Ok(UnknownValue::sfixed64(v.try_into()?))
585 }
586
587 fn int32(
588 v: impl TryInto<i32, Error = impl std::error::Error + Send + Sync + 'static>,
589 ) -> anyhow::Result<UnknownValue> {
590 Ok(UnknownValue::int32(v.try_into()?))
591 }
592
593 fn int64(
594 v: impl TryInto<i64, Error = impl std::error::Error + Send + Sync + 'static>,
595 ) -> anyhow::Result<UnknownValue> {
596 Ok(UnknownValue::int64(v.try_into()?))
597 }
598
599 fn uint32(
600 v: impl TryInto<u32, Error = impl std::error::Error + Send + Sync + 'static>,
601 ) -> anyhow::Result<UnknownValue> {
602 Ok(UnknownValue::Varint(v.try_into()? as u64))
603 }
604
605 fn uint64(
606 v: impl TryInto<u64, Error = impl std::error::Error + Send + Sync + 'static>,
607 ) -> anyhow::Result<UnknownValue> {
608 Ok(UnknownValue::Varint(v.try_into()?))
609 }
610
611 fn sint32(
612 v: impl TryInto<i32, Error = impl std::error::Error + Send + Sync + 'static>,
613 ) -> anyhow::Result<UnknownValue> {
614 Ok(UnknownValue::sint32(v.try_into()?))
615 }
616
617 fn sint64(
618 v: impl TryInto<i64, Error = impl std::error::Error + Send + Sync + 'static>,
619 ) -> anyhow::Result<UnknownValue> {
620 Ok(UnknownValue::sint64(v.try_into()?))
621 }
622
623 fn add_option_value_message_to_unknown_fields(
624 &self,
625 field_type: &TypeResolved,
626 field_num: u32,
627 options: &mut UnknownFields,
628 option_value: &ProtobufConstantMessage,
629 option_name_for_diag: &str,
630 ) -> anyhow::Result<()> {
631 match &field_type {
632 TypeResolved::Message(ma) => {
633 let m = self
634 .resolver
635 .find_message_by_abs_name(ma)
636 .map_err(OptionResolverError::OtherError)?
637 .t;
638 let mut unknown_fields = UnknownFields::new();
639 for (n, v) in &option_value.fields {
640 match n {
641 ProtobufConstantMessageFieldName::Regular(n) => {
642 let field = m
643 .field_by_name(n.as_str())
644 .ok_or_else(|| OptionResolverError::UnknownFieldName(n.clone()))?;
645
646 let field_type = self.resolver.field_type(&ma, n, &field.typ)?;
647
648 self.add_option_value_to_unknown_fields(
649 &field_type,
650 field.number as u32,
651 &mut unknown_fields,
652 v,
653 option_name_for_diag,
654 )
655 .map_err(OptionResolverError::OtherError)?;
656 }
657 ProtobufConstantMessageFieldName::Extension(..) => {
658 }
660 ProtobufConstantMessageFieldName::AnyTypeUrl(..) => {
661 }
663 }
664 }
665
666 options.add_value(
667 field_num,
668 UnknownValue::LengthDelimited(unknown_fields.write_to_bytes()),
669 );
670
671 Ok(())
672 }
673 _ => Err(OptionResolverError::MessageFieldRequiresMessageConstant.into()),
674 }
675 }
676
677 fn custom_option_builtin<M>(
678 &self,
679 _scope: &ProtobufAbsPathRef,
680 options: &mut M,
681 option: &ProtobufIdent,
682 option_value: &ProtobufConstant,
683 ) -> anyhow::Result<()>
684 where
685 M: MessageFull,
686 {
687 if M::descriptor().full_name() == "google.protobuf.FieldOptions" {
688 if option.get() == "default" || option.get() == "json_name" {
689 return Ok(());
691 }
692 }
693 match M::descriptor().field_by_name(option.get()) {
694 Some(field) => {
695 if field.is_repeated_or_map() {
696 return Err(OptionResolverError::BuiltinOptionPointsToNonSingularField(
697 M::descriptor().full_name().to_owned(),
698 option.get().to_owned(),
699 )
700 .into());
701 }
702
703 field.set_singular_field(
704 options,
705 option_value.as_type(field.singular_runtime_type())?,
706 );
707 return Ok(());
708 }
709 None => {
710 return Err(OptionResolverError::BuiltinOptionNotFound(
711 M::descriptor().full_name().to_owned(),
712 option.get().to_owned(),
713 )
714 .into())
715 }
716 }
717 }
718
719 fn custom_option<M>(
720 &self,
721 scope: &ProtobufAbsPathRef,
722 options: &mut M,
723 option: &model::ProtobufOption,
724 ) -> anyhow::Result<()>
725 where
726 M: MessageFull,
727 {
728 match &option.name {
729 ProtobufOptionName::Builtin(simple) => {
730 self.custom_option_builtin(scope, options, simple, &option.value)
731 }
732 ProtobufOptionName::Ext(e) => self.custom_option_ext(scope, options, e, &option.value),
733 }
734 }
735
736 fn custom_options<M>(
737 &self,
738 scope: &ProtobufAbsPathRef,
739 input: &[model::ProtobufOption],
740 ) -> anyhow::Result<Option<M>>
741 where
742 M: MessageFull,
743 {
744 if input.is_empty() {
745 return Ok(None);
748 }
749
750 let mut options = M::new();
751
752 for option in input {
753 self.custom_option(scope, &mut options, option)?;
754 }
755 Ok(Some(options))
756 }
757
758 fn file_options(
759 &self,
760 scope: &ProtobufAbsPath,
761 input: &[model::ProtobufOption],
762 ) -> anyhow::Result<Option<protobuf::descriptor::FileOptions>> {
763 self.custom_options(scope, input)
764 }
765
766 fn enum_options(
767 &self,
768 scope: &ProtobufAbsPathRef,
769 input: &[model::ProtobufOption],
770 ) -> anyhow::Result<Option<protobuf::descriptor::EnumOptions>> {
771 self.custom_options(scope, input)
772 }
773
774 fn enum_value_options(
775 &self,
776 scope: &ProtobufAbsPathRef,
777 input: &[model::ProtobufOption],
778 ) -> anyhow::Result<Option<protobuf::descriptor::EnumValueOptions>> {
779 self.custom_options(scope, input)
780 }
781
782 fn field_options(
783 &self,
784 scope: &ProtobufAbsPathRef,
785 input: &[model::ProtobufOption],
786 ) -> anyhow::Result<Option<protobuf::descriptor::FieldOptions>> {
787 self.custom_options(scope, input)
788 }
789
790 fn message_options(
791 &self,
792 scope: &ProtobufAbsPathRef,
793 input: &[model::ProtobufOption],
794 ) -> anyhow::Result<Option<protobuf::descriptor::MessageOptions>> {
795 self.custom_options(scope, input)
796 }
797
798 fn oneof_options(
799 &self,
800 scope: &ProtobufAbsPathRef,
801 input: &[model::ProtobufOption],
802 ) -> anyhow::Result<Option<protobuf::descriptor::OneofOptions>> {
803 self.custom_options(scope, input)
804 }
805
806 fn method(
807 &self,
808 method_proto: &mut MethodDescriptorProto,
809 method_model: &model::Method,
810 ) -> anyhow::Result<()> {
811 method_proto.options = self.service_method_options(&method_model.options)?.into();
812 Ok(())
813 }
814
815 fn service_options(
816 &self,
817 input: &[model::ProtobufOption],
818 ) -> anyhow::Result<Option<protobuf::descriptor::ServiceOptions>> {
819 self.custom_options(&self.resolver.current_file.package, input)
820 }
821
822 fn service_method_options(
823 &self,
824 input: &[model::ProtobufOption],
825 ) -> anyhow::Result<Option<protobuf::descriptor::MethodOptions>> {
826 self.custom_options(&self.resolver.current_file.package, input)
827 }
828
829 fn service(
830 &self,
831 service_proto: &mut ServiceDescriptorProto,
832 service_model: &WithLoc<model::Service>,
833 ) -> anyhow::Result<()> {
834 service_proto.options = self.service_options(&service_model.options)?.into();
835
836 for service_method_model in &service_model.methods {
837 let mut method_proto = service_proto
838 .method
839 .iter_mut()
840 .find(|method| method.name() == service_method_model.name)
841 .unwrap();
842 self.method(&mut method_proto, service_method_model)?;
843 }
844
845 Ok(())
846 }
847
848 fn enum_value(
849 &self,
850 scope: &ProtobufAbsPathRef,
851 enum_value_proto: &mut EnumValueDescriptorProto,
852 enum_value_model: &model::EnumValue,
853 ) -> anyhow::Result<()> {
854 enum_value_proto.options = self
855 .enum_value_options(scope, &enum_value_model.options)?
856 .into();
857 Ok(())
858 }
859
860 fn enumeration(
861 &self,
862 scope: &ProtobufAbsPathRef,
863 enum_proto: &mut EnumDescriptorProto,
864 enum_model: &WithLoc<model::Enumeration>,
865 ) -> anyhow::Result<()> {
866 enum_proto.options = self.enum_options(scope, &enum_model.options)?.into();
867
868 for enum_value_model in &enum_model.values {
869 let mut enum_value_proto = enum_proto
870 .value
871 .iter_mut()
872 .find(|v| v.name() == enum_value_model.name)
873 .unwrap();
874 self.enum_value(scope, &mut enum_value_proto, enum_value_model)?;
875 }
876
877 Ok(())
878 }
879
880 fn oneof(
881 &self,
882 scope: &ProtobufAbsPathRef,
883 oneof_proto: &mut OneofDescriptorProto,
884 oneof_model: &model::OneOf,
885 ) -> anyhow::Result<()> {
886 oneof_proto.options = self.oneof_options(scope, &oneof_model.options)?.into();
887 Ok(())
888 }
889
890 fn field(
891 &self,
892 scope: &ProtobufAbsPathRef,
893 field_proto: &mut FieldDescriptorProto,
894 field_model: &model::Field,
895 ) -> anyhow::Result<()> {
896 field_proto.options = self.field_options(scope, &field_model.options)?.into();
897 Ok(())
898 }
899
900 fn message(
901 &self,
902 scope: &ProtobufAbsPathRef,
903 message_proto: &mut DescriptorProto,
904 message_model: &WithLoc<model::Message>,
905 ) -> anyhow::Result<()> {
906 message_proto.options = self.message_options(scope, &message_model.options)?.into();
907
908 let mut nested_scope = scope.to_owned();
909 nested_scope.push_simple(ProtobufIdentRef::new(&message_proto.name()));
910
911 for field_model in &message_model.regular_fields_including_in_oneofs() {
912 let mut field_proto = message_proto
913 .field
914 .iter_mut()
915 .find(|field| field.name() == field_model.name)
916 .unwrap();
917 self.field(&nested_scope, &mut field_proto, field_model)?;
918 }
919 for field_model in &message_model.extensions {
920 let field_proto = message_proto
921 .extension
922 .iter_mut()
923 .find(|field| field.name() == field_model.field.name)
924 .unwrap();
925 self.field(&nested_scope, field_proto, &field_model.field)?;
926 }
927
928 for nested_message_model in &message_model.messages {
929 let nested_message_proto = message_proto
930 .nested_type
931 .iter_mut()
932 .find(|nested_message_proto| {
933 nested_message_proto.name() == nested_message_model.name
934 })
935 .unwrap();
936 self.message(&nested_scope, nested_message_proto, nested_message_model)?;
937 }
938
939 for nested_enum_model in &message_model.enums {
940 let nested_enum_proto = message_proto
941 .enum_type
942 .iter_mut()
943 .find(|nested_enum_proto| nested_enum_proto.name() == nested_enum_model.name)
944 .unwrap();
945 self.enumeration(&nested_scope, nested_enum_proto, nested_enum_model)?;
946 }
947
948 for oneof_model in &message_model.oneofs() {
949 let oneof_proto = message_proto
950 .oneof_decl
951 .iter_mut()
952 .find(|oneof_proto| oneof_proto.name() == oneof_model.name)
953 .unwrap();
954 self.oneof(&nested_scope, oneof_proto, oneof_model)?;
955 }
956
957 Ok(())
958 }
959
960 pub(crate) fn file(&self, output: &mut FileDescriptorProto) -> anyhow::Result<()> {
961 let _ = &self.descriptor_without_options;
963
964 for message_model in &self.resolver.current_file.messages {
965 let message_proto = output
966 .message_type
967 .iter_mut()
968 .find(|m| m.name() == message_model.name)
969 .unwrap();
970 self.message(
971 &self.resolver.current_file.package,
972 message_proto,
973 message_model,
974 )?;
975 }
976
977 for enum_model in &self.resolver.current_file.enums {
978 let enum_proto = output
979 .enum_type
980 .iter_mut()
981 .find(|e| e.name() == enum_model.name)
982 .unwrap();
983 self.enumeration(&self.resolver.current_file.package, enum_proto, enum_model)?;
984 }
985
986 for service_proto in &mut output.service {
987 let service_model = self
988 .resolver
989 .current_file
990 .services
991 .iter()
992 .find(|s| s.name == service_proto.name())
993 .unwrap();
994 self.service(service_proto, service_model)?;
995 }
996
997 for extension_model in &self.resolver.current_file.extensions {
998 let extension_proto = output
999 .extension
1000 .iter_mut()
1001 .find(|e| e.name() == extension_model.field.name)
1002 .unwrap();
1003 self.field(
1004 &self.resolver.current_file.package,
1005 extension_proto,
1006 &extension_model.field,
1007 )?;
1008 }
1009
1010 output.options = self
1011 .file_options(
1012 &self.resolver.current_file.package,
1013 &self.resolver.current_file.options,
1014 )?
1015 .into();
1016
1017 Ok(())
1018 }
1019}