blob: ffdb5d1e8d03fdb38cd9ee5723d3562ba9d37465 [file] [log] [blame]
Sapan Bhatia3cfdf632017-06-08 05:14:03 +02001import plyxproto.model as m
Sapan Bhatiadb183c22017-06-23 02:47:42 -07002from plyxproto.helpers import Visitor
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -07003import pdb
4import argparse
Sapan Bhatia3cfdf632017-06-08 05:14:03 +02005import plyxproto.parser as plyxproto
Sapan Bhatiaea6ff752017-07-14 01:52:18 -04006from plyxproto.logicparser import FOLParser, FOLLexer
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -07007import traceback
8import sys
9import jinja2
10import os
Sapan Bhatiaea6ff752017-07-14 01:52:18 -040011import ply.lex as lex
12import ply.yacc as yacc
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -070013
14class Stack(list):
15 def push(self,x):
16 self.append(x)
17
Sapan Bhatia3cfdf632017-06-08 05:14:03 +020018def str_to_dict(s):
19 lst = s.rsplit('.',1)
20 name = lst[-1]
21
22 if len(lst)==2:
23 package = lst[0]
24 else:
25 package = ''
26
27 return {'name': name, 'package': package, 'fqn': s}
28
Sapan Bhatiaea6ff752017-07-14 01:52:18 -040029
Sapan Bhatiaae9645c2017-05-05 15:35:54 +020030def replace_link(obj):
31 try:
32 link = obj.link
33 try:
34 through = link['through']
35 except KeyError:
36 through = None
37
38 try:
39 through_str = through[1:-1]
40 except TypeError:
41 through_str = None
42
Sapan Bhatia3cfdf632017-06-08 05:14:03 +020043 if through_str:
44 through_dict = str_to_dict(through_str)
45 else:
46 through_dict = {}
47
48 model_dict = str_to_dict(link['model'][1:-1])
49
50 ls = m.LinkSpec(obj, m.LinkDefinition(link['link'][1:-1],obj.name,model_dict,link['port'][1:-1],through_dict))
Sapan Bhatiaae9645c2017-05-05 15:35:54 +020051 return ls
52 except:
53 return obj
54
Sapan Bhatiadb183c22017-06-23 02:47:42 -070055class Proto2XProto(Visitor):
Sapan Bhatiaea6ff752017-07-14 01:52:18 -040056 fol_lexer = lex.lex(module=FOLLexer())
57 fol_parser = yacc.yacc(module=FOLParser(), start='goal')
58
Matteo Scandolo67654fa2017-06-09 09:33:17 -070059 def __init__(self):
60 super(Proto2XProto, self).__init__()
61
62 self.stack = Stack()
63 self.count_stack = Stack()
64 self.content=""
65 self.offset=0
66 self.statementsChanged=0
67 self.message_options = {}
68 self.options = {}
69 self.current_message_name = None
70
71 self.xproto_message_options = ['bases']
72 self.xproto_field_options = ['model']
73 self.verbose = 0
74 self.first_field = True
75 self.first_method = True
Sapan Bhatiaae9645c2017-05-05 15:35:54 +020076
Sapan Bhatiaea6ff752017-07-14 01:52:18 -040077 def replace_policy(self, obj):
78 if isinstance(obj, m.OptionStatement):
79 rhs = obj.value.value.pval
80 if rhs.startswith('"') and rhs.endswith('"'):
81 rhs = rhs[1:-1]
82
83 if rhs.startswith('policy:'):
84 str = rhs.split(':')[1]
85 val = self.fol_parser.parse(str, lexer = self.fol_lexer)
86
87 return m.PolicyDefinition(obj.name, val)
88
89 return obj
90
Sapan Bhatiaae9645c2017-05-05 15:35:54 +020091 def proto_to_xproto_field(self, obj):
92 try:
93 opts = {}
94 for fd in obj.fieldDirective:
95 k = fd.pval.name.value.pval
96 v = fd.pval.value.value.pval
97 opts[k]=v
98
99 if ('model' in opts and 'link' in opts and 'port' in opts):
100 obj.link = opts
101 pass
102 except KeyError:
103 raise
104
105 def proto_to_xproto_message(self, obj):
106 try:
Sapan Bhatiaea6ff752017-07-14 01:52:18 -0400107 try:
108 bases = self.message_options['bases'].split(',')
109 except KeyError:
110 bases = []
111
Sapan Bhatia3cfdf632017-06-08 05:14:03 +0200112 bases = map(lambda x:str_to_dict(x[1:-1]), bases)
Sapan Bhatiaae9645c2017-05-05 15:35:54 +0200113 obj.bases = bases
114 except KeyError:
115 raise
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700116
117 def map_field(self, obj, s):
118 if 'model' in s:
119 link = m.LinkDefinition('onetoone','src','name','dst', obj.linespan, obj.lexspan, obj.p)
120 lspec = m.LinkSpec(link, obj)
121 else:
122 lspec = obj
123 return lspec
124
125
126 def get_stack(self):
Matteo Scandolo67654fa2017-06-09 09:33:17 -0700127 return self.stack
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700128
129 def visit_PackageStatement(self, obj):
130 '''Ignore'''
131 return True
132
133 def visit_ImportStatement(self, obj):
134 '''Ignore'''
135 return True
136
137 def visit_OptionStatement(self, obj):
Sapan Bhatiaae9645c2017-05-05 15:35:54 +0200138 if (self.current_message_name):
139 k = obj.name.value.pval
140 self.message_options[k] = obj.value.value.pval
141 if (k in self.xproto_message_options):
142 obj.mark_for_deletion = True
143 else:
144 self.options[obj.name.value.pval] = obj.value.value.pval
145
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700146 return True
147
148 def visit_LU(self, obj):
149 return True
150
151 def visit_default(self, obj):
152 return True
153
154 def visit_FieldDirective(self, obj):
155 return True
156
157 def visit_FieldDirective_post(self, obj):
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700158 return True
159
160 def visit_FieldType(self, obj):
161 return True
162
163 def visit_LinkDefinition(self, obj):
164 return True
165
166 def visit_FieldDefinition(self, obj):
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700167 return True
168
169 def visit_FieldDefinition_post(self, obj):
Sapan Bhatiaae9645c2017-05-05 15:35:54 +0200170 self.proto_to_xproto_field(obj)
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700171 return True
172
173 def visit_EnumFieldDefinition(self, obj):
174 return True
175
176 def visit_EnumDefinition(self, obj):
177 return True
178
179 def visit_MessageDefinition(self, obj):
Sapan Bhatiaae9645c2017-05-05 15:35:54 +0200180 self.current_message_name = obj.name.value.pval
181 self.message_options = {}
182
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700183 return True
184
185 def visit_MessageDefinition_post(self, obj):
Sapan Bhatiaae9645c2017-05-05 15:35:54 +0200186 self.proto_to_xproto_message(obj)
187 obj.body = filter(lambda x:not hasattr(x, 'mark_for_deletion'), obj.body)
188 obj.body = map(replace_link, obj.body)
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700189
Sapan Bhatiaae9645c2017-05-05 15:35:54 +0200190 self.current_message_name = None
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700191 return True
192
193 def visit_MessageExtension(self, obj):
194 return True
195
196 def visit_MethodDefinition(self, obj):
197 return True
198
199 def visit_ServiceDefinition(self, obj):
200 return True
201
202 def visit_ExtensionsDirective(self, obj):
203 return True
204
205 def visit_Literal(self, obj):
206 return True
207
208 def visit_Name(self, obj):
209 return True
210
211 def visit_DotName(self, obj):
212 return True
213
214 def visit_Proto(self, obj):
215 self.count_stack.push(len(obj.body))
216 return True
217
218 def visit_Proto_post(self, obj):
Sapan Bhatiaea6ff752017-07-14 01:52:18 -0400219
220 obj.body = [self.replace_policy(o) for o in obj.body]
Sapan Bhatiaff1b8fa2017-04-10 19:44:38 -0700221 return True
222
223 def visit_LinkSpec(self, obj):
224 return False