[CORD-1630] Adding description and verbose_name to models in xproto

Change-Id: I24db1aded7263c7433e00bc33cb272916cb0ce73
diff --git a/docs/modeling_conventions.md b/docs/modeling_conventions.md
index 947bc90..8f0371f 100644
--- a/docs/modeling_conventions.md
+++ b/docs/modeling_conventions.md
@@ -51,7 +51,7 @@
 
 | Attribute          | Effect             |
 |--------------------|--------------------|
-| verbose_name="..." | Provides a label to be used in the GUI display for this field. Differs from the field name itself, which is used to create the column in the database table.|
+| verbose_name="..." | Provides a label to be used in the GUI display for this field. Differs from the field name itself, which is used to create the database table.|
 | verbose_name_plural="..." | Way to override the verbose name for this field.|
 | help_text="..." | Provides some context-based help for the field; will show up in the GUI display.|
 | default=... | Allows a predefined default value to be specified.|
@@ -60,6 +60,7 @@
 | blank=True | Allows the field to be present but empty.|
 | null=True | Allows the field to have a value of null if the field is blank.|
 | editable=False | If you would like to make this a readOnly field to the user.|
+| gui_hidden=True | Hide a particular field from the GUI. This can be specified for an entire model.|
 
 The following Field-level optional attributes should not be used (or use judiciously).
 
@@ -122,6 +123,8 @@
 | app_label          | Necessary if models are defined in modules other than models.py  In our core application we split out the model definitions into their own modules for clarity -- each of the models not derived from the XOSBase needs to explicitly state the "core" as the application this object is associated to. For example, XOSBase and User.|
 | order_with_respect_to | |
 | ordering | Defines the default column to order lists of the object type by. For example, Users => email.|
+| description | Provide an explation of the model. It's rendered in the GUI to help the operator.|
+| gui_hidden=True | Hide a particular model from the GUI. This can be specified for a single field.|
 
 
 
diff --git a/lib/xos-genx/tests/translator_test.py b/lib/xos-genx/tests/translator_test.py
index f936113..48c1a81 100644
--- a/lib/xos-genx/tests/translator_test.py
+++ b/lib/xos-genx/tests/translator_test.py
@@ -133,7 +133,7 @@
 option app_label = "test";
 
 message Foo {
-    option gui_hidden = "True";
+    option gui_hidden = True;
     required string name = 1 [ null = "False", blank="False"];
 }
 
@@ -271,6 +271,50 @@
         self.assertIn('{model: ServiceDependency, type: onetomany, on_field: provider_service}', output)
         self.assertIn('{model: ServiceDependency, type: onetomany, on_field: provider_service}', output)
 
+    def test_model_description(self):
+        xproto = \
+"""
+option app_label = "test";
+
+message Foo {
+    option description="This is the Foo model";
+    required string name = 1 [ null = "False", blank="False"];
+    required string isolation = 14 [default = "vm", choices = "(('vm', 'Virtual Machine'), ('container', 'Container'), ('container_vm', 'Container In VM'))", max_length = 30, blank = False, null = False, db_index = False];
+}
+
+message Bar {
+    required string name = 1;
+}
+"""
+
+        args = FakeArgs()
+        args.inputs = xproto
+        args.target = 'modeldefs.xtarget'
+        output = XOSGenerator.generate(args)
+        self.assertIn('description: "This is the Foo model"', output)
+
+    def test_model_verbose_name(self):
+        xproto = \
+"""
+option app_label = "test";
+
+message Foo {
+    option verbose_name="Verbose Foo Name";
+    required string name = 1 [ null = "False", blank="False"];
+    required string isolation = 14 [default = "vm", choices = "(('vm', 'Virtual Machine'), ('container', 'Container'), ('container_vm', 'Container In VM'))", max_length = 30, blank = False, null = False, db_index = False];
+}
+
+message Bar {
+    required string name = 1;
+}
+"""
+
+        args = FakeArgs()
+        args.inputs = xproto
+        args.target = 'modeldefs.xtarget'
+        output = XOSGenerator.generate(args)
+        self.assertIn('verbose_name: "Verbose Foo Name"', output)
+
 if __name__ == '__main__':
     unittest.main()
 
