diff --git a/lib/src/modules/mod.rs b/lib/src/modules/mod.rs index d6dbcdfed..0d7dab5bb 100644 --- a/lib/src/modules/mod.rs +++ b/lib/src/modules/mod.rs @@ -492,7 +492,7 @@ pub mod mods { /// Returns the documentation for the current field. pub fn doc(&self) -> Option<&str> { - self.struct_field.doc.as_deref() + self.struct_field.doc } } diff --git a/lib/src/scanner/mod.rs b/lib/src/scanner/mod.rs index 9a2cbce42..3d5d346a7 100644 --- a/lib/src/scanner/mod.rs +++ b/lib/src/scanner/mod.rs @@ -703,6 +703,7 @@ impl<'r> Scanner<'r> { &module_root_descriptor, module_output.as_deref(), generate_fields_for_enums, + false, ); if let Some(module_output) = module_output { diff --git a/lib/src/symbols/mod.rs b/lib/src/symbols/mod.rs index f006a080b..6fddb9080 100644 --- a/lib/src/symbols/mod.rs +++ b/lib/src/symbols/mod.rs @@ -357,6 +357,7 @@ mod tests { &TestProto2::descriptor(), None, true, + false, ); assert_eq!(test.lookup("int32_zero").unwrap().ty(), Type::Integer); @@ -436,6 +437,7 @@ mod tests { &descriptor, Some(message.as_ref()), true, + false, ); assert_eq!( diff --git a/lib/src/types/structure.rs b/lib/src/types/structure.rs index 9fb9d3d94..460c09448 100644 --- a/lib/src/types/structure.rs +++ b/lib/src/types/structure.rs @@ -99,12 +99,15 @@ pub(crate) struct StructField { /// Field type and value. pub type_value: TypeValue, /// Access control list (ACL) for accessing this struct field. + #[serde(skip)] pub acl: Option>, /// Deprecation notice that must be shown when the field is used in a /// rule. This is `None` for non-deprecated fields. + #[serde(skip)] pub deprecation_notice: Option, /// Description of the field extracted from the .proto file. - pub doc: Option, + #[serde(skip)] + pub doc: Option<&'static str>, } /// A dynamic structure with one or more fields. @@ -347,11 +350,8 @@ impl Struct { /// be [`None`]. /// /// The `generate_fields_for_enums` controls whether the enums defined - /// by the proto will be included as fields in the structure. Enums are - /// required only at compile time, so that the compiler can look up the - /// enums by name and resolve their values, but at scan time enums are - /// not necessary because their values are already embedded in the code. - /// The scanner never asks for an enum by field index. + /// by the proto will be included in the structure. These are required + /// only at compile time, or when constant folding is disabled. /// /// Also notice that a .proto file can define enums at the top level, /// outside any message. Those enums will be handled as if they were @@ -383,6 +383,7 @@ impl Struct { msg_descriptor: &MessageDescriptor, msg: Option<&dyn MessageDyn>, generate_fields_for_enums: bool, + generate_compile_time_fields: bool, ) -> Rc { let syntax = msg_descriptor.file_descriptor().syntax(); let mut fields = Vec::new(); @@ -403,18 +404,21 @@ impl Struct { &ty, msg.and_then(|msg| fd.get_singular(msg)), generate_fields_for_enums, + generate_compile_time_fields, syntax, ), RuntimeFieldType::Repeated(ty) => Self::new_array( &ty, msg.map(|msg| fd.get_repeated(msg)), generate_fields_for_enums, + generate_compile_time_fields, ), RuntimeFieldType::Map(key_ty, value_ty) => Self::new_map( &key_ty, &value_ty, msg.map(|msg| fd.get_map(msg)), generate_fields_for_enums, + generate_compile_time_fields, syntax, ), }; @@ -437,10 +441,22 @@ impl Struct { StructField { // Index is initially zero, will be adjusted later. type_value: value, - acl: Self::acl(&fd), - deprecation_notice: Self::deprecation_notice(&fd), + acl: if generate_compile_time_fields { + Self::acl(&fd) + } else { + None + }, + deprecation_notice: if generate_compile_time_fields { + Self::deprecation_notice(&fd) + } else { + None + }, number, - doc: Self::field_doc(msg_descriptor.full_name(), number), + doc: if generate_compile_time_fields { + Self::field_doc(msg_descriptor.full_name(), number) + } else { + None + }, }, )); } @@ -788,7 +804,7 @@ impl Struct { }) } - fn field_doc(msg_name: &str, field_number: u64) -> Option { + fn field_doc(msg_name: &str, field_number: u64) -> Option<&'static str> { use crate::modules::field_docs::FIELD_DOCS; let idx = FIELD_DOCS .binary_search_by(|&(name, number, _)| match name.cmp(msg_name) { @@ -796,7 +812,7 @@ impl Struct { ord => ord, }) .ok()?; - Some(FIELD_DOCS[idx].2.to_string()) + Some(FIELD_DOCS[idx].2) } /// Given a protobuf type and value returns a [`TypeValue`]. @@ -823,6 +839,7 @@ impl Struct { ty: &RuntimeType, value: Option, enum_as_fields: bool, + generate_compile_time_fields: bool, syntax: Syntax, ) -> TypeValue { match ty { @@ -880,12 +897,14 @@ impl Struct { msg_descriptor, value, enum_as_fields, + generate_compile_time_fields, ) } else { Self::from_proto_descriptor_and_msg( msg_descriptor, None, enum_as_fields, + generate_compile_time_fields, ) }; TypeValue::Struct(structure) @@ -897,6 +916,7 @@ impl Struct { ty: &RuntimeType, repeated: Option, enum_as_fields: bool, + generate_compile_time_fields: bool, ) -> TypeValue { let array = match ty { RuntimeType::I32 => { @@ -904,7 +924,7 @@ impl Struct { Array::Integers( repeated .into_iter() - .map(|value| value.to_i32().unwrap() as i64) + .map(|value| Self::value_as_i64(value)) .collect(), ) } else { @@ -916,7 +936,7 @@ impl Struct { Array::Integers( repeated .into_iter() - .map(|value| value.to_i64().unwrap()) + .map(|value| Self::value_as_i64(value)) .collect(), ) } else { @@ -928,7 +948,7 @@ impl Struct { Array::Integers( repeated .into_iter() - .map(|value| value.to_u32().unwrap() as i64) + .map(|value| Self::value_as_i64(value)) .collect(), ) } else { @@ -936,14 +956,23 @@ impl Struct { } } RuntimeType::U64 => { - todo!() + if let Some(repeated) = repeated { + Array::Integers( + repeated + .into_iter() + .map(|value| Self::value_as_i64(value)) + .collect(), + ) + } else { + Array::Integers(vec![]) + } } RuntimeType::F32 => { if let Some(repeated) = repeated { Array::Floats( repeated .into_iter() - .map(|value| value.to_f32().unwrap() as f64) + .map(|value| Self::value_as_f64(value)) .collect(), ) } else { @@ -955,7 +984,7 @@ impl Struct { Array::Floats( repeated .into_iter() - .map(|value| value.to_f64().unwrap()) + .map(|value| Self::value_as_f64(value)) .collect(), ) } else { @@ -967,7 +996,7 @@ impl Struct { Array::Bools( repeated .into_iter() - .map(|value| value.to_bool().unwrap()) + .map(|value| Self::value_as_bool(value)) .collect(), ) } else { @@ -1026,6 +1055,7 @@ impl Struct { msg_descriptor, value, enum_as_fields, + generate_compile_time_fields, ) }) .collect(), @@ -1036,6 +1066,7 @@ impl Struct { msg_descriptor, None, enum_as_fields, + generate_compile_time_fields, ), ]) } @@ -1050,6 +1081,7 @@ impl Struct { value_ty: &RuntimeType, map: Option, enum_as_fields: bool, + generate_compile_time_fields: bool, syntax: Syntax, ) -> TypeValue { let map = match key_ty { @@ -1057,6 +1089,7 @@ impl Struct { value_ty, map, enum_as_fields, + generate_compile_time_fields, syntax, ), RuntimeType::I32 @@ -1066,6 +1099,7 @@ impl Struct { value_ty, map, enum_as_fields, + generate_compile_time_fields, syntax, ), ty => { @@ -1080,6 +1114,7 @@ impl Struct { value_ty: &RuntimeType, map: Option, enum_as_fields: bool, + generate_compile_time_fields: bool, syntax: Syntax, ) -> Map { if let Some(map) = map { @@ -1091,6 +1126,7 @@ impl Struct { value_ty, Some(value), enum_as_fields, + generate_compile_time_fields, syntax, ), ); @@ -1102,6 +1138,7 @@ impl Struct { value_ty, None, enum_as_fields, + generate_compile_time_fields, syntax, )), map: Default::default(), @@ -1113,6 +1150,7 @@ impl Struct { value_ty: &RuntimeType, map: Option, enum_as_fields: bool, + generate_compile_time_fields: bool, syntax: Syntax, ) -> Map { if let Some(map) = map { @@ -1124,6 +1162,7 @@ impl Struct { value_ty, Some(value), enum_as_fields, + generate_compile_time_fields, syntax, ), ); @@ -1135,6 +1174,7 @@ impl Struct { value_ty, None, enum_as_fields, + generate_compile_time_fields, syntax, )), map: Default::default(), @@ -1146,12 +1186,14 @@ impl Struct { msg_descriptor: &MessageDescriptor, value: ReflectValueRef, enum_as_fields: bool, + generate_compile_time_fields: bool, ) -> Rc { if let ReflectValueRef::Message(m) = value { Struct::from_proto_descriptor_and_msg( msg_descriptor, Some(m.deref()), enum_as_fields, + generate_compile_time_fields, ) } else { unreachable!() @@ -1226,6 +1268,7 @@ impl From<&dyn RegisteredModule> for Rc { &module.root_descriptor(), None, true, + true, ); // Get a mutable reference for the module's structure. This is @@ -1308,6 +1351,7 @@ mod tests { &TestProto2::descriptor(), None, true, + true, ); let structure = Rc::::get_mut(&mut structure).unwrap();