1mod group;
2mod map;
3mod message;
4mod oneof;
5mod scalar;
6
7use std::fmt;
8use std::slice;
9
10use anyhow::{bail, Error};
11use proc_macro2::TokenStream;
12use quote::quote;
13use syn::punctuated::Punctuated;
14use syn::{Attribute, Expr, ExprLit, Lit, LitBool, LitInt, Meta, MetaNameValue, Token};
15
16#[derive(Clone)]
17pub enum Field {
18 Scalar(scalar::Field),
20 Message(message::Field),
22 Map(map::Field),
24 Oneof(oneof::Field),
26 Group(group::Field),
28}
29
30impl Field {
31 pub fn new(attrs: Vec<Attribute>, inferred_tag: Option<u32>) -> Result<Option<Field>, Error> {
36 let attrs = prost_attrs(attrs)?;
37
38 let field = if let Some(field) = scalar::Field::new(&attrs, inferred_tag)? {
41 Field::Scalar(field)
42 } else if let Some(field) = message::Field::new(&attrs, inferred_tag)? {
43 Field::Message(field)
44 } else if let Some(field) = map::Field::new(&attrs, inferred_tag)? {
45 Field::Map(field)
46 } else if let Some(field) = oneof::Field::new(&attrs)? {
47 Field::Oneof(field)
48 } else if let Some(field) = group::Field::new(&attrs, inferred_tag)? {
49 Field::Group(field)
50 } else {
51 bail!("no type attribute");
52 };
53
54 Ok(Some(field))
55 }
56
57 pub fn new_oneof(attrs: Vec<Attribute>) -> Result<Option<Field>, Error> {
62 let attrs = prost_attrs(attrs)?;
63
64 let field = if let Some(field) = scalar::Field::new_oneof(&attrs)? {
67 Field::Scalar(field)
68 } else if let Some(field) = message::Field::new_oneof(&attrs)? {
69 Field::Message(field)
70 } else if let Some(field) = map::Field::new_oneof(&attrs)? {
71 Field::Map(field)
72 } else if let Some(field) = group::Field::new_oneof(&attrs)? {
73 Field::Group(field)
74 } else {
75 bail!("no type attribute for oneof field");
76 };
77
78 Ok(Some(field))
79 }
80
81 pub fn tags(&self) -> Vec<u32> {
82 match *self {
83 Field::Scalar(ref scalar) => vec![scalar.tag],
84 Field::Message(ref message) => vec![message.tag],
85 Field::Map(ref map) => vec![map.tag],
86 Field::Oneof(ref oneof) => oneof.tags.clone(),
87 Field::Group(ref group) => vec![group.tag],
88 }
89 }
90
91 pub fn encode(&self, ident: TokenStream) -> TokenStream {
93 match *self {
94 Field::Scalar(ref scalar) => scalar.encode(ident),
95 Field::Message(ref message) => message.encode(ident),
96 Field::Map(ref map) => map.encode(ident),
97 Field::Oneof(ref oneof) => oneof.encode(ident),
98 Field::Group(ref group) => group.encode(ident),
99 }
100 }
101
102 pub fn merge(&self, ident: TokenStream) -> TokenStream {
105 match *self {
106 Field::Scalar(ref scalar) => scalar.merge(ident),
107 Field::Message(ref message) => message.merge(ident),
108 Field::Map(ref map) => map.merge(ident),
109 Field::Oneof(ref oneof) => oneof.merge(ident),
110 Field::Group(ref group) => group.merge(ident),
111 }
112 }
113
114 pub fn encoded_len(&self, ident: TokenStream) -> TokenStream {
116 match *self {
117 Field::Scalar(ref scalar) => scalar.encoded_len(ident),
118 Field::Map(ref map) => map.encoded_len(ident),
119 Field::Message(ref msg) => msg.encoded_len(ident),
120 Field::Oneof(ref oneof) => oneof.encoded_len(ident),
121 Field::Group(ref group) => group.encoded_len(ident),
122 }
123 }
124
125 pub fn clear(&self, ident: TokenStream) -> TokenStream {
127 match *self {
128 Field::Scalar(ref scalar) => scalar.clear(ident),
129 Field::Message(ref message) => message.clear(ident),
130 Field::Map(ref map) => map.clear(ident),
131 Field::Oneof(ref oneof) => oneof.clear(ident),
132 Field::Group(ref group) => group.clear(ident),
133 }
134 }
135
136 pub fn default(&self) -> TokenStream {
137 match *self {
138 Field::Scalar(ref scalar) => scalar.default(),
139 _ => quote!(::core::default::Default::default()),
140 }
141 }
142
143 pub fn debug(&self, ident: TokenStream) -> TokenStream {
145 match *self {
146 Field::Scalar(ref scalar) => {
147 let wrapper = scalar.debug(quote!(ScalarWrapper));
148 quote! {
149 {
150 #wrapper
151 ScalarWrapper(&#ident)
152 }
153 }
154 }
155 Field::Map(ref map) => {
156 let wrapper = map.debug(quote!(MapWrapper));
157 quote! {
158 {
159 #wrapper
160 MapWrapper(&#ident)
161 }
162 }
163 }
164 _ => quote!(&#ident),
165 }
166 }
167
168 pub fn methods(&self, ident: &TokenStream) -> Option<TokenStream> {
169 match *self {
170 Field::Scalar(ref scalar) => scalar.methods(ident),
171 Field::Map(ref map) => map.methods(ident),
172 _ => None,
173 }
174 }
175}
176
177#[derive(Clone, Copy, PartialEq, Eq)]
178pub enum Label {
179 Optional,
181 Required,
183 Repeated,
185}
186
187impl Label {
188 fn as_str(self) -> &'static str {
189 match self {
190 Label::Optional => "optional",
191 Label::Required => "required",
192 Label::Repeated => "repeated",
193 }
194 }
195
196 fn variants() -> slice::Iter<'static, Label> {
197 const VARIANTS: &[Label] = &[Label::Optional, Label::Required, Label::Repeated];
198 VARIANTS.iter()
199 }
200
201 fn from_attr(attr: &Meta) -> Option<Label> {
204 if let Meta::Path(ref path) = *attr {
205 for &label in Label::variants() {
206 if path.is_ident(label.as_str()) {
207 return Some(label);
208 }
209 }
210 }
211 None
212 }
213}
214
215impl fmt::Debug for Label {
216 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217 f.write_str(self.as_str())
218 }
219}
220
221impl fmt::Display for Label {
222 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
223 f.write_str(self.as_str())
224 }
225}
226
227fn prost_attrs(attrs: Vec<Attribute>) -> Result<Vec<Meta>, Error> {
229 let mut result = Vec::new();
230 for attr in attrs.iter() {
231 if let Meta::List(meta_list) = &attr.meta {
232 if meta_list.path.is_ident("prost") {
233 result.extend(
234 meta_list
235 .parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)?
236 .into_iter(),
237 )
238 }
239 }
240 }
241 Ok(result)
242}
243
244pub fn set_option<T>(option: &mut Option<T>, value: T, message: &str) -> Result<(), Error>
245where
246 T: fmt::Debug,
247{
248 if let Some(ref existing) = *option {
249 bail!("{}: {:?} and {:?}", message, existing, value);
250 }
251 *option = Some(value);
252 Ok(())
253}
254
255pub fn set_bool(b: &mut bool, message: &str) -> Result<(), Error> {
256 if *b {
257 bail!("{}", message);
258 } else {
259 *b = true;
260 Ok(())
261 }
262}
263
264fn bool_attr(key: &str, attr: &Meta) -> Result<Option<bool>, Error> {
267 if !attr.path().is_ident(key) {
268 return Ok(None);
269 }
270 match *attr {
271 Meta::Path(..) => Ok(Some(true)),
272 Meta::List(ref meta_list) => Ok(Some(meta_list.parse_args::<LitBool>()?.value())),
273 Meta::NameValue(MetaNameValue {
274 value:
275 Expr::Lit(ExprLit {
276 lit: Lit::Str(ref lit),
277 ..
278 }),
279 ..
280 }) => lit
281 .value()
282 .parse::<bool>()
283 .map_err(Error::from)
284 .map(Option::Some),
285 Meta::NameValue(MetaNameValue {
286 value:
287 Expr::Lit(ExprLit {
288 lit: Lit::Bool(LitBool { value, .. }),
289 ..
290 }),
291 ..
292 }) => Ok(Some(value)),
293 _ => bail!("invalid {} attribute", key),
294 }
295}
296
297fn word_attr(key: &str, attr: &Meta) -> bool {
299 if let Meta::Path(ref path) = *attr {
300 path.is_ident(key)
301 } else {
302 false
303 }
304}
305
306pub(super) fn tag_attr(attr: &Meta) -> Result<Option<u32>, Error> {
307 if !attr.path().is_ident("tag") {
308 return Ok(None);
309 }
310 match *attr {
311 Meta::List(ref meta_list) => Ok(Some(meta_list.parse_args::<LitInt>()?.base10_parse()?)),
312 Meta::NameValue(MetaNameValue {
313 value: Expr::Lit(ref expr),
314 ..
315 }) => match expr.lit {
316 Lit::Str(ref lit) => lit
317 .value()
318 .parse::<u32>()
319 .map_err(Error::from)
320 .map(Option::Some),
321 Lit::Int(ref lit) => Ok(Some(lit.base10_parse()?)),
322 _ => bail!("invalid tag attribute: {:?}", attr),
323 },
324 _ => bail!("invalid tag attribute: {:?}", attr),
325 }
326}
327
328fn tags_attr(attr: &Meta) -> Result<Option<Vec<u32>>, Error> {
329 if !attr.path().is_ident("tags") {
330 return Ok(None);
331 }
332 match *attr {
333 Meta::List(ref meta_list) => Ok(Some(
334 meta_list
335 .parse_args_with(Punctuated::<LitInt, Token![,]>::parse_terminated)?
336 .iter()
337 .map(LitInt::base10_parse)
338 .collect::<Result<Vec<_>, _>>()?,
339 )),
340 Meta::NameValue(MetaNameValue {
341 value:
342 Expr::Lit(ExprLit {
343 lit: Lit::Str(ref lit),
344 ..
345 }),
346 ..
347 }) => lit
348 .value()
349 .split(',')
350 .map(|s| s.trim().parse::<u32>().map_err(Error::from))
351 .collect::<Result<Vec<u32>, _>>()
352 .map(Some),
353 _ => bail!("invalid tag attribute: {:?}", attr),
354 }
355}