line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Google::ProtocolBuffers::CodeGen;
|
2
|
1
|
|
|
1
|
|
7
|
use strict;
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
44
|
|
3
|
1
|
|
|
1
|
|
6
|
use warnings;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
71
|
|
4
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
7
|
use Google::ProtocolBuffers::Constants qw/:types :labels :complex_types/;
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
1446
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
my %primitive_types = reverse (
|
8
|
|
|
|
|
|
|
TYPE_DOUBLE => TYPE_DOUBLE,
|
9
|
|
|
|
|
|
|
TYPE_FLOAT => TYPE_FLOAT,
|
10
|
|
|
|
|
|
|
TYPE_INT64 => TYPE_INT64,
|
11
|
|
|
|
|
|
|
TYPE_UINT64 => TYPE_UINT64,
|
12
|
|
|
|
|
|
|
TYPE_INT32 => TYPE_INT32,
|
13
|
|
|
|
|
|
|
TYPE_FIXED64=> TYPE_FIXED64,
|
14
|
|
|
|
|
|
|
TYPE_FIXED32=> TYPE_FIXED32,
|
15
|
|
|
|
|
|
|
TYPE_BOOL => TYPE_BOOL,
|
16
|
|
|
|
|
|
|
TYPE_STRING => TYPE_STRING,
|
17
|
|
|
|
|
|
|
TYPE_GROUP => TYPE_GROUP, ##
|
18
|
|
|
|
|
|
|
TYPE_MESSAGE=> TYPE_MESSAGE, ## should never appear, because 'message' is a 'complex type'
|
19
|
|
|
|
|
|
|
TYPE_BYTES => TYPE_BYTES,
|
20
|
|
|
|
|
|
|
TYPE_UINT32 => TYPE_UINT32,
|
21
|
|
|
|
|
|
|
TYPE_ENUM => TYPE_ENUM, ##
|
22
|
|
|
|
|
|
|
TYPE_SFIXED32=>TYPE_SFIXED32,
|
23
|
|
|
|
|
|
|
TYPE_SFIXED64=>TYPE_SFIXED64,
|
24
|
|
|
|
|
|
|
TYPE_SINT32 => TYPE_SINT32,
|
25
|
|
|
|
|
|
|
TYPE_SINT64 => TYPE_SINT64,
|
26
|
|
|
|
|
|
|
);
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
my %labels = reverse (
|
29
|
|
|
|
|
|
|
LABEL_OPTIONAL => LABEL_OPTIONAL,
|
30
|
|
|
|
|
|
|
LABEL_REQUIRED => LABEL_REQUIRED,
|
31
|
|
|
|
|
|
|
LABEL_REPEATED => LABEL_REPEATED,
|
32
|
|
|
|
|
|
|
);
|
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub _get_perl_literal {
|
35
|
79
|
|
|
79
|
|
56
|
my $v = shift;
|
36
|
79
|
|
|
|
|
47
|
my $opts = shift;
|
37
|
|
|
|
|
|
|
|
38
|
79
|
100
|
|
|
|
168
|
if ($v =~ /^-?\d+$/) {
|
|
|
100
|
|
|
|
|
|
39
|
|
|
|
|
|
|
## integer literal
|
40
|
55
|
100
|
100
|
|
|
134
|
if ($v>0x7fff_ffff || $v<-0x8000_0000) {
|
41
|
3
|
|
|
|
|
6
|
return "Math::BigInt->new('$v')";
|
42
|
|
|
|
|
|
|
} else {
|
43
|
52
|
|
|
|
|
57
|
return "$v";
|
44
|
|
|
|
|
|
|
}
|
45
|
|
|
|
|
|
|
} elsif ($v =~ /[-+]?\d*\.\d+([Ee][\+-]?\d+)?|[-+]?\d+[Ee][\+-]?\d+/i) {
|
46
|
|
|
|
|
|
|
## floating point literal
|
47
|
4
|
|
|
|
|
7
|
return "$v";
|
48
|
|
|
|
|
|
|
} else {
|
49
|
|
|
|
|
|
|
## string literal
|
50
|
20
|
|
|
|
|
57
|
$v =~ s/([\x00-\x1f'"\\$@%\x80-\xff])/ '\\x{' . sprintf("%02x", ord($1)) . '}' /ge;
|
|
16
|
|
|
|
|
31
|
|
51
|
20
|
|
|
|
|
31
|
return qq["$v"];
|
52
|
|
|
|
|
|
|
}
|
53
|
|
|
|
|
|
|
}
|
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
sub generate_code_of_enum {
|
56
|
5
|
|
|
5
|
0
|
5
|
my $self = shift;
|
57
|
5
|
|
|
|
|
4
|
my $opts = shift;
|
58
|
|
|
|
|
|
|
|
59
|
5
|
|
33
|
|
|
14
|
my $class_name = ref($self) || $self;
|
60
|
5
|
|
|
|
|
4
|
my $fields_text;
|
61
|
5
|
|
|
|
|
5
|
foreach my $f (@{ $self->_pb_fields_list }) {
|
|
5
|
|
|
|
|
13
|
|
62
|
21
|
|
|
|
|
32
|
my ($name, $value) = @$f;
|
63
|
21
|
|
|
|
|
21
|
$value = _get_perl_literal($value, $opts);
|
64
|
21
|
|
|
|
|
34
|
$fields_text .= " ['$name', $value],\n";
|
65
|
|
|
|
|
|
|
}
|
66
|
|
|
|
|
|
|
|
67
|
5
|
|
|
|
|
18
|
return <<"CODE";
|
68
|
|
|
|
|
|
|
unless ($class_name->can('_pb_fields_list')) {
|
69
|
|
|
|
|
|
|
Google::ProtocolBuffers->create_enum(
|
70
|
|
|
|
|
|
|
'$class_name',
|
71
|
|
|
|
|
|
|
[
|
72
|
|
|
|
|
|
|
$fields_text
|
73
|
|
|
|
|
|
|
]
|
74
|
|
|
|
|
|
|
);
|
75
|
|
|
|
|
|
|
}
|
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
CODE
|
78
|
|
|
|
|
|
|
}
|
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
sub generate_code_of_message_or_group {
|
82
|
34
|
|
|
34
|
0
|
30
|
my $self = shift;
|
83
|
34
|
|
|
|
|
29
|
my $opts = shift;
|
84
|
|
|
|
|
|
|
|
85
|
34
|
50
|
|
|
|
108
|
my $create_what =
|
|
|
100
|
|
|
|
|
|
86
|
|
|
|
|
|
|
($self->_pb_complex_type_kind==MESSAGE) ? 'create_message' :
|
87
|
|
|
|
|
|
|
($self->_pb_complex_type_kind==GROUP) ? 'create_group' : die;
|
88
|
|
|
|
|
|
|
|
89
|
34
|
|
33
|
|
|
92
|
my $class_name = ref($self) || $self;
|
90
|
|
|
|
|
|
|
|
91
|
34
|
|
|
|
|
21
|
my $fields_text = ''; # may be empty, as empty messages are allowed
|
92
|
34
|
|
|
|
|
30
|
foreach my $f (@{ $self->_pb_fields_list }) {
|
|
34
|
|
|
|
|
85
|
|
93
|
226
|
|
|
|
|
310
|
my ($label, $type, $name, $field_number, $default_value) = @$f;
|
94
|
|
|
|
|
|
|
|
95
|
226
|
50
|
|
|
|
305
|
die unless $labels{$label};
|
96
|
226
|
|
|
|
|
196
|
$label = "Google::ProtocolBuffers::Constants::$labels{$label}()";
|
97
|
|
|
|
|
|
|
|
98
|
226
|
100
|
|
|
|
249
|
if ($primitive_types{$type}) {
|
99
|
176
|
|
|
|
|
169
|
$type = "Google::ProtocolBuffers::Constants::$primitive_types{$type}()";
|
100
|
|
|
|
|
|
|
} else {
|
101
|
50
|
|
|
|
|
45
|
$type = "'$type'";
|
102
|
|
|
|
|
|
|
}
|
103
|
|
|
|
|
|
|
|
104
|
226
|
100
|
|
|
|
226
|
$default_value = (defined $default_value) ?
|
105
|
|
|
|
|
|
|
_get_perl_literal($default_value, $opts) : 'undef';
|
106
|
226
|
|
|
|
|
395
|
$fields_text .= <<"FIELD";
|
107
|
|
|
|
|
|
|
[
|
108
|
|
|
|
|
|
|
$label,
|
109
|
|
|
|
|
|
|
$type,
|
110
|
|
|
|
|
|
|
'$name', $field_number, $default_value
|
111
|
|
|
|
|
|
|
],
|
112
|
|
|
|
|
|
|
FIELD
|
113
|
|
|
|
|
|
|
}
|
114
|
|
|
|
|
|
|
|
115
|
34
|
|
|
|
|
28
|
my $oneofs_text = " undef,\n"; |
116
|
34
|
50
|
|
|
|
246
|
if ($self->can('_pb_oneofs')) { |
117
|
0
|
|
|
|
|
0
|
$oneofs_text = " {\n"; |
118
|
0
|
|
|
|
|
0
|
while (my ($name, $fields) = each %{$self->_pb_oneofs}) { |
|
0
|
|
|
|
|
0
|
|
119
|
0
|
|
|
|
|
0
|
$oneofs_text .= " '$name' => [\n"; |
120
|
0
|
|
|
|
|
0
|
foreach my $f (@$fields) { |
121
|
0
|
|
|
|
|
0
|
$oneofs_text .= " '$f',\n"; |
122
|
|
|
|
|
|
|
} |
123
|
0
|
|
|
|
|
0
|
$oneofs_text .= " ],\n"; |
124
|
|
|
|
|
|
|
} |
125
|
0
|
|
|
|
|
0
|
$oneofs_text .= " },\n"; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
34
|
|
|
|
|
33
|
my $options = '';
|
129
|
34
|
|
|
|
|
34
|
foreach my $opt_name (qw/create_accessors follow_best_practice/) {
|
130
|
68
|
100
|
|
|
|
107
|
if ($opts->{$opt_name}) {
|
131
|
34
|
|
|
|
|
45
|
$options .= "'$opt_name' => 1, "
|
132
|
|
|
|
|
|
|
}
|
133
|
|
|
|
|
|
|
}
|
134
|
|
|
|
|
|
|
|
135
|
34
|
|
|
|
|
367
|
return <<"CODE";
|
136
|
|
|
|
|
|
|
unless ($class_name->can('_pb_fields_list')) {
|
137
|
|
|
|
|
|
|
Google::ProtocolBuffers->$create_what(
|
138
|
|
|
|
|
|
|
'$class_name',
|
139
|
|
|
|
|
|
|
[
|
140
|
|
|
|
|
|
|
$fields_text
|
141
|
|
|
|
|
|
|
],
|
142
|
|
|
|
|
|
|
$oneofs_text |
143
|
|
|
|
|
|
|
{ $options }
|
144
|
|
|
|
|
|
|
);
|
145
|
|
|
|
|
|
|
}
|
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
CODE
|
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
}
|
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
1;
|