├── .gitignore ├── Cargo.toml ├── README.md ├── gen-test ├── src ├── de.rs ├── descriptor.rs ├── error.rs ├── lib.rs └── value.rs ├── testdata ├── descriptors.pb ├── google │ └── protobuf │ │ ├── unittest.proto │ │ ├── unittest_import.proto │ │ └── unittest_import_public.proto └── hash └── tests ├── lib.rs └── protobuf_unittest ├── mod.rs ├── unittest.rs ├── unittest_import.rs └── unittest_import_public.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | *.bk 3 | Cargo.lock 4 | .idea 5 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["David Flemström "] 3 | description = "Support for Google Protocol Buffers in combination with serde" 4 | documentation = "https://docs.rs/serde-protobuf" 5 | homepage = "https://github.com/dflemstr/serde-protobuf" 6 | include = ["src/**/*", "tests/**/*", "testdata/**/*", "Cargo.toml"] 7 | keywords = ["serde", "protocol", "buffers", "protobuf", "google"] 8 | license = "Apache-2.0" 9 | name = "serde-protobuf" 10 | repository = "https://github.com/dflemstr/serde-protobuf" 11 | version = "0.8.3-alpha.0" 12 | edition = "2018" 13 | 14 | [dependencies] 15 | linked-hash-map = "0.5.4" 16 | log = "0.4.14" 17 | protobuf = "2.23.0" 18 | serde = "1.0.125" 19 | thiserror = "1.0.24" 20 | 21 | [dev-dependencies] 22 | serde-value = "0.7.0" 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # `serde-protobuf` [![crates.io badge](https://img.shields.io/crates/v/serde-protobuf.svg)](https://crates.io/crates/serde-protobuf) [![docs.rs badge](https://docs.rs/serde-protobuf/badge.svg)](https://docs.rs/serde-protobuf) 2 | 3 | Support for [Google protocol buffers][1] in combination with `serde`. 4 | 5 | The crate is split up into several logical parts. 6 | 7 | * The [`descriptor`](https://dflemstr.github.io/rq/serde_protobuf/descriptor/index.html) module provides an API for managing dynamically 8 | loaded protocol buffer schemata. 9 | * The [`value`](https://dflemstr.github.io/rq/serde_protobuf/value/index.html) module provides structs that can hold any raw protocol 10 | buffer decoded data (but the representation is heavily coupled with a schema). 11 | * The [`de`](https://dflemstr.github.io/rq/serde_protobuf/de/index.html) module can be used to deserialize binary encoded protocol buffer 12 | messages given some schema descriptors. 13 | 14 | Serialization is not yet implemented in this version. 15 | 16 | [1]: https://developers.google.com/protocol-buffers/ 17 | -------------------------------------------------------------------------------- /gen-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh -eu 2 | # Use this to regenerate all the test data that's derived from .proto 3 | # files. This script only does so if any of the test files have 4 | # changed, since it can't be done during CI, because it requires 5 | # 'protoc' and 'protoc-gen-rust'. 6 | dir=$(dirname "$0") 7 | testdata="$dir/testdata" 8 | hash="$testdata/hash" 9 | 10 | # This dance is needed to make mktemp work on both Mac OS X and 11 | # GNU/Linux 12 | newhash=$(mktemp 2>/dev/null || mktemp -t "serde_protobuf-gen-test") 13 | 14 | # This dance is needed to implement md5 sums on both Mac OS X and 15 | # GNU/Linux 16 | if which md5 1>/dev/null 2>/dev/null 17 | then md5sum='md5 -r' 18 | elif which md5sum 1>/dev/null 2>/dev/null 19 | then md5sum='md5sum' 20 | else echo 'No md5 utility found; exiting'; exit 1 21 | fi 22 | 23 | (cd "$testdata" && find . -type f \( -name '*.proto' -o -name '*.pb' \) -exec $md5sum {} \; | LC_ALL=C sort -k 2 | awk '{print $1, $2}'> "$newhash") 24 | 25 | if [ ! -f "$hash" ] || ! diff "$hash" "$newhash" 26 | then 27 | echo >&2 'Changes detected; rebuilding protobuf' 28 | mkdir -p "$dir/tests/protobuf_unittest" 29 | protoc -I "$testdata" --rust_out "$dir/tests/protobuf_unittest" "$testdata/google/protobuf/unittest.proto" 30 | protoc -I "$testdata" --rust_out "$dir/tests/protobuf_unittest" "$testdata/google/protobuf/unittest_import.proto" 31 | protoc -I "$testdata" --rust_out "$dir/tests/protobuf_unittest" "$testdata/google/protobuf/unittest_import_public.proto" 32 | protoc -I "$testdata" --include_imports -o "$testdata/descriptors.pb" "$testdata/google/protobuf/unittest.proto" 33 | mv "$newhash" "$hash" 34 | else 35 | echo >&2 'Protobuf test data is up to date' 36 | fi 37 | -------------------------------------------------------------------------------- /src/de.rs: -------------------------------------------------------------------------------- 1 | //! Deserialization of binary protocol buffer encoded data. 2 | //! 3 | //! All deserialization operations require a previously loaded set of schema descriptors; see the 4 | //! [`descriptor`](../descriptor/index.html) module for more information. 5 | //! 6 | //! Provided that a set of descriptors have been loaded, a `Deserializer` can be used to deserialize 7 | //! a stream of bytes into something that implements `Deserialize`. 8 | //! 9 | //! ``` 10 | //! extern crate serde; 11 | //! extern crate protobuf; 12 | //! extern crate serde_protobuf; 13 | //! extern crate serde_value; 14 | //! 15 | //! use std::fs; 16 | //! use serde::de::Deserialize; 17 | //! use serde_protobuf::descriptor::Descriptors; 18 | //! use serde_protobuf::de::Deserializer; 19 | //! use serde_value::Value; 20 | //! 21 | //! # use std::io; 22 | //! # #[derive(Debug)] struct Error; 23 | //! # impl From for Error { 24 | //! # fn from(a: protobuf::ProtobufError) -> Error { 25 | //! # Error 26 | //! # } 27 | //! # } 28 | //! # impl From for Error { 29 | //! # fn from(a: io::Error) -> Error { 30 | //! # Error 31 | //! # } 32 | //! # } 33 | //! # impl From for Error { 34 | //! # fn from(a: serde_protobuf::error::Error) -> Error { 35 | //! # Error 36 | //! # } 37 | //! # } 38 | //! # impl From for Error { 39 | //! # fn from(a: serde_protobuf::error::CompatError) -> Error { 40 | //! # Error 41 | //! # } 42 | //! # } 43 | //! # fn foo() -> Result<(), Error> { 44 | //! // Load a descriptor registry (see descriptor module) 45 | //! let mut file = fs::File::open("testdata/descriptors.pb")?; 46 | //! let proto = protobuf::parse_from_reader(&mut file)?; 47 | //! let descriptors = Descriptors::from_proto(&proto); 48 | //! 49 | //! // Set up some data to read 50 | //! let data = &[8, 42]; 51 | //! let mut input = protobuf::CodedInputStream::from_bytes(data); 52 | //! 53 | //! // Create a deserializer 54 | //! let name = ".protobuf_unittest.TestAllTypes"; 55 | //! let mut deserializer = Deserializer::for_named_message(&descriptors, name, input)?; 56 | //! 57 | //! // Deserialize some struct 58 | //! let value = Value::deserialize(&mut deserializer)?; 59 | //! # println!("{:?}", value); 60 | //! # Ok(()) 61 | //! # } 62 | //! # fn main() { 63 | //! # foo().unwrap(); 64 | //! # } 65 | //! ``` 66 | 67 | use crate::descriptor; 68 | use crate::error; 69 | 70 | use crate::value; 71 | use protobuf; 72 | use serde; 73 | use std::collections; 74 | use std::fmt; 75 | use std::vec; 76 | 77 | /// A deserializer that can deserialize a single message type. 78 | pub struct Deserializer<'de> { 79 | descriptors: &'de descriptor::Descriptors, 80 | descriptor: &'de descriptor::MessageDescriptor, 81 | input: protobuf::CodedInputStream<'de>, 82 | } 83 | 84 | struct MessageVisitor<'de> { 85 | descriptors: &'de descriptor::Descriptors, 86 | descriptor: &'de descriptor::MessageDescriptor, 87 | fields: collections::btree_map::IntoIter, 88 | field: Option<(&'de descriptor::FieldDescriptor, value::Field)>, 89 | } 90 | 91 | struct MessageKeyDeserializer<'de> { 92 | descriptor: &'de descriptor::FieldDescriptor, 93 | } 94 | 95 | struct MessageFieldDeserializer<'de> { 96 | descriptors: &'de descriptor::Descriptors, 97 | descriptor: &'de descriptor::FieldDescriptor, 98 | field: Option, 99 | } 100 | 101 | struct RepeatedValueVisitor<'de> { 102 | descriptors: &'de descriptor::Descriptors, 103 | descriptor: &'de descriptor::FieldDescriptor, 104 | values: vec::IntoIter, 105 | } 106 | 107 | struct ValueDeserializer<'de> { 108 | descriptors: &'de descriptor::Descriptors, 109 | descriptor: &'de descriptor::FieldDescriptor, 110 | value: Option, 111 | } 112 | 113 | impl<'de> Deserializer<'de> { 114 | /// Constructs a new protocol buffer deserializer for the specified message type. 115 | /// 116 | /// The caller must ensure that all of the information needed by the specified message 117 | /// descriptor is available in the associated descriptors registry. 118 | pub fn new( 119 | descriptors: &'de descriptor::Descriptors, 120 | descriptor: &'de descriptor::MessageDescriptor, 121 | input: protobuf::CodedInputStream<'de>, 122 | ) -> Deserializer<'de> { 123 | Deserializer { 124 | descriptors, 125 | descriptor, 126 | input, 127 | } 128 | } 129 | 130 | /// Constructs a new protocol buffer deserializer for the specified named message type. 131 | /// 132 | /// The message type name must be fully quailified (for example 133 | /// `".google.protobuf.FileDescriptorSet"`). 134 | pub fn for_named_message( 135 | descriptors: &'de descriptor::Descriptors, 136 | message_name: &str, 137 | input: protobuf::CodedInputStream<'de>, 138 | ) -> error::Result> { 139 | if let Some(message) = descriptors.message_by_name(message_name) { 140 | Ok(Deserializer::new(descriptors, message, input)) 141 | } else { 142 | Err(error::Error::UnknownMessage { 143 | name: message_name.to_owned(), 144 | }) 145 | } 146 | } 147 | } 148 | 149 | impl<'de> fmt::Debug for Deserializer<'de> { 150 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 151 | f.debug_struct("Deserializer").finish() 152 | } 153 | } 154 | 155 | impl<'de, 'b> serde::Deserializer<'de> for &'b mut Deserializer<'de> { 156 | type Error = error::CompatError; 157 | 158 | forward_to_deserialize_any! { 159 | bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes 160 | byte_buf option unit unit_struct newtype_struct seq tuple 161 | tuple_struct map struct enum identifier ignored_any 162 | } 163 | 164 | #[inline] 165 | fn deserialize_any(self, visitor: V) -> Result 166 | where 167 | V: serde::de::Visitor<'de>, 168 | { 169 | let mut message = value::Message::new(self.descriptor); 170 | message.merge_from(self.descriptors, self.descriptor, &mut self.input)?; 171 | visitor.visit_map(MessageVisitor::new( 172 | self.descriptors, 173 | self.descriptor, 174 | message, 175 | )) 176 | } 177 | } 178 | 179 | impl<'de> MessageVisitor<'de> { 180 | #[inline] 181 | fn new( 182 | descriptors: &'de descriptor::Descriptors, 183 | descriptor: &'de descriptor::MessageDescriptor, 184 | value: value::Message, 185 | ) -> MessageVisitor<'de> { 186 | let fields = value.fields.into_iter(); 187 | let field = None; 188 | MessageVisitor { 189 | descriptors, 190 | descriptor, 191 | fields, 192 | field, 193 | } 194 | } 195 | } 196 | 197 | impl<'de> serde::de::MapAccess<'de> for MessageVisitor<'de> { 198 | type Error = error::CompatError; 199 | 200 | #[inline] 201 | fn next_key_seed(&mut self, seed: K) -> error::CompatResult> 202 | where 203 | K: serde::de::DeserializeSeed<'de>, 204 | { 205 | if let Some((k, v)) = self.fields.next() { 206 | let descriptor = self 207 | .descriptor 208 | .field_by_number(k) 209 | .expect("Lost track of field"); 210 | let key = seed.deserialize(MessageKeyDeserializer::new(descriptor))?; 211 | self.field = Some((descriptor, v)); 212 | Ok(Some(key)) 213 | } else { 214 | Ok(None) 215 | } 216 | } 217 | 218 | #[inline] 219 | fn next_value_seed(&mut self, seed: V) -> error::CompatResult 220 | where 221 | V: serde::de::DeserializeSeed<'de>, 222 | { 223 | let (descriptor, field) = self 224 | .field 225 | .take() 226 | .expect("visit_value was called before visit_key"); 227 | 228 | seed.deserialize(MessageFieldDeserializer::new( 229 | self.descriptors, 230 | descriptor, 231 | field, 232 | )) 233 | } 234 | } 235 | 236 | impl<'de> MessageKeyDeserializer<'de> { 237 | #[inline] 238 | fn new(descriptor: &'de descriptor::FieldDescriptor) -> MessageKeyDeserializer<'de> { 239 | MessageKeyDeserializer { descriptor } 240 | } 241 | } 242 | 243 | impl<'de> serde::Deserializer<'de> for MessageKeyDeserializer<'de> { 244 | type Error = error::CompatError; 245 | 246 | forward_to_deserialize_any! { 247 | bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes 248 | byte_buf option unit unit_struct newtype_struct seq tuple 249 | tuple_struct map struct enum identifier ignored_any 250 | } 251 | 252 | #[inline] 253 | fn deserialize_any(self, visitor: V) -> error::CompatResult 254 | where 255 | V: serde::de::Visitor<'de>, 256 | { 257 | visitor.visit_str(self.descriptor.name()) 258 | } 259 | } 260 | 261 | impl<'de> MessageFieldDeserializer<'de> { 262 | #[inline] 263 | fn new( 264 | descriptors: &'de descriptor::Descriptors, 265 | descriptor: &'de descriptor::FieldDescriptor, 266 | field: value::Field, 267 | ) -> MessageFieldDeserializer<'de> { 268 | let field = Some(field); 269 | MessageFieldDeserializer { 270 | descriptors, 271 | descriptor, 272 | field, 273 | } 274 | } 275 | } 276 | 277 | impl<'de> serde::Deserializer<'de> for MessageFieldDeserializer<'de> { 278 | type Error = error::CompatError; 279 | 280 | forward_to_deserialize_any! { 281 | bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes 282 | byte_buf option unit unit_struct newtype_struct seq tuple 283 | tuple_struct map struct enum identifier ignored_any 284 | } 285 | 286 | #[inline] 287 | fn deserialize_any(mut self, visitor: V) -> error::CompatResult 288 | where 289 | V: serde::de::Visitor<'de>, 290 | { 291 | let ds = self.descriptors; 292 | let d = self.descriptor; 293 | match self.field.take() { 294 | Some(value::Field::Singular(None)) => { 295 | if d.field_label() == descriptor::FieldLabel::Optional { 296 | visitor.visit_none() 297 | } else { 298 | visitor.visit_unit() 299 | } 300 | } 301 | Some(value::Field::Singular(Some(v))) => { 302 | if d.field_label() == descriptor::FieldLabel::Optional { 303 | visitor.visit_some(ValueDeserializer::new(ds, d, v)) 304 | } else { 305 | visit_value(ds, d, v, visitor) 306 | } 307 | } 308 | Some(value::Field::Repeated(vs)) => { 309 | visitor.visit_seq(&mut RepeatedValueVisitor::new(ds, d, vs.into_iter())) 310 | } 311 | None => Err(error::Error::EndOfStream.into()), 312 | } 313 | } 314 | } 315 | 316 | impl<'de> RepeatedValueVisitor<'de> { 317 | #[inline] 318 | fn new( 319 | descriptors: &'de descriptor::Descriptors, 320 | descriptor: &'de descriptor::FieldDescriptor, 321 | values: vec::IntoIter, 322 | ) -> RepeatedValueVisitor<'de> { 323 | RepeatedValueVisitor { 324 | descriptors, 325 | descriptor, 326 | values, 327 | } 328 | } 329 | } 330 | 331 | impl<'de> serde::de::SeqAccess<'de> for RepeatedValueVisitor<'de> { 332 | type Error = error::CompatError; 333 | 334 | #[inline] 335 | fn next_element_seed(&mut self, seed: A) -> error::CompatResult> 336 | where 337 | A: serde::de::DeserializeSeed<'de>, 338 | { 339 | let ds = self.descriptors; 340 | let d = self.descriptor; 341 | match self.values.next() { 342 | Some(v) => Ok(Some(seed.deserialize(ValueDeserializer::new(ds, d, v))?)), 343 | None => Ok(None), 344 | } 345 | } 346 | 347 | #[inline] 348 | fn size_hint(&self) -> Option { 349 | self.values.size_hint().1 350 | } 351 | } 352 | 353 | impl<'de> ValueDeserializer<'de> { 354 | #[inline] 355 | fn new( 356 | descriptors: &'de descriptor::Descriptors, 357 | descriptor: &'de descriptor::FieldDescriptor, 358 | value: value::Value, 359 | ) -> ValueDeserializer<'de> { 360 | let value = Some(value); 361 | ValueDeserializer { 362 | descriptors, 363 | descriptor, 364 | value, 365 | } 366 | } 367 | } 368 | 369 | impl<'de> serde::Deserializer<'de> for ValueDeserializer<'de> { 370 | type Error = error::CompatError; 371 | 372 | forward_to_deserialize_any! { 373 | bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes 374 | byte_buf option unit unit_struct newtype_struct seq tuple 375 | tuple_struct map struct enum identifier ignored_any 376 | } 377 | 378 | #[inline] 379 | fn deserialize_any(mut self, visitor: V) -> error::CompatResult 380 | where 381 | V: serde::de::Visitor<'de>, 382 | { 383 | match self.value.take() { 384 | Some(value) => visit_value(self.descriptors, self.descriptor, value, visitor), 385 | None => Err(error::Error::EndOfStream.into()), 386 | } 387 | } 388 | } 389 | 390 | #[inline] 391 | fn visit_value<'de, V>( 392 | descriptors: &'de descriptor::Descriptors, 393 | descriptor: &'de descriptor::FieldDescriptor, 394 | value: value::Value, 395 | visitor: V, 396 | ) -> error::CompatResult 397 | where 398 | V: serde::de::Visitor<'de>, 399 | { 400 | match value { 401 | value::Value::Bool(v) => visitor.visit_bool(v), 402 | value::Value::I32(v) => visitor.visit_i32(v), 403 | value::Value::I64(v) => visitor.visit_i64(v), 404 | value::Value::U32(v) => visitor.visit_u32(v), 405 | value::Value::U64(v) => visitor.visit_u64(v), 406 | value::Value::F32(v) => visitor.visit_f32(v), 407 | value::Value::F64(v) => visitor.visit_f64(v), 408 | value::Value::Bytes(v) => visitor.visit_byte_buf(v), 409 | value::Value::String(v) => visitor.visit_string(v), 410 | value::Value::Message(m) => { 411 | if let descriptor::FieldType::Message(d) = descriptor.field_type(descriptors) { 412 | visitor.visit_map(MessageVisitor::new(descriptors, d, m)) 413 | } else { 414 | panic!("A field with a message value doesn't have a message type!") 415 | } 416 | } 417 | value::Value::Enum(e) => { 418 | if let descriptor::FieldType::Enum(d) = descriptor.field_type(descriptors) { 419 | visitor.visit_str(d.value_by_number(e).unwrap().name()) 420 | } else { 421 | panic!("A field with an enum value doesn't have an enum type!") 422 | } 423 | } 424 | } 425 | } 426 | -------------------------------------------------------------------------------- /src/descriptor.rs: -------------------------------------------------------------------------------- 1 | //! Dynamic descriptors for protocol buffer schemata. 2 | //! 3 | //! The descriptors are optimized for read performance, i.e. to be used by a parser to parse actual 4 | //! protocol buffer data. 5 | //! 6 | //! They can be constructed either from pre-compiled protocol buffer-serialized descriptors as 7 | //! defined in [`descriptor.proto`][1], or manually by incrementally building a custom protocol 8 | //! buffer schema. 9 | //! 10 | //! ## Pre-compiled schemas 11 | //! 12 | //! Given a protocol buffer schema `schema.proto`, it can be compiled into a binary file descriptor 13 | //! set using the `protoc` tool: 14 | //! 15 | //! ```text 16 | //! protoc schema.proto -o testdata/descriptors.pb 17 | //! ``` 18 | //! 19 | //! The binary file descriptor set can then be parsed into a `Descriptors` instance: 20 | //! 21 | //! ``` 22 | //! extern crate serde_protobuf; 23 | //! extern crate protobuf; 24 | //! 25 | //! use std::fs; 26 | //! use serde_protobuf::descriptor::Descriptors; 27 | //! 28 | //! # use std::io; 29 | //! # #[derive(Debug)] struct Error; 30 | //! # impl From for Error { 31 | //! # fn from(a: protobuf::ProtobufError) -> Error { 32 | //! # Error 33 | //! # } 34 | //! # } 35 | //! # impl From for Error { 36 | //! # fn from(a: io::Error) -> Error { 37 | //! # Error 38 | //! # } 39 | //! # } 40 | //! # fn foo() -> Result<(), Error> { 41 | //! let mut file = fs::File::open("testdata/descriptors.pb")?; 42 | //! let proto = protobuf::parse_from_reader(&mut file)?; 43 | //! let descriptors = Descriptors::from_proto(&proto); 44 | //! # Ok(()) 45 | //! # } 46 | //! # fn main() { 47 | //! # foo().unwrap(); 48 | //! # } 49 | //! ``` 50 | //! 51 | //! ## Manually built schemas 52 | //! 53 | //! A descriptor can be built at run-time by incrementally adding new message types and fields: 54 | //! 55 | //! ``` 56 | //! use serde_protobuf::descriptor::*; 57 | //! 58 | //! // Create a new message type 59 | //! let mut m = MessageDescriptor::new(".mypackage.Person"); 60 | //! m.add_field(FieldDescriptor::new("name", 1, FieldLabel::Optional, 61 | //! InternalFieldType::String, None)); 62 | //! m.add_field(FieldDescriptor::new("age", 2, FieldLabel::Optional, 63 | //! InternalFieldType::Int32, None)); 64 | //! 65 | //! // Create a new enum type 66 | //! let mut e = EnumDescriptor::new(".mypackage.Color"); 67 | //! e.add_value(EnumValueDescriptor::new("BLUE", 1)); 68 | //! e.add_value(EnumValueDescriptor::new("RED", 2)); 69 | //! 70 | //! // Add the generated types to a descriptor registry 71 | //! let mut descriptors = Descriptors::new(); 72 | //! descriptors.add_message(m); 73 | //! descriptors.add_enum(e); 74 | //! ``` 75 | //! 76 | //! ## Exploring descriptors 77 | //! 78 | //! The descriptors contain various indices that can be used to quickly look up information: 79 | //! 80 | //! ``` 81 | //! # extern crate serde_protobuf; 82 | //! # extern crate protobuf; 83 | //! # use std::fs; 84 | //! # use serde_protobuf::descriptor::Descriptors; 85 | //! # fn main() { 86 | //! # let mut file = fs::File::open("testdata/descriptors.pb").unwrap(); 87 | //! # let proto = protobuf::parse_from_reader(&mut file).unwrap(); 88 | //! // Given a set of descriptors using one of the above methods: 89 | //! let descriptors = Descriptors::from_proto(&proto); 90 | //! assert_eq!(7, descriptors.message_by_name(".protobuf_unittest.TestAllTypes").unwrap() 91 | //! .field_by_name("optional_fixed32").unwrap() 92 | //! .number()); 93 | //! # } 94 | //! ``` 95 | //! 96 | //! ## Optimizing reference look-ups 97 | //! 98 | //! Certain descriptor look-ups require following references that can be quite expensive to look up. 99 | //! Instead, a one-time cost can be payed to resolve these references and make all following 100 | //! look-ups cheaper. This should be done after all needed descriptors have been loaded: 101 | //! 102 | //! ``` 103 | //! # extern crate serde_protobuf; 104 | //! # extern crate protobuf; 105 | //! # use std::fs; 106 | //! # use serde_protobuf::descriptor::*; 107 | //! # fn main() { 108 | //! # let mut file = fs::File::open("testdata/descriptors.pb").unwrap(); 109 | //! # let proto = protobuf::parse_from_reader(&mut file).unwrap(); 110 | //! // Load some descriptors as usual: 111 | //! let mut descriptors = Descriptors::from_proto(&proto); 112 | //! 113 | //! // Resolve references internally to speed up lookups: 114 | //! descriptors.resolve_refs(); 115 | //! 116 | //! // This should now be faster 117 | //! match descriptors.message_by_name(".protobuf_unittest.TestAllTypes").unwrap() 118 | //! .field_by_name("optional_nested_message").unwrap() 119 | //! .field_type(&descriptors) { 120 | //! FieldType::Message(m) => 121 | //! assert_eq!(1, m.field_by_name("bb").unwrap() 122 | //! .number()), 123 | //! _ => unreachable!(), 124 | //! } 125 | //! # } 126 | //! ``` 127 | //! 128 | //! [1]: https://github.com/google/protobuf/blob/master/src/google/protobuf/descriptor.proto 129 | use std::f32; 130 | use std::f64; 131 | 132 | use linked_hash_map; 133 | use protobuf::descriptor; 134 | 135 | use crate::error; 136 | use crate::value; 137 | 138 | /// An ID used for internal tracking of resolved message descriptors. 139 | /// 140 | /// It is not possible to construct a value of this type from outside this module. 141 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 142 | pub struct MessageId(usize); 143 | 144 | /// An ID used for internal tracking of resolved enum descriptors. 145 | /// 146 | /// It is not possible to construct a value of this type from outside this module. 147 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 148 | pub struct EnumId(usize); 149 | 150 | /// An ID used for internal tracking of resolved enum values. 151 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 152 | struct EnumValueId(usize); 153 | 154 | /// An ID used for internal tracking of resolved fields. 155 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 156 | struct FieldId(usize); 157 | 158 | /// A registry for any number of protocol buffer descriptors. 159 | #[derive(Debug, Default)] 160 | pub struct Descriptors { 161 | // All found descriptors 162 | messages: Vec, 163 | enums: Vec, 164 | 165 | // Indices 166 | messages_by_name: linked_hash_map::LinkedHashMap, 167 | enums_by_name: linked_hash_map::LinkedHashMap, 168 | } 169 | 170 | /// A descriptor for a single protocol buffer message type. 171 | // TODO: Support oneof? 172 | #[derive(Debug)] 173 | pub struct MessageDescriptor { 174 | name: String, 175 | 176 | // All found descriptors 177 | fields: Vec, 178 | 179 | // Indices 180 | fields_by_name: linked_hash_map::LinkedHashMap, 181 | fields_by_number: linked_hash_map::LinkedHashMap, 182 | } 183 | 184 | /// A descriptor for a single protocol buffer enum type. 185 | #[derive(Debug)] 186 | pub struct EnumDescriptor { 187 | name: String, 188 | 189 | // All found descriptors 190 | values: Vec, 191 | 192 | // Indices 193 | values_by_name: linked_hash_map::LinkedHashMap, 194 | values_by_number: linked_hash_map::LinkedHashMap, 195 | } 196 | 197 | /// A descriptor for a single protocol buffer enum value. 198 | #[derive(Debug)] 199 | pub struct EnumValueDescriptor { 200 | name: String, 201 | number: i32, 202 | } 203 | 204 | /// A label that a field can be given to indicate its cardinality. 205 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 206 | pub enum FieldLabel { 207 | /// There can be zero or one value. 208 | Optional, 209 | /// There must be exactly one value. 210 | Required, 211 | /// There can be any number of values. 212 | Repeated, 213 | } 214 | 215 | /// The externally visible type of a field. 216 | /// 217 | /// This type representation borrows references to any referenced descriptors. 218 | #[derive(Debug)] 219 | pub enum FieldType<'a> { 220 | /// A message that is yet to be resolved. 221 | UnresolvedMessage(&'a str), 222 | /// An enum that is yet to be resolved. 223 | UnresolvedEnum(&'a str), 224 | /// The `double` type. 225 | Double, 226 | /// The `float` type. 227 | Float, 228 | /// The `int64` type. 229 | Int64, 230 | /// The `uint64` type. 231 | UInt64, 232 | /// The `int32` type. 233 | Int32, 234 | /// The `fixed64` type. 235 | Fixed64, 236 | /// The `fixed32` type. 237 | Fixed32, 238 | /// The `bool` type. 239 | Bool, 240 | /// The `string` type. 241 | String, 242 | /// The `group` type. 243 | Group, 244 | /// A resolved message type. 245 | Message(&'a MessageDescriptor), 246 | /// The `bytes` type. 247 | Bytes, 248 | /// The `uint32` type. 249 | UInt32, 250 | /// A resolved enum type. 251 | Enum(&'a EnumDescriptor), 252 | /// The `sfixed32` type. 253 | SFixed32, 254 | /// The `sfixed64` type. 255 | SFixed64, 256 | /// The `sint32` type. 257 | SInt32, 258 | /// The `sint64` type. 259 | SInt64, 260 | } 261 | 262 | /// The internally tracked type of a field. 263 | /// 264 | /// The type owns all of its data, and can refer to an internally tracked ID for resolved type 265 | /// references. It's by design not possible to construct those IDs from outside this module. 266 | #[derive(Debug, Eq, PartialEq)] 267 | pub enum InternalFieldType { 268 | /// A message that is yet to be resolved. 269 | UnresolvedMessage(String), 270 | /// An enum that is yet to be resolved. 271 | UnresolvedEnum(String), 272 | /// The `double` type. 273 | Double, 274 | /// The `float` type. 275 | Float, 276 | /// The `int64` type. 277 | Int64, 278 | /// The `uint64` type. 279 | UInt64, 280 | /// The `int32` type. 281 | Int32, 282 | /// The `fixed64` type. 283 | Fixed64, 284 | /// The `fixed32` type. 285 | Fixed32, 286 | /// The `bool` type. 287 | Bool, 288 | /// The `string` type. 289 | String, 290 | /// The `group` type. 291 | Group, 292 | /// A resolved message type. 293 | Message(MessageId), 294 | /// The `bytes` type. 295 | Bytes, 296 | /// The `uint32` type. 297 | UInt32, 298 | /// A resolved enum type. 299 | Enum(EnumId), 300 | /// The `sfixed32` type. 301 | SFixed32, 302 | /// The `sfixed64` type. 303 | SFixed64, 304 | /// The `sint32` type. 305 | SInt32, 306 | /// The `sint64` type. 307 | SInt64, 308 | } 309 | 310 | /// A descriptor for a single protocol buffer message field. 311 | #[derive(Debug)] 312 | pub struct FieldDescriptor { 313 | name: String, 314 | number: i32, 315 | field_label: FieldLabel, 316 | field_type: InternalFieldType, 317 | default_value: Option, 318 | } 319 | 320 | impl Descriptors { 321 | /// Creates a new empty descriptor set. 322 | pub fn new() -> Descriptors { 323 | Descriptors { 324 | messages: Vec::new(), 325 | enums: Vec::new(), 326 | 327 | messages_by_name: linked_hash_map::LinkedHashMap::new(), 328 | enums_by_name: linked_hash_map::LinkedHashMap::new(), 329 | } 330 | } 331 | 332 | /// Builds a descriptor set from the specified protocol buffer file descriptor set. 333 | pub fn from_proto(file_set_proto: &descriptor::FileDescriptorSet) -> Descriptors { 334 | let mut descriptors = Descriptors::new(); 335 | descriptors.add_file_set_proto(file_set_proto); 336 | descriptors 337 | } 338 | 339 | /// Looks up a message by its fully qualified name (i.e. `.foo.package.Message`). 340 | #[inline] 341 | pub fn message_by_name(&self, name: &str) -> Option<&MessageDescriptor> { 342 | self.messages_by_name.get(name).map(|m| &self.messages[m.0]) 343 | } 344 | 345 | /// Looks up an enum by its fully qualified name (i.e. `.foo.package.Enum`). 346 | #[inline] 347 | pub fn enum_by_name(&self, name: &str) -> Option<&EnumDescriptor> { 348 | self.enums_by_name.get(name).map(|e| &self.enums[e.0]) 349 | } 350 | 351 | /// Adds all types defined in the specified protocol buffer file descriptor set to this 352 | /// registry. 353 | pub fn add_file_set_proto(&mut self, file_set_proto: &descriptor::FileDescriptorSet) { 354 | for file_proto in file_set_proto.get_file().iter() { 355 | self.add_file_proto(file_proto); 356 | } 357 | } 358 | 359 | /// Adds all types defined in the specified protocol buffer file descriptor to this registry. 360 | pub fn add_file_proto(&mut self, file_proto: &descriptor::FileDescriptorProto) { 361 | let path = if file_proto.has_package() { 362 | format!(".{}", file_proto.get_package()) 363 | } else { 364 | "".to_owned() 365 | }; 366 | 367 | for message_proto in file_proto.get_message_type().iter() { 368 | self.add_message_proto(&path, message_proto); 369 | } 370 | 371 | for enum_proto in file_proto.get_enum_type().iter() { 372 | self.add_enum(EnumDescriptor::from_proto(&path, enum_proto)); 373 | } 374 | } 375 | 376 | /// Adds a message and all nested types within that message from the specified protocol buffer 377 | /// descriptor. 378 | pub fn add_message_proto(&mut self, path: &str, message_proto: &descriptor::DescriptorProto) { 379 | let message_descriptor = MessageDescriptor::from_proto(path, message_proto); 380 | 381 | for nested_message_proto in message_proto.get_nested_type().iter() { 382 | self.add_message_proto(message_descriptor.name(), nested_message_proto); 383 | } 384 | 385 | for nested_enum_proto in message_proto.get_enum_type().iter() { 386 | self.add_enum(EnumDescriptor::from_proto( 387 | message_descriptor.name(), 388 | nested_enum_proto, 389 | )); 390 | } 391 | 392 | self.add_message(message_descriptor); 393 | } 394 | 395 | /// Adds a single custom built message descriptor. 396 | pub fn add_message(&mut self, descriptor: MessageDescriptor) { 397 | let name = descriptor.name.clone(); 398 | let message_id = MessageId(store(&mut self.messages, descriptor)); 399 | self.messages_by_name.insert(name, message_id); 400 | } 401 | 402 | /// Adds a single custom built enum descriptor. 403 | pub fn add_enum(&mut self, descriptor: EnumDescriptor) { 404 | let name = descriptor.name.clone(); 405 | let enum_id = EnumId(store(&mut self.enums, descriptor)); 406 | self.enums_by_name.insert(name, enum_id); 407 | } 408 | 409 | /// Resolves all internal descriptor type references, making them cheaper to follow. 410 | pub fn resolve_refs(&mut self) { 411 | for m in &mut self.messages { 412 | for f in &mut m.fields { 413 | let field_type = &mut f.field_type; 414 | let new = match *field_type { 415 | InternalFieldType::UnresolvedMessage(ref name) => { 416 | if let Some(res) = self.messages_by_name.get(name) { 417 | Some(InternalFieldType::Message(*res)) 418 | } else { 419 | warn!("Inconsistent schema; unknown message type {}", name); 420 | None 421 | } 422 | } 423 | InternalFieldType::UnresolvedEnum(ref name) => { 424 | if let Some(res) = self.enums_by_name.get(name) { 425 | Some(InternalFieldType::Enum(*res)) 426 | } else { 427 | warn!("Inconsistent schema; unknown enum type {}", name); 428 | None 429 | } 430 | } 431 | _ => None, 432 | }; 433 | 434 | if let Some(t) = new { 435 | *field_type = t; 436 | } 437 | } 438 | } 439 | } 440 | } 441 | 442 | impl MessageDescriptor { 443 | /// Creates a new message descriptor with the specified message name. 444 | pub fn new(name: S) -> MessageDescriptor 445 | where 446 | S: Into, 447 | { 448 | MessageDescriptor { 449 | name: name.into(), 450 | fields: Vec::new(), 451 | fields_by_name: linked_hash_map::LinkedHashMap::new(), 452 | fields_by_number: linked_hash_map::LinkedHashMap::new(), 453 | } 454 | } 455 | 456 | /// Reads a message descriptor from a parsed Protobuf descriptor. 457 | pub fn from_proto(path: &str, proto: &descriptor::DescriptorProto) -> MessageDescriptor { 458 | let name = format!("{}.{}", path, proto.get_name()); 459 | let mut message_descriptor = MessageDescriptor::new(name); 460 | 461 | for field_proto in proto.get_field().iter() { 462 | message_descriptor.add_field(FieldDescriptor::from_proto(field_proto)); 463 | } 464 | 465 | message_descriptor 466 | } 467 | 468 | /// All of the fields in the descriptor. 469 | pub fn fields(&self) -> &[FieldDescriptor] { 470 | &self.fields 471 | } 472 | 473 | /// The name of the message. 474 | #[inline] 475 | pub fn name(&self) -> &str { 476 | &self.name 477 | } 478 | 479 | /// Finds a field by field name. 480 | #[inline] 481 | pub fn field_by_name(&self, name: &str) -> Option<&FieldDescriptor> { 482 | self.fields_by_name.get(name).map(|f| &self.fields[f.0]) 483 | } 484 | 485 | /// Finds a field by field number. 486 | #[inline] 487 | pub fn field_by_number(&self, number: i32) -> Option<&FieldDescriptor> { 488 | self.fields_by_number 489 | .get(&number) 490 | .map(|f| &self.fields[f.0]) 491 | } 492 | 493 | /// Adds a new field to the descriptor. 494 | pub fn add_field(&mut self, descriptor: FieldDescriptor) { 495 | let name = descriptor.name.clone(); 496 | let number = descriptor.number; 497 | 498 | let field_id = FieldId(store(&mut self.fields, descriptor)); 499 | 500 | self.fields_by_name.insert(name, field_id); 501 | self.fields_by_number.insert(number, field_id); 502 | } 503 | } 504 | 505 | impl EnumDescriptor { 506 | /// Creates a new enum descriptor with the specified enum name. 507 | pub fn new(name: S) -> EnumDescriptor 508 | where 509 | S: Into, 510 | { 511 | EnumDescriptor { 512 | name: name.into(), 513 | values: Vec::new(), 514 | values_by_name: linked_hash_map::LinkedHashMap::new(), 515 | values_by_number: linked_hash_map::LinkedHashMap::new(), 516 | } 517 | } 518 | 519 | /// Reads an enum descriptor from a parsed Protobuf descriptor. 520 | pub fn from_proto(path: &str, proto: &descriptor::EnumDescriptorProto) -> EnumDescriptor { 521 | let enum_name = format!("{}.{}", path, proto.get_name()); 522 | 523 | let mut enum_descriptor = EnumDescriptor::new(enum_name); 524 | 525 | for value_proto in proto.get_value().iter() { 526 | enum_descriptor.add_value(EnumValueDescriptor::from_proto(value_proto)); 527 | } 528 | 529 | enum_descriptor 530 | } 531 | 532 | /// The name of the enum. 533 | #[inline] 534 | pub fn name(&self) -> &str { 535 | &self.name 536 | } 537 | 538 | /// Adds an enum value to the enum. 539 | pub fn add_value(&mut self, descriptor: EnumValueDescriptor) { 540 | let name = descriptor.name.clone(); 541 | let number = descriptor.number; 542 | 543 | let value_id = EnumValueId(store(&mut self.values, descriptor)); 544 | 545 | self.values_by_name.insert(name, value_id); 546 | self.values_by_number.insert(number, value_id); 547 | } 548 | 549 | /// Finds a value by name. 550 | #[inline] 551 | pub fn value_by_name(&self, name: &str) -> Option<&EnumValueDescriptor> { 552 | self.values_by_name.get(name).map(|v| &self.values[v.0]) 553 | } 554 | 555 | /// Finds a value by number. 556 | #[inline] 557 | pub fn value_by_number(&self, number: i32) -> Option<&EnumValueDescriptor> { 558 | self.values_by_number 559 | .get(&number) 560 | .map(|v| &self.values[v.0]) 561 | } 562 | } 563 | 564 | impl EnumValueDescriptor { 565 | /// Creates a new enum value descriptor with the given number. 566 | pub fn new(name: S, number: i32) -> EnumValueDescriptor 567 | where 568 | S: Into, 569 | { 570 | let name = name.into(); 571 | EnumValueDescriptor { name, number } 572 | } 573 | 574 | /// Reads an enum value descriptor from a parsed Protobuf descriptor. 575 | pub fn from_proto(proto: &descriptor::EnumValueDescriptorProto) -> EnumValueDescriptor { 576 | EnumValueDescriptor::new(proto.get_name().to_owned(), proto.get_number()) 577 | } 578 | 579 | /// The name of the enum value. 580 | #[inline] 581 | pub fn name(&self) -> &str { 582 | &self.name 583 | } 584 | 585 | /// The number of the enum value. 586 | #[inline] 587 | pub fn number(&self) -> i32 { 588 | self.number 589 | } 590 | } 591 | 592 | impl FieldLabel { 593 | /// Converts a proto field label into a native field label. 594 | pub fn from_proto(proto: descriptor::FieldDescriptorProto_Label) -> FieldLabel { 595 | use protobuf::descriptor::FieldDescriptorProto_Label::*; 596 | 597 | match proto { 598 | LABEL_OPTIONAL => FieldLabel::Optional, 599 | LABEL_REQUIRED => FieldLabel::Required, 600 | LABEL_REPEATED => FieldLabel::Repeated, 601 | } 602 | } 603 | 604 | /// Whether the label is repeated. 605 | #[inline] 606 | pub fn is_repeated(self) -> bool { 607 | self == FieldLabel::Repeated 608 | } 609 | } 610 | 611 | impl InternalFieldType { 612 | /// Converts a proto field type into a native field type. 613 | pub fn from_proto( 614 | proto: descriptor::FieldDescriptorProto_Type, 615 | type_name: &str, 616 | ) -> InternalFieldType { 617 | use protobuf::descriptor::FieldDescriptorProto_Type::*; 618 | match proto { 619 | TYPE_DOUBLE => InternalFieldType::Double, 620 | TYPE_FLOAT => InternalFieldType::Float, 621 | TYPE_INT64 => InternalFieldType::Int64, 622 | TYPE_UINT64 => InternalFieldType::UInt64, 623 | TYPE_INT32 => InternalFieldType::Int32, 624 | TYPE_FIXED64 => InternalFieldType::Fixed64, 625 | TYPE_FIXED32 => InternalFieldType::Fixed32, 626 | TYPE_BOOL => InternalFieldType::Bool, 627 | TYPE_STRING => InternalFieldType::String, 628 | TYPE_GROUP => InternalFieldType::Group, 629 | TYPE_MESSAGE => InternalFieldType::UnresolvedMessage(type_name.to_owned()), 630 | TYPE_BYTES => InternalFieldType::Bytes, 631 | TYPE_UINT32 => InternalFieldType::UInt32, 632 | TYPE_ENUM => InternalFieldType::UnresolvedEnum(type_name.to_owned()), 633 | TYPE_SFIXED32 => InternalFieldType::SFixed32, 634 | TYPE_SFIXED64 => InternalFieldType::SFixed64, 635 | TYPE_SINT32 => InternalFieldType::SInt32, 636 | TYPE_SINT64 => InternalFieldType::SInt64, 637 | } 638 | } 639 | 640 | #[inline] 641 | fn resolve<'a>(&'a self, descriptors: &'a Descriptors) -> FieldType<'a> { 642 | match *self { 643 | InternalFieldType::UnresolvedMessage(ref n) => { 644 | if let Some(m) = descriptors.message_by_name(n) { 645 | FieldType::Message(m) 646 | } else { 647 | FieldType::UnresolvedMessage(n) 648 | } 649 | } 650 | InternalFieldType::UnresolvedEnum(ref n) => { 651 | if let Some(e) = descriptors.enum_by_name(n) { 652 | FieldType::Enum(e) 653 | } else { 654 | FieldType::UnresolvedEnum(n) 655 | } 656 | } 657 | InternalFieldType::Double => FieldType::Double, 658 | InternalFieldType::Float => FieldType::Float, 659 | InternalFieldType::Int64 => FieldType::Int64, 660 | InternalFieldType::UInt64 => FieldType::UInt64, 661 | InternalFieldType::Int32 => FieldType::Int32, 662 | InternalFieldType::Fixed64 => FieldType::Fixed64, 663 | InternalFieldType::Fixed32 => FieldType::Fixed32, 664 | InternalFieldType::Bool => FieldType::Bool, 665 | InternalFieldType::String => FieldType::String, 666 | InternalFieldType::Group => FieldType::Group, 667 | InternalFieldType::Message(m) => FieldType::Message(&descriptors.messages[m.0]), 668 | InternalFieldType::Bytes => FieldType::Bytes, 669 | InternalFieldType::UInt32 => FieldType::UInt32, 670 | InternalFieldType::Enum(e) => FieldType::Enum(&descriptors.enums[e.0]), 671 | InternalFieldType::SFixed32 => FieldType::SFixed32, 672 | InternalFieldType::SFixed64 => FieldType::SFixed64, 673 | InternalFieldType::SInt32 => FieldType::SInt32, 674 | InternalFieldType::SInt64 => FieldType::SInt64, 675 | } 676 | } 677 | } 678 | 679 | impl FieldDescriptor { 680 | /// Creates a new field descriptor. 681 | pub fn new( 682 | name: S, 683 | number: i32, 684 | field_label: FieldLabel, 685 | field_type: InternalFieldType, 686 | default_value: Option, 687 | ) -> FieldDescriptor 688 | where 689 | S: Into, 690 | { 691 | let name = name.into(); 692 | FieldDescriptor { 693 | name, 694 | number, 695 | field_label, 696 | field_type, 697 | default_value, 698 | } 699 | } 700 | 701 | /// Reads a field descriptor from a parsed Protobuf descriptor. 702 | pub fn from_proto(proto: &descriptor::FieldDescriptorProto) -> FieldDescriptor { 703 | let name = proto.get_name().to_owned(); 704 | let number = proto.get_number(); 705 | let field_label = FieldLabel::from_proto(proto.get_label()); 706 | let field_type = 707 | InternalFieldType::from_proto(proto.get_field_type(), proto.get_type_name()); 708 | let default_value = if proto.has_default_value() { 709 | // TODO: report error? 710 | parse_default_value(proto.get_default_value(), &field_type).ok() 711 | } else { 712 | None 713 | }; 714 | 715 | FieldDescriptor::new(name, number, field_label, field_type, default_value) 716 | } 717 | 718 | /// The name of the field. 719 | #[inline] 720 | pub fn name(&self) -> &str { 721 | &self.name 722 | } 723 | 724 | /// The number of the field. 725 | #[inline] 726 | pub fn number(&self) -> i32 { 727 | self.number 728 | } 729 | 730 | /// The label of the field. 731 | #[inline] 732 | pub fn field_label(&self) -> FieldLabel { 733 | self.field_label 734 | } 735 | 736 | /// Whether the field is repeated. 737 | #[inline] 738 | pub fn is_repeated(&self) -> bool { 739 | self.field_label == FieldLabel::Repeated 740 | } 741 | 742 | /// The type of the field. 743 | #[inline] 744 | pub fn field_type<'a>(&'a self, descriptors: &'a Descriptors) -> FieldType<'a> { 745 | self.field_type.resolve(descriptors) 746 | } 747 | 748 | /// The default value of the field. 749 | #[inline] 750 | pub fn default_value(&self) -> Option<&value::Value> { 751 | self.default_value.as_ref() 752 | } 753 | } 754 | 755 | fn store(vec: &mut Vec, elem: A) -> usize { 756 | let idx = vec.len(); 757 | vec.push(elem); 758 | idx 759 | } 760 | 761 | fn parse_default_value(value: &str, field_type: &InternalFieldType) -> error::Result { 762 | use std::str::FromStr; 763 | 764 | fn bad(v: &str) -> error::Error { 765 | error::Error::BadDefaultValue { 766 | default_value: v.to_owned(), 767 | } 768 | } 769 | 770 | match *field_type { 771 | InternalFieldType::UnresolvedMessage(_) 772 | | InternalFieldType::UnresolvedEnum(_) 773 | | InternalFieldType::Message(_) 774 | | InternalFieldType::Enum(_) => Err(bad(value)), 775 | InternalFieldType::Bool => bool::from_str(value) 776 | .map(value::Value::Bool) 777 | .map_err(|_| bad(value)), 778 | InternalFieldType::Double => match value { 779 | "inf" => Ok(value::Value::F64(f64::INFINITY)), 780 | "-inf" => Ok(value::Value::F64(f64::NEG_INFINITY)), 781 | "nan" => Ok(value::Value::F64(f64::NAN)), 782 | _ => f64::from_str(value) 783 | .map(value::Value::F64) 784 | .map_err(|_| bad(value)), 785 | }, 786 | InternalFieldType::Float => match value { 787 | "inf" => Ok(value::Value::F32(f32::INFINITY)), 788 | "-inf" => Ok(value::Value::F32(f32::NEG_INFINITY)), 789 | "nan" => Ok(value::Value::F32(f32::NAN)), 790 | _ => f32::from_str(value) 791 | .map(value::Value::F32) 792 | .map_err(|_| bad(value)), 793 | }, 794 | InternalFieldType::Int32 | InternalFieldType::SFixed32 | InternalFieldType::SInt32 => { 795 | i32::from_str(value) 796 | .map(value::Value::I32) 797 | .map_err(|_| bad(value)) 798 | } 799 | InternalFieldType::Int64 | InternalFieldType::SFixed64 | InternalFieldType::SInt64 => { 800 | i64::from_str(value) 801 | .map(value::Value::I64) 802 | .map_err(|_| bad(value)) 803 | } 804 | InternalFieldType::UInt32 | InternalFieldType::Fixed32 => u32::from_str(value) 805 | .map(value::Value::U32) 806 | .map_err(|_| bad(value)), 807 | InternalFieldType::UInt64 | InternalFieldType::Fixed64 => u64::from_str(value) 808 | .map(value::Value::U64) 809 | .map_err(|_| bad(value)), 810 | InternalFieldType::String => Ok(value::Value::String(value.to_owned())), 811 | InternalFieldType::Group => unimplemented!(), 812 | InternalFieldType::Bytes => Ok(value::Value::Bytes( 813 | value.chars().map(|c| c as u8).collect(), 814 | )), 815 | } 816 | } 817 | 818 | #[cfg(test)] 819 | mod test { 820 | use std::fs; 821 | 822 | use protobuf::{self, descriptor::FileDescriptorSet, Message}; 823 | 824 | use super::FieldLabel::*; 825 | use super::FieldType::*; 826 | use super::*; 827 | 828 | fn load_descriptors() -> Descriptors { 829 | let mut file = fs::File::open("testdata/descriptors.pb").unwrap(); 830 | let proto = FileDescriptorSet::parse_from_reader(&mut file).unwrap(); 831 | 832 | Descriptors::from_proto(&proto) 833 | } 834 | 835 | macro_rules! check_field { 836 | ($id:ident, $msg:expr, $field:expr, $t:pat, $label:expr, $num:expr) => { 837 | #[test] 838 | fn $id() { 839 | let mut d = load_descriptors(); 840 | d.resolve_refs(); 841 | let msg = d.message_by_name($msg).unwrap(); 842 | let field_by_name = msg.field_by_name($field).unwrap(); 843 | match field_by_name.field_type(&d) { 844 | $t => (), 845 | t => panic!("Expected type {}, got {:?}", stringify!($t), t), 846 | } 847 | assert_eq!(field_by_name.name(), $field); 848 | assert_eq!(field_by_name.number(), $num); 849 | assert_eq!(field_by_name.field_label(), $label); 850 | 851 | let field_by_number = msg.field_by_number($num).unwrap(); 852 | match field_by_number.field_type(&d) { 853 | $t => (), 854 | t => panic!("Expected type {}, got {:?}", stringify!($t), t), 855 | } 856 | assert_eq!(field_by_number.name(), $field); 857 | assert_eq!(field_by_number.number(), $num); 858 | assert_eq!(field_by_number.field_label(), $label); 859 | } 860 | }; 861 | } 862 | 863 | macro_rules! check_enum_value { 864 | ($id:ident, $enu:expr, $value:expr, $num:expr) => { 865 | #[test] 866 | fn $id() { 867 | let mut d = load_descriptors(); 868 | d.resolve_refs(); 869 | let enu = d.enum_by_name($enu).unwrap(); 870 | let value_by_name = enu.value_by_name($value).unwrap(); 871 | assert_eq!(value_by_name.name(), $value); 872 | assert_eq!(value_by_name.number(), $num); 873 | 874 | let value_by_number = enu.value_by_number($num).unwrap(); 875 | assert_eq!(value_by_number.name(), $value); 876 | assert_eq!(value_by_number.number(), $num); 877 | } 878 | }; 879 | } 880 | 881 | check_field!( 882 | optional_int32_field, 883 | ".protobuf_unittest.TestAllTypes", 884 | "optional_int32", 885 | Int32, 886 | Optional, 887 | 1 888 | ); 889 | 890 | check_field!( 891 | optional_int64_field, 892 | ".protobuf_unittest.TestAllTypes", 893 | "optional_int64", 894 | Int64, 895 | Optional, 896 | 2 897 | ); 898 | 899 | check_field!( 900 | optional_uint32_field, 901 | ".protobuf_unittest.TestAllTypes", 902 | "optional_uint32", 903 | UInt32, 904 | Optional, 905 | 3 906 | ); 907 | 908 | check_field!( 909 | optional_uint64_field, 910 | ".protobuf_unittest.TestAllTypes", 911 | "optional_uint64", 912 | UInt64, 913 | Optional, 914 | 4 915 | ); 916 | 917 | check_field!( 918 | optional_sint32_field, 919 | ".protobuf_unittest.TestAllTypes", 920 | "optional_sint32", 921 | SInt32, 922 | Optional, 923 | 5 924 | ); 925 | 926 | check_field!( 927 | optional_sint64_field, 928 | ".protobuf_unittest.TestAllTypes", 929 | "optional_sint64", 930 | SInt64, 931 | Optional, 932 | 6 933 | ); 934 | 935 | check_field!( 936 | optional_fixed32_field, 937 | ".protobuf_unittest.TestAllTypes", 938 | "optional_fixed32", 939 | Fixed32, 940 | Optional, 941 | 7 942 | ); 943 | 944 | check_field!( 945 | optional_fixed64_field, 946 | ".protobuf_unittest.TestAllTypes", 947 | "optional_fixed64", 948 | Fixed64, 949 | Optional, 950 | 8 951 | ); 952 | 953 | check_field!( 954 | optional_sfixed32_field, 955 | ".protobuf_unittest.TestAllTypes", 956 | "optional_sfixed32", 957 | SFixed32, 958 | Optional, 959 | 9 960 | ); 961 | 962 | check_field!( 963 | optional_sfixed64_field, 964 | ".protobuf_unittest.TestAllTypes", 965 | "optional_sfixed64", 966 | SFixed64, 967 | Optional, 968 | 10 969 | ); 970 | 971 | check_field!( 972 | optional_float_field, 973 | ".protobuf_unittest.TestAllTypes", 974 | "optional_float", 975 | Float, 976 | Optional, 977 | 11 978 | ); 979 | 980 | check_field!( 981 | optional_double_field, 982 | ".protobuf_unittest.TestAllTypes", 983 | "optional_double", 984 | Double, 985 | Optional, 986 | 12 987 | ); 988 | 989 | check_field!( 990 | optional_bool_field, 991 | ".protobuf_unittest.TestAllTypes", 992 | "optional_bool", 993 | Bool, 994 | Optional, 995 | 13 996 | ); 997 | 998 | check_field!( 999 | optional_string_field, 1000 | ".protobuf_unittest.TestAllTypes", 1001 | "optional_string", 1002 | String, 1003 | Optional, 1004 | 14 1005 | ); 1006 | 1007 | check_field!( 1008 | optional_bytes_field, 1009 | ".protobuf_unittest.TestAllTypes", 1010 | "optional_bytes", 1011 | Bytes, 1012 | Optional, 1013 | 15 1014 | ); 1015 | 1016 | check_field!( 1017 | repeated_int32_field, 1018 | ".protobuf_unittest.TestAllTypes", 1019 | "repeated_int32", 1020 | Int32, 1021 | Repeated, 1022 | 31 1023 | ); 1024 | 1025 | check_field!( 1026 | repeated_int64_field, 1027 | ".protobuf_unittest.TestAllTypes", 1028 | "repeated_int64", 1029 | Int64, 1030 | Repeated, 1031 | 32 1032 | ); 1033 | 1034 | check_field!( 1035 | repeated_uint32_field, 1036 | ".protobuf_unittest.TestAllTypes", 1037 | "repeated_uint32", 1038 | UInt32, 1039 | Repeated, 1040 | 33 1041 | ); 1042 | 1043 | check_field!( 1044 | repeated_uint64_field, 1045 | ".protobuf_unittest.TestAllTypes", 1046 | "repeated_uint64", 1047 | UInt64, 1048 | Repeated, 1049 | 34 1050 | ); 1051 | 1052 | check_field!( 1053 | repeated_sint32_field, 1054 | ".protobuf_unittest.TestAllTypes", 1055 | "repeated_sint32", 1056 | SInt32, 1057 | Repeated, 1058 | 35 1059 | ); 1060 | 1061 | check_field!( 1062 | repeated_sint64_field, 1063 | ".protobuf_unittest.TestAllTypes", 1064 | "repeated_sint64", 1065 | SInt64, 1066 | Repeated, 1067 | 36 1068 | ); 1069 | 1070 | check_field!( 1071 | repeated_fixed32_field, 1072 | ".protobuf_unittest.TestAllTypes", 1073 | "repeated_fixed32", 1074 | Fixed32, 1075 | Repeated, 1076 | 37 1077 | ); 1078 | 1079 | check_field!( 1080 | repeated_fixed64_field, 1081 | ".protobuf_unittest.TestAllTypes", 1082 | "repeated_fixed64", 1083 | Fixed64, 1084 | Repeated, 1085 | 38 1086 | ); 1087 | 1088 | check_field!( 1089 | repeated_sfixed32_field, 1090 | ".protobuf_unittest.TestAllTypes", 1091 | "repeated_sfixed32", 1092 | SFixed32, 1093 | Repeated, 1094 | 39 1095 | ); 1096 | 1097 | check_field!( 1098 | repeated_sfixed64_field, 1099 | ".protobuf_unittest.TestAllTypes", 1100 | "repeated_sfixed64", 1101 | SFixed64, 1102 | Repeated, 1103 | 40 1104 | ); 1105 | 1106 | check_field!( 1107 | repeated_float_field, 1108 | ".protobuf_unittest.TestAllTypes", 1109 | "repeated_float", 1110 | Float, 1111 | Repeated, 1112 | 41 1113 | ); 1114 | 1115 | check_field!( 1116 | repeated_double_field, 1117 | ".protobuf_unittest.TestAllTypes", 1118 | "repeated_double", 1119 | Double, 1120 | Repeated, 1121 | 42 1122 | ); 1123 | 1124 | check_field!( 1125 | repeated_bool_field, 1126 | ".protobuf_unittest.TestAllTypes", 1127 | "repeated_bool", 1128 | Bool, 1129 | Repeated, 1130 | 43 1131 | ); 1132 | 1133 | check_field!( 1134 | repeated_string_field, 1135 | ".protobuf_unittest.TestAllTypes", 1136 | "repeated_string", 1137 | String, 1138 | Repeated, 1139 | 44 1140 | ); 1141 | 1142 | check_field!( 1143 | repeated_bytes_field, 1144 | ".protobuf_unittest.TestAllTypes", 1145 | "repeated_bytes", 1146 | Bytes, 1147 | Repeated, 1148 | 45 1149 | ); 1150 | 1151 | check_field!( 1152 | repppeated_message_field, 1153 | ".protobuf_unittest.TestAllTypes", 1154 | "repeated_foreign_message", 1155 | Message(..), 1156 | Repeated, 1157 | 49 1158 | ); 1159 | 1160 | check_field!( 1161 | repeated_enum_field, 1162 | ".protobuf_unittest.TestAllTypes", 1163 | "repeated_foreign_enum", 1164 | Enum(..), 1165 | Repeated, 1166 | 52 1167 | ); 1168 | 1169 | check_field!( 1170 | required_field_a, 1171 | ".protobuf_unittest.TestRequired", 1172 | "a", 1173 | Int32, 1174 | Required, 1175 | 1 1176 | ); 1177 | 1178 | check_field!( 1179 | required_field_b, 1180 | ".protobuf_unittest.TestRequired", 1181 | "b", 1182 | Int32, 1183 | Required, 1184 | 3 1185 | ); 1186 | 1187 | check_enum_value!( 1188 | enum_value_foo, 1189 | ".protobuf_unittest.ForeignEnum", 1190 | "FOREIGN_FOO", 1191 | 4 1192 | ); 1193 | 1194 | check_enum_value!( 1195 | enum_value_bar, 1196 | ".protobuf_unittest.ForeignEnum", 1197 | "FOREIGN_BAR", 1198 | 5 1199 | ); 1200 | 1201 | check_enum_value!( 1202 | enum_value_baz, 1203 | ".protobuf_unittest.ForeignEnum", 1204 | "FOREIGN_BAZ", 1205 | 6 1206 | ); 1207 | } 1208 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | //! Common error types for this crate. 2 | use std::fmt; 3 | use std::result; 4 | 5 | use protobuf; 6 | use protobuf::wire_format; 7 | use serde; 8 | use thiserror::Error; 9 | 10 | /// A result whose error type is `Error`. 11 | pub type Result = result::Result; 12 | 13 | /// An error that may occur when dealing with Protobuf. 14 | #[derive(Debug, Error)] 15 | pub enum Error { 16 | /// A native protobuf error. 17 | #[error("protobuf error")] 18 | Protobuf(#[source] protobuf::ProtobufError), 19 | /// The end of stream was reached. 20 | #[error("end of stream")] 21 | EndOfStream, 22 | /// An unknown enum type was encountered. 23 | #[error("unknown enum: {name}")] 24 | UnknownEnum { 25 | /// The name of the enum. 26 | name: String, 27 | }, 28 | /// An unknown enum value was encountered. 29 | #[error("unknown enum value: {value}")] 30 | UnknownEnumValue { 31 | /// The number of the enum value. 32 | value: i32, 33 | }, 34 | /// An unknown message type was encountered. 35 | #[error("unknown message: {name}")] 36 | UnknownMessage { 37 | /// The name of the message. 38 | name: String, 39 | }, 40 | /// An unexpected wire type was received. 41 | #[error("bad wire type: {wire_type:?}")] 42 | BadWireType { 43 | /// The encountered wire type. 44 | wire_type: wire_format::WireType, 45 | }, 46 | /// A default value that can't be parsed was received. 47 | #[error("bad default value: {default_value:?}")] 48 | BadDefaultValue { 49 | /// The default value that couldn't be parsed. 50 | default_value: String, 51 | }, 52 | /// Some user-defined error occurred. 53 | #[error("{message}")] 54 | Custom { 55 | /// The user-defined error message. 56 | message: String, 57 | }, 58 | } 59 | 60 | /// A result whose error type is `CompatError`. 61 | pub type CompatResult = result::Result; 62 | 63 | /// A compatibility error for use with `serde`. 64 | #[derive(Debug, Error)] 65 | pub struct CompatError(#[from] Error); 66 | 67 | impl From for Error { 68 | fn from(e: protobuf::error::ProtobufError) -> Self { 69 | Error::Protobuf(e) 70 | } 71 | } 72 | 73 | impl CompatError { 74 | /// Converts this compatibility error into the underlying error. 75 | pub fn into_error(self) -> Error { 76 | self.0 77 | } 78 | } 79 | 80 | impl fmt::Display for CompatError { 81 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 82 | self.0.fmt(f) 83 | } 84 | } 85 | 86 | impl serde::de::Error for CompatError { 87 | fn custom(msg: T) -> CompatError 88 | where 89 | T: fmt::Display, 90 | { 91 | CompatError(Error::Custom { 92 | message: msg.to_string(), 93 | }) 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Support for [Google protocol buffers][1] in combination with `serde`. 2 | //! 3 | //! The crate is split up into several logical parts. 4 | //! 5 | //! * The [`descriptor`](descriptor/index.html) module provides an API for managing dynamically 6 | //! loaded protocol buffer schemata. 7 | //! * The [`value`](value/index.html) module provides structs that can hold any raw protocol 8 | //! buffer decoded data (but the representation is heavily coupled with a schema). 9 | //! * The [`de`](de/index.html) module can be used to deserialize binary encoded protocol buffer 10 | //! messages given some schema descriptors. 11 | //! 12 | //! Serialization is not yet implemented in this version. 13 | //! 14 | //! [1]: https://developers.google.com/protocol-buffers/ 15 | #![deny(warnings)] 16 | #![deny(clippy::all)] 17 | #![deny( 18 | missing_debug_implementations, 19 | missing_docs, 20 | trivial_casts, 21 | trivial_numeric_casts, 22 | unused_extern_crates, 23 | unused_import_braces, 24 | unused_qualifications 25 | )] 26 | #[macro_use] 27 | extern crate log; 28 | #[macro_use] 29 | extern crate serde; 30 | 31 | pub mod de; 32 | pub mod descriptor; 33 | pub mod error; 34 | pub mod value; 35 | 36 | pub use crate::error::Error; 37 | -------------------------------------------------------------------------------- /src/value.rs: -------------------------------------------------------------------------------- 1 | //! Types for representing runtime Protobuf values. 2 | use std::collections; 3 | 4 | use protobuf; 5 | use protobuf::wire_format; 6 | 7 | use crate::descriptor; 8 | use crate::error; 9 | 10 | /// Any protobuf value. 11 | #[derive(Clone, Debug)] 12 | pub enum Value { 13 | /// A boolean value. 14 | Bool(bool), 15 | /// A 32-bit signed integer. 16 | I32(i32), 17 | /// A 64-bit signed integer. 18 | I64(i64), 19 | /// A 32-bit unsigned integer. 20 | U32(u32), 21 | /// A 64-bit unsigned integer. 22 | U64(u64), 23 | /// A 32-bit floating point value. 24 | F32(f32), 25 | /// A 64-bit floating point value. 26 | F64(f64), 27 | /// A byte vector. 28 | Bytes(Vec), 29 | /// A string. 30 | String(String), 31 | /// An enum value. 32 | Enum(i32), 33 | /// A message. 34 | Message(Message), 35 | } 36 | 37 | /// A message value. 38 | #[derive(Clone, Debug)] 39 | pub struct Message { 40 | /// Known fields on the message. 41 | pub fields: collections::BTreeMap, 42 | /// Unknown fields on the message. 43 | pub unknown: protobuf::UnknownFields, 44 | } 45 | 46 | /// A message field value. 47 | #[derive(Clone, Debug)] 48 | pub enum Field { 49 | /// A field with a single value. 50 | Singular(Option), 51 | /// A field with several (repeated) values. 52 | Repeated(Vec), 53 | } 54 | 55 | impl Message { 56 | /// Creates a message given a Protobuf descriptor. 57 | #[inline] 58 | pub fn new(message: &descriptor::MessageDescriptor) -> Message { 59 | let mut m = Message { 60 | fields: collections::BTreeMap::new(), 61 | unknown: protobuf::UnknownFields::new(), 62 | }; 63 | 64 | for field in message.fields() { 65 | m.fields.insert( 66 | field.number(), 67 | if field.is_repeated() { 68 | Field::Repeated(Vec::new()) 69 | } else { 70 | Field::Singular(field.default_value().cloned()) 71 | }, 72 | ); 73 | } 74 | 75 | m 76 | } 77 | 78 | /// Merge data from the given input stream into this message. 79 | #[inline] 80 | pub fn merge_from( 81 | &mut self, 82 | descriptors: &descriptor::Descriptors, 83 | message: &descriptor::MessageDescriptor, 84 | input: &mut protobuf::CodedInputStream, 85 | ) -> error::Result<()> { 86 | while !input.eof()? { 87 | let (number, wire_type) = input.read_tag_unpack()?; 88 | 89 | if let Some(field) = message.field_by_number(number as i32) { 90 | let value = self.ensure_field(field); 91 | value.merge_from(descriptors, field, input, wire_type)?; 92 | } else { 93 | use protobuf::rt::read_unknown_or_skip_group as u; 94 | u(number, wire_type, input, &mut self.unknown)?; 95 | } 96 | } 97 | Ok(()) 98 | } 99 | 100 | #[inline] 101 | fn ensure_field(&mut self, field: &descriptor::FieldDescriptor) -> &mut Field { 102 | self.fields 103 | .entry(field.number()) 104 | .or_insert_with(|| Field::new(field)) 105 | } 106 | } 107 | 108 | impl Field { 109 | /// Creates a field given a Protobuf descriptor. 110 | #[inline] 111 | pub fn new(field: &descriptor::FieldDescriptor) -> Field { 112 | if field.is_repeated() { 113 | Field::Repeated(Vec::new()) 114 | } else { 115 | Field::Singular(None) 116 | } 117 | } 118 | 119 | /// Merge data from the given input stream into this field. 120 | #[inline] 121 | pub fn merge_from( 122 | &mut self, 123 | descriptors: &descriptor::Descriptors, 124 | field: &descriptor::FieldDescriptor, 125 | input: &mut protobuf::CodedInputStream, 126 | wire_type: protobuf::wire_format::WireType, 127 | ) -> error::Result<()> { 128 | // Make the type dispatch below more compact 129 | use crate::descriptor::FieldType::*; 130 | use protobuf::wire_format::WireType::*; 131 | use protobuf::CodedInputStream as I; 132 | 133 | // Singular scalar 134 | macro_rules! ss { 135 | ($expected_wire_type:expr, $visit_func:expr, $reader:expr) => { 136 | self.merge_scalar(input, wire_type, $expected_wire_type, $visit_func, $reader) 137 | }; 138 | } 139 | 140 | // Packable scalar 141 | macro_rules! ps { 142 | ($expected_wire_type:expr, $visit_func:expr, $reader:expr) => { 143 | self.merge_packable_scalar( 144 | input, 145 | wire_type, 146 | $expected_wire_type, 147 | $visit_func, 148 | $reader, 149 | ) 150 | }; 151 | ($expected_wire_type:expr, $size:expr, $visit_func:expr, $reader:expr) => { 152 | // TODO: use size to pre-allocate buffer space 153 | self.merge_packable_scalar( 154 | input, 155 | wire_type, 156 | $expected_wire_type, 157 | $visit_func, 158 | $reader, 159 | ) 160 | }; 161 | } 162 | 163 | match field.field_type(descriptors) { 164 | Bool => ps!(WireTypeVarint, Value::Bool, I::read_bool), 165 | Int32 => ps!(WireTypeVarint, Value::I32, I::read_int32), 166 | Int64 => ps!(WireTypeVarint, Value::I64, I::read_int64), 167 | SInt32 => ps!(WireTypeVarint, Value::I32, I::read_sint32), 168 | SInt64 => ps!(WireTypeVarint, Value::I64, I::read_sint64), 169 | UInt32 => ps!(WireTypeVarint, Value::U32, I::read_uint32), 170 | UInt64 => ps!(WireTypeVarint, Value::U64, I::read_uint64), 171 | Fixed32 => ps!(WireTypeFixed32, 4, Value::U32, I::read_fixed32), 172 | Fixed64 => ps!(WireTypeFixed64, 8, Value::U64, I::read_fixed64), 173 | SFixed32 => ps!(WireTypeFixed32, 4, Value::I32, I::read_sfixed32), 174 | SFixed64 => ps!(WireTypeFixed64, 8, Value::I64, I::read_sfixed64), 175 | Float => ps!(WireTypeFixed32, 4, Value::F32, I::read_float), 176 | Double => ps!(WireTypeFixed64, 8, Value::F64, I::read_double), 177 | Bytes => ss!(WireTypeLengthDelimited, Value::Bytes, I::read_bytes), 178 | String => ss!(WireTypeLengthDelimited, Value::String, I::read_string), 179 | Enum(_) => self.merge_enum(input, wire_type), 180 | Message(ref m) => self.merge_message(input, descriptors, m, wire_type), 181 | Group => unimplemented!(), 182 | UnresolvedEnum(e) => Err(error::Error::UnknownEnum { name: e.to_owned() }), 183 | UnresolvedMessage(m) => Err(error::Error::UnknownMessage { name: m.to_owned() }), 184 | } 185 | } 186 | 187 | #[inline] 188 | fn merge_scalar<'a, A, V, R>( 189 | &mut self, 190 | input: &mut protobuf::CodedInputStream<'a>, 191 | actual_wire_type: wire_format::WireType, 192 | expected_wire_type: wire_format::WireType, 193 | value_ctor: V, 194 | reader: R, 195 | ) -> error::Result<()> 196 | where 197 | V: Fn(A) -> Value, 198 | R: Fn(&mut protobuf::CodedInputStream<'a>) -> protobuf::ProtobufResult, 199 | { 200 | if expected_wire_type == actual_wire_type { 201 | self.put(value_ctor(reader(input)?)); 202 | Ok(()) 203 | } else { 204 | Err(error::Error::BadWireType { 205 | wire_type: actual_wire_type, 206 | }) 207 | } 208 | } 209 | 210 | #[inline] 211 | fn merge_packable_scalar<'a, A, V, R>( 212 | &mut self, 213 | input: &mut protobuf::CodedInputStream<'a>, 214 | actual_wire_type: wire_format::WireType, 215 | expected_wire_type: wire_format::WireType, 216 | value_ctor: V, 217 | reader: R, 218 | ) -> error::Result<()> 219 | where 220 | V: Fn(A) -> Value, 221 | R: Fn(&mut protobuf::CodedInputStream<'a>) -> protobuf::ProtobufResult, 222 | { 223 | if wire_format::WireType::WireTypeLengthDelimited == actual_wire_type { 224 | let len = input.read_raw_varint64()?; 225 | 226 | let old_limit = input.push_limit(len)?; 227 | while !input.eof()? { 228 | self.put(value_ctor(reader(input)?)); 229 | } 230 | input.pop_limit(old_limit); 231 | 232 | Ok(()) 233 | } else { 234 | self.merge_scalar( 235 | input, 236 | actual_wire_type, 237 | expected_wire_type, 238 | value_ctor, 239 | reader, 240 | ) 241 | } 242 | } 243 | 244 | #[inline] 245 | fn merge_enum( 246 | &mut self, 247 | input: &mut protobuf::CodedInputStream, 248 | actual_wire_type: wire_format::WireType, 249 | ) -> error::Result<()> { 250 | if wire_format::WireType::WireTypeVarint == actual_wire_type { 251 | let v = input.read_raw_varint32()? as i32; 252 | self.put(Value::Enum(v)); 253 | Ok(()) 254 | } else { 255 | Err(error::Error::BadWireType { 256 | wire_type: actual_wire_type, 257 | }) 258 | } 259 | } 260 | 261 | #[inline] 262 | fn merge_message( 263 | &mut self, 264 | input: &mut protobuf::CodedInputStream, 265 | descriptors: &descriptor::Descriptors, 266 | message: &descriptor::MessageDescriptor, 267 | actual_wire_type: wire_format::WireType, 268 | ) -> error::Result<()> { 269 | if wire_format::WireType::WireTypeLengthDelimited == actual_wire_type { 270 | let len = input.read_raw_varint64()?; 271 | let mut msg = match *self { 272 | Field::Singular(ref mut o) => { 273 | if let Some(Value::Message(m)) = o.take() { 274 | m 275 | } else { 276 | Message::new(message) 277 | } 278 | } 279 | _ => Message::new(message), 280 | }; 281 | 282 | let old_limit = input.push_limit(len)?; 283 | msg.merge_from(descriptors, message, input)?; 284 | input.pop_limit(old_limit); 285 | 286 | self.put(Value::Message(msg)); 287 | Ok(()) 288 | } else { 289 | Err(error::Error::BadWireType { 290 | wire_type: actual_wire_type, 291 | }) 292 | } 293 | } 294 | 295 | #[inline] 296 | fn put(&mut self, value: Value) { 297 | match *self { 298 | Field::Singular(ref mut s) => *s = Some(value), 299 | Field::Repeated(ref mut r) => r.push(value), 300 | } 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /testdata/descriptors.pb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dflemstr/serde-protobuf/1aba2daa8e29eae8e5f786643b573e8250e417a7/testdata/descriptors.pb -------------------------------------------------------------------------------- /testdata/google/protobuf/unittest.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: kenton@google.com (Kenton Varda) 32 | // Based on original Protocol Buffers design by 33 | // Sanjay Ghemawat, Jeff Dean, and others. 34 | // 35 | // A proto file we will use for unit testing. 36 | 37 | syntax = "proto2"; 38 | 39 | // Some generic_services option(s) added automatically. 40 | // See: http://go/proto2-generic-services-default 41 | option cc_generic_services = true; // auto-added 42 | option java_generic_services = true; // auto-added 43 | option py_generic_services = true; // auto-added 44 | option cc_enable_arenas = true; 45 | 46 | import "google/protobuf/unittest_import.proto"; 47 | 48 | // We don't put this in a package within proto2 because we need to make sure 49 | // that the generated code doesn't depend on being in the proto2 namespace. 50 | // In test_util.h we do "using namespace unittest = protobuf_unittest". 51 | package protobuf_unittest; 52 | 53 | // Protos optimized for SPEED use a strict superset of the generated code 54 | // of equivalent ones optimized for CODE_SIZE, so we should optimize all our 55 | // tests for speed unless explicitly testing code size optimization. 56 | option optimize_for = SPEED; 57 | 58 | option java_outer_classname = "UnittestProto"; 59 | 60 | // This proto includes every type of field in both singular and repeated 61 | // forms. 62 | message TestAllTypes { 63 | message NestedMessage { 64 | // The field name "b" fails to compile in proto1 because it conflicts with 65 | // a local variable named "b" in one of the generated methods. Doh. 66 | // This file needs to compile in proto1 to test backwards-compatibility. 67 | optional int32 bb = 1; 68 | } 69 | 70 | enum NestedEnum { 71 | FOO = 1; 72 | BAR = 2; 73 | BAZ = 3; 74 | NEG = -1; // Intentionally negative. 75 | } 76 | 77 | // Singular 78 | optional int32 optional_int32 = 1; 79 | optional int64 optional_int64 = 2; 80 | optional uint32 optional_uint32 = 3; 81 | optional uint64 optional_uint64 = 4; 82 | optional sint32 optional_sint32 = 5; 83 | optional sint64 optional_sint64 = 6; 84 | optional fixed32 optional_fixed32 = 7; 85 | optional fixed64 optional_fixed64 = 8; 86 | optional sfixed32 optional_sfixed32 = 9; 87 | optional sfixed64 optional_sfixed64 = 10; 88 | optional float optional_float = 11; 89 | optional double optional_double = 12; 90 | optional bool optional_bool = 13; 91 | optional string optional_string = 14; 92 | optional bytes optional_bytes = 15; 93 | 94 | /* 95 | optional group OptionalGroup = 16 { 96 | optional int32 a = 17; 97 | } 98 | */ 99 | 100 | optional NestedMessage optional_nested_message = 18; 101 | optional ForeignMessage optional_foreign_message = 19; 102 | optional protobuf_unittest_import.ImportMessage optional_import_message = 20; 103 | 104 | optional NestedEnum optional_nested_enum = 21; 105 | optional ForeignEnum optional_foreign_enum = 22; 106 | optional protobuf_unittest_import.ImportEnum optional_import_enum = 23; 107 | 108 | optional string optional_string_piece = 24 [ctype=STRING_PIECE]; 109 | optional string optional_cord = 25 [ctype=CORD]; 110 | 111 | // Defined in unittest_import_public.proto 112 | optional protobuf_unittest_import.PublicImportMessage 113 | optional_public_import_message = 26; 114 | 115 | optional NestedMessage optional_lazy_message = 27 [lazy=true]; 116 | 117 | // Repeated 118 | repeated int32 repeated_int32 = 31; 119 | repeated int64 repeated_int64 = 32; 120 | repeated uint32 repeated_uint32 = 33; 121 | repeated uint64 repeated_uint64 = 34; 122 | repeated sint32 repeated_sint32 = 35; 123 | repeated sint64 repeated_sint64 = 36; 124 | repeated fixed32 repeated_fixed32 = 37; 125 | repeated fixed64 repeated_fixed64 = 38; 126 | repeated sfixed32 repeated_sfixed32 = 39; 127 | repeated sfixed64 repeated_sfixed64 = 40; 128 | repeated float repeated_float = 41; 129 | repeated double repeated_double = 42; 130 | repeated bool repeated_bool = 43; 131 | repeated string repeated_string = 44; 132 | repeated bytes repeated_bytes = 45; 133 | 134 | /* 135 | repeated group RepeatedGroup = 46 { 136 | optional int32 a = 47; 137 | } 138 | */ 139 | 140 | repeated NestedMessage repeated_nested_message = 48; 141 | repeated ForeignMessage repeated_foreign_message = 49; 142 | repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50; 143 | 144 | repeated NestedEnum repeated_nested_enum = 51; 145 | repeated ForeignEnum repeated_foreign_enum = 52; 146 | repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53; 147 | 148 | repeated string repeated_string_piece = 54 [ctype=STRING_PIECE]; 149 | repeated string repeated_cord = 55 [ctype=CORD]; 150 | 151 | repeated NestedMessage repeated_lazy_message = 57 [lazy=true]; 152 | 153 | // Singular with defaults 154 | optional int32 default_int32 = 61 [default = 41 ]; 155 | optional int64 default_int64 = 62 [default = 42 ]; 156 | optional uint32 default_uint32 = 63 [default = 43 ]; 157 | optional uint64 default_uint64 = 64 [default = 44 ]; 158 | optional sint32 default_sint32 = 65 [default = -45 ]; 159 | optional sint64 default_sint64 = 66 [default = 46 ]; 160 | optional fixed32 default_fixed32 = 67 [default = 47 ]; 161 | optional fixed64 default_fixed64 = 68 [default = 48 ]; 162 | optional sfixed32 default_sfixed32 = 69 [default = 49 ]; 163 | optional sfixed64 default_sfixed64 = 70 [default = -50 ]; 164 | optional float default_float = 71 [default = 51.5 ]; 165 | optional double default_double = 72 [default = 52e3 ]; 166 | optional bool default_bool = 73 [default = true ]; 167 | optional string default_string = 74 [default = "hello"]; 168 | optional bytes default_bytes = 75 [default = "world"]; 169 | 170 | optional NestedEnum default_nested_enum = 81 [default = BAR ]; 171 | optional ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR]; 172 | optional protobuf_unittest_import.ImportEnum 173 | default_import_enum = 83 [default = IMPORT_BAR]; 174 | 175 | optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"]; 176 | optional string default_cord = 85 [ctype=CORD,default="123"]; 177 | 178 | // For oneof test 179 | oneof oneof_field { 180 | uint32 oneof_uint32 = 111; 181 | NestedMessage oneof_nested_message = 112; 182 | string oneof_string = 113; 183 | bytes oneof_bytes = 114; 184 | } 185 | } 186 | 187 | // This proto includes a recusively nested message. 188 | message NestedTestAllTypes { 189 | optional NestedTestAllTypes child = 1; 190 | optional TestAllTypes payload = 2; 191 | repeated NestedTestAllTypes repeated_child = 3; 192 | } 193 | 194 | message TestDeprecatedFields { 195 | optional int32 deprecated_int32 = 1 [deprecated=true]; 196 | } 197 | 198 | // Define these after TestAllTypes to make sure the compiler can handle 199 | // that. 200 | message ForeignMessage { 201 | optional int32 c = 1; 202 | } 203 | 204 | enum ForeignEnum { 205 | FOREIGN_FOO = 4; 206 | FOREIGN_BAR = 5; 207 | FOREIGN_BAZ = 6; 208 | } 209 | 210 | message TestReservedFields { 211 | reserved 2, 15, 9 to 11; 212 | reserved "bar", "baz"; 213 | } 214 | 215 | message TestAllExtensions { 216 | extensions 1 to max; 217 | } 218 | 219 | extend TestAllExtensions { 220 | // Singular 221 | optional int32 optional_int32_extension = 1; 222 | optional int64 optional_int64_extension = 2; 223 | optional uint32 optional_uint32_extension = 3; 224 | optional uint64 optional_uint64_extension = 4; 225 | optional sint32 optional_sint32_extension = 5; 226 | optional sint64 optional_sint64_extension = 6; 227 | optional fixed32 optional_fixed32_extension = 7; 228 | optional fixed64 optional_fixed64_extension = 8; 229 | optional sfixed32 optional_sfixed32_extension = 9; 230 | optional sfixed64 optional_sfixed64_extension = 10; 231 | optional float optional_float_extension = 11; 232 | optional double optional_double_extension = 12; 233 | optional bool optional_bool_extension = 13; 234 | optional string optional_string_extension = 14; 235 | optional bytes optional_bytes_extension = 15; 236 | 237 | /* 238 | optional group OptionalGroup_extension = 16 { 239 | optional int32 a = 17; 240 | } 241 | */ 242 | 243 | optional TestAllTypes.NestedMessage optional_nested_message_extension = 18; 244 | optional ForeignMessage optional_foreign_message_extension = 19; 245 | optional protobuf_unittest_import.ImportMessage 246 | optional_import_message_extension = 20; 247 | 248 | optional TestAllTypes.NestedEnum optional_nested_enum_extension = 21; 249 | optional ForeignEnum optional_foreign_enum_extension = 22; 250 | optional protobuf_unittest_import.ImportEnum 251 | optional_import_enum_extension = 23; 252 | 253 | optional string optional_string_piece_extension = 24 [ctype=STRING_PIECE]; 254 | optional string optional_cord_extension = 25 [ctype=CORD]; 255 | 256 | optional protobuf_unittest_import.PublicImportMessage 257 | optional_public_import_message_extension = 26; 258 | 259 | optional TestAllTypes.NestedMessage 260 | optional_lazy_message_extension = 27 [lazy=true]; 261 | 262 | // Repeated 263 | repeated int32 repeated_int32_extension = 31; 264 | repeated int64 repeated_int64_extension = 32; 265 | repeated uint32 repeated_uint32_extension = 33; 266 | repeated uint64 repeated_uint64_extension = 34; 267 | repeated sint32 repeated_sint32_extension = 35; 268 | repeated sint64 repeated_sint64_extension = 36; 269 | repeated fixed32 repeated_fixed32_extension = 37; 270 | repeated fixed64 repeated_fixed64_extension = 38; 271 | repeated sfixed32 repeated_sfixed32_extension = 39; 272 | repeated sfixed64 repeated_sfixed64_extension = 40; 273 | repeated float repeated_float_extension = 41; 274 | repeated double repeated_double_extension = 42; 275 | repeated bool repeated_bool_extension = 43; 276 | repeated string repeated_string_extension = 44; 277 | repeated bytes repeated_bytes_extension = 45; 278 | 279 | /* 280 | repeated group RepeatedGroup_extension = 46 { 281 | optional int32 a = 47; 282 | } 283 | */ 284 | 285 | repeated TestAllTypes.NestedMessage repeated_nested_message_extension = 48; 286 | repeated ForeignMessage repeated_foreign_message_extension = 49; 287 | repeated protobuf_unittest_import.ImportMessage 288 | repeated_import_message_extension = 50; 289 | 290 | repeated TestAllTypes.NestedEnum repeated_nested_enum_extension = 51; 291 | repeated ForeignEnum repeated_foreign_enum_extension = 52; 292 | repeated protobuf_unittest_import.ImportEnum 293 | repeated_import_enum_extension = 53; 294 | 295 | repeated string repeated_string_piece_extension = 54 [ctype=STRING_PIECE]; 296 | repeated string repeated_cord_extension = 55 [ctype=CORD]; 297 | 298 | repeated TestAllTypes.NestedMessage 299 | repeated_lazy_message_extension = 57 [lazy=true]; 300 | 301 | // Singular with defaults 302 | optional int32 default_int32_extension = 61 [default = 41 ]; 303 | optional int64 default_int64_extension = 62 [default = 42 ]; 304 | optional uint32 default_uint32_extension = 63 [default = 43 ]; 305 | optional uint64 default_uint64_extension = 64 [default = 44 ]; 306 | optional sint32 default_sint32_extension = 65 [default = -45 ]; 307 | optional sint64 default_sint64_extension = 66 [default = 46 ]; 308 | optional fixed32 default_fixed32_extension = 67 [default = 47 ]; 309 | optional fixed64 default_fixed64_extension = 68 [default = 48 ]; 310 | optional sfixed32 default_sfixed32_extension = 69 [default = 49 ]; 311 | optional sfixed64 default_sfixed64_extension = 70 [default = -50 ]; 312 | optional float default_float_extension = 71 [default = 51.5 ]; 313 | optional double default_double_extension = 72 [default = 52e3 ]; 314 | optional bool default_bool_extension = 73 [default = true ]; 315 | optional string default_string_extension = 74 [default = "hello"]; 316 | optional bytes default_bytes_extension = 75 [default = "world"]; 317 | 318 | optional TestAllTypes.NestedEnum 319 | default_nested_enum_extension = 81 [default = BAR]; 320 | optional ForeignEnum 321 | default_foreign_enum_extension = 82 [default = FOREIGN_BAR]; 322 | optional protobuf_unittest_import.ImportEnum 323 | default_import_enum_extension = 83 [default = IMPORT_BAR]; 324 | 325 | optional string default_string_piece_extension = 84 [ctype=STRING_PIECE, 326 | default="abc"]; 327 | optional string default_cord_extension = 85 [ctype=CORD, default="123"]; 328 | 329 | // For oneof test 330 | optional uint32 oneof_uint32_extension = 111; 331 | optional TestAllTypes.NestedMessage oneof_nested_message_extension = 112; 332 | optional string oneof_string_extension = 113; 333 | optional bytes oneof_bytes_extension = 114; 334 | } 335 | 336 | message TestNestedExtension { 337 | extend TestAllExtensions { 338 | // Check for bug where string extensions declared in tested scope did not 339 | // compile. 340 | optional string test = 1002 [default="test"]; 341 | // Used to test if generated extension name is correct when there are 342 | // underscores. 343 | optional string nested_string_extension = 1003; 344 | } 345 | } 346 | 347 | // We have separate messages for testing required fields because it's 348 | // annoying to have to fill in required fields in TestProto in order to 349 | // do anything with it. Note that we don't need to test every type of 350 | // required filed because the code output is basically identical to 351 | // optional fields for all types. 352 | message TestRequired { 353 | required int32 a = 1; 354 | optional int32 dummy2 = 2; 355 | required int32 b = 3; 356 | 357 | extend TestAllExtensions { 358 | optional TestRequired single = 1000; 359 | repeated TestRequired multi = 1001; 360 | } 361 | 362 | // Pad the field count to 32 so that we can test that IsInitialized() 363 | // properly checks multiple elements of has_bits_. 364 | optional int32 dummy4 = 4; 365 | optional int32 dummy5 = 5; 366 | optional int32 dummy6 = 6; 367 | optional int32 dummy7 = 7; 368 | optional int32 dummy8 = 8; 369 | optional int32 dummy9 = 9; 370 | optional int32 dummy10 = 10; 371 | optional int32 dummy11 = 11; 372 | optional int32 dummy12 = 12; 373 | optional int32 dummy13 = 13; 374 | optional int32 dummy14 = 14; 375 | optional int32 dummy15 = 15; 376 | optional int32 dummy16 = 16; 377 | optional int32 dummy17 = 17; 378 | optional int32 dummy18 = 18; 379 | optional int32 dummy19 = 19; 380 | optional int32 dummy20 = 20; 381 | optional int32 dummy21 = 21; 382 | optional int32 dummy22 = 22; 383 | optional int32 dummy23 = 23; 384 | optional int32 dummy24 = 24; 385 | optional int32 dummy25 = 25; 386 | optional int32 dummy26 = 26; 387 | optional int32 dummy27 = 27; 388 | optional int32 dummy28 = 28; 389 | optional int32 dummy29 = 29; 390 | optional int32 dummy30 = 30; 391 | optional int32 dummy31 = 31; 392 | optional int32 dummy32 = 32; 393 | 394 | required int32 c = 33; 395 | } 396 | 397 | message TestRequiredForeign { 398 | optional TestRequired optional_message = 1; 399 | repeated TestRequired repeated_message = 2; 400 | optional int32 dummy = 3; 401 | } 402 | 403 | // Test that we can use NestedMessage from outside TestAllTypes. 404 | message TestForeignNested { 405 | optional TestAllTypes.NestedMessage foreign_nested = 1; 406 | } 407 | 408 | // TestEmptyMessage is used to test unknown field support. 409 | message TestEmptyMessage { 410 | } 411 | 412 | // Like above, but declare all field numbers as potential extensions. No 413 | // actual extensions should ever be defined for this type. 414 | message TestEmptyMessageWithExtensions { 415 | extensions 1 to max; 416 | } 417 | 418 | message TestMultipleExtensionRanges { 419 | extensions 42; 420 | extensions 4143 to 4243; 421 | extensions 65536 to max; 422 | } 423 | 424 | // Test that really large tag numbers don't break anything. 425 | message TestReallyLargeTagNumber { 426 | // The largest possible tag number is 2^28 - 1, since the wire format uses 427 | // three bits to communicate wire type. 428 | optional int32 a = 1; 429 | optional int32 bb = 268435455; 430 | } 431 | 432 | message TestRecursiveMessage { 433 | optional TestRecursiveMessage a = 1; 434 | optional int32 i = 2; 435 | } 436 | 437 | // Test that mutual recursion works. 438 | message TestMutualRecursionA { 439 | optional TestMutualRecursionB bb = 1; 440 | } 441 | 442 | message TestMutualRecursionB { 443 | optional TestMutualRecursionA a = 1; 444 | optional int32 optional_int32 = 2; 445 | } 446 | 447 | // Test that groups have disjoint field numbers from their siblings and 448 | // parents. This is NOT possible in proto1; only google.protobuf. When attempting 449 | // to compile with proto1, this will emit an error; so we only include it 450 | // in protobuf_unittest_proto. 451 | message TestDupFieldNumber { // NO_PROTO1 452 | optional int32 a = 1; // NO_PROTO1 453 | /* 454 | optional group Foo = 2 { optional int32 a = 1; } // NO_PROTO1 455 | optional group Bar = 3 { optional int32 a = 1; } // NO_PROTO1 456 | */ 457 | } // NO_PROTO1 458 | 459 | // Additional messages for testing lazy fields. 460 | message TestEagerMessage { 461 | optional TestAllTypes sub_message = 1 [lazy=false]; 462 | } 463 | message TestLazyMessage { 464 | optional TestAllTypes sub_message = 1 [lazy=true]; 465 | } 466 | 467 | // Needed for a Python test. 468 | message TestNestedMessageHasBits { 469 | message NestedMessage { 470 | repeated int32 nestedmessage_repeated_int32 = 1; 471 | repeated ForeignMessage nestedmessage_repeated_foreignmessage = 2; 472 | } 473 | optional NestedMessage optional_nested_message = 1; 474 | } 475 | 476 | 477 | // Test an enum that has multiple values with the same number. 478 | enum TestEnumWithDupValue { 479 | option allow_alias = true; 480 | 481 | FOO1 = 1; 482 | BAR1 = 2; 483 | BAZ = 3; 484 | FOO2 = 1; 485 | BAR2 = 2; 486 | } 487 | 488 | // Test an enum with large, unordered values. 489 | enum TestSparseEnum { 490 | SPARSE_A = 123; 491 | SPARSE_B = 62374; 492 | SPARSE_C = 12589234; 493 | SPARSE_D = -15; 494 | SPARSE_E = -53452; 495 | SPARSE_F = 0; 496 | SPARSE_G = 2; 497 | } 498 | 499 | // Test message with CamelCase field names. This violates Protocol Buffer 500 | // standard style. 501 | message TestCamelCaseFieldNames { 502 | optional int32 PrimitiveField = 1; 503 | optional string StringField = 2; 504 | optional ForeignEnum EnumField = 3; 505 | optional ForeignMessage MessageField = 4; 506 | optional string StringPieceField = 5 [ctype=STRING_PIECE]; 507 | optional string CordField = 6 [ctype=CORD]; 508 | 509 | repeated int32 RepeatedPrimitiveField = 7; 510 | repeated string RepeatedStringField = 8; 511 | repeated ForeignEnum RepeatedEnumField = 9; 512 | repeated ForeignMessage RepeatedMessageField = 10; 513 | repeated string RepeatedStringPieceField = 11 [ctype=STRING_PIECE]; 514 | repeated string RepeatedCordField = 12 [ctype=CORD]; 515 | } 516 | 517 | 518 | // We list fields out of order, to ensure that we're using field number and not 519 | // field index to determine serialization order. 520 | message TestFieldOrderings { 521 | optional string my_string = 11; 522 | extensions 2 to 10; 523 | optional int64 my_int = 1; 524 | extensions 12 to 100; 525 | optional float my_float = 101; 526 | message NestedMessage { 527 | optional int64 oo = 2; 528 | // The field name "b" fails to compile in proto1 because it conflicts with 529 | // a local variable named "b" in one of the generated methods. Doh. 530 | // This file needs to compile in proto1 to test backwards-compatibility. 531 | optional int32 bb = 1; 532 | } 533 | 534 | optional NestedMessage optional_nested_message = 200; 535 | } 536 | 537 | 538 | extend TestFieldOrderings { 539 | optional string my_extension_string = 50; 540 | optional int32 my_extension_int = 5; 541 | } 542 | 543 | 544 | message TestExtremeDefaultValues { 545 | /* 546 | optional bytes escaped_bytes = 1 [default = "\0\001\a\b\f\n\r\t\v\\\'\"\xfe"]; 547 | */ 548 | optional uint32 large_uint32 = 2 [default = 0xFFFFFFFF]; 549 | optional uint64 large_uint64 = 3 [default = 0xFFFFFFFFFFFFFFFF]; 550 | optional int32 small_int32 = 4 [default = -0x7FFFFFFF]; 551 | optional int64 small_int64 = 5 [default = -0x7FFFFFFFFFFFFFFF]; 552 | optional int32 really_small_int32 = 21 [default = -0x80000000]; 553 | optional int64 really_small_int64 = 22 [default = -0x8000000000000000]; 554 | 555 | // The default value here is UTF-8 for "\u1234". (We could also just type 556 | // the UTF-8 text directly into this text file rather than escape it, but 557 | // lots of people use editors that would be confused by this.) 558 | optional string utf8_string = 6 [default = "\341\210\264"]; 559 | 560 | // Tests for single-precision floating-point values. 561 | optional float zero_float = 7 [default = 0]; 562 | optional float one_float = 8 [default = 1]; 563 | optional float small_float = 9 [default = 1.5]; 564 | optional float negative_one_float = 10 [default = -1]; 565 | optional float negative_float = 11 [default = -1.5]; 566 | // Using exponents 567 | optional float large_float = 12 [default = 2E8]; 568 | optional float small_negative_float = 13 [default = -8e-28]; 569 | 570 | // Text for nonfinite floating-point values. 571 | /* 572 | optional double inf_double = 14 [default = inf]; 573 | optional double neg_inf_double = 15 [default = -inf]; 574 | optional double nan_double = 16 [default = nan]; 575 | optional float inf_float = 17 [default = inf]; 576 | optional float neg_inf_float = 18 [default = -inf]; 577 | optional float nan_float = 19 [default = nan]; 578 | */ 579 | 580 | // Tests for C++ trigraphs. 581 | // Trigraphs should be escaped in C++ generated files, but they should not be 582 | // escaped for other languages. 583 | // Note that in .proto file, "\?" is a valid way to escape ? in string 584 | // literals. 585 | optional string cpp_trigraph = 20 [default = "? \? ?? \?? \??? ??/ ?\?-"]; 586 | 587 | // String defaults containing the character '\000' 588 | optional string string_with_zero = 23 [default = "hel\000lo"]; 589 | optional bytes bytes_with_zero = 24 [default = "wor\000ld"]; 590 | optional string string_piece_with_zero = 25 [ctype=STRING_PIECE, 591 | default="ab\000c"]; 592 | optional string cord_with_zero = 26 [ctype=CORD, 593 | default="12\0003"]; 594 | optional string replacement_string = 27 [default="${unknown}"]; 595 | } 596 | 597 | message SparseEnumMessage { 598 | optional TestSparseEnum sparse_enum = 1; 599 | } 600 | 601 | // Test String and Bytes: string is for valid UTF-8 strings 602 | message OneString { 603 | optional string data = 1; 604 | } 605 | 606 | message MoreString { 607 | repeated string data = 1; 608 | } 609 | 610 | message OneBytes { 611 | optional bytes data = 1; 612 | } 613 | 614 | message MoreBytes { 615 | repeated bytes data = 1; 616 | } 617 | 618 | // Test int32, uint32, int64, uint64, and bool are all compatible 619 | message Int32Message { 620 | optional int32 data = 1; 621 | } 622 | 623 | message Uint32Message { 624 | optional uint32 data = 1; 625 | } 626 | 627 | message Int64Message { 628 | optional int64 data = 1; 629 | } 630 | 631 | message Uint64Message { 632 | optional uint64 data = 1; 633 | } 634 | 635 | message BoolMessage { 636 | optional bool data = 1; 637 | } 638 | 639 | // Test oneofs. 640 | message TestOneof { 641 | oneof foo { 642 | int32 foo_int = 1; 643 | string foo_string = 2; 644 | TestAllTypes foo_message = 3; 645 | /* 646 | group FooGroup = 4 { 647 | optional int32 a = 5; 648 | optional string b = 6; 649 | } 650 | */ 651 | } 652 | } 653 | 654 | message TestOneofBackwardsCompatible { 655 | optional int32 foo_int = 1; 656 | optional string foo_string = 2; 657 | optional TestAllTypes foo_message = 3; 658 | /* 659 | optional group FooGroup = 4 { 660 | optional int32 a = 5; 661 | optional string b = 6; 662 | } 663 | */ 664 | } 665 | 666 | message TestOneof2 { 667 | oneof foo { 668 | int32 foo_int = 1; 669 | string foo_string = 2; 670 | string foo_cord = 3 [ctype=CORD]; 671 | string foo_string_piece = 4 [ctype=STRING_PIECE]; 672 | bytes foo_bytes = 5; 673 | NestedEnum foo_enum = 6; 674 | NestedMessage foo_message = 7; 675 | /* 676 | group FooGroup = 8 { 677 | optional int32 a = 9; 678 | optional string b = 10; 679 | } 680 | */ 681 | NestedMessage foo_lazy_message = 11 [lazy=true]; 682 | } 683 | 684 | oneof bar { 685 | int32 bar_int = 12 [default = 5]; 686 | /* 687 | string bar_string = 13 [default = "STRING"]; 688 | string bar_cord = 14 [ctype=CORD, default = "CORD"]; 689 | string bar_string_piece = 15 [ctype=STRING_PIECE, default = "SPIECE"]; 690 | bytes bar_bytes = 16 [default = "BYTES"]; 691 | */ 692 | NestedEnum bar_enum = 17 [default = BAR]; 693 | } 694 | 695 | optional int32 baz_int = 18; 696 | optional string baz_string = 19 [default = "BAZ"]; 697 | 698 | message NestedMessage { 699 | optional int64 qux_int = 1; 700 | repeated int32 corge_int = 2; 701 | } 702 | 703 | enum NestedEnum { 704 | FOO = 1; 705 | BAR = 2; 706 | BAZ = 3; 707 | } 708 | } 709 | 710 | message TestRequiredOneof { 711 | oneof foo { 712 | int32 foo_int = 1; 713 | string foo_string = 2; 714 | NestedMessage foo_message = 3; 715 | } 716 | message NestedMessage { 717 | required double required_double = 1; 718 | } 719 | } 720 | 721 | 722 | // Test messages for packed fields 723 | 724 | message TestPackedTypes { 725 | repeated int32 packed_int32 = 90 [packed = true]; 726 | repeated int64 packed_int64 = 91 [packed = true]; 727 | repeated uint32 packed_uint32 = 92 [packed = true]; 728 | repeated uint64 packed_uint64 = 93 [packed = true]; 729 | repeated sint32 packed_sint32 = 94 [packed = true]; 730 | repeated sint64 packed_sint64 = 95 [packed = true]; 731 | repeated fixed32 packed_fixed32 = 96 [packed = true]; 732 | repeated fixed64 packed_fixed64 = 97 [packed = true]; 733 | repeated sfixed32 packed_sfixed32 = 98 [packed = true]; 734 | repeated sfixed64 packed_sfixed64 = 99 [packed = true]; 735 | repeated float packed_float = 100 [packed = true]; 736 | repeated double packed_double = 101 [packed = true]; 737 | repeated bool packed_bool = 102 [packed = true]; 738 | repeated ForeignEnum packed_enum = 103 [packed = true]; 739 | } 740 | 741 | // A message with the same fields as TestPackedTypes, but without packing. Used 742 | // to test packed <-> unpacked wire compatibility. 743 | message TestUnpackedTypes { 744 | repeated int32 unpacked_int32 = 90 [packed = false]; 745 | repeated int64 unpacked_int64 = 91 [packed = false]; 746 | repeated uint32 unpacked_uint32 = 92 [packed = false]; 747 | repeated uint64 unpacked_uint64 = 93 [packed = false]; 748 | repeated sint32 unpacked_sint32 = 94 [packed = false]; 749 | repeated sint64 unpacked_sint64 = 95 [packed = false]; 750 | repeated fixed32 unpacked_fixed32 = 96 [packed = false]; 751 | repeated fixed64 unpacked_fixed64 = 97 [packed = false]; 752 | repeated sfixed32 unpacked_sfixed32 = 98 [packed = false]; 753 | repeated sfixed64 unpacked_sfixed64 = 99 [packed = false]; 754 | repeated float unpacked_float = 100 [packed = false]; 755 | repeated double unpacked_double = 101 [packed = false]; 756 | repeated bool unpacked_bool = 102 [packed = false]; 757 | repeated ForeignEnum unpacked_enum = 103 [packed = false]; 758 | } 759 | 760 | message TestPackedExtensions { 761 | extensions 1 to max; 762 | } 763 | 764 | extend TestPackedExtensions { 765 | repeated int32 packed_int32_extension = 90 [packed = true]; 766 | repeated int64 packed_int64_extension = 91 [packed = true]; 767 | repeated uint32 packed_uint32_extension = 92 [packed = true]; 768 | repeated uint64 packed_uint64_extension = 93 [packed = true]; 769 | repeated sint32 packed_sint32_extension = 94 [packed = true]; 770 | repeated sint64 packed_sint64_extension = 95 [packed = true]; 771 | repeated fixed32 packed_fixed32_extension = 96 [packed = true]; 772 | repeated fixed64 packed_fixed64_extension = 97 [packed = true]; 773 | repeated sfixed32 packed_sfixed32_extension = 98 [packed = true]; 774 | repeated sfixed64 packed_sfixed64_extension = 99 [packed = true]; 775 | repeated float packed_float_extension = 100 [packed = true]; 776 | repeated double packed_double_extension = 101 [packed = true]; 777 | repeated bool packed_bool_extension = 102 [packed = true]; 778 | repeated ForeignEnum packed_enum_extension = 103 [packed = true]; 779 | } 780 | 781 | message TestUnpackedExtensions { 782 | extensions 1 to max; 783 | } 784 | 785 | extend TestUnpackedExtensions { 786 | repeated int32 unpacked_int32_extension = 90 [packed = false]; 787 | repeated int64 unpacked_int64_extension = 91 [packed = false]; 788 | repeated uint32 unpacked_uint32_extension = 92 [packed = false]; 789 | repeated uint64 unpacked_uint64_extension = 93 [packed = false]; 790 | repeated sint32 unpacked_sint32_extension = 94 [packed = false]; 791 | repeated sint64 unpacked_sint64_extension = 95 [packed = false]; 792 | repeated fixed32 unpacked_fixed32_extension = 96 [packed = false]; 793 | repeated fixed64 unpacked_fixed64_extension = 97 [packed = false]; 794 | repeated sfixed32 unpacked_sfixed32_extension = 98 [packed = false]; 795 | repeated sfixed64 unpacked_sfixed64_extension = 99 [packed = false]; 796 | repeated float unpacked_float_extension = 100 [packed = false]; 797 | repeated double unpacked_double_extension = 101 [packed = false]; 798 | repeated bool unpacked_bool_extension = 102 [packed = false]; 799 | repeated ForeignEnum unpacked_enum_extension = 103 [packed = false]; 800 | } 801 | 802 | // Used by ExtensionSetTest/DynamicExtensions. The test actually builds 803 | // a set of extensions to TestAllExtensions dynamically, based on the fields 804 | // of this message type. 805 | message TestDynamicExtensions { 806 | enum DynamicEnumType { 807 | DYNAMIC_FOO = 2200; 808 | DYNAMIC_BAR = 2201; 809 | DYNAMIC_BAZ = 2202; 810 | } 811 | message DynamicMessageType { 812 | optional int32 dynamic_field = 2100; 813 | } 814 | 815 | optional fixed32 scalar_extension = 2000; 816 | optional ForeignEnum enum_extension = 2001; 817 | optional DynamicEnumType dynamic_enum_extension = 2002; 818 | 819 | optional ForeignMessage message_extension = 2003; 820 | optional DynamicMessageType dynamic_message_extension = 2004; 821 | 822 | repeated string repeated_extension = 2005; 823 | repeated sint32 packed_extension = 2006 [packed = true]; 824 | } 825 | 826 | message TestRepeatedScalarDifferentTagSizes { 827 | // Parsing repeated fixed size values used to fail. This message needs to be 828 | // used in order to get a tag of the right size; all of the repeated fields 829 | // in TestAllTypes didn't trigger the check. 830 | repeated fixed32 repeated_fixed32 = 12; 831 | // Check for a varint type, just for good measure. 832 | repeated int32 repeated_int32 = 13; 833 | 834 | // These have two-byte tags. 835 | repeated fixed64 repeated_fixed64 = 2046; 836 | repeated int64 repeated_int64 = 2047; 837 | 838 | // Three byte tags. 839 | repeated float repeated_float = 262142; 840 | repeated uint64 repeated_uint64 = 262143; 841 | } 842 | 843 | // Test that if an optional or required message/group field appears multiple 844 | // times in the input, they need to be merged. 845 | message TestParsingMerge { 846 | // RepeatedFieldsGenerator defines matching field types as TestParsingMerge, 847 | // except that all fields are repeated. In the tests, we will serialize the 848 | // RepeatedFieldsGenerator to bytes, and parse the bytes to TestParsingMerge. 849 | // Repeated fields in RepeatedFieldsGenerator are expected to be merged into 850 | // the corresponding required/optional fields in TestParsingMerge. 851 | message RepeatedFieldsGenerator { 852 | repeated TestAllTypes field1 = 1; 853 | repeated TestAllTypes field2 = 2; 854 | repeated TestAllTypes field3 = 3; 855 | /* 856 | repeated group Group1 = 10 { 857 | optional TestAllTypes field1 = 11; 858 | } 859 | repeated group Group2 = 20 { 860 | optional TestAllTypes field1 = 21; 861 | } 862 | */ 863 | repeated TestAllTypes ext1 = 1000; 864 | repeated TestAllTypes ext2 = 1001; 865 | } 866 | required TestAllTypes required_all_types = 1; 867 | optional TestAllTypes optional_all_types = 2; 868 | repeated TestAllTypes repeated_all_types = 3; 869 | /* 870 | optional group OptionalGroup = 10 { 871 | optional TestAllTypes optional_group_all_types = 11; 872 | } 873 | repeated group RepeatedGroup = 20 { 874 | optional TestAllTypes repeated_group_all_types = 21; 875 | } 876 | */ 877 | extensions 1000 to max; 878 | extend TestParsingMerge { 879 | optional TestAllTypes optional_ext = 1000; 880 | repeated TestAllTypes repeated_ext = 1001; 881 | } 882 | } 883 | 884 | message TestCommentInjectionMessage { 885 | // */ <- This should not close the generated doc comment 886 | optional string a = 1 [default="*/ <- Neither should this."]; 887 | } 888 | 889 | 890 | // Test that RPC services work. 891 | message FooRequest {} 892 | message FooResponse {} 893 | 894 | message FooClientMessage {} 895 | message FooServerMessage{} 896 | 897 | service TestService { 898 | rpc Foo(FooRequest) returns (FooResponse); 899 | rpc Bar(BarRequest) returns (BarResponse); 900 | } 901 | 902 | 903 | message BarRequest {} 904 | message BarResponse {} 905 | -------------------------------------------------------------------------------- /testdata/google/protobuf/unittest_import.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: kenton@google.com (Kenton Varda) 32 | // Based on original Protocol Buffers design by 33 | // Sanjay Ghemawat, Jeff Dean, and others. 34 | // 35 | // A proto file which is imported by unittest.proto to test importing. 36 | 37 | syntax = "proto2"; 38 | 39 | // We don't put this in a package within proto2 because we need to make sure 40 | // that the generated code doesn't depend on being in the proto2 namespace. 41 | // In test_util.h we do 42 | // "using namespace unittest_import = protobuf_unittest_import". 43 | package protobuf_unittest_import; 44 | 45 | option optimize_for = SPEED; 46 | option cc_enable_arenas = true; 47 | 48 | // Exercise the java_package option. 49 | option java_package = "com.google.protobuf.test"; 50 | 51 | // Do not set a java_outer_classname here to verify that Proto2 works without 52 | // one. 53 | 54 | // Test public import 55 | import public "google/protobuf/unittest_import_public.proto"; 56 | 57 | message ImportMessage { 58 | optional int32 d = 1; 59 | } 60 | 61 | enum ImportEnum { 62 | IMPORT_FOO = 7; 63 | IMPORT_BAR = 8; 64 | IMPORT_BAZ = 9; 65 | } 66 | 67 | 68 | // To use an enum in a map, it must has the first value as 0. 69 | enum ImportEnumForMap { 70 | UNKNOWN = 0; 71 | FOO = 1; 72 | BAR = 2; 73 | } 74 | -------------------------------------------------------------------------------- /testdata/google/protobuf/unittest_import_public.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: liujisi@google.com (Pherl Liu) 32 | 33 | syntax = "proto2"; 34 | 35 | package protobuf_unittest_import; 36 | 37 | option java_package = "com.google.protobuf.test"; 38 | 39 | message PublicImportMessage { 40 | optional int32 e = 1; 41 | } 42 | -------------------------------------------------------------------------------- /testdata/hash: -------------------------------------------------------------------------------- 1 | 8a798ab3fd4a058dd0645558acae8d45 ./descriptors.pb 2 | 5fda4891b1f7d3c33135758d069ed0ce ./google/protobuf/unittest.proto 3 | 201e71517077e6f56b5d661ad2cc0369 ./google/protobuf/unittest_import.proto 4 | eabe5ab2423d22f4116ac7d8c66f84a9 ./google/protobuf/unittest_import_public.proto 5 | -------------------------------------------------------------------------------- /tests/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate protobuf; 2 | extern crate serde; 3 | extern crate serde_value; 4 | 5 | extern crate serde_protobuf; 6 | 7 | use std::collections; 8 | use std::fs; 9 | 10 | use serde_protobuf::de; 11 | use serde_protobuf::descriptor; 12 | 13 | mod protobuf_unittest; 14 | 15 | macro_rules! value { 16 | (bool: $v:expr) => { 17 | serde_value::Value::Bool($v) 18 | }; 19 | 20 | (usize: $v:expr) => { 21 | serde_value::Value::USize($v) 22 | }; 23 | (u8: $v:expr) => { 24 | serde_value::Value::U8($v) 25 | }; 26 | (u16: $v:expr) => { 27 | serde_value::Value::U16($v) 28 | }; 29 | (u32: $v:expr) => { 30 | serde_value::Value::U32($v) 31 | }; 32 | (u64: $v:expr) => { 33 | serde_value::Value::U64($v) 34 | }; 35 | 36 | (isize: $v:expr) => { 37 | serde_value::Value::ISize($v) 38 | }; 39 | (i8: $v:expr) => { 40 | serde_value::Value::I8($v) 41 | }; 42 | (i16: $v:expr) => { 43 | serde_value::Value::I16($v) 44 | }; 45 | (i32: $v:expr) => { 46 | serde_value::Value::I32($v) 47 | }; 48 | (i64: $v:expr) => { 49 | serde_value::Value::I64($v) 50 | }; 51 | 52 | (f32: $v:expr) => { 53 | serde_value::Value::F32($v) 54 | }; 55 | (f64: $v:expr) => { 56 | serde_value::Value::F64($v) 57 | }; 58 | 59 | (char: $v:expr) => { 60 | serde_value::Value::Char($v) 61 | }; 62 | (str: $v:expr) => { 63 | serde_value::Value::String($v.to_owned()) 64 | }; 65 | (string: $v:expr) => { 66 | serde_value::Value::String($v) 67 | }; 68 | (unit) => { 69 | serde_value::Value::Unit 70 | }; 71 | (unit_struct $v:expr) => { 72 | serde_value::Value::UnitStruct($v) 73 | }; 74 | (some $($t:tt)+) => { 75 | serde_value::Value::Option(Some(Box::new(value!($($t)+)))) 76 | }; 77 | (none) => { 78 | serde_value::Value::Option(None) 79 | }; 80 | (newtype $($t:tt)+) => { 81 | serde_value::Value::Newtype(Box::new(value!($($t)+))) 82 | }; 83 | (seq [$(($($t:tt)+)),*]) => { 84 | { 85 | let mut values = Vec::new(); 86 | $( 87 | values.push(value!($($t)+)); 88 | )* 89 | serde_value::Value::Seq(values) 90 | } 91 | }; 92 | (map {$(($($k:tt)+) => ($($v:tt)+)),*}) => { 93 | { 94 | let mut map = collections::BTreeMap::new(); 95 | $( 96 | map.insert(value!($($k)+), value!($($v)+)); 97 | )* 98 | serde_value::Value::Map(map) 99 | } 100 | }; 101 | (bytes: $v:expr) => { 102 | serde_value::Value::Bytes($v.to_vec()) 103 | }; 104 | (byte_buf: $v:expr) => { 105 | serde_value::Value::Bytes($v) 106 | }; 107 | } 108 | 109 | trait Subset { 110 | fn subset_of(&self, other: &Self) -> bool; 111 | } 112 | 113 | impl Subset for serde_value::Value { 114 | fn subset_of(&self, other: &Self) -> bool { 115 | use serde_value::Value::*; 116 | match (self, other) { 117 | (&Map(ref ma), &Map(ref mb)) => { 118 | for (ka, va) in ma { 119 | if let Some(vb) = mb.get(ka) { 120 | if !va.subset_of(vb) { 121 | return false; 122 | } 123 | } else { 124 | return false; 125 | } 126 | } 127 | true 128 | } 129 | (&Option(Some(ref sa)), &Option(Some(ref sb))) => sa.subset_of(&*sb), 130 | _ => self == other, 131 | } 132 | } 133 | } 134 | 135 | macro_rules! assert_subset { 136 | ($left:expr , $right:expr) => {{ 137 | match (&$left, &$right) { 138 | (left_val, right_val) => { 139 | if !(left_val.subset_of(right_val)) { 140 | panic!( 141 | "assertion failed: `(left.subset_of(right))` \ 142 | (left: `{:?}`, right: `{:?}`)", 143 | left_val, right_val 144 | ) 145 | } 146 | } 147 | } 148 | }}; 149 | } 150 | 151 | macro_rules! roundtrip { 152 | ($t:ty, $v:ident, $s:stmt) => {{ 153 | use serde::de::Deserialize; 154 | use protobuf::Message; 155 | 156 | let mut file = fs::File::open("testdata/descriptors.pb").unwrap(); 157 | let proto = protobuf::descriptor::FileDescriptorSet::parse_from_reader(&mut file).unwrap(); 158 | let descriptors = descriptor::Descriptors::from_proto(&proto); 159 | 160 | let mut $v = <$t>::new(); 161 | $s 162 | let bytes = protobuf::Message::write_to_bytes(&mut $v).unwrap(); 163 | let input = protobuf::CodedInputStream::from_bytes(&bytes); 164 | 165 | let message_name = format!(".{}", protobuf::Message::descriptor(&$v).full_name()); 166 | 167 | let mut deserializer = 168 | de::Deserializer::for_named_message(&descriptors, &message_name, input).unwrap(); 169 | serde_value::Value::deserialize(&mut deserializer).unwrap() 170 | }}; 171 | } 172 | 173 | #[test] 174 | fn roundtrip_optional_message() { 175 | let v = roundtrip!(protobuf_unittest::unittest::TestAllTypes, v, { 176 | v.mut_optional_nested_message().set_bb(1); 177 | }); 178 | 179 | assert_subset!( 180 | value!(map { 181 | (str: "optional_nested_message") => (some map { 182 | (str: "bb") => (some i32: 1) 183 | }) 184 | }), 185 | v 186 | ) 187 | } 188 | 189 | #[test] 190 | fn roundtrip_optional_enum() { 191 | let v = roundtrip!(protobuf_unittest::unittest::TestAllTypes, v, { 192 | v.set_optional_nested_enum(protobuf_unittest::unittest::TestAllTypes_NestedEnum::BAZ); 193 | }); 194 | 195 | assert_subset!( 196 | value!(map { 197 | (str: "optional_nested_enum") => (some str: "BAZ") 198 | }), 199 | v 200 | ) 201 | } 202 | 203 | #[test] 204 | fn roundtrip_required() { 205 | let v = roundtrip!(protobuf_unittest::unittest::TestRequired, v, { 206 | v.set_a(1); 207 | v.set_b(2); 208 | v.set_c(3); 209 | }); 210 | 211 | assert_subset!( 212 | value!(map { 213 | (str: "a") => (i32: 1), 214 | (str: "b") => (i32: 2), 215 | (str: "c") => (i32: 3) 216 | }), 217 | v 218 | ) 219 | } 220 | 221 | #[test] 222 | fn roundtrip_repeated_message() { 223 | let v = roundtrip!(protobuf_unittest::unittest::TestAllTypes, v, { 224 | v.mut_repeated_nested_message().push_default().set_bb(1); 225 | v.mut_repeated_nested_message().push_default().set_bb(2); 226 | v.mut_repeated_nested_message().push_default().set_bb(3); 227 | }); 228 | 229 | assert_subset!( 230 | value!(map { 231 | (str: "repeated_nested_message") => (seq [ 232 | (map { 233 | (str: "bb") => (some i32: 1) 234 | }), 235 | (map { 236 | (str: "bb") => (some i32: 2) 237 | }), 238 | (map { 239 | (str: "bb") => (some i32: 3) 240 | }) 241 | ]) 242 | }), 243 | v 244 | ) 245 | } 246 | 247 | #[test] 248 | fn roundtrip_repeated_enum() { 249 | let v = roundtrip!(protobuf_unittest::unittest::TestAllTypes, v, { 250 | v.mut_repeated_nested_enum() 251 | .push(protobuf_unittest::unittest::TestAllTypes_NestedEnum::BAZ); 252 | v.mut_repeated_nested_enum() 253 | .push(protobuf_unittest::unittest::TestAllTypes_NestedEnum::FOO); 254 | v.mut_repeated_nested_enum() 255 | .push(protobuf_unittest::unittest::TestAllTypes_NestedEnum::BAR); 256 | }); 257 | 258 | assert_subset!( 259 | value!(map { 260 | (str: "repeated_nested_enum") => (seq [(str: "BAZ"), (str: "FOO"), (str: "BAR")]) 261 | }), 262 | v 263 | ) 264 | } 265 | 266 | #[test] 267 | fn roundtrip_recursive() { 268 | let v = roundtrip!(protobuf_unittest::unittest::TestRecursiveMessage, v, { 269 | v.mut_a().mut_a().set_i(3); 270 | v.mut_a().mut_a().mut_a().mut_a().set_i(4); 271 | }); 272 | 273 | assert_subset!( 274 | value!(map { 275 | (str: "a") => (some map { 276 | (str: "a") => (some map { 277 | (str: "i") => (some i32: 3), 278 | (str: "a") => (some map { 279 | (str: "a") => (some map { 280 | (str: "i") => (some i32: 4) 281 | }) 282 | }) 283 | }) 284 | }) 285 | }), 286 | v 287 | ) 288 | } 289 | 290 | macro_rules! check_roundtrip_singular { 291 | ($id:ident, $field:ident, $setter:ident, $v:expr, $($p:tt)+) => { 292 | #[test] 293 | fn $id() { 294 | let v = roundtrip!(protobuf_unittest::unittest::TestAllTypes, v, { 295 | v.$setter($v); 296 | }); 297 | assert_subset!(value!(map { 298 | (str: stringify!($field)) => ($($p)+: $v) 299 | }), v) 300 | } 301 | } 302 | } 303 | 304 | check_roundtrip_singular!(roundtrip_optional_int32, optional_int32, set_optional_int32, 42, some i32); 305 | check_roundtrip_singular!(roundtrip_optional_int64, optional_int64, set_optional_int64, 42, some i64); 306 | check_roundtrip_singular!(roundtrip_optional_uint32, optional_uint32, set_optional_uint32, 42, some u32); 307 | check_roundtrip_singular!(roundtrip_optional_uint64, optional_uint64, set_optional_uint64, 42, some u64); 308 | check_roundtrip_singular!(roundtrip_optional_sint32, optional_sint32, set_optional_sint32, 42, some i32); 309 | check_roundtrip_singular!(roundtrip_optional_sint64, optional_sint64, set_optional_sint64, 42, some i64); 310 | check_roundtrip_singular!(roundtrip_optional_fixed32, optional_fixed32, set_optional_fixed32, 42, some u32); 311 | check_roundtrip_singular!(roundtrip_optional_fixed64, optional_fixed64, set_optional_fixed64, 42, some u64); 312 | check_roundtrip_singular!(roundtrip_optional_sfixed32, optional_sfixed32, set_optional_sfixed32, 42, some i32); 313 | check_roundtrip_singular!(roundtrip_optional_sfixed64, optional_sfixed64, set_optional_sfixed64, 42, some i64); 314 | check_roundtrip_singular!(roundtrip_optional_float, optional_float, set_optional_float, 0.4, some f32); 315 | check_roundtrip_singular!(roundtrip_optional_double, optional_double, set_optional_double, 0.4, some f64); 316 | check_roundtrip_singular!(roundtrip_optional_bool, optional_bool, set_optional_bool, true, some bool); 317 | check_roundtrip_singular!(roundtrip_optional_string, optional_string, set_optional_string, "hello".to_owned(), some string); 318 | check_roundtrip_singular!(roundtrip_optional_bytes, optional_bytes, set_optional_bytes, vec![1, 2, 3], some byte_buf); 319 | 320 | macro_rules! check_roundtrip_default { 321 | ($id:ident, $field:ident, $v:expr, $($p:tt)+) => { 322 | #[test] 323 | fn $id() { 324 | let v = roundtrip!(protobuf_unittest::unittest::TestAllTypes, v, {}); 325 | assert_subset!(value!(map { 326 | (str: stringify!($field)) => ($($p)+: $v) 327 | }), v) 328 | } 329 | } 330 | } 331 | 332 | check_roundtrip_default!(roundtrip_default_int32, default_int32, 41, some i32); 333 | check_roundtrip_default!(roundtrip_default_int64, default_int64, 42, some i64); 334 | check_roundtrip_default!(roundtrip_default_uint32, default_uint32, 43, some u32); 335 | check_roundtrip_default!(roundtrip_default_uint64, default_uint64, 44, some u64); 336 | check_roundtrip_default!(roundtrip_default_sint32, default_sint32, -45, some i32); 337 | check_roundtrip_default!(roundtrip_default_sint64, default_sint64, 46, some i64); 338 | check_roundtrip_default!(roundtrip_default_fixed32, default_fixed32, 47, some u32); 339 | check_roundtrip_default!(roundtrip_default_fixed64, default_fixed64, 48, some u64); 340 | check_roundtrip_default!(roundtrip_default_sfixed32, default_sfixed32, 49, some i32); 341 | check_roundtrip_default!(roundtrip_default_sfixed64, default_sfixed64, -50, some i64); 342 | check_roundtrip_default!(roundtrip_default_float, default_float, 51.5, some f32); 343 | check_roundtrip_default!(roundtrip_default_double, default_double, 52e3, some f64); 344 | check_roundtrip_default!(roundtrip_default_bool, default_bool, true, some bool); 345 | check_roundtrip_default!(roundtrip_default_string, default_string, "hello".to_owned(), some string); 346 | check_roundtrip_default!(roundtrip_default_bytes, default_bytes, "world".as_bytes().to_owned(), some byte_buf); 347 | 348 | macro_rules! check_roundtrip_repeated { 349 | ($id:ident, $field:ident, $mut_getter:ident, [$($v:expr),+], $p:tt) => { 350 | #[test] 351 | fn $id() { 352 | let v = roundtrip!(protobuf_unittest::unittest::TestAllTypes, v, { 353 | $( 354 | v.$mut_getter().push($v); 355 | )+ 356 | }); 357 | assert_subset!(value!(map { 358 | (str: stringify!($field)) => (seq [$(($p: $v)),+]) 359 | }), v) 360 | } 361 | } 362 | } 363 | 364 | check_roundtrip_repeated!( 365 | roundtrip_repeated_int32, 366 | repeated_int32, 367 | mut_repeated_int32, 368 | [42, 21, 0], 369 | i32 370 | ); 371 | check_roundtrip_repeated!( 372 | roundtrip_repeated_int64, 373 | repeated_int64, 374 | mut_repeated_int64, 375 | [42, 21, 0], 376 | i64 377 | ); 378 | check_roundtrip_repeated!( 379 | roundtrip_repeated_uint32, 380 | repeated_uint32, 381 | mut_repeated_uint32, 382 | [42, 21, 0], 383 | u32 384 | ); 385 | check_roundtrip_repeated!( 386 | roundtrip_repeated_uint64, 387 | repeated_uint64, 388 | mut_repeated_uint64, 389 | [42, 21, 0], 390 | u64 391 | ); 392 | check_roundtrip_repeated!( 393 | roundtrip_repeated_sint32, 394 | repeated_sint32, 395 | mut_repeated_sint32, 396 | [42, 21, 0], 397 | i32 398 | ); 399 | check_roundtrip_repeated!( 400 | roundtrip_repeated_sint64, 401 | repeated_sint64, 402 | mut_repeated_sint64, 403 | [42, 21, 0], 404 | i64 405 | ); 406 | check_roundtrip_repeated!( 407 | roundtrip_repeated_fixed32, 408 | repeated_fixed32, 409 | mut_repeated_fixed32, 410 | [42, 21, 0], 411 | u32 412 | ); 413 | check_roundtrip_repeated!( 414 | roundtrip_repeated_fixed64, 415 | repeated_fixed64, 416 | mut_repeated_fixed64, 417 | [42, 21, 0], 418 | u64 419 | ); 420 | check_roundtrip_repeated!( 421 | roundtrip_repeated_sfixed32, 422 | repeated_sfixed32, 423 | mut_repeated_sfixed32, 424 | [42, 21, 0], 425 | i32 426 | ); 427 | check_roundtrip_repeated!( 428 | roundtrip_repeated_sfixed64, 429 | repeated_sfixed64, 430 | mut_repeated_sfixed64, 431 | [42, 21, 0], 432 | i64 433 | ); 434 | check_roundtrip_repeated!( 435 | roundtrip_repeated_float, 436 | repeated_float, 437 | mut_repeated_float, 438 | [0.4, 0.0, 1.0], 439 | f32 440 | ); 441 | check_roundtrip_repeated!( 442 | roundtrip_repeated_double, 443 | repeated_double, 444 | mut_repeated_double, 445 | [0.4, 0.0, 1.0], 446 | f64 447 | ); 448 | check_roundtrip_repeated!( 449 | roundtrip_repeated_bool, 450 | repeated_bool, 451 | mut_repeated_bool, 452 | [true, true, false], 453 | bool 454 | ); 455 | check_roundtrip_repeated!( 456 | roundtrip_repeated_string, 457 | repeated_string, 458 | mut_repeated_string, 459 | ["hello".to_owned(), "".to_owned()], 460 | string 461 | ); 462 | check_roundtrip_repeated!( 463 | roundtrip_repeated_bytes, 464 | repeated_bytes, 465 | mut_repeated_bytes, 466 | [vec![1, 2, 3], vec![2, 3, 4]], 467 | byte_buf 468 | ); 469 | -------------------------------------------------------------------------------- /tests/protobuf_unittest/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod unittest; 2 | pub mod unittest_import; 3 | pub mod unittest_import_public; 4 | -------------------------------------------------------------------------------- /tests/protobuf_unittest/unittest_import.rs: -------------------------------------------------------------------------------- 1 | // This file is generated by rust-protobuf 2.23.0. Do not edit 2 | // @generated 3 | 4 | // https://github.com/rust-lang/rust-clippy/issues/702 5 | #![allow(unknown_lints)] 6 | #![allow(clippy::all)] 7 | 8 | #![allow(unused_attributes)] 9 | #![cfg_attr(rustfmt, rustfmt::skip)] 10 | 11 | #![allow(box_pointers)] 12 | #![allow(dead_code)] 13 | #![allow(missing_docs)] 14 | #![allow(non_camel_case_types)] 15 | #![allow(non_snake_case)] 16 | #![allow(non_upper_case_globals)] 17 | #![allow(trivial_casts)] 18 | #![allow(unused_imports)] 19 | #![allow(unused_results)] 20 | //! Generated file from `google/protobuf/unittest_import.proto` 21 | 22 | /// Generated files are compatible only with the same version 23 | /// of protobuf runtime. 24 | // const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_23_0; 25 | 26 | #[derive(PartialEq,Clone,Default)] 27 | pub struct ImportMessage { 28 | // message fields 29 | d: ::std::option::Option, 30 | // special fields 31 | pub unknown_fields: ::protobuf::UnknownFields, 32 | pub cached_size: ::protobuf::CachedSize, 33 | } 34 | 35 | impl<'a> ::std::default::Default for &'a ImportMessage { 36 | fn default() -> &'a ImportMessage { 37 | ::default_instance() 38 | } 39 | } 40 | 41 | impl ImportMessage { 42 | pub fn new() -> ImportMessage { 43 | ::std::default::Default::default() 44 | } 45 | 46 | // optional int32 d = 1; 47 | 48 | 49 | pub fn get_d(&self) -> i32 { 50 | self.d.unwrap_or(0) 51 | } 52 | pub fn clear_d(&mut self) { 53 | self.d = ::std::option::Option::None; 54 | } 55 | 56 | pub fn has_d(&self) -> bool { 57 | self.d.is_some() 58 | } 59 | 60 | // Param is passed by value, moved 61 | pub fn set_d(&mut self, v: i32) { 62 | self.d = ::std::option::Option::Some(v); 63 | } 64 | } 65 | 66 | impl ::protobuf::Message for ImportMessage { 67 | fn is_initialized(&self) -> bool { 68 | true 69 | } 70 | 71 | fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { 72 | while !is.eof()? { 73 | let (field_number, wire_type) = is.read_tag_unpack()?; 74 | match field_number { 75 | 1 => { 76 | if wire_type != ::protobuf::wire_format::WireTypeVarint { 77 | return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); 78 | } 79 | let tmp = is.read_int32()?; 80 | self.d = ::std::option::Option::Some(tmp); 81 | }, 82 | _ => { 83 | ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; 84 | }, 85 | }; 86 | } 87 | ::std::result::Result::Ok(()) 88 | } 89 | 90 | // Compute sizes of nested messages 91 | #[allow(unused_variables)] 92 | fn compute_size(&self) -> u32 { 93 | let mut my_size = 0; 94 | if let Some(v) = self.d { 95 | my_size += ::protobuf::rt::value_size(1, v, ::protobuf::wire_format::WireTypeVarint); 96 | } 97 | my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); 98 | self.cached_size.set(my_size); 99 | my_size 100 | } 101 | 102 | fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { 103 | if let Some(v) = self.d { 104 | os.write_int32(1, v)?; 105 | } 106 | os.write_unknown_fields(self.get_unknown_fields())?; 107 | ::std::result::Result::Ok(()) 108 | } 109 | 110 | fn get_cached_size(&self) -> u32 { 111 | self.cached_size.get() 112 | } 113 | 114 | fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { 115 | &self.unknown_fields 116 | } 117 | 118 | fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { 119 | &mut self.unknown_fields 120 | } 121 | 122 | fn as_any(&self) -> &dyn (::std::any::Any) { 123 | self as &dyn (::std::any::Any) 124 | } 125 | fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { 126 | self as &mut dyn (::std::any::Any) 127 | } 128 | fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { 129 | self 130 | } 131 | 132 | fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { 133 | Self::descriptor_static() 134 | } 135 | 136 | fn new() -> ImportMessage { 137 | ImportMessage::new() 138 | } 139 | 140 | fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { 141 | static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; 142 | descriptor.get(|| { 143 | let mut fields = ::std::vec::Vec::new(); 144 | fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( 145 | "d", 146 | |m: &ImportMessage| { &m.d }, 147 | |m: &mut ImportMessage| { &mut m.d }, 148 | )); 149 | ::protobuf::reflect::MessageDescriptor::new_pb_name::( 150 | "ImportMessage", 151 | fields, 152 | file_descriptor_proto() 153 | ) 154 | }) 155 | } 156 | 157 | fn default_instance() -> &'static ImportMessage { 158 | static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; 159 | instance.get(ImportMessage::new) 160 | } 161 | } 162 | 163 | impl ::protobuf::Clear for ImportMessage { 164 | fn clear(&mut self) { 165 | self.d = ::std::option::Option::None; 166 | self.unknown_fields.clear(); 167 | } 168 | } 169 | 170 | impl ::std::fmt::Debug for ImportMessage { 171 | fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { 172 | ::protobuf::text_format::fmt(self, f) 173 | } 174 | } 175 | 176 | impl ::protobuf::reflect::ProtobufValue for ImportMessage { 177 | fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { 178 | ::protobuf::reflect::ReflectValueRef::Message(self) 179 | } 180 | } 181 | 182 | #[derive(Clone,PartialEq,Eq,Debug,Hash)] 183 | pub enum ImportEnum { 184 | IMPORT_FOO = 7, 185 | IMPORT_BAR = 8, 186 | IMPORT_BAZ = 9, 187 | } 188 | 189 | impl ::protobuf::ProtobufEnum for ImportEnum { 190 | fn value(&self) -> i32 { 191 | *self as i32 192 | } 193 | 194 | fn from_i32(value: i32) -> ::std::option::Option { 195 | match value { 196 | 7 => ::std::option::Option::Some(ImportEnum::IMPORT_FOO), 197 | 8 => ::std::option::Option::Some(ImportEnum::IMPORT_BAR), 198 | 9 => ::std::option::Option::Some(ImportEnum::IMPORT_BAZ), 199 | _ => ::std::option::Option::None 200 | } 201 | } 202 | 203 | fn values() -> &'static [Self] { 204 | static values: &'static [ImportEnum] = &[ 205 | ImportEnum::IMPORT_FOO, 206 | ImportEnum::IMPORT_BAR, 207 | ImportEnum::IMPORT_BAZ, 208 | ]; 209 | values 210 | } 211 | 212 | fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { 213 | static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; 214 | descriptor.get(|| { 215 | ::protobuf::reflect::EnumDescriptor::new_pb_name::("ImportEnum", file_descriptor_proto()) 216 | }) 217 | } 218 | } 219 | 220 | impl ::std::marker::Copy for ImportEnum { 221 | } 222 | 223 | // Note, `Default` is implemented although default value is not 0 224 | impl ::std::default::Default for ImportEnum { 225 | fn default() -> Self { 226 | ImportEnum::IMPORT_FOO 227 | } 228 | } 229 | 230 | impl ::protobuf::reflect::ProtobufValue for ImportEnum { 231 | fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { 232 | ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) 233 | } 234 | } 235 | 236 | #[derive(Clone,PartialEq,Eq,Debug,Hash)] 237 | pub enum ImportEnumForMap { 238 | UNKNOWN = 0, 239 | FOO = 1, 240 | BAR = 2, 241 | } 242 | 243 | impl ::protobuf::ProtobufEnum for ImportEnumForMap { 244 | fn value(&self) -> i32 { 245 | *self as i32 246 | } 247 | 248 | fn from_i32(value: i32) -> ::std::option::Option { 249 | match value { 250 | 0 => ::std::option::Option::Some(ImportEnumForMap::UNKNOWN), 251 | 1 => ::std::option::Option::Some(ImportEnumForMap::FOO), 252 | 2 => ::std::option::Option::Some(ImportEnumForMap::BAR), 253 | _ => ::std::option::Option::None 254 | } 255 | } 256 | 257 | fn values() -> &'static [Self] { 258 | static values: &'static [ImportEnumForMap] = &[ 259 | ImportEnumForMap::UNKNOWN, 260 | ImportEnumForMap::FOO, 261 | ImportEnumForMap::BAR, 262 | ]; 263 | values 264 | } 265 | 266 | fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { 267 | static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; 268 | descriptor.get(|| { 269 | ::protobuf::reflect::EnumDescriptor::new_pb_name::("ImportEnumForMap", file_descriptor_proto()) 270 | }) 271 | } 272 | } 273 | 274 | impl ::std::marker::Copy for ImportEnumForMap { 275 | } 276 | 277 | impl ::std::default::Default for ImportEnumForMap { 278 | fn default() -> Self { 279 | ImportEnumForMap::UNKNOWN 280 | } 281 | } 282 | 283 | impl ::protobuf::reflect::ProtobufValue for ImportEnumForMap { 284 | fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { 285 | ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) 286 | } 287 | } 288 | 289 | static file_descriptor_proto_data: &'static [u8] = b"\ 290 | \n%google/protobuf/unittest_import.proto\x12\x18protobuf_unittest_import\ 291 | \x1a,google/protobuf/unittest_import_public.protoP\0\"\x1d\n\rImportMess\ 292 | age\x12\x0c\n\x01d\x18\x01\x20\x01(\x05R\x01d*<\n\nImportEnum\x12\x0e\n\ 293 | \nIMPORT_FOO\x10\x07\x12\x0e\n\nIMPORT_BAR\x10\x08\x12\x0e\n\nIMPORT_BAZ\ 294 | \x10\t*1\n\x10ImportEnumForMap\x12\x0b\n\x07UNKNOWN\x10\0\x12\x07\n\x03F\ 295 | OO\x10\x01\x12\x07\n\x03BAR\x10\x02B\x1f\n\x18com.google.protobuf.testH\ 296 | \x01\xf8\x01\x01J\xc0\x15\n\x06\x12\x04$\0H\x01\n\x98\x0e\n\x01\x0c\x12\ 297 | \x03$\0\x122\xc1\x0c\x20Protocol\x20Buffers\x20-\x20Google's\x20data\x20\ 298 | interchange\x20format\n\x20Copyright\x202008\x20Google\x20Inc.\x20\x20Al\ 299 | l\x20rights\x20reserved.\n\x20https://developers.google.com/protocol-buf\ 300 | fers/\n\n\x20Redistribution\x20and\x20use\x20in\x20source\x20and\x20bina\ 301 | ry\x20forms,\x20with\x20or\x20without\n\x20modification,\x20are\x20permi\ 302 | tted\x20provided\x20that\x20the\x20following\x20conditions\x20are\n\x20m\ 303 | et:\n\n\x20\x20\x20\x20\x20*\x20Redistributions\x20of\x20source\x20code\ 304 | \x20must\x20retain\x20the\x20above\x20copyright\n\x20notice,\x20this\x20\ 305 | list\x20of\x20conditions\x20and\x20the\x20following\x20disclaimer.\n\x20\ 306 | \x20\x20\x20\x20*\x20Redistributions\x20in\x20binary\x20form\x20must\x20\ 307 | reproduce\x20the\x20above\n\x20copyright\x20notice,\x20this\x20list\x20o\ 308 | f\x20conditions\x20and\x20the\x20following\x20disclaimer\n\x20in\x20the\ 309 | \x20documentation\x20and/or\x20other\x20materials\x20provided\x20with\ 310 | \x20the\n\x20distribution.\n\x20\x20\x20\x20\x20*\x20Neither\x20the\x20n\ 311 | ame\x20of\x20Google\x20Inc.\x20nor\x20the\x20names\x20of\x20its\n\x20con\ 312 | tributors\x20may\x20be\x20used\x20to\x20endorse\x20or\x20promote\x20prod\ 313 | ucts\x20derived\x20from\n\x20this\x20software\x20without\x20specific\x20\ 314 | prior\x20written\x20permission.\n\n\x20THIS\x20SOFTWARE\x20IS\x20PROVIDE\ 315 | D\x20BY\x20THE\x20COPYRIGHT\x20HOLDERS\x20AND\x20CONTRIBUTORS\n\x20\"AS\ 316 | \x20IS\"\x20AND\x20ANY\x20EXPRESS\x20OR\x20IMPLIED\x20WARRANTIES,\x20INC\ 317 | LUDING,\x20BUT\x20NOT\n\x20LIMITED\x20TO,\x20THE\x20IMPLIED\x20WARRANTIE\ 318 | S\x20OF\x20MERCHANTABILITY\x20AND\x20FITNESS\x20FOR\n\x20A\x20PARTICULAR\ 319 | \x20PURPOSE\x20ARE\x20DISCLAIMED.\x20IN\x20NO\x20EVENT\x20SHALL\x20THE\ 320 | \x20COPYRIGHT\n\x20OWNER\x20OR\x20CONTRIBUTORS\x20BE\x20LIABLE\x20FOR\ 321 | \x20ANY\x20DIRECT,\x20INDIRECT,\x20INCIDENTAL,\n\x20SPECIAL,\x20EXEMPLAR\ 322 | Y,\x20OR\x20CONSEQUENTIAL\x20DAMAGES\x20(INCLUDING,\x20BUT\x20NOT\n\x20L\ 323 | IMITED\x20TO,\x20PROCUREMENT\x20OF\x20SUBSTITUTE\x20GOODS\x20OR\x20SERVI\ 324 | CES;\x20LOSS\x20OF\x20USE,\n\x20DATA,\x20OR\x20PROFITS;\x20OR\x20BUSINES\ 325 | S\x20INTERRUPTION)\x20HOWEVER\x20CAUSED\x20AND\x20ON\x20ANY\n\x20THEORY\ 326 | \x20OF\x20LIABILITY,\x20WHETHER\x20IN\x20CONTRACT,\x20STRICT\x20LIABILIT\ 327 | Y,\x20OR\x20TORT\n\x20(INCLUDING\x20NEGLIGENCE\x20OR\x20OTHERWISE)\x20AR\ 328 | ISING\x20IN\x20ANY\x20WAY\x20OUT\x20OF\x20THE\x20USE\n\x20OF\x20THIS\x20\ 329 | SOFTWARE,\x20EVEN\x20IF\x20ADVISED\x20OF\x20THE\x20POSSIBILITY\x20OF\x20\ 330 | SUCH\x20DAMAGE.\n2\xc9\x01\x20Author:\x20kenton@google.com\x20(Kenton\ 331 | \x20Varda)\n\x20\x20Based\x20on\x20original\x20Protocol\x20Buffers\x20de\ 332 | sign\x20by\n\x20\x20Sanjay\x20Ghemawat,\x20Jeff\x20Dean,\x20and\x20other\ 333 | s.\n\n\x20A\x20proto\x20file\x20which\x20is\x20imported\x20by\x20unittes\ 334 | t.proto\x20to\x20test\x20importing.\n\n\xf5\x01\n\x01\x02\x12\x03*\0!\ 335 | \x1a\xea\x01\x20We\x20don't\x20put\x20this\x20in\x20a\x20package\x20with\ 336 | in\x20proto2\x20because\x20we\x20need\x20to\x20make\x20sure\n\x20that\ 337 | \x20the\x20generated\x20code\x20doesn't\x20depend\x20on\x20being\x20in\ 338 | \x20the\x20proto2\x20namespace.\n\x20In\x20test_util.h\x20we\x20do\n\x20\ 339 | \"using\x20namespace\x20unittest_import\x20=\x20protobuf_unittest_import\ 340 | \".\n\n\x08\n\x01\x08\x12\x03,\0\x1c\n\t\n\x02\x08\t\x12\x03,\0\x1c\n\ 341 | \x08\n\x01\x08\x12\x03-\0\x1f\n\t\n\x02\x08\x1f\x12\x03-\0\x1f\n\x08\n\ 342 | \x01\x08\x12\x030\01\n.\n\x02\x08\x01\x12\x030\01\x1a#\x20Exercise\x20th\ 343 | e\x20java_package\x20option.\n\ns\n\x02\x03\0\x12\x036\0=\x1a\x14\x20Tes\ 344 | t\x20public\x20import\n2R\x20Do\x20not\x20set\x20a\x20java_outer_classna\ 345 | me\x20here\x20to\x20verify\x20that\x20Proto2\x20works\x20without\n\x20on\ 346 | e.\n\n\t\n\x02\n\0\x12\x036\x07\r\n\n\n\x02\x04\0\x12\x048\0:\x01\n\n\n\ 347 | \x03\x04\0\x01\x12\x038\x08\x15\n\x0b\n\x04\x04\0\x02\0\x12\x039\x02\x17\ 348 | \n\x0c\n\x05\x04\0\x02\0\x04\x12\x039\x02\n\n\x0c\n\x05\x04\0\x02\0\x05\ 349 | \x12\x039\x0b\x10\n\x0c\n\x05\x04\0\x02\0\x01\x12\x039\x11\x12\n\x0c\n\ 350 | \x05\x04\0\x02\0\x03\x12\x039\x15\x16\n\n\n\x02\x05\0\x12\x04<\0@\x01\n\ 351 | \n\n\x03\x05\0\x01\x12\x03<\x05\x0f\n\x0b\n\x04\x05\0\x02\0\x12\x03=\x02\ 352 | \x11\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03=\x02\x0c\n\x0c\n\x05\x05\0\x02\ 353 | \0\x02\x12\x03=\x0f\x10\n\x0b\n\x04\x05\0\x02\x01\x12\x03>\x02\x11\n\x0c\ 354 | \n\x05\x05\0\x02\x01\x01\x12\x03>\x02\x0c\n\x0c\n\x05\x05\0\x02\x01\x02\ 355 | \x12\x03>\x0f\x10\n\x0b\n\x04\x05\0\x02\x02\x12\x03?\x02\x11\n\x0c\n\x05\ 356 | \x05\0\x02\x02\x01\x12\x03?\x02\x0c\n\x0c\n\x05\x05\0\x02\x02\x02\x12\ 357 | \x03?\x0f\x10\nH\n\x02\x05\x01\x12\x04D\0H\x01\x1a<\x20To\x20use\x20an\ 358 | \x20enum\x20in\x20a\x20map,\x20it\x20must\x20has\x20the\x20first\x20valu\ 359 | e\x20as\x200.\n\n\n\n\x03\x05\x01\x01\x12\x03D\x05\x15\n\x0b\n\x04\x05\ 360 | \x01\x02\0\x12\x03E\x02\x0e\n\x0c\n\x05\x05\x01\x02\0\x01\x12\x03E\x02\t\ 361 | \n\x0c\n\x05\x05\x01\x02\0\x02\x12\x03E\x0c\r\n\x0b\n\x04\x05\x01\x02\ 362 | \x01\x12\x03F\x02\n\n\x0c\n\x05\x05\x01\x02\x01\x01\x12\x03F\x02\x05\n\ 363 | \x0c\n\x05\x05\x01\x02\x01\x02\x12\x03F\x08\t\n\x0b\n\x04\x05\x01\x02\ 364 | \x02\x12\x03G\x02\n\n\x0c\n\x05\x05\x01\x02\x02\x01\x12\x03G\x02\x05\n\ 365 | \x0c\n\x05\x05\x01\x02\x02\x02\x12\x03G\x08\t\ 366 | "; 367 | 368 | static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; 369 | 370 | fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { 371 | ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() 372 | } 373 | 374 | pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { 375 | file_descriptor_proto_lazy.get(|| { 376 | parse_descriptor_proto() 377 | }) 378 | } 379 | -------------------------------------------------------------------------------- /tests/protobuf_unittest/unittest_import_public.rs: -------------------------------------------------------------------------------- 1 | // This file is generated by rust-protobuf 2.23.0. Do not edit 2 | // @generated 3 | 4 | // https://github.com/rust-lang/rust-clippy/issues/702 5 | #![allow(unknown_lints)] 6 | #![allow(clippy::all)] 7 | 8 | #![allow(unused_attributes)] 9 | #![cfg_attr(rustfmt, rustfmt::skip)] 10 | 11 | #![allow(box_pointers)] 12 | #![allow(dead_code)] 13 | #![allow(missing_docs)] 14 | #![allow(non_camel_case_types)] 15 | #![allow(non_snake_case)] 16 | #![allow(non_upper_case_globals)] 17 | #![allow(trivial_casts)] 18 | #![allow(unused_imports)] 19 | #![allow(unused_results)] 20 | //! Generated file from `google/protobuf/unittest_import_public.proto` 21 | 22 | /// Generated files are compatible only with the same version 23 | /// of protobuf runtime. 24 | // const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_23_0; 25 | 26 | #[derive(PartialEq,Clone,Default)] 27 | pub struct PublicImportMessage { 28 | // message fields 29 | e: ::std::option::Option, 30 | // special fields 31 | pub unknown_fields: ::protobuf::UnknownFields, 32 | pub cached_size: ::protobuf::CachedSize, 33 | } 34 | 35 | impl<'a> ::std::default::Default for &'a PublicImportMessage { 36 | fn default() -> &'a PublicImportMessage { 37 | ::default_instance() 38 | } 39 | } 40 | 41 | impl PublicImportMessage { 42 | pub fn new() -> PublicImportMessage { 43 | ::std::default::Default::default() 44 | } 45 | 46 | // optional int32 e = 1; 47 | 48 | 49 | pub fn get_e(&self) -> i32 { 50 | self.e.unwrap_or(0) 51 | } 52 | pub fn clear_e(&mut self) { 53 | self.e = ::std::option::Option::None; 54 | } 55 | 56 | pub fn has_e(&self) -> bool { 57 | self.e.is_some() 58 | } 59 | 60 | // Param is passed by value, moved 61 | pub fn set_e(&mut self, v: i32) { 62 | self.e = ::std::option::Option::Some(v); 63 | } 64 | } 65 | 66 | impl ::protobuf::Message for PublicImportMessage { 67 | fn is_initialized(&self) -> bool { 68 | true 69 | } 70 | 71 | fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { 72 | while !is.eof()? { 73 | let (field_number, wire_type) = is.read_tag_unpack()?; 74 | match field_number { 75 | 1 => { 76 | if wire_type != ::protobuf::wire_format::WireTypeVarint { 77 | return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); 78 | } 79 | let tmp = is.read_int32()?; 80 | self.e = ::std::option::Option::Some(tmp); 81 | }, 82 | _ => { 83 | ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; 84 | }, 85 | }; 86 | } 87 | ::std::result::Result::Ok(()) 88 | } 89 | 90 | // Compute sizes of nested messages 91 | #[allow(unused_variables)] 92 | fn compute_size(&self) -> u32 { 93 | let mut my_size = 0; 94 | if let Some(v) = self.e { 95 | my_size += ::protobuf::rt::value_size(1, v, ::protobuf::wire_format::WireTypeVarint); 96 | } 97 | my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); 98 | self.cached_size.set(my_size); 99 | my_size 100 | } 101 | 102 | fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { 103 | if let Some(v) = self.e { 104 | os.write_int32(1, v)?; 105 | } 106 | os.write_unknown_fields(self.get_unknown_fields())?; 107 | ::std::result::Result::Ok(()) 108 | } 109 | 110 | fn get_cached_size(&self) -> u32 { 111 | self.cached_size.get() 112 | } 113 | 114 | fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { 115 | &self.unknown_fields 116 | } 117 | 118 | fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { 119 | &mut self.unknown_fields 120 | } 121 | 122 | fn as_any(&self) -> &dyn (::std::any::Any) { 123 | self as &dyn (::std::any::Any) 124 | } 125 | fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { 126 | self as &mut dyn (::std::any::Any) 127 | } 128 | fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { 129 | self 130 | } 131 | 132 | fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { 133 | Self::descriptor_static() 134 | } 135 | 136 | fn new() -> PublicImportMessage { 137 | PublicImportMessage::new() 138 | } 139 | 140 | fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { 141 | static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; 142 | descriptor.get(|| { 143 | let mut fields = ::std::vec::Vec::new(); 144 | fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( 145 | "e", 146 | |m: &PublicImportMessage| { &m.e }, 147 | |m: &mut PublicImportMessage| { &mut m.e }, 148 | )); 149 | ::protobuf::reflect::MessageDescriptor::new_pb_name::( 150 | "PublicImportMessage", 151 | fields, 152 | file_descriptor_proto() 153 | ) 154 | }) 155 | } 156 | 157 | fn default_instance() -> &'static PublicImportMessage { 158 | static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; 159 | instance.get(PublicImportMessage::new) 160 | } 161 | } 162 | 163 | impl ::protobuf::Clear for PublicImportMessage { 164 | fn clear(&mut self) { 165 | self.e = ::std::option::Option::None; 166 | self.unknown_fields.clear(); 167 | } 168 | } 169 | 170 | impl ::std::fmt::Debug for PublicImportMessage { 171 | fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { 172 | ::protobuf::text_format::fmt(self, f) 173 | } 174 | } 175 | 176 | impl ::protobuf::reflect::ProtobufValue for PublicImportMessage { 177 | fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { 178 | ::protobuf::reflect::ReflectValueRef::Message(self) 179 | } 180 | } 181 | 182 | static file_descriptor_proto_data: &'static [u8] = b"\ 183 | \n,google/protobuf/unittest_import_public.proto\x12\x18protobuf_unittest\ 184 | _import\"#\n\x13PublicImportMessage\x12\x0c\n\x01e\x18\x01\x20\x01(\x05R\ 185 | \x01eB\x1a\n\x18com.google.protobuf.testJ\xfd\r\n\x06\x12\x04\x20\0(\x01\ 186 | \n\xf6\x0c\n\x01\x0c\x12\x03\x20\0\x122\xc1\x0c\x20Protocol\x20Buffers\ 187 | \x20-\x20Google's\x20data\x20interchange\x20format\n\x20Copyright\x20200\ 188 | 8\x20Google\x20Inc.\x20\x20All\x20rights\x20reserved.\n\x20https://devel\ 189 | opers.google.com/protocol-buffers/\n\n\x20Redistribution\x20and\x20use\ 190 | \x20in\x20source\x20and\x20binary\x20forms,\x20with\x20or\x20without\n\ 191 | \x20modification,\x20are\x20permitted\x20provided\x20that\x20the\x20foll\ 192 | owing\x20conditions\x20are\n\x20met:\n\n\x20\x20\x20\x20\x20*\x20Redistr\ 193 | ibutions\x20of\x20source\x20code\x20must\x20retain\x20the\x20above\x20co\ 194 | pyright\n\x20notice,\x20this\x20list\x20of\x20conditions\x20and\x20the\ 195 | \x20following\x20disclaimer.\n\x20\x20\x20\x20\x20*\x20Redistributions\ 196 | \x20in\x20binary\x20form\x20must\x20reproduce\x20the\x20above\n\x20copyr\ 197 | ight\x20notice,\x20this\x20list\x20of\x20conditions\x20and\x20the\x20fol\ 198 | lowing\x20disclaimer\n\x20in\x20the\x20documentation\x20and/or\x20other\ 199 | \x20materials\x20provided\x20with\x20the\n\x20distribution.\n\x20\x20\ 200 | \x20\x20\x20*\x20Neither\x20the\x20name\x20of\x20Google\x20Inc.\x20nor\ 201 | \x20the\x20names\x20of\x20its\n\x20contributors\x20may\x20be\x20used\x20\ 202 | to\x20endorse\x20or\x20promote\x20products\x20derived\x20from\n\x20this\ 203 | \x20software\x20without\x20specific\x20prior\x20written\x20permission.\n\ 204 | \n\x20THIS\x20SOFTWARE\x20IS\x20PROVIDED\x20BY\x20THE\x20COPYRIGHT\x20HO\ 205 | LDERS\x20AND\x20CONTRIBUTORS\n\x20\"AS\x20IS\"\x20AND\x20ANY\x20EXPRESS\ 206 | \x20OR\x20IMPLIED\x20WARRANTIES,\x20INCLUDING,\x20BUT\x20NOT\n\x20LIMITE\ 207 | D\x20TO,\x20THE\x20IMPLIED\x20WARRANTIES\x20OF\x20MERCHANTABILITY\x20AND\ 208 | \x20FITNESS\x20FOR\n\x20A\x20PARTICULAR\x20PURPOSE\x20ARE\x20DISCLAIMED.\ 209 | \x20IN\x20NO\x20EVENT\x20SHALL\x20THE\x20COPYRIGHT\n\x20OWNER\x20OR\x20C\ 210 | ONTRIBUTORS\x20BE\x20LIABLE\x20FOR\x20ANY\x20DIRECT,\x20INDIRECT,\x20INC\ 211 | IDENTAL,\n\x20SPECIAL,\x20EXEMPLARY,\x20OR\x20CONSEQUENTIAL\x20DAMAGES\ 212 | \x20(INCLUDING,\x20BUT\x20NOT\n\x20LIMITED\x20TO,\x20PROCUREMENT\x20OF\ 213 | \x20SUBSTITUTE\x20GOODS\x20OR\x20SERVICES;\x20LOSS\x20OF\x20USE,\n\x20DA\ 214 | TA,\x20OR\x20PROFITS;\x20OR\x20BUSINESS\x20INTERRUPTION)\x20HOWEVER\x20C\ 215 | AUSED\x20AND\x20ON\x20ANY\n\x20THEORY\x20OF\x20LIABILITY,\x20WHETHER\x20\ 216 | IN\x20CONTRACT,\x20STRICT\x20LIABILITY,\x20OR\x20TORT\n\x20(INCLUDING\ 217 | \x20NEGLIGENCE\x20OR\x20OTHERWISE)\x20ARISING\x20IN\x20ANY\x20WAY\x20OUT\ 218 | \x20OF\x20THE\x20USE\n\x20OF\x20THIS\x20SOFTWARE,\x20EVEN\x20IF\x20ADVIS\ 219 | ED\x20OF\x20THE\x20POSSIBILITY\x20OF\x20SUCH\x20DAMAGE.\n2(\x20Author:\ 220 | \x20liujisi@google.com\x20(Pherl\x20Liu)\n\n\x08\n\x01\x02\x12\x03\"\0!\ 221 | \n\x08\n\x01\x08\x12\x03$\01\n\t\n\x02\x08\x01\x12\x03$\01\n\n\n\x02\x04\ 222 | \0\x12\x04&\0(\x01\n\n\n\x03\x04\0\x01\x12\x03&\x08\x1b\n\x0b\n\x04\x04\ 223 | \0\x02\0\x12\x03'\x02\x17\n\x0c\n\x05\x04\0\x02\0\x04\x12\x03'\x02\n\n\ 224 | \x0c\n\x05\x04\0\x02\0\x05\x12\x03'\x0b\x10\n\x0c\n\x05\x04\0\x02\0\x01\ 225 | \x12\x03'\x11\x12\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03'\x15\x16\ 226 | "; 227 | 228 | static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; 229 | 230 | fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { 231 | ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() 232 | } 233 | 234 | pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { 235 | file_descriptor_proto_lazy.get(|| { 236 | parse_descriptor_proto() 237 | }) 238 | } 239 | --------------------------------------------------------------------------------