@@ -9,21 +9,28 @@ use prost_types::{
9
9
DescriptorProto , FieldDescriptorProto , FileDescriptorProto ,
10
10
} ;
11
11
12
+ use crate :: path:: PathMap ;
13
+
12
14
/// `MessageGraph` builds a graph of messages whose edges correspond to nesting.
13
15
/// The goal is to recognize when message types are recursively nested, so
14
16
/// that fields can be boxed when necessary.
15
17
pub struct MessageGraph {
16
18
index : HashMap < String , NodeIndex > ,
17
19
graph : Graph < String , ( ) > ,
18
20
messages : HashMap < String , DescriptorProto > ,
21
+ boxed : PathMap < ( ) > ,
19
22
}
20
23
21
24
impl MessageGraph {
22
- pub fn new < ' a > ( files : impl Iterator < Item = & ' a FileDescriptorProto > ) -> MessageGraph {
25
+ pub ( crate ) fn new < ' a > (
26
+ files : impl Iterator < Item = & ' a FileDescriptorProto > ,
27
+ boxed : PathMap < ( ) > ,
28
+ ) -> MessageGraph {
23
29
let mut msg_graph = MessageGraph {
24
30
index : HashMap :: new ( ) ,
25
31
graph : Graph :: new ( ) ,
26
32
messages : HashMap :: new ( ) ,
33
+ boxed,
27
34
} ;
28
35
29
36
for file in files {
@@ -74,6 +81,11 @@ impl MessageGraph {
74
81
}
75
82
}
76
83
84
+ /// Try get a message descriptor from current message graph
85
+ pub fn get_message ( & self , message : & str ) -> Option < & DescriptorProto > {
86
+ self . messages . get ( message)
87
+ }
88
+
77
89
/// Returns true if message type `inner` is nested in message type `outer`.
78
90
pub fn is_nested ( & self , outer : & str , inner : & str ) -> bool {
79
91
let outer = match self . index . get ( outer) {
@@ -91,8 +103,9 @@ impl MessageGraph {
91
103
/// Returns `true` if this message can automatically derive Copy trait.
92
104
pub fn can_message_derive_copy ( & self , fq_message_name : & str ) -> bool {
93
105
assert_eq ! ( "." , & fq_message_name[ ..1 ] ) ;
94
- let msg = self . messages . get ( fq_message_name) . unwrap ( ) ;
95
- msg. field
106
+ self . get_message ( fq_message_name)
107
+ . unwrap ( )
108
+ . field
96
109
. iter ( )
97
110
. all ( |field| self . can_field_derive_copy ( fq_message_name, field) )
98
111
}
@@ -105,10 +118,17 @@ impl MessageGraph {
105
118
) -> bool {
106
119
assert_eq ! ( "." , & fq_message_name[ ..1 ] ) ;
107
120
121
+ // repeated field cannot derive Copy
108
122
if field. label ( ) == Label :: Repeated {
109
123
false
110
124
} else if field. r#type ( ) == Type :: Message {
111
- if self . is_nested ( field. type_name ( ) , fq_message_name) {
125
+ // nested and boxed messages cannot derive Copy
126
+ if self . is_nested ( field. type_name ( ) , fq_message_name)
127
+ || self
128
+ . boxed
129
+ . get_first_field ( fq_message_name, field. name ( ) )
130
+ . is_some ( )
131
+ {
112
132
false
113
133
} else {
114
134
self . can_message_derive_copy ( field. type_name ( ) )
0 commit comments