1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/bin/bash -f
# mcpack2pb - Make protobuf be front-end of mcpack/compack
# Copyright (c) 2015 Baidu.com, Inc. All Rights Reserved
# Author: The baidu-rpc authors (pbrpc@baidu.com)
# Date: Mon Oct 19 17:17:36 CST 2015
# source shflags from current directory
mydir="${BASH_SOURCE%/*}"
if [[ ! -d "$mydir" ]]; then mydir="$PWD"; fi
. $mydir/shflags
# command-line flags
DEFINE_string ns '' 'Namespace of the idl file'
DEFINE_boolean pb3 false 'Use new data structures introduced in protobuf 3'
# parse the command-line
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
# Printing to stderr
function error() {
>&2 echo "idl2proto: $@"
}
if [[ "$1" == "" ]]; then
flags_help
exit 1
fi
if [[ $(basename "$1" | awk -F. '{print $2}') != "idl" ]]; then
error "$1 is not an idl file";
exit 1
fi
package_statement=""
if [[ "$FLAGS_ns" != "" ]]; then
package_statement="package $FLAGS_ns;\n"
fi
sed -e ':a;N;$!ba;s/=\s*\n\+/=/g' $1 | \
sed -e 's/;\//; \//g' \
-e 's/^\(\s*#\(define\>\|if\|endif\|undef\)\)/\/\/ \1/g' \
-e 's/^\s*struct\>/message/g' \
-e 's/\<\(range\|regex\|rest\)\s*\(([^)]*)\)\s*,*\(.*\)/\3 \/\/\1\2/g' \
-e 's/\<default(\([^)]*\))\s*,*/[default=\1]/g' \
-e 's/^\s*\(\w\+\s\+\w\+\)\s*\[[0-9]*\]\(.*\)/rrepeated \1\2/g' \
-e 's/^\s*\(\w\+\s\+\w\+\s*=.*\)\<\(vector\|array\)(\w*)\s*,*\(.*\)/rrepeated \1\3/g' \
-e 's/^\s*\(\w\+\s\+\w\+\s*=.*\)\<map(\w*)\s*,*\(.*\)/map \1\2/g' \
-e 's/^\s*map\s\+\(\w\+\s\+\w\+\s*=.*\)\<optional()\s*,*\(.*\)/map \1\2/g' \
-e 's/^\s*\(\w\+\s\+\w\+\s*=.*\)\<optional()\s*,*\(.*\)/optional \1\2/g' \
-e 's/^\s*rrepeated\s\+\(\w\+\s\+\w\+\s*=.*\)\<optional()\s*,*\(.*\)/repeated \1\2/g' \
-e 's/^\s*\(\(optional\|repeated\|rrepeated\|map\)\s\+\w\+\s\+\w\+\)\s*=/\1 /g' \
-e 's/^\s*\(\(optional\|repeated\|rrepeated\|map\)\s\+\w\+\s\+\w\+\)\s*;/\1 ;/g' \
-e 's/^\s*\(\w\+\s\+\w\+\)\s*;/required \1 ;/g' \
-e 's/^\s*\(\w\+\s\+\w\+\)\s*=\(.*\)/required \1 \2/g' \
-e 's/\[default=\(0\|""\)\]//g' \
-e 's/^\(\s*\)\w\+\s\+\(\w\+\)\s*(\s*\(\w\+\)\s\+\w\+\s*,\s*out\s\+\(\w\+\)\s\+\w\+\s*)\s*;/\1rpc \2(\3) returns (\4);/g' \
-e 's/^\s*#include *\"\([^.]*\.\)idl *\"/import \"\1proto\";/g' | \
awk 'BEGIN{\
typemap["uint64_t"] = "uint64";\
typemap["int64_t"] = "int64";\
typemap["int32_t"] = "int32";\
typemap["uint32_t"] = "uint32";\
typemap["int16_t"] = "int32";\
typemap["uint16_t"] = "uint32";\
typemap["int8_t"] = "int32";\
typemap["uint8_t"] = "uint32";\
typemap["binary"] = "bytes";\
idlopt["int8_t"] = "[(idl_type)=IDL_INT8]";\
idlopt["uint8_t"] = "[(idl_type)=IDL_UINT8]";\
idlopt["int16_t"] = "[(idl_type)=IDL_INT16]";\
idlopt["uint16_t"] = "[(idl_type)=IDL_UINT16]";\
primitives["int8_t"] = 1; \
primitives["int16_t"] = 1; \
primitives["int32_t"] = 1; \
primitives["int64_t"] = 1; \
primitives["uint8_t"] = 1; \
primitives["uint16_t"] = 1; \
primitives["uint32_t"] = 1; \
primitives["uint64_t"] = 1; \
primitives["bool"] = 1; \
primitives["float"] = 1; \
primitives["double"] = 1; \
print "// Converted from '$1' by public/mcpack2pb/idl2proto\n" \
"syntax=\"proto2\";\n" \
"import \"idl_options.proto\";\n" \
"option (idl_support) = true;\n\n" \
"option cc_generic_services = true;\n" \
"'"$package_statement"'" \
}{\
if ($1 == "message") {\
count = 0;\
message_name = $2; \
print $0;\
} else if ($1 == "required" || $1 == "optional" || \
$1 == "repeated" || $1 == "rrepeated" || \
$1 == "map") { \
if ($1 == "rrepeated") { $1 = "repeated"; $4 = "[(idl_on)=1]"$4 } \
if ($1 == "repeated" && ($2 in primitives)) { $4 = "[packed=true]"$4 } \
if ($2 in idlopt) { $4 = idlopt[$2]$4 } \
if ($2 in typemap) { $2 = typemap[$2] } \
if ($1 == "map") { \
if ("'"$FLAGS_pb3"'" == "0") { \
$1 = "map<string,";\
$2 = $2">";\
} else {\
$1 = "repeated"; \
if (!($2 in need_map)) {\
need_map[$2] = message_name; \
} \
$2 = need_map[$2] "MapEntry_string_" $2; \
}\
} \
$3 = $3" = "++count;\
if ($5 ~ /^\/\// || $5 ~ /^\/\*/) {\
len_before = length($1) + length($2) + length($3) + length($4) + 3;\
spaces = "";\
for (; len_before < 50; ++len_before) {\
spaces = spaces" ";\
}\
$5 = spaces $5;\
}\
print " "$0;\
} else { print $0 }\
} END{\
for (value in need_map) { \
print "\nmessage " need_map[value] "MapEntry_string_" value " {\n" \
" required string key = 1;\n" \
" optional " value " value = 2;\n" \
"}"; \
}\
}' | \
sed -e 's/ ;/; /g' -e 's/};/}/g' -e 's/\]\[/, /g'