#!/bin/bash -f # mcpack2pb - Make protobuf be front-end of mcpack/compack # Copyright (c) 2015 Baidu.com, Inc. All Rights Reserved # 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 brpc/tools/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'