THRIFT-4238 JSON generator: make annotation-aware
Client: json
Autor: Stig Bakken <stig@zedge.net>

This closes #1299
diff --git a/compiler/cpp/src/thrift/generate/t_json_generator.cc b/compiler/cpp/src/thrift/generate/t_json_generator.cc
index f3d67e0..153ec35 100644
--- a/compiler/cpp/src/thrift/generate/t_json_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_json_generator.cc
@@ -264,6 +264,15 @@
 
   write_string(get_type_name(ttype));
 
+  if (ttype->annotations_.size() > 0) {
+    write_key_and("annotations");
+    start_object();
+    for (map<string, string>::iterator it = ttype->annotations_.begin(); it != ttype->annotations_.end(); ++it) {
+      write_key_and_string(it->first, it->second);
+    }
+    end_object();
+  }
+
   if (ttype->is_struct() || ttype->is_xception()) {
     write_key_and_string("class", get_qualified_name(ttype));
   } else if (ttype->is_map()) {
@@ -445,6 +454,14 @@
   if (ttypedef->has_doc()) {
     write_key_and_string("doc", ttypedef->get_doc());
   }
+  if (ttypedef->annotations_.size() > 0) {
+    write_key_and("annotations");
+    start_object();
+    for (map<string, string>::iterator it = ttypedef->annotations_.begin(); it != ttypedef->annotations_.end(); ++it) {
+      write_key_and_string(it->first, it->second);
+    }
+    end_object();
+  }
   end_object();
 }
 
@@ -544,6 +561,15 @@
     write_key_and_string("doc", tenum->get_doc());
   }
 
+  if (tenum->annotations_.size() > 0) {
+      write_key_and("annotations");
+      start_object();
+      for (map<string, string>::iterator it = tenum->annotations_.begin(); it != tenum->annotations_.end(); ++it) {
+        write_key_and_string(it->first, it->second);
+      }
+      end_object();
+  }
+
   write_key_and("members");
   start_array();
   vector<t_enum_value*> values = tenum->get_constants();
@@ -574,6 +600,15 @@
     write_key_and_string("doc", tstruct->get_doc());
   }
 
+  if (tstruct->annotations_.size() > 0) {
+    write_key_and("annotations");
+    start_object();
+    for (map<string, string>::iterator it = tstruct->annotations_.begin(); it != tstruct->annotations_.end(); ++it) {
+      write_key_and_string(it->first, it->second);
+    }
+    end_object();
+  }
+
   write_key_and_bool("isException", tstruct->is_xception());
 
   write_key_and_bool("isUnion", tstruct->is_union());
@@ -605,6 +640,15 @@
     write_key_and_string("doc", tservice->get_doc());
   }
 
+  if (tservice->annotations_.size() > 0) {
+    write_key_and("annotations");
+    start_object();
+    for (map<string, string>::iterator it = tservice->annotations_.begin(); it != tservice->annotations_.end(); ++it) {
+      write_key_and_string(it->first, it->second);
+    }
+    end_object();
+  }
+
   write_key_and("functions");
   start_array();
   vector<t_function*> functions = tservice->get_functions();
@@ -633,6 +677,15 @@
     write_key_and_string("doc", tfunc->get_doc());
   }
 
+  if (tfunc->annotations_.size() > 0) {
+    write_key_and("annotations");
+    start_object();
+    for (map<string, string>::iterator it = tfunc->annotations_.begin(); it != tfunc->annotations_.end(); ++it) {
+      write_key_and_string(it->first, it->second);
+    }
+    end_object();
+  }
+
   write_key_and("arguments");
   start_array();
   vector<t_field*> members = tfunc->get_arglist()->get_members();
@@ -670,6 +723,15 @@
     write_key_and_string("doc", field->get_doc());
   }
 
+  if (field->annotations_.size() > 0) {
+    write_key_and("annotations");
+    start_object();
+    for (map<string, string>::iterator it = field->annotations_.begin(); it != field->annotations_.end(); ++it) {
+      write_key_and_string(it->first, it->second);
+    }
+    end_object();
+  }
+
   write_key_and("required");
   switch (field->get_req()) {
   case t_field::T_REQUIRED:
diff --git a/lib/json/schema.json b/lib/json/schema.json
index 011b4d3..d058a7c 100644
--- a/lib/json/schema.json
+++ b/lib/json/schema.json
@@ -273,6 +273,13 @@
           "required": [ "functions" ]
         }
       ]
+    },
+    "annotations": {
+      "title": "Map of annotation names to values",
+      "type": "object",
+      "additionalProperties": {
+        "type": "string"
+      }
     }
   },
 
@@ -296,6 +303,12 @@
       },
       "uniqueItems": true
     },
+    "namespaces": {
+      "type": "object",
+      "additionalProperties": {
+        "type": "string"
+      }
+    },
     "enums": {
       "type": "array",
       "items": {
@@ -326,5 +339,6 @@
         "$ref": "#/definitions/service"
       }
     }
-  }
+  },
+  "additionalProperties": false
 }