CORD-1320: Implement pure protobuf support for policies
Change-Id: Ifaeba28d1aea46cb9f9f674d75c6c65cf104435f
diff --git a/lib/xos-genx/Makefile b/lib/xos-genx/Makefile
index 70ae716..898f154 100644
--- a/lib/xos-genx/Makefile
+++ b/lib/xos-genx/Makefile
@@ -1,2 +1,3 @@
test:
- nosetests -s -v --with-id
\ No newline at end of file
+ nosetests -s -v --with-id
+
diff --git a/lib/xos-genx/tests/pure_proto_test.py b/lib/xos-genx/tests/pure_proto_test.py
index 836b0b0..1f165fb 100644
--- a/lib/xos-genx/tests/pure_proto_test.py
+++ b/lib/xos-genx/tests/pure_proto_test.py
@@ -83,6 +83,34 @@
self.assertEqual(count1, count2)
+ def test_pure_policies(self):
+ xproto = \
+"""
+policy my_policy < exists x:a=b >
+"""
+
+ proto = \
+"""
+option my_policy = "policy:< exists x:a=b >";
+"""
+ target = XProtoTestHelpers.write_tmp_target(
+"""
+{{ policies }}
+""")
+
+ args_xproto = FakeArgs()
+ args_xproto.inputs = xproto
+ args_xproto.target = target
+ xproto_gen = XOSGenerator.generate(args_xproto)
+
+ args_proto = FakeArgs()
+ args_proto.inputs = proto
+ args_proto.target = target
+ args_proto.rev = True
+ proto_gen = XOSGenerator.generate(args_proto)
+
+ self.assertEqual(proto_gen, xproto_gen)
+
if __name__ == '__main__':
unittest.main()
diff --git a/lib/xos-genx/xosgenx/proto2xproto.py b/lib/xos-genx/xosgenx/proto2xproto.py
index 3723e7c..ffdb5d1 100644
--- a/lib/xos-genx/xosgenx/proto2xproto.py
+++ b/lib/xos-genx/xosgenx/proto2xproto.py
@@ -3,10 +3,13 @@
import pdb
import argparse
import plyxproto.parser as plyxproto
+from plyxproto.logicparser import FOLParser, FOLLexer
import traceback
import sys
import jinja2
import os
+import ply.lex as lex
+import ply.yacc as yacc
class Stack(list):
def push(self,x):
@@ -23,6 +26,7 @@
return {'name': name, 'package': package, 'fqn': s}
+
def replace_link(obj):
try:
link = obj.link
@@ -49,6 +53,9 @@
return obj
class Proto2XProto(Visitor):
+ fol_lexer = lex.lex(module=FOLLexer())
+ fol_parser = yacc.yacc(module=FOLParser(), start='goal')
+
def __init__(self):
super(Proto2XProto, self).__init__()
@@ -67,6 +74,20 @@
self.first_field = True
self.first_method = True
+ def replace_policy(self, obj):
+ if isinstance(obj, m.OptionStatement):
+ rhs = obj.value.value.pval
+ if rhs.startswith('"') and rhs.endswith('"'):
+ rhs = rhs[1:-1]
+
+ if rhs.startswith('policy:'):
+ str = rhs.split(':')[1]
+ val = self.fol_parser.parse(str, lexer = self.fol_lexer)
+
+ return m.PolicyDefinition(obj.name, val)
+
+ return obj
+
def proto_to_xproto_field(self, obj):
try:
opts = {}
@@ -83,7 +104,11 @@
def proto_to_xproto_message(self, obj):
try:
- bases = self.message_options['bases'].split(',')
+ try:
+ bases = self.message_options['bases'].split(',')
+ except KeyError:
+ bases = []
+
bases = map(lambda x:str_to_dict(x[1:-1]), bases)
obj.bases = bases
except KeyError:
@@ -191,6 +216,8 @@
return True
def visit_Proto_post(self, obj):
+
+ obj.body = [self.replace_policy(o) for o in obj.body]
return True
def visit_LinkSpec(self, obj):