update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b third try
[osm/UI.git] / skyquake / plugins / composer / src / schemas / yang / confd2model.js
1 //: /*
2 //: *
3 //: * Copyright 2016 RIFT.IO Inc
4 //: *
5 //: * Licensed under the Apache License, Version 2.0 (the "License");
6 //: * you may not use this file except in compliance with the License.
7 //: * You may obtain a copy of the License at
8 //: *
9 //: * http://www.apache.org/licenses/LICENSE-2.0
10 //: *
11 //: * Unless required by applicable law or agreed to in writing, software
12 //: * distributed under the License is distributed on an "AS IS" BASIS,
13 //: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 //: * See the License for the specific language governing permissions and
15 //: * limitations under the License.
16 //: *
17 //: */
18 //:
19 //: 'use strict';
20 //:
21 //: // the models to be transformed into the output DSL JSON meta file
22 //: var yang = [require('./json-nsd.json'), require('./json-vnfd.json')];
23 //:
24 //: var _ = require('lodash');
25 //: var inet = require('./ietf-inet-types.yang.json');
26 //:
27 //: var utils = {
28 //: resolvePath(obj, path) {
29 //: // supports a.b, a[1] and foo[bar], etc.
30 //: // where obj is ['nope', 'yes', {a: {b: 1}, foo: 2}]
31 //: // then [1] returns 'yes'; [2].a.b returns 1; [2].a[foo] returns 2;
32 //: path = path.split(/[\.\[\]]/).filter(d => d);
33 //: return path.reduce((r, p) => {
34 //: if (r) {
35 //: return r[p];
36 //: }
37 //: }, obj);
38 //: },
39 //: assignPathValue(obj, path, value) {
40 //: path = path.split(/[\.\[\]]/).filter(d => d);
41 //: // enable look-ahead to determine if type is array or object
42 //: const pathCopy = path.slice();
43 //: // last item in path used to assign value on the resolved object
44 //: const name = path.pop();
45 //: const resolvedObj = path.reduce((r, p, i) => {
46 //: if (typeof(r[p]) !== 'object') {
47 //: // look-ahead to see if next path item is a number
48 //: const isArray = !isNaN(parseInt(pathCopy[i + 1], 10));
49 //: r[p] = isArray ? [] : {}
50 //: }
51 //: return r[p];
52 //: }, obj);
53 //: resolvedObj[name] = value;
54 //: }
55 //: };
56 //:
57 //: var isType = d => /^(leaf|leaf-list|list|container|choice|case|uses)$/.test(d);
58 //:
59 //: function deriveCardinalityFromProperty(property, typeName) {
60 //: if (String(property.mandatory) === 'true') {
61 //: return '1';
62 //: }
63 //: let min = 0, max = Infinity;
64 //: if (property.hasOwnProperty('min-elements')) {
65 //: min = parseInt(property['min-elements'], 10) || 0;
66 //: }
67 //: if (property.hasOwnProperty('max-elements')) {
68 //: max = parseInt(property['max-elements'], 10) || Infinity;
69 //: } else {
70 //: if (!/^(list|leaf-list)$/.test(typeName)) {
71 //: max = '1';
72 //: }
73 //: }
74 //: if (min > max) {
75 //: return String(min);
76 //: }
77 //: if (min === max) {
78 //: return String(min);
79 //: }
80 //: return String(min) + '..' + (max === Infinity ? 'N' : max);
81 //: }
82 //:
83 //: function cleanWhitespace(text) {
84 //: if (typeof text === 'string') {
85 //: return text.replace(/\s+/g, ' ');
86 //: }
87 //: return text;
88 //: }
89 //:
90 //: function buildProperties(typeData, typeName) {
91 //: var properties = [];
92 //: Object.keys(typeData).forEach(name => {
93 //: var property = typeData[name];
94 //: var listKey = typeName === 'list' ? String(property.key).split(/\s/).filter(k => k && k !== 'undefined') : false;
95 //: var meta = {
96 //: name: name,
97 //: type: typeName,
98 //: description: cleanWhitespace(property.description),
99 //: cardinality: deriveCardinalityFromProperty(property, typeName),
100 //: 'data-type': property.type,
101 //: properties: Object.keys(property).filter(isType).reduce((r, childType) => {
102 //: return r.concat(buildProperties(property[childType], childType));
103 //: }, [])
104 //: };
105 //: if (listKey) {
106 //: meta.key = listKey;
107 //: }
108 //: properties.push(meta);
109 //: });
110 //: return properties;
111 //: }
112 //:
113 //: function lookupUses(uses, yang) {
114 //: function doLookup(lookupTypeName) {
115 //: var key;
116 //: // warn: hardcoded prefix support for mano-types - other prefixes will be ignored
117 //: if (/^manotypes:/.test(lookupTypeName)) {
118 //: var moduleName = lookupTypeName.split(':')[1];
119 //: key = ['dependencies.mano-types.module.mano-types.grouping', moduleName].join('.');
120 //: } else {
121 //: var name = yang.name.replace(/^rw-/, '');
122 //: key = ['dependencies', name, 'module', name, 'grouping', lookupTypeName].join('.');
123 //: }
124 //: return utils.resolvePath(yang, key);
125 //: }
126 //: if (typeof uses === 'object') {
127 //: return Object.keys(uses).reduce((result, key) => {
128 //: var found = doLookup(key);
129 //: Object.keys(found).filter(isType).forEach(type => {
130 //: var property = result[type] || (result[type] = {});
131 //: Object.assign(property, found[type]);
132 //: });
133 //: return result;
134 //: }, {});
135 //: } else if (typeof uses === 'string') {
136 //: return doLookup(uses);
137 //: }
138 //: return {};
139 //: }
140 //:
141 //: function lookupTypedef(property, yang) {
142 //: var key;
143 //: var lookupTypeName = property.type;
144 //: // warn: hardcoded prefix support - other prefixes will be ignored
145 //: if (/^manotypes:/.test(lookupTypeName)) {
146 //: var lookupName = lookupTypeName.split(':')[1];
147 //: key = ['dependencies.mano-types.module.mano-types.typedef', lookupName].join('.');
148 //: } else if (/^inet:/.test(lookupTypeName)) {
149 //: var lookupName = lookupTypeName.split(':')[1];
150 //: yang = inet;
151 //: key = ['schema.module.ietf-inet-types.typedef', lookupName].join('.');
152 //: }
153 //: if (key) {
154 //: return utils.resolvePath(yang, key);
155 //: }
156 //: }
157 //:
158 //: function resolveUses(property, yang) {
159 //: var childData = property.uses;
160 //: var resolved = lookupUses(childData, yang);
161 //: //console.log('uses', childData, 'found', resolved);
162 //: Object.keys(resolved).forEach(type => {
163 //: var parentTypes = property[type] || (property[type] = {});
164 //: // copy types into the parent types bucket
165 //: Object.assign(parentTypes, resolveReferences(yang, resolved[type]));
166 //: });
167 //: delete property.uses;
168 //: }
169 //:
170 //: function resolveTypedef(property, yang) {
171 //: if (/:/.test(property.type)) {
172 //: var found = lookupTypedef(property, yang);
173 //: if (found) {
174 //: Object.assign(property, found);
175 //: }
176 //: }
177 //: }
178 //:
179 //: function resolveReferences(yang, data) {
180 //: var dataClone = _.cloneDeep(data);
181 //: function doResolve(typeData) {
182 //: Object.keys(typeData).forEach(name => {
183 //: var property = typeData[name];
184 //: resolveTypedef(property, yang);
185 //: Object.keys(property).filter(isType).forEach(childType => {
186 //: if (childType === 'uses') {
187 //: resolveUses(property, yang);
188 //: } else {
189 //: doResolve(property[childType]);
190 //: }
191 //: });
192 //: });
193 //: }
194 //: doResolve(dataClone);
195 //: return dataClone;
196 //: }
197 //:
198 //: function module(yang) {
199 //: let module;
200 //: var name = yang.name.replace(/^rw-/, '');
201 //: if (!name) {
202 //: throw 'no name given in json yang';
203 //: }
204 //: const path = ['container', name + '-catalog'].join('.');
205 //: module = utils.resolvePath(yang, path);
206 //:
207 //: if (!module) {
208 //: module = utils.resolvePath(yang, ['schema', 'module', name, path].join('.'));
209 //: }
210 //: if (!module) {
211 //: module = utils.resolvePath(yang, ['dependencies', name, 'module', name, path].join('.'));
212 //: }
213 //: if (!module) {
214 //: throw 'cannot find the module' + name;
215 //: }
216 //:
217 //: // module/agument/nsd:nsd-catalog/nsd:nsd/meta
218 //: const augLeafPath = ['schema.module', 'rw-' + name, 'augment', '/' + name + ':' + name + '-catalog/' + name + ':' + name, 'leaf'];
219 //: const meta = utils.resolvePath(yang, augLeafPath.concat('meta').join('.'));
220 //:
221 //: const putLeafPath = ['dependencies', name, 'module', name, path, 'list', name, 'leaf'];
222 //:
223 //: if (meta) {
224 //: utils.assignPathValue(yang, putLeafPath.concat(['meta']).join('.'), meta);
225 //: }
226 //:
227 //: // module/agument/nsd:nsd-catalog/nsd:nsd/logo
228 //: const logo = utils.resolvePath(yang, augLeafPath.concat('logo').join('.'));
229 //: if (logo) {
230 //: utils.assignPathValue(yang, putLeafPath.concat(['logo']).join('.'), logo);
231 //: }
232 //: var data = module.list;
233 //:
234 //: return {name: name, data: resolveReferences(yang, data)};
235 //:
236 //: }
237 //:
238 //: function reduceModule(result, module) {
239 //: result[module.name] = buildProperties(module.data, 'list')[0];
240 //: return result;
241 //: }
242 //:
243 //: var result = yang.map(module).reduce(reduceModule, {});
244 //:
245 //: console.log(JSON.stringify(result, null, 5));