diff --git a/lib/xos-genx/xosgenx/targets/modeldefs.xtarget b/lib/xos-genx/xosgenx/targets/modeldefs.xtarget
index ec8df1c..3b0790a 100644
--- a/lib/xos-genx/xosgenx/targets/modeldefs.xtarget
+++ b/lib/xos-genx/xosgenx/targets/modeldefs.xtarget
@@ -2,6 +2,12 @@
 {%- for m in proto.messages | sort(attribute='name') %}
 {%- if m.name != 'XOSBase'  and xproto_unquote(xproto_first_non_empty([m.options.gui_hidden, 'False'])) != 'True' %}
 - app: {{ xproto_unquote(xproto_first_non_empty([m.options.name, m.options.app_label, options.name, context.app_label])) }}
+  {%- if m.options.description %}
+  description: "{{ xproto_unquote(m.options.description) }}"
+  {%- endif %}
+  {%- if m.options.verbose_name %}
+  verbose_name: "{{ xproto_unquote(m.options.verbose_name) }}"
+  {%- endif %}
   fields: 
   {%- set id_field = {'type':'int32', 'name':'id', 'options':{}} %}
   {% for f in (xproto_base_fields(m, proto.message_table) + m.fields + [id_field]) | sort(attribute='name') -%}
diff --git a/lib/xos-genx/xosgenx/targets/service.xtarget b/lib/xos-genx/xosgenx/targets/service.xtarget
index bf14b83..7b90aea 100644
--- a/lib/xos-genx/xosgenx/targets/service.xtarget
+++ b/lib/xos-genx/xosgenx/targets/service.xtarget
@@ -41,7 +41,7 @@
   class Meta:
       app_label = {{ xproto_first_non_empty([m.options.app_label, options.app_label, options.name, "Set an app label in your xproto!"]) | lower}}
       # name = {{ xproto_first_non_empty([m.options.name, options.name, "Set a name in your xproto!"]) }}
-      verbose_name = {{ xproto_first_non_empty([m.options.verbose_name, options.verbose_name, "Set a verbose name in your xproto!"]) }}
+      verbose_name = "{{ xproto_unquote(xproto_first_non_empty([m.options.verbose_name, m.name])) }}"
 
   # Primitive Fields (Not Relations)
   {% for f in m.fields %}
diff --git a/xos/core/models/core.xproto b/xos/core/models/core.xproto
index 36af669..05e9c04 100644
--- a/xos/core/models/core.xproto
+++ b/xos/core/models/core.xproto
@@ -33,7 +33,7 @@
 
 message User::user_policy (AbstractBaseUser,PlModelMixIn) {
      option skip_django = True;
-     option tosca_description = "An XOS User";
+     option description = "An XOS User";
 
      required string email = 1 [db_index = True, max_length = 255, null = False, blank = False];
      required string username = 2 [default = "Something", max_length = 255, content_type = "stripped", blank = False, null = False, db_index = False];
@@ -601,6 +601,8 @@
 }
 
 message XOSGuiExtension (XOSBase) {
+     option verbose_name="XOS GUI Extension";
+     option description="This model holds the instruction to load an extension in the GUI";
      required string name = 1 [max_length = 200, content_type = "stripped", blank = False, help_text = "Name of the GUI Extensions", null = False, db_index = False];
      required string files = 2 [max_length = 1024, content_type = "stripped", blank = False, help_text = "List of comma separated file composing the view", null = False, db_index = False];
 }
diff --git a/xos/coreapi/protos/modeldefs.proto b/xos/coreapi/protos/modeldefs.proto
index 91d2652..b95a31c 100644
--- a/xos/coreapi/protos/modeldefs.proto
+++ b/xos/coreapi/protos/modeldefs.proto
@@ -43,6 +43,8 @@
     repeated ModelField fields = 2;
     repeated FieldRelation relations = 3;
     string app = 4;
+    string verbose_name = 5;
+    string description = 6;
 };
 
 message ModelDefs {