summaryrefslogtreecommitdiffhomepage
path: root/tools/pyang_plugins/bgpyang2golang.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/pyang_plugins/bgpyang2golang.py')
-rw-r--r--tools/pyang_plugins/bgpyang2golang.py126
1 files changed, 84 insertions, 42 deletions
diff --git a/tools/pyang_plugins/bgpyang2golang.py b/tools/pyang_plugins/bgpyang2golang.py
index 03b274c1..c61d9c85 100644
--- a/tools/pyang_plugins/bgpyang2golang.py
+++ b/tools/pyang_plugins/bgpyang2golang.py
@@ -15,6 +15,7 @@
import StringIO
+import sys
from pyang import plugin
_COPYRIGHT_NOTICE = """
@@ -34,7 +35,7 @@ _COPYRIGHT_NOTICE = """
// limitations under the License.
"""
-emitted_type_names = []
+emitted_type_names = {}
def pyang_plugin_init():
@@ -46,61 +47,79 @@ class GolangPlugin(plugin.PyangPlugin):
fmts['golang'] = self
def emit(self, ctx, modules, fd):
- emit_golang(ctx, modules[0], fd)
+ ctx.golang_identity_map = {}
+ ctx.golang_typedef_map = {}
+ ctx.golang_struct_def = []
+ ctx.golang_struct_names = {}
-def emit_golang(ctx, module, fd):
+ ctx.prefix_rel = {}
+ ctx.module_deps = []
- ctx.golang_identity_map = {}
- ctx.golang_typedef_map = {}
- ctx.golang_struct_def = []
- ctx.golang_struct_names = {}
+ check_module_deps(ctx, modules[0])
+ # visit yang statements
+ visit_modules(ctx)
+ # emit bgp_configs
+ emit_go(ctx)
- # visit typedef
- visit_typedef(ctx, module)
- visit_typedef(ctx, ctx.get_module('routing-policy'))
- visit_typedef(ctx, ctx.get_module('bgp-multiprotocol'))
- visit_typedef(ctx, ctx.get_module('bgp-operational'))
- # visit identity
- visit_identity(ctx, ctx.get_module('routing-policy'))
- visit_identity(ctx, ctx.get_module('bgp-multiprotocol'))
- visit_identity(ctx, ctx.get_module('bgp-operational'))
- visit_children(ctx, module, module.i_children)
+def visit_modules(ctx):
+
+ # visit typedef and identity
+ for module in ctx.module_deps:
+ visit_typedef(ctx, module)
+ visit_identity(ctx, module)
+
+ # visit container
+ for module in ctx.module_deps:
+ visit_children(ctx, module, module.i_children)
+
+
+def emit_go(ctx):
+
ctx.golang_struct_def.reverse()
done = set()
# emit
generate_header(ctx)
- emit_typedef(ctx, module)
- emit_typedef(ctx, ctx.get_module('routing-policy'))
- emit_typedef(ctx, ctx.get_module('bgp-multiprotocol'))
- emit_typedef(ctx, ctx.get_module('bgp-operational'))
+ for mod in ctx.module_deps:
+ if mod not in _module_excluded:
+ emit_typedef(ctx, mod)
for struct in ctx.golang_struct_def:
struct_name = struct.arg
if struct_name in done:
continue
- emit_class_def(ctx, struct, struct_name)
+ emit_class_def(ctx, struct, struct_name, struct.module_prefix)
done.add(struct_name)
-def emit_class_def(ctx, c, struct_name):
+def check_module_deps(ctx, module):
- o = StringIO.StringIO()
- struct_name_org = struct_name
- struct_name = convert_to_golang(struct_name)
+ own_prefix = module.i_prefix
+ for k, v in module.i_prefixes.items():
+ mod = ctx.get_module(v[0])
+ if mod.i_prefix != own_prefix:
+ check_module_deps(ctx, mod)
- print >> o, '//struct for container %s' % struct_name_org
- print >> o, 'type %s struct {' % struct_name
- for child in c.i_children:
+ ctx.prefix_rel[mod.i_prefix] = k
+ if mod not in ctx.module_deps \
+ and mod.i_modulename not in _module_excluded:
+ ctx.module_deps.append(mod)
- val_name = child.arg
- val_name_go = convert_to_golang(child.arg)
- module_name = child.i_orig_module.i_prefix
- print >> o, ' // original -> %s:%s' % (module_name, val_name)
+def emit_class_def(ctx, yang_statement, struct_name, prefix):
+
+ o = StringIO.StringIO()
+ print >> o, '//struct for container %s:%s' % (prefix, struct_name)
+ print >> o, 'type %s struct {' % convert_to_golang(struct_name)
+ for child in yang_statement.i_children:
+ container_or_list_name = child.arg
+ val_name_go = convert_to_golang(child.arg)
+ child_prefix = get_orig_prefix(child.i_orig_module)
+ print >> o, ' // original -> %s:%s' % \
+ (child_prefix, container_or_list_name)
# case leaf
if is_leaf(child):
@@ -118,8 +137,8 @@ def emit_class_def(ctx, c, struct_name):
# case translation required
elif is_translation_required(type_obj):
- print >> o, ' //%s\'s original type is %s'\
- % (val_name, type_obj.arg)
+ print >> o, ' //%s:%s\'s original type is %s'\
+ % (child_prefix, container_or_list_name, type_name)
emit_type_name = translate_type(type_name)
# case other primitives
@@ -159,12 +178,14 @@ def emit_class_def(ctx, c, struct_name):
# case container
elif is_container(child):
- t = ctx.golang_struct_names[val_name]
+ key = child_prefix+':'+container_or_list_name
+ t = ctx.golang_struct_names[key]
emit_type_name = t.golang_name
# case list
elif is_list(child):
- t = ctx.golang_struct_names[val_name]
+ key = child_prefix+':'+container_or_list_name
+ t = ctx.golang_struct_names[key]
val_name_go = val_name_go + 'List'
emit_type_name = '[]' + t.golang_name
@@ -177,16 +198,27 @@ def emit_class_def(ctx, c, struct_name):
print o.getvalue()
-def visit_children(ctx, module, children, prefix=''):
+def get_orig_prefix(module):
+ orig = module.i_orig_module
+ if orig:
+ get_orig_prefix(orig)
+ else:
+ return module.i_prefix
+
+
+def visit_children(ctx, module, children):
for c in children:
+ prefix = get_orig_prefix(c.i_orig_module)
t = c.search_one('type')
type_name = t.arg if t is not None else None
if is_list(c) or is_container(c):
c.golang_name = convert_to_golang(c.arg)
ctx.golang_struct_def.append(c)
- ctx.golang_struct_names[c.arg] = c
+ c.module_prefix = prefix
+ ctx.golang_struct_names[prefix+':'+c.arg] = c
+
if hasattr(c, 'i_children'):
- visit_children(ctx, module, c.i_children, prefix + ' ')
+ visit_children(ctx, module, c.i_children)
def visit_typedef(ctx, module):
@@ -200,6 +232,8 @@ def visit_typedef(ctx, module):
stmts.golang_name = 'PeerTypeDef'
child_map[name] = stmts
ctx.golang_typedef_map[prefix] = child_map
+ if ctx.prefix_rel[prefix] != prefix:
+ ctx.golang_typedef_map[ctx.prefix_rel[prefix]] = child_map
def visit_identity(ctx, module):
@@ -243,9 +277,13 @@ def emit_typedef(ctx, module):
type_name_org = name
type_name = stmt.golang_name
if type_name in emitted_type_names:
+ warn = "warning %s: %s has already been emitted from %s.\n"\
+ % (prefix+":"+type_name_org, type_name_org,
+ emitted_type_names[type_name])
+ sys.stderr.write(warn)
continue
- emitted_type_names.append(type_name)
+ emitted_type_names[type_name] = prefix+":"+type_name_org
t = stmt.search_one('type')
o = StringIO.StringIO()
@@ -341,7 +379,6 @@ _type_translation_map = {
'inet:ip-address': 'net.IP',
'inet:ipv4-address': 'net.IP',
'inet:as-number': 'uint32',
- 'rr-cluster-id-type': 'uint32',
}
@@ -358,6 +395,11 @@ _type_builtin = ["union",
]
+_module_excluded = ["ietf-inet-types",
+ "ietf-yang-types",
+ ]
+
+
def generate_header(ctx):
print _COPYRIGHT_NOTICE
print 'package config'