chore: auto import pb file

This commit is contained in:
appflowy 2022-06-17 16:42:18 +08:00
parent 40bcb63627
commit d30d42e841
17 changed files with 120 additions and 37 deletions

View File

@ -1,6 +1,6 @@
syntax = "proto3";
import "field_entities.proto";
import "field_entities.proto";
message CreateSelectOptionPayload {
FieldIdentifierPayload field_identifier = 1;
string option_name = 2;

View File

@ -1,6 +1,6 @@
syntax = "proto3";
import "cell_entities.proto";
import "cell_entities.proto";
message DateTypeOption {
DateFormat date_format = 1;
TimeFormat time_format = 2;

View File

@ -1,6 +1,6 @@
syntax = "proto3";
import "format.proto";
import "format.proto";
message NumberTypeOption {
NumberFormat format = 1;
uint32 scale = 2;

View File

@ -1,6 +1,7 @@
syntax = "proto3";
import "cell_entities.proto";
import "cell_entities.proto";
import "cell_entities.proto";
message SingleSelectTypeOption {
repeated SelectOption options = 1;
bool disable_color = 2;

View File

@ -1,5 +1,4 @@
syntax = "proto3";
enum ErrorCode {
Internal = 0;
UserUnauthorized = 2;

View File

@ -1,6 +1,6 @@
syntax = "proto3";
import "view.proto";
import "view.proto";
message App {
string id = 1;
string workspace_id = 2;

View File

@ -1,6 +1,7 @@
syntax = "proto3";
import "view.proto";
import "view.proto";
import "view.proto";
message ViewInfo {
string id = 1;
string belong_to_id = 2;

View File

@ -1,7 +1,7 @@
syntax = "proto3";
import "app.proto";
import "view.proto";
message Workspace {
string id = 1;
string name = 2;

View File

@ -1,5 +1,4 @@
syntax = "proto3";
message Field {
string id = 1;
string name = 2;

View File

@ -1,6 +1,5 @@
syntax = "proto3";
import "field.proto";
message Grid {
string id = 1;
repeated FieldOrder field_orders = 2;

View File

@ -1,5 +1,4 @@
syntax = "proto3";
message ViewExtData {
ViewFilter filter = 1;
ViewGroup group = 2;

View File

@ -1,6 +1,7 @@
syntax = "proto3";
import "revision.proto";
import "revision.proto";
import "revision.proto";
message CreateTextBlockParams {
string id = 1;
RepeatedRevision revisions = 2;

View File

@ -1,6 +1,6 @@
syntax = "proto3";
import "revision.proto";
import "revision.proto";
message ClientRevisionWSData {
string object_id = 1;
ClientRevisionWSDataType ty = 2;

View File

@ -2,7 +2,7 @@
#![allow(dead_code)]
#![allow(unused_imports)]
#![allow(unused_results)]
use crate::code_gen::protobuf_file::template::{EnumTemplate, StructTemplate};
use crate::code_gen::protobuf_file::template::{EnumTemplate, StructTemplate, RUST_TYPE_MAP};
use crate::code_gen::protobuf_file::{parse_crate_info_from_path, ProtoFile, ProtobufCrateContext};
use crate::code_gen::util::*;
use fancy_regex::Regex;
@ -57,19 +57,28 @@ fn parse_files_protobuf(proto_crate_path: &Path, proto_output_path: &Path) -> Ve
let structs = get_ast_structs(&ast);
let proto_file = format!("{}.proto", &file_name);
let proto_file_path = path_string_with_component(proto_output_path, vec![&proto_file]);
let mut proto_file_content = find_proto_syntax(proto_file_path.as_ref());
let proto_syntax = find_proto_syntax(proto_file_path.as_ref());
let mut proto_content = String::new();
// The types that are not defined in the current file.
let mut ref_types: Vec<String> = vec![];
structs.iter().for_each(|s| {
let mut struct_template = StructTemplate::new();
struct_template.set_message_struct_name(&s.name);
s.fields.iter().filter(|f| f.attrs.pb_index().is_some()).for_each(|f| {
struct_template.set_field(f);
s.fields
.iter()
.filter(|field| field.attrs.pb_index().is_some())
.for_each(|field| {
ref_types.push(field.ty_as_str().to_string());
struct_template.set_field(field);
});
let s = struct_template.render().unwrap();
proto_file_content.push_str(s.as_ref());
proto_file_content.push('\n');
proto_content.push_str(s.as_ref());
proto_content.push('\n');
});
let enums = get_ast_enums(&ast);
@ -77,17 +86,26 @@ fn parse_files_protobuf(proto_crate_path: &Path, proto_output_path: &Path) -> Ve
let mut enum_template = EnumTemplate::new();
enum_template.set_message_enum(e);
let s = enum_template.render().unwrap();
proto_file_content.push_str(s.as_ref());
proto_file_content.push('\n');
proto_content.push_str(s.as_ref());
ref_types.push(e.name.clone());
proto_content.push('\n');
});
if !enums.is_empty() || !structs.is_empty() {
let structs: Vec<String> = structs.iter().map(|s| s.name.clone()).collect();
let enums: Vec<String> = enums.iter().map(|e| e.name.clone()).collect();
ref_types.retain(|s| !structs.contains(&s));
ref_types.retain(|s| !enums.contains(&s));
let info = ProtoFile {
file_path: path.clone(),
file_name: file_name.clone(),
structs: structs.iter().map(|s| s.name.clone()).collect(),
enums: enums.iter().map(|e| e.name.clone()).collect(),
generated_content: proto_file_content.clone(),
ref_types,
structs,
enums,
syntax: proto_syntax,
content: proto_content,
};
gen_proto_vec.push(info);
}
@ -148,12 +166,12 @@ pub struct Struct<'a> {
lazy_static! {
static ref SYNTAX_REGEX: Regex = Regex::new("syntax.*;").unwrap();
static ref IMPORT_REGEX: Regex = Regex::new("(import\\s).*;").unwrap();
// static ref IMPORT_REGEX: Regex = Regex::new("(import\\s).*;").unwrap();
}
fn find_proto_syntax(path: &str) -> String {
if !Path::new(path).exists() {
return String::from("syntax = \"proto3\";\n\n");
return String::from("syntax = \"proto3\";\n");
}
let mut result = String::new();
@ -165,13 +183,12 @@ fn find_proto_syntax(path: &str) -> String {
////Result<Option<Match<'t>>>
if let Ok(Some(m)) = SYNTAX_REGEX.find(line) {
result.push_str(m.as_str());
result.push('\n');
}
if let Ok(Some(m)) = IMPORT_REGEX.find(line) {
result.push_str(m.as_str());
result.push('\n');
}
// if let Ok(Some(m)) = IMPORT_REGEX.find(line) {
// result.push_str(m.as_str());
// result.push('\n');
// }
});
result.push('\n');

View File

@ -7,6 +7,7 @@ use crate::code_gen::protobuf_file::proto_info::ProtobufCrateContext;
use crate::code_gen::protobuf_file::ProtoFile;
use crate::code_gen::util::*;
use crate::code_gen::ProtoCache;
use std::collections::HashMap;
use std::fs::File;
use std::path::Path;
use std::{fs::OpenOptions, io::Write};
@ -49,16 +50,66 @@ impl ProtoGenerator {
}
fn write_proto_files(crate_contexts: &[ProtobufCrateContext]) {
let file_path_content_map = crate_contexts
.iter()
.map(|ctx| {
ctx.files
.iter()
.map(|file| {
(
file.file_path.clone(),
ProtoFileSymbol {
file_name: file.file_name.clone(),
symbols: file.symbols(),
},
)
})
.collect::<HashMap<String, ProtoFileSymbol>>()
})
.flatten()
.collect::<HashMap<String, ProtoFileSymbol>>();
for context in crate_contexts {
let dir = context.protobuf_crate.proto_output_path();
context.files.iter().for_each(|info| {
let proto_file = format!("{}.proto", &info.file_name);
context.files.iter().for_each(|file| {
// syntax
let mut file_content = file.syntax.clone();
// import
file_content.push_str(&gen_import_content(&file, &file_path_content_map));
// content
file_content.push_str(&file.content);
let proto_file = format!("{}.proto", &file.file_name);
let proto_file_path = path_string_with_component(&dir, vec![&proto_file]);
save_content_to_file_with_diff_prompt(&info.generated_content, proto_file_path.as_ref());
save_content_to_file_with_diff_prompt(&file_content, proto_file_path.as_ref());
});
}
}
fn gen_import_content(current_file: &ProtoFile, file_path_symbols_map: &HashMap<String, ProtoFileSymbol>) -> String {
let mut import_content = String::new();
file_path_symbols_map
.iter()
.for_each(|(file_path, proto_file_symbols)| {
if file_path != &current_file.file_path {
current_file.ref_types.iter().for_each(|ref_type| {
if proto_file_symbols.symbols.contains(ref_type) {
import_content.push_str(&format!("import \"{}.proto\";\n", proto_file_symbols.file_name));
}
});
}
});
import_content
}
struct ProtoFileSymbol {
file_name: String,
symbols: Vec<String>,
}
fn write_rust_crate_mod_file(crate_contexts: &[ProtobufCrateContext]) {
for context in crate_contexts {
let mod_path = context.protobuf_crate.proto_model_mod_file();

View File

@ -106,8 +106,24 @@ pub struct ProtoFile {
pub file_path: String,
pub file_name: String,
pub structs: Vec<String>,
pub ref_types: Vec<String>,
pub enums: Vec<String>,
pub generated_content: String,
// proto syntax. "proto3" or "proto2"
pub syntax: String,
// proto message content
pub content: String,
}
impl ProtoFile {
pub fn symbols(&self) -> Vec<String> {
let mut symbols = self.structs.clone();
let mut enum_symbols = self.enums.clone();
symbols.append(&mut enum_symbols);
symbols
}
}
pub fn parse_crate_info_from_path(roots: Vec<String>) -> Vec<ProtobufCrate> {

View File

@ -4,7 +4,7 @@ use phf::phf_map;
use tera::Context;
// Protobuf data type : https://developers.google.com/protocol-buffers/docs/proto3
static RUST_TYPE_MAP: phf::Map<&'static str, &'static str> = phf_map! {
pub static RUST_TYPE_MAP: phf::Map<&'static str, &'static str> = phf_map! {
"String" => "string",
"i64" => "int64",
"i32" => "int32",