THRIFT-5749 Option to enable RTTI info
Client: Delphi
Patch: Jens Geyer
diff --git a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
index 4264d85..fbf6709 100644
--- a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
@@ -76,6 +76,7 @@
     xmldoc_ = false;
     async_ = false;
     com_types_ = false;
+    rtti_ = false;
     for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
       if( iter->first.compare("ansistr_binary") == 0) {
         ansistr_binary_ = true;
@@ -93,6 +94,8 @@
         async_ = true;
       } else if( iter->first.compare("com_types") == 0) {
         com_types_ = true;
+      } else if( iter->first.compare("rtti") == 0) {
+        rtti_ = true;
       } else {
         throw "unknown option delphi:" + iter->first;
       }
@@ -472,6 +475,7 @@
   bool xmldoc_;
   bool async_;
   bool com_types_;
+  bool rtti_;
   void indent_up_impl() { ++indent_impl_; };
   void indent_down_impl() { --indent_impl_; };
   std::string indent_impl() {
@@ -720,10 +724,14 @@
   f_all << autogen_comment() << endl;
   generate_delphi_doc(f_all, program_);
   f_all << "unit " << unitname << ";" << endl << endl;
-  f_all << "{$WARN SYMBOL_DEPRECATED OFF}" << endl << endl;
+  f_all << "{$WARN SYMBOL_DEPRECATED OFF}" << endl;
   if(com_types_) {
-    f_all << "{$MINENUMSIZE 4}" << endl << endl;
+    f_all << "{$MINENUMSIZE 4}" << endl;
   }
+  if(rtti_) {
+    f_all << "{$IFOPT M+} {$DEFINE TYPEINFO_WAS_ON} {$ELSE} {$UNDEF TYPEINFO_WAS_ON} {$ENDIF}" << endl;
+  }
+  f_all << endl;
   f_all << "interface" << endl << endl;
   f_all << "uses" << endl;
 
@@ -759,6 +767,7 @@
   indent(f_all) << "c" << tmp_unit << "_Option_Async          = " << (async_ ? "True" : "False") << ";" << endl;
   indent(f_all) << "c" << tmp_unit << "_Option_COM_types      = " << (com_types_ ? "True" : "False") << ";" << endl;
   indent(f_all) << "c" << tmp_unit << "_Option_Old_Names      = " << (old_names_ ? "True" : "False") << ";" << endl;
+  indent(f_all) << "c" << tmp_unit << "_Option_RTTI           = " << (rtti_ ? "True" : "False") << ";" << endl;
   indent_down();
 
   f_all << endl;
@@ -1661,6 +1670,10 @@
   if ((!is_exception) || is_x_factory) {
 
     generate_delphi_doc(out, tstruct);
+    if(rtti_) {
+      indent(out) << "{$TYPEINFO ON}" << endl;
+      indent(out) << "{$RTTI INHERIT}" << endl;
+    }
     indent(out) << struct_intf_name << " = interface(IBase)" << endl;
     indent_up();
 
@@ -1705,7 +1718,11 @@
     }
 
     indent_down();
-    indent(out) << "end;" << endl << endl;
+    indent(out) << "end;" << endl;
+    if(rtti_) {
+      indent(out) << "{$IFNDEF TYPEINFO_WAS_ON} {$TYPEINFO OFF} {$ENDIF}" << endl;
+    }
+    indent(out) << endl;
   }
 
   generate_delphi_doc(out, tstruct);
@@ -4058,4 +4075,5 @@
     "    xmldoc:          Enable XMLDoc comments for Help Insight etc.\n"
     "    async:           Generate IAsync interface to use Parallel Programming Library (XE7+ only).\n"
     "    com_types:       Use COM-compatible data types (e.g. WideString).\n"
-    "    old_names:       Compatibility: generate \"reserved\" identifiers with '_' postfix instead of '&' prefix.\n")
+    "    old_names:       Compatibility: generate \"reserved\" identifiers with '_' postfix instead of '&' prefix.\n"
+    "    rtti:            Activate {$TYPEINFO} and {$RTTI} at the generated API interfaces.\n")
diff --git a/lib/delphi/src/Thrift.Protocol.pas b/lib/delphi/src/Thrift.Protocol.pas
index c6b1a00..0134ddf 100644
--- a/lib/delphi/src/Thrift.Protocol.pas
+++ b/lib/delphi/src/Thrift.Protocol.pas
@@ -18,6 +18,7 @@
  *)
 
 {$SCOPEDENUMS ON}
+{$IFOPT M+} {$DEFINE TYPEINFO_WAS_ON} {$ELSE} {$UNDEF TYPEINFO_WAS_ON} {$ENDIF}
 
 unit Thrift.Protocol;
 
@@ -335,11 +336,15 @@
     constructor Create( const aTransport : ITransport); virtual;
   end;
 
+  {$TYPEINFO ON}
+  {$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])}
   IBase = interface( ISupportsToString)
     ['{AFF6CECA-5200-4540-950E-9B89E0C1C00C}']
     procedure Read( const prot: IProtocol);
     procedure Write( const prot: IProtocol);
   end;
+  {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
+  {$IFNDEF TYPEINFO_WAS_ON} {$TYPEINFO OFF} {$ENDIF}
 
 
   IThriftBytes = interface( ISupportsToString)