Fix merge conflicts and generated code logic in generator.rs
This commit is contained in:
+71
-53
@@ -1,6 +1,6 @@
|
||||
use crate::google::protobuf::descriptor::{
|
||||
DescriptorProto, EnumDescriptorProto, FieldDescriptorProto, FileDescriptorProto,
|
||||
FileDescriptorSet, OneofDescriptorProto,
|
||||
FileDescriptorSet, MessageOptions, OneofDescriptorProto,
|
||||
};
|
||||
use roto_runtime::ProtoAccessor;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
@@ -33,11 +33,16 @@ pub fn to_snake_case(s: &str) -> String {
|
||||
result
|
||||
}
|
||||
|
||||
fn map_type_to_rust_accessor(field_type: i32, label: i32) -> (String, String) {
|
||||
fn map_type_to_rust_accessor(field_type: i32, label: i32, is_map: bool) -> (String, String) {
|
||||
if label == 3 {
|
||||
// LABEL_REPEATED
|
||||
let iterator_type = if is_map {
|
||||
"roto_runtime::MapFieldIterator<'a>"
|
||||
} else {
|
||||
"roto_runtime::RepeatedFieldIterator<'a>"
|
||||
};
|
||||
return (
|
||||
"roto_runtime::RepeatedFieldIterator<'a>".to_string(),
|
||||
iterator_type.to_string(),
|
||||
"".to_string(), // Not used for repeated fields in the same way
|
||||
);
|
||||
}
|
||||
@@ -160,8 +165,24 @@ fn write_message(msg_proto: &DescriptorProto, output: &mut String) {
|
||||
let f_type = field_proto.r#type().unwrap() as i32;
|
||||
let f_label = field_proto.label().unwrap() as i32;
|
||||
let oneof_index = field_proto.oneof_index().ok();
|
||||
let is_map = field_proto
|
||||
.options()
|
||||
.map(|opt| {
|
||||
MessageOptions::new(opt)
|
||||
.unwrap()
|
||||
.map_entry()
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.unwrap_or(false);
|
||||
|
||||
fields_info.push((field_name.to_string(), tag, f_type, f_label, oneof_index));
|
||||
fields_info.push((
|
||||
field_name.to_string(),
|
||||
tag,
|
||||
f_type,
|
||||
f_label,
|
||||
oneof_index,
|
||||
is_map,
|
||||
));
|
||||
}
|
||||
|
||||
let mut oneofs = Vec::new();
|
||||
@@ -173,7 +194,7 @@ fn write_message(msg_proto: &DescriptorProto, output: &mut String) {
|
||||
output.push_str(&format!("pub struct {}<'a> {{\n", msg_name));
|
||||
output.push_str(" accessor: roto_runtime::ProtoAccessor<'a>,\n");
|
||||
|
||||
for (field_name, _tag, _f_type, f_label, _oneof_index) in &fields_info {
|
||||
for (field_name, _tag, _f_type, f_label, _oneof_index, _is_map) in &fields_info {
|
||||
if *f_label == 3 {
|
||||
output.push_str(&format!(" {}_start: Option<usize>,\n", field_name));
|
||||
output.push_str(&format!(" {}_end: Option<usize>,\n", field_name));
|
||||
@@ -186,41 +207,38 @@ fn write_message(msg_proto: &DescriptorProto, output: &mut String) {
|
||||
output.push_str(&format!("impl<'a> {}<'a> {{\n", msg_name));
|
||||
output.push_str(" pub fn new(data: &'a [u8]) -> roto_runtime::Result<Self> {\n");
|
||||
output.push_str(" let accessor = roto_runtime::ProtoAccessor::new(data)?;\n");
|
||||
if !fields_info.is_empty() {
|
||||
for (name, _, _, label, _) in &fields_info {
|
||||
if *label == 3 {
|
||||
output.push_str(&format!(" let mut {}_start = None;\n", name));
|
||||
output.push_str(&format!(" let mut {}_end = None;\n", name));
|
||||
} else {
|
||||
output.push_str(&format!(" let mut {}_offset = None;\n", name));
|
||||
}
|
||||
for (name, _, _, label, _oneof_index, _is_map) in &fields_info {
|
||||
if *label == 3 {
|
||||
output.push_str(&format!(" let mut {}_start = None;\n", name));
|
||||
output.push_str(&format!(" let mut {}_end = None;\n", name));
|
||||
} else {
|
||||
output.push_str(&format!(" let mut {}_offset = None;\n", name));
|
||||
}
|
||||
|
||||
output.push_str(" for item in accessor.fields() {\n");
|
||||
output.push_str(" let (offset, tag, _) = item?;\n");
|
||||
|
||||
for (name, tag, _, label, _) in &fields_info {
|
||||
if *label == 3 {
|
||||
output.push_str(&format!(" if tag.field_number == {} {{\n", tag));
|
||||
output.push_str(&format!(
|
||||
" if {}_start.is_none() {{ {}_start = Some(offset); }}\n",
|
||||
name, name
|
||||
));
|
||||
output.push_str(&format!(" {}_end = Some(offset);\n", name));
|
||||
output.push_str(" }\n");
|
||||
} else {
|
||||
output.push_str(&format!(
|
||||
" if tag.field_number == {} {{ {}_offset = Some(offset); }}\n",
|
||||
tag, name
|
||||
));
|
||||
}
|
||||
}
|
||||
output.push_str(" }\n\n");
|
||||
}
|
||||
|
||||
output.push_str(" for item in accessor.fields() {\n");
|
||||
output.push_str(" let (offset, tag, _) = item?;\n");
|
||||
for (name, tag, _, label, _oneof_index, _is_map) in &fields_info {
|
||||
if *label == 3 {
|
||||
output.push_str(&format!(" if tag.field_number == {} {{\n", tag));
|
||||
output.push_str(&format!(
|
||||
" if {}_start.is_none() {{ {}_start = Some(offset); }}\n",
|
||||
name, name
|
||||
));
|
||||
output.push_str(&format!(" {}_end = Some(offset);\n", name));
|
||||
output.push_str(" }\n");
|
||||
} else {
|
||||
output.push_str(&format!(
|
||||
" if tag.field_number == {} {{ {}_offset = Some(offset); }}\n",
|
||||
tag, name
|
||||
));
|
||||
}
|
||||
}
|
||||
output.push_str(" }\n\n");
|
||||
|
||||
output.push_str(" Ok(Self {\n");
|
||||
output.push_str(" accessor,\n");
|
||||
for (name, _, _, label, _) in &fields_info {
|
||||
for (name, _, _, label, _oneof_index, _is_map) in &fields_info {
|
||||
if *label == 3 {
|
||||
output.push_str(&format!("{}_start, {}_end,\n", name, name));
|
||||
} else {
|
||||
@@ -229,8 +247,8 @@ fn write_message(msg_proto: &DescriptorProto, output: &mut String) {
|
||||
}
|
||||
output.push_str(" })\n }\n\n");
|
||||
|
||||
for (field_name, tag, f_type, f_label, _oneof_index) in &fields_info {
|
||||
let (rust_type, logic) = map_type_to_rust_accessor(*f_type, *f_label);
|
||||
for (field_name, tag, f_type, f_label, _oneof_index, is_map) in &fields_info {
|
||||
let (rust_type, logic) = map_type_to_rust_accessor(*f_type, *f_label, *is_map);
|
||||
let safe_name = if field_name == "type" {
|
||||
format!("r#{}", field_name)
|
||||
} else {
|
||||
@@ -238,19 +256,19 @@ fn write_message(msg_proto: &DescriptorProto, output: &mut String) {
|
||||
};
|
||||
|
||||
if *f_label == 3 {
|
||||
output.push_str(&format!(
|
||||
" pub fn {}(&self) -> {} {{\n",
|
||||
safe_name, rust_type
|
||||
));
|
||||
output.push_str(&format!(
|
||||
" match (self.{}_start, self.{}_end) {{\n",
|
||||
field_name, field_name
|
||||
));
|
||||
output.push_str(&format!(" (Some(start), Some(end)) => self.accessor.iter_repeated_range({}, start, end),\n", tag));
|
||||
output.push_str(&format!(
|
||||
" _ => self.accessor.iter_repeated({}),\n",
|
||||
tag
|
||||
));
|
||||
if *is_map {
|
||||
output.push_str(&format!(" (Some(start), Some(end)) => roto_runtime::MapFieldIterator::new(self.accessor.iter_repeated_range({}, start, end)),\n", tag));
|
||||
output.push_str(&format!(
|
||||
" _ => roto_runtime::MapFieldIterator::new(self.accessor.iter_repeated({})),\n",
|
||||
tag
|
||||
));
|
||||
} else {
|
||||
output.push_str(&format!(" (Some(start), Some(end)) => self.accessor.iter_repeated_range({}, start, end),\n", tag));
|
||||
output.push_str(&format!(
|
||||
" _ => self.accessor.iter_repeated({}),\n",
|
||||
tag
|
||||
));
|
||||
}
|
||||
output.push_str(" }\n }\n\n");
|
||||
} else {
|
||||
output.push_str(&format!(
|
||||
@@ -282,7 +300,7 @@ fn write_message(msg_proto: &DescriptorProto, output: &mut String) {
|
||||
" pub fn which_{}(&self) -> roto_runtime::Result<Option<{}::{}<'a>>> {{\n",
|
||||
snake_oneof_name, msg_name, pascal_oneof_name
|
||||
));
|
||||
for (field_name, _tag, _f_type, _f_label, f_oneof_index) in &fields_info {
|
||||
for (field_name, _tag, _f_type, _f_label, f_oneof_index, _is_map) in &fields_info {
|
||||
if *f_oneof_index == Some(oneof_index as i32) {
|
||||
let safe_field_name = if field_name == "type" {
|
||||
format!("r#{}", field_name)
|
||||
@@ -416,9 +434,9 @@ fn write_message(msg_proto: &DescriptorProto, output: &mut String) {
|
||||
let oneof_name = oneof_desc.name().unwrap();
|
||||
let pascal_oneof_name = to_pascal_case(oneof_name);
|
||||
output.push_str(&format!("pub enum {}<'a> {{\n", pascal_oneof_name));
|
||||
for (field_name, _tag, f_type, f_label, f_oneof_index) in &fields_info {
|
||||
for (field_name, _tag, f_type, f_label, f_oneof_index, _is_map) in &fields_info {
|
||||
if *f_oneof_index == Some(oneof_index as i32) {
|
||||
let (rust_type, _) = map_type_to_rust_accessor(*f_type, *f_label);
|
||||
let (rust_type, _) = map_type_to_rust_accessor(*f_type, *f_label, *_is_map);
|
||||
let safe_field_name = if field_name == "type" {
|
||||
format!("r#{}", field_name)
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user