diff --git a/experiments/proto2yang/proto2yang.py b/experiments/proto2yang/proto2yang.py
new file mode 100755
index 0000000..8d9a40b
--- /dev/null
+++ b/experiments/proto2yang/proto2yang.py
@@ -0,0 +1,494 @@
+#!/usr/bin/env python
+#
+# Copyright 2016 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""protoc plugin to convert a protobuf schema to a yang schema
+
+   - basic support for message, fields. enumeration, service, method
+
+   - yang semantic rules needs to be implemented
+
+   - to run this plugin :
+
+   $ python -m grpc.tools.protoc -I.
+   --plugin=protoc-gen-custom=./proto2yang.py --custom_out=. <proto file>.proto
+
+   - the above will produce a ietf-<proto file>.yang file formatted for yang
+
+   - two examples of proto that can be used in the same directory are
+   yang.proto and addressbook.proto
+
+"""
+
+import sys
+
+from jinja2 import Template
+from google.protobuf.compiler import plugin_pb2 as plugin
+from descriptor_parser import DescriptorParser
+
+from google.protobuf.descriptor import FieldDescriptor
+
+template_yang = Template("""
+module ietf-{{ module.name }} {
+    yang-version 1.1;
+    namespace "urn:ietf:params:xml:ns:yang:ietf-{{ module.name }}";
+    prefix "voltha";
+
+    organization "CORD";
+    contact
+        " Any name";
+
+    description
+        "{{ module.description }}";
+
+    revision "2016-11-15" {
+        description "Initial revision.";
+        reference "reference";
+    }
+
+    {% for enum in module.enums %}
+    typedef {{ enum.name }} {
+        type enumeration {
+        {% for v in enum.value %}
+            enum {{ v.name }} {
+                description "{{ v.description }}";
+            }
+        {% endfor %}
+        }
+        description
+            "{{ enum.description }}";
+    }
+    {% endfor %}
+
+    {% for message in module.messages recursive %}
+    {% if message.name in module.referenced_messages %}
+    grouping {{ message.name }} {
+    {% else %}
+    container {{ message.name }} {
+    {% endif %}
+        description
+            "{{ message.description }}";
+        {% for field in message.fields %}
+        {% if field.type_ref %}
+        {% for dict_item in module.referred_messages_with_keys %}
+                {% if dict_item.name == field.type %}
+        list {{ field.name }} {
+            key "{{ dict_item.key }}";
+            {% if not field.repeated %}
+            max-elements 1;
+            {% endif %}
+            uses {{ field.type }};
+            description
+                "{{ field.description }}";
+        }
+                {% endif %}
+        {% endfor %}
+        {% elif field.repeated %}
+        list {{ field.name }} {
+            key "{{ field.name }}";
+            leaf {{ field.name }} {
+                {% if field.type == "decimal64" %}
+                type {{ field.type }} {
+                   fraction-digits 5;
+                }
+                {% else %}
+                type {{ field.type }};
+                {% endif %}
+                description
+                    "{{ field.description }}";
+            }
+            description
+                "{{ field.description }}";
+        }
+        {% else %}
+        leaf {{ field.name }} {
+            {% if field.type == "decimal64" %}
+            type {{ field.type }} {
+               fraction-digits 5;
+            }
+            {% else %}
+            type {{ field.type }};
+            {% endif %}
+            description
+                "{{ field.description }}";
+        }
+        {% endif %}
+
+        {% endfor %}
+        {% for enum_type in message.enums %}
+        typedef {{ enum_type.name }} {
+            type enumeration {
+            {% for v in enum_type.value %}
+                enum {{ v.name }} {
+                    description "{{ v.description }}";
+                }
+            {% endfor %}
+            }
+            description
+                "{{ enum_type.description }}";
+        }
+
+        {% endfor %}
+    {% if message.messages %}
+    {{ loop (message.messages)|indent(4, false) }}
+    {% endif %}
+    }
+
+    {% endfor %}
+    {% for service in module.services %}
+    {% if service.description %}
+    /*  {{ service.description }}" */
+    {% endif %}
+    {% for method in service.methods %}
+    rpc {{ service.service }}-{{ method.method }} {
+        description
+            "{{ method.description }}";
+        {% if method.input %}
+        input {
+            {% if method.input_ref %}
+            uses {{ method.input }};
+            {% else %}
+            leaf {{ method.input }} {
+                type {{ method.input }};
+            }
+            {% endif %}
+        }
+        {% endif %}
+        {% if method.output %}
+        output {
+            {% if method.output_ref %}
+            uses {{ method.output }};
+            {% else %}
+            leaf {{ method.output }} {
+                type {{ method.output }};
+            }
+            {% endif %}
+        }
+        {% endif %}
+    }
+
+    {% endfor %}
+
+    {% endfor %}
+}
+""", trim_blocks=True, lstrip_blocks=True)
+
+
+def traverse_messages(message_types, prefix, referenced_messages):
+    messages = []
+    for message_type in message_types:
+        assert message_type['_type'] == 'google.protobuf.DescriptorProto'
+
+        # full_name = prefix + '-' + message_type['name']
+        full_name = message_type['name']
+
+        # parse the fields
+        fields = traverse_fields(message_type.get('field', []), full_name,
+                                 referenced_messages)
+
+        # parse the enums
+        enums = traverse_enums(message_type.get('enum_type', []), full_name)
+
+        # parse nested messages
+        nested = message_type.get('nested_type', [])
+        nested_messages = traverse_messages(nested, full_name,
+                                            referenced_messages)
+        messages.append(
+            {
+                'name': full_name,
+                'fields': fields,
+                'enums': enums,
+                # 'extensions': extensions,
+                'messages': nested_messages,
+                'description': remove_unsupported_characters(
+                    message_type.get('_description', '')),
+                # 'extension_ranges': extension_ranges,
+                # 'oneof': oneof
+            }
+        )
+    return messages
+
+
+def traverse_fields(fields_desc, prefix, referenced_messages):
+    fields = []
+    for field in fields_desc:
+        assert field['_type'] == 'google.protobuf.FieldDescriptorProto'
+        yang_base_type = is_base_type(field['type'])
+        _type = get_yang_type(field)
+        if not yang_base_type:
+            referenced_messages.append(_type)
+
+        fields.append(
+            {
+                # 'name': prefix + '-' + field.get('name', ''),
+                'name': field.get('name', ''),
+                'label': field.get('label', ''),
+                'repeated': field['label'] == FieldDescriptor.LABEL_REPEATED,
+                'number': field.get('number', ''),
+                'options': field.get('options', ''),
+                'type_name': field.get('type_name', ''),
+                'type': _type,
+                'type_ref': not yang_base_type,
+                'description': remove_unsupported_characters(field.get(
+                    '_description', ''))
+            }
+        )
+    return fields
+
+
+def traverse_enums(enums_desc, prefix):
+    enums = []
+    for enum in enums_desc:
+        assert enum['_type'] == 'google.protobuf.EnumDescriptorProto'
+        # full_name = prefix + '-' + enum.get('name', '')
+        full_name = enum.get('name', '')
+        enums.append(
+            {
+                'name': full_name,
+                'value': enum.get('value', ''),
+                'description': remove_unsupported_characters(enum.get(
+                    '_description', ''))
+            }
+        )
+    return enums
+
+
+def traverse_services(service_desc, referenced_messages):
+    services = []
+    for service in service_desc:
+        methods = []
+        for method in service.get('method', []):
+            assert method['_type'] == 'google.protobuf.MethodDescriptorProto'
+
+            input_name = method.get('input_type')
+            input_ref = False
+            if not is_base_type(input_name):
+                input_name = remove_first_character_if_match(input_name, '.')
+                # input_name = input_name.replace(".", "-")
+                input_name = input_name.split('.')[-1]
+                referenced_messages.append(input_name)
+                input_ref = True
+
+            output_name = method.get('output_type')
+            output_ref = False
+            if not is_base_type(output_name):
+                output_name = remove_first_character_if_match(output_name, '.')
+                # output_name = output_name.replace(".", "-")
+                output_name = output_name.split('.')[-1]
+                referenced_messages.append(output_name)
+                output_ref = True
+
+            methods.append(
+                {
+                    'method': method.get('name', ''),
+                    'input': input_name,
+                    'input_ref': input_ref,
+                    'output': output_name,
+                    'output_ref': output_ref,
+                    'description': remove_unsupported_characters(method.get(
+                        '_description', '')),
+                    'server_streaming': method.get('server_streaming',
+                                                   False) == True
+                }
+            )
+        services.append(
+            {
+                'service': service.get('name', ''),
+                'methods': methods,
+                'description': remove_unsupported_characters(service.get(
+                    '_description', '')),
+            }
+        )
+    return services
+
+
+def rchop(thestring, ending):
+    if thestring.endswith(ending):
+        return thestring[:-len(ending)]
+    return thestring
+
+
+def traverse_desc(descriptor):
+    referenced_messages = []
+    name = rchop(descriptor.get('name', ''), '.proto')
+    package = descriptor.get('package', '')
+    description = descriptor.get('_description', '')
+    messages = traverse_messages(descriptor.get('message_type', []),
+                                 package, referenced_messages)
+    enums = traverse_enums(descriptor.get('enum_type', []), package)
+    services = traverse_services(descriptor.get('service', []),
+                                 referenced_messages)
+    # extensions = _traverse_extensions(descriptors)
+    # options = _traverse_options(descriptors)
+    set_messages_keys(messages)
+    unique_referred_messages_with_keys = []
+    for message_name in list(set(referenced_messages)):
+        unique_referred_messages_with_keys.append(
+            {
+                'name': message_name,
+                'key': get_message_key(message_name, messages)
+            }
+        )
+
+    data = {
+        'name': name,
+        'package': package,
+        'description': description,
+        'messages': messages,
+        'enums': enums,
+        'services': services,
+        'referenced_messages': list(set(referenced_messages)),
+        # TODO:  simplify for easier jinja2 template use
+        'referred_messages_with_keys': unique_referred_messages_with_keys,
+        # 'extensions': extensions,
+        # 'options': options
+    }
+    return data
+
+
+def set_messages_keys(messages):
+    for message in messages:
+        message['key'] = _get_message_key(message)
+        if message['messages']:
+            set_messages_keys(message['messages'])
+
+
+def _get_message_key(message):
+    # assume key is first yang base type field
+    for field in message['fields']:
+        if not field['type_ref']:
+            return field['name']
+    # no key yet - search nested messaged
+    if message['messages']:
+        return get_message_key(message['messages'])
+    else:
+        return None
+
+
+def get_message_key(message_name, messages):
+    for message in messages:
+        if message_name == message['name']:
+            return message['key']
+        if message['messages']:
+            return get_message_key(message_name, message['messages'])
+    return None
+
+
+def generate_code(request, response):
+    assert isinstance(request, plugin.CodeGeneratorRequest)
+
+    parser = DescriptorParser()
+
+    # idx = 1
+    for proto_file in request.proto_file:
+        native_data = parser.parse_file_descriptor(proto_file,
+                                                   type_tag_name='_type',
+                                                   fold_comments=True)
+
+        # print native_data
+        yang_data = traverse_desc(native_data)
+
+        f = response.file.add()
+        # TODO: We should have a separate file for each output. There is an
+        # issue reusing the same filename with an incremental suffix.  Using
+        # a different file name works but not the actual proto file name
+        f.name = '{}-{}'.format('ietf', proto_file.name.replace('.proto',
+                                                                '.yang'))
+        # f.name = '{}_{}{}'.format(_rchop(proto_file.name, '.proto'), idx,
+        #                            '.yang')
+        # idx += 1
+        f.content = template_yang.render(module=yang_data)
+
+
+def get_yang_type(field):
+    type = field['type']
+    if type in YANG_TYPE_MAP.keys():
+        _type, _ = YANG_TYPE_MAP[type]
+        if _type in ['enumeration', 'message', 'group']:
+            return field['type_name'].split('.')[-1]
+            # return remove_first_character_if_match(field['type_name'],
+            #                                        '.').replace('.', '-')
+        else:
+            return _type
+    else:
+        return type
+
+
+def is_base_type(type):
+    # check numeric value of the type first
+    if type in YANG_TYPE_MAP.keys():
+        _type, _ = YANG_TYPE_MAP[type]
+        return _type not in ['message', 'group']
+    else:
+        # proto name of the type
+        result = [_format for (_, _format) in YANG_TYPE_MAP.values() if
+                  _format == type and _format not in ['message', 'group']]
+        return len(result) > 0
+
+
+def remove_unsupported_characters(text):
+    unsupported_characters = ["{", "}", "[", "]", "\"", "\\", "*", "/"]
+    return ''.join([i if i not in unsupported_characters else ' ' for i in
+                    text])
+
+
+def remove_first_character_if_match(str, char):
+    if str.startswith(char):
+        return str[1:]
+    return str
+
+
+YANG_TYPE_MAP = {
+    FieldDescriptor.TYPE_BOOL: ('boolean', 'boolean'),
+    FieldDescriptor.TYPE_BYTES: ('binary', 'byte'),
+    FieldDescriptor.TYPE_DOUBLE: ('decimal64', 'double'),
+    FieldDescriptor.TYPE_ENUM: ('enumeration', 'enum'),
+    FieldDescriptor.TYPE_FIXED32: ('int32', 'int64'),
+    FieldDescriptor.TYPE_FIXED64: ('int64', 'uint64'),
+    FieldDescriptor.TYPE_FLOAT: ('decimal64', 'float'),
+    FieldDescriptor.TYPE_INT32: ('int32', 'int32'),
+    FieldDescriptor.TYPE_INT64: ('int64', 'int64'),
+    FieldDescriptor.TYPE_SFIXED32: ('int32', 'int32'),
+    FieldDescriptor.TYPE_SFIXED64: ('int64', 'int64'),
+    FieldDescriptor.TYPE_STRING: ('string', 'string'),
+    FieldDescriptor.TYPE_SINT32: ('int32', 'int32'),
+    FieldDescriptor.TYPE_SINT64: ('int64', 'int64'),
+    FieldDescriptor.TYPE_UINT32: ('uint32', 'int64'),
+    FieldDescriptor.TYPE_UINT64: ('uint64', 'uint64'),
+    FieldDescriptor.TYPE_MESSAGE: ('message', 'message'),
+    FieldDescriptor.TYPE_GROUP: ('group', 'group')
+}
+
+if __name__ == '__main__':
+    # Read request message from stdin
+    data = sys.stdin.read()
+
+    # Parse request
+    request = plugin.CodeGeneratorRequest()
+    request.ParseFromString(data)
+
+    # Create response
+    response = plugin.CodeGeneratorResponse()
+
+    # Generate code
+    generate_code(request, response)
+
+    # Serialise response message
+    output = response.SerializeToString()
+
+    # Write to stdout
+    sys.stdout.write(output)
+    # print is_base_type(9)
