summaryrefslogtreecommitdiffhomepage
path: root/tools/pyang_plugins/bgpyang2golang.py
diff options
context:
space:
mode:
authorHiroshi Yokoi <yokoi.hiroshi@po.ntts.co.jp>2015-07-15 19:53:53 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-07-31 16:26:17 +0900
commit0b4b806c06f0ee50bb1bc1b30c38399553687abd (patch)
tree6898ec9eeb21a26668012c1c7743772da7b72214 /tools/pyang_plugins/bgpyang2golang.py
parent2ad42ead02cce21cf71b3dde0731e8f5c6d4ac6a (diff)
config: use the latest openconfig yang
Diffstat (limited to 'tools/pyang_plugins/bgpyang2golang.py')
-rw-r--r--tools/pyang_plugins/bgpyang2golang.py147
1 files changed, 124 insertions, 23 deletions
diff --git a/tools/pyang_plugins/bgpyang2golang.py b/tools/pyang_plugins/bgpyang2golang.py
index c5912bda..9fe8a8ee 100644
--- a/tools/pyang_plugins/bgpyang2golang.py
+++ b/tools/pyang_plugins/bgpyang2golang.py
@@ -75,14 +75,15 @@ class GolangPlugin(plugin.PyangPlugin):
# load augment module
if ctx.opts.augment:
aug_mod_path = ctx.opts.augment
- try:
- fd = open(aug_mod_path)
- text = fd.read()
- except IOError as ex:
- sys.stderr.write("error %s: %s\n" % (aug_mod_path, str(ex)))
- sys.exit(1)
- aug_mod = ctx.add_module(aug_mod_path, text)
- check_module_deps(ctx, aug_mod)
+ for p in aug_mod_path.split(","):
+ with open(p) as fd:
+ try:
+ text = fd.read()
+ except IOError as ex:
+ sys.stderr.write("error %s: %s\n" % (aug_mod_path, str(ex)))
+ sys.exit(1)
+ aug_mod = ctx.add_module(p, text)
+ check_module_deps(ctx, aug_mod)
# visit yang statements
visit_modules(ctx)
@@ -115,7 +116,7 @@ def emit_go(ctx):
emit_typedef(ctx, mod)
for struct in ctx.golang_struct_def:
- struct_name = struct.arg
+ struct_name = struct.uniq_name
if struct_name in done:
continue
emit_class_def(ctx, struct, struct_name, struct.module_prefix)
@@ -136,13 +137,21 @@ def check_module_deps(ctx, module):
ctx.module_deps.append(mod)
+def dig_leafref(type_obj):
+ reftype = type_obj.i_type_spec.i_target_node.search_one('type')
+ if is_leafref(reftype):
+ return dig_leafref(reftype)
+ else:
+ return reftype
+
+
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, '//struct for container %s:%s' % (prefix, yang_statement.arg)
print >> o, 'type %s struct {' % convert_to_golang(struct_name)
for child in yang_statement.i_children:
- container_or_list_name = child.arg
+ container_or_list_name = child.uniq_name
val_name_go = convert_to_golang(child.arg)
child_prefix = get_orig_prefix(child.i_orig_module)
print >> o, ' // original -> %s:%s' % \
@@ -153,14 +162,21 @@ def emit_class_def(ctx, yang_statement, struct_name, prefix):
type_obj = child.search_one('type')
type_name = type_obj.arg
+
# case identityref
if type_name == 'identityref':
emit_type_name = 'string'
# case leafref
elif type_name == 'leafref':
- t = type_obj.i_type_spec.i_target_node.search_one('type')
- emit_type_name = t.arg
+ t = dig_leafref(type_obj)
+ if is_translation_required(t):
+ print >> o, ' //%s:%s\'s original type is %s' \
+ % (child_prefix, container_or_list_name, t.arg)
+ emit_type_name = translate_type(t.arg)
+ else:
+ emit_type_name = t.arg
+
# case translation required
elif is_translation_required(type_obj):
@@ -176,8 +192,13 @@ def emit_class_def(ctx, yang_statement, struct_name, prefix):
else:
base_module = type_obj.i_orig_module.i_prefix
t = lookup_typedef(ctx, base_module, type_name)
+ # print(t)
emit_type_name = t.golang_name
+ # case 'case'
+ if is_case(child):
+ continue
+
# case leaflist
if is_leaflist(child):
type_obj = child.search_one('type')
@@ -204,7 +225,7 @@ def emit_class_def(ctx, yang_statement, struct_name, prefix):
emit_type_name = '[]'+t.golang_name
# case container
- elif is_container(child):
+ elif is_container(child) or is_choice(child):
key = child_prefix+':'+container_or_list_name
t = ctx.golang_struct_names[key]
emit_type_name = t.golang_name
@@ -235,19 +256,70 @@ def get_orig_prefix(module):
def visit_children(ctx, module, children):
for c in children:
- prefix = get_orig_prefix(c.i_orig_module)
+
+ prefix = ''
+ if is_case(c):
+ prefix = get_orig_prefix(c.parent.i_orig_module)
+ c.i_orig_module = c.parent.i_orig_module
+ else:
+ prefix = get_orig_prefix(c.i_orig_module)
+
+ c.uniq_name = c.arg
+ if c.arg == 'config':
+ c.uniq_name = c.parent.uniq_name + '-config'
+
+ if c.arg == 'state':
+
+ c.uniq_name = c.parent.uniq_name + '-state'
+
+ if c.arg == 'graceful-restart' and prefix == 'bgp-mp':
+ c.uniq_name = 'mp-graceful-restart'
+
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)
- c.module_prefix = prefix
- ctx.golang_struct_names[prefix+':'+c.arg] = c
+
+ if is_list(c) or is_container(c) or is_choice(c):
+ c.golang_name = convert_to_golang(c.uniq_name)
+
+ if is_choice(c):
+ picks = pickup_choice(c)
+ c.i_children = picks
+
+ if ctx.golang_struct_names.get(prefix+':'+c.uniq_name):
+ ext_c = ctx.golang_struct_names.get(prefix+':'+c.uniq_name)
+ ext_c_child_count = len(getattr(ext_c, "i_children"))
+ current_c_child_count = len(getattr(c, "i_children"))
+ if ext_c_child_count < current_c_child_count:
+ c.module_prefix = prefix
+ ctx.golang_struct_names[prefix+':'+c.uniq_name] = c
+ idx = ctx.golang_struct_def.index(ext_c)
+ ctx.golang_struct_def[idx] = c
+ else:
+ c.module_prefix = prefix
+ ctx.golang_struct_names[prefix+':'+c.uniq_name] = c
+ ctx.golang_struct_def.append(c)
if hasattr(c, 'i_children'):
visit_children(ctx, module, c.i_children)
+def pickup_choice(c):
+ element = []
+ for child in c.i_children:
+ if is_case(child):
+ element = element + child.i_children
+
+ return element
+
+
+def get_type_spec(stmt):
+ for s in stmt.substmts:
+ if hasattr(s, 'i_type_spec'):
+ type_sp = s.i_type_spec
+ return type_sp.name
+
+ return None
+
+
def visit_typedef(ctx, module):
prefix = module.i_prefix
child_map = {}
@@ -258,6 +330,7 @@ def visit_typedef(ctx, module):
if stmts.golang_name == 'PeerType':
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
@@ -301,6 +374,11 @@ def emit_typedef(ctx, module):
prefix = module.i_prefix
t_map = ctx.golang_typedef_map[prefix]
for name, stmt in t_map.items():
+
+ # skip identityref type because currently skip identity
+ if get_type_spec(stmt) == 'identityref':
+ continue
+
type_name_org = name
type_name = stmt.golang_name
if type_name in emitted_type_names:
@@ -324,6 +402,7 @@ def emit_typedef(ctx, module):
print >> o, 'const ('
already_added_iota = False
+ already_added_type = False
for sub in t.substmts:
if sub.search_one('value'):
enum_value = " = "+sub.search_one('value').arg
@@ -333,8 +412,14 @@ def emit_typedef(ctx, module):
else:
enum_value = " = iota"
already_added_iota = True
+
+
enum_name = convert_const_prefix(sub.arg)
- print >> o, ' %s_%s%s' % (const_prefix, enum_name, enum_value)
+
+ t = type_name if not already_added_type else ""
+ already_added_type = True
+
+ print >> o, ' %s_%s %s%s' % (const_prefix, enum_name, t, enum_value)
print >> o, ')'
elif t.arg == 'union':
print >> o, '// typedef for typedef %s:%s'\
@@ -373,6 +458,10 @@ def is_reference(s):
return s.arg in ['leafref', 'identityref']
+def is_leafref(s):
+ return s.arg in ['leafref']
+
+
def is_leaf(s):
return s.keyword in ['leaf']
@@ -389,6 +478,14 @@ def is_container(s):
return s.keyword in ['container']
+def is_case(s):
+ return s.keyword in ['case']
+
+
+def is_choice(s):
+ return s.keyword in ['choice']
+
+
def is_builtin_type(t):
return t.arg in _type_builtin
@@ -399,14 +496,18 @@ def is_translation_required(t):
_type_translation_map = {
'union': 'string',
- 'enumeration': 'string',
+ 'enumeration': 'uint32',
'decimal64': 'float64',
'boolean': 'bool',
'empty': 'bool',
'inet:ip-address': 'net.IP',
+ 'inet:ip-prefix': 'net.IPNet',
'inet:ipv4-address': 'net.IP',
'inet:as-number': 'uint32',
'bgp-set-community-option-type' : 'string',
+ 'identityref' : 'string',
+ 'inet:port-number': 'uint16',
+ 'yang:timeticks': 'int64',
}