Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/src/modules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down
1 change: 1 addition & 0 deletions lib/src/scanner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions lib/src/symbols/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ mod tests {
&TestProto2::descriptor(),
None,
true,
false,
);

assert_eq!(test.lookup("int32_zero").unwrap().ty(), Type::Integer);
Expand Down Expand Up @@ -436,6 +437,7 @@ mod tests {
&descriptor,
Some(message.as_ref()),
true,
false,
);

assert_eq!(
Expand Down
80 changes: 62 additions & 18 deletions lib/src/types/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Vec<AclEntry>>,
/// 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<DeprecationNotice>,
/// Description of the field extracted from the .proto file.
pub doc: Option<String>,
#[serde(skip)]
pub doc: Option<&'static str>,
}

/// A dynamic structure with one or more fields.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -383,6 +383,7 @@ impl Struct {
msg_descriptor: &MessageDescriptor,
msg: Option<&dyn MessageDyn>,
generate_fields_for_enums: bool,
generate_compile_time_fields: bool,
) -> Rc<Self> {
let syntax = msg_descriptor.file_descriptor().syntax();
let mut fields = Vec::new();
Expand All @@ -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,
),
};
Expand All @@ -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
},
},
));
}
Expand Down Expand Up @@ -788,15 +804,15 @@ impl Struct {
})
}

fn field_doc(msg_name: &str, field_number: u64) -> Option<String> {
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) {
std::cmp::Ordering::Equal => number.cmp(&field_number),
ord => ord,
})
.ok()?;
Some(FIELD_DOCS[idx].2.to_string())
Some(FIELD_DOCS[idx].2)
}

/// Given a protobuf type and value returns a [`TypeValue`].
Expand All @@ -823,6 +839,7 @@ impl Struct {
ty: &RuntimeType,
value: Option<ReflectValueRef>,
enum_as_fields: bool,
generate_compile_time_fields: bool,
syntax: Syntax,
) -> TypeValue {
match ty {
Expand Down Expand Up @@ -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)
Expand All @@ -897,14 +916,15 @@ impl Struct {
ty: &RuntimeType,
repeated: Option<ReflectRepeatedRef>,
enum_as_fields: bool,
generate_compile_time_fields: bool,
) -> TypeValue {
let array = match ty {
RuntimeType::I32 => {
if let Some(repeated) = repeated {
Array::Integers(
repeated
.into_iter()
.map(|value| value.to_i32().unwrap() as i64)
.map(|value| Self::value_as_i64(value))
.collect(),
)
} else {
Expand All @@ -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 {
Expand All @@ -928,22 +948,31 @@ impl Struct {
Array::Integers(
repeated
.into_iter()
.map(|value| value.to_u32().unwrap() as i64)
.map(|value| Self::value_as_i64(value))
.collect(),
)
} else {
Array::Integers(vec![])
}
}
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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -1026,6 +1055,7 @@ impl Struct {
msg_descriptor,
value,
enum_as_fields,
generate_compile_time_fields,
)
})
.collect(),
Expand All @@ -1036,6 +1066,7 @@ impl Struct {
msg_descriptor,
None,
enum_as_fields,
generate_compile_time_fields,
),
])
}
Expand All @@ -1050,13 +1081,15 @@ impl Struct {
value_ty: &RuntimeType,
map: Option<ReflectMapRef>,
enum_as_fields: bool,
generate_compile_time_fields: bool,
syntax: Syntax,
) -> TypeValue {
let map = match key_ty {
RuntimeType::String => Self::new_map_with_string_key(
value_ty,
map,
enum_as_fields,
generate_compile_time_fields,
syntax,
),
RuntimeType::I32
Expand All @@ -1066,6 +1099,7 @@ impl Struct {
value_ty,
map,
enum_as_fields,
generate_compile_time_fields,
syntax,
),
ty => {
Expand All @@ -1080,6 +1114,7 @@ impl Struct {
value_ty: &RuntimeType,
map: Option<ReflectMapRef>,
enum_as_fields: bool,
generate_compile_time_fields: bool,
syntax: Syntax,
) -> Map {
if let Some(map) = map {
Expand All @@ -1091,6 +1126,7 @@ impl Struct {
value_ty,
Some(value),
enum_as_fields,
generate_compile_time_fields,
syntax,
),
);
Expand All @@ -1102,6 +1138,7 @@ impl Struct {
value_ty,
None,
enum_as_fields,
generate_compile_time_fields,
syntax,
)),
map: Default::default(),
Expand All @@ -1113,6 +1150,7 @@ impl Struct {
value_ty: &RuntimeType,
map: Option<ReflectMapRef>,
enum_as_fields: bool,
generate_compile_time_fields: bool,
syntax: Syntax,
) -> Map {
if let Some(map) = map {
Expand All @@ -1124,6 +1162,7 @@ impl Struct {
value_ty,
Some(value),
enum_as_fields,
generate_compile_time_fields,
syntax,
),
);
Expand All @@ -1135,6 +1174,7 @@ impl Struct {
value_ty,
None,
enum_as_fields,
generate_compile_time_fields,
syntax,
)),
map: Default::default(),
Expand All @@ -1146,12 +1186,14 @@ impl Struct {
msg_descriptor: &MessageDescriptor,
value: ReflectValueRef,
enum_as_fields: bool,
generate_compile_time_fields: bool,
) -> Rc<Self> {
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!()
Expand Down Expand Up @@ -1226,6 +1268,7 @@ impl From<&dyn RegisteredModule> for Rc<Struct> {
&module.root_descriptor(),
None,
true,
true,
);

// Get a mutable reference for the module's structure. This is
Expand Down Expand Up @@ -1308,6 +1351,7 @@ mod tests {
&TestProto2::descriptor(),
None,
true,
true,
);

let structure = Rc::<Struct>::get_mut(&mut structure).unwrap();
Expand Down
Loading