You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by je...@apache.org on 2016/04/21 23:02:56 UTC

[1/2] thrift git commit: THRIFT-3790 Fix Delphi named pipe client to use timeout even when pipe doesn't yet exist Client: Delphi Patch: Kyle Johnson

Repository: thrift
Updated Branches:
  refs/heads/master 8077883a7 -> e0e3240d6


THRIFT-3790 Fix Delphi named pipe client to use timeout even when pipe doesn't yet exist
Client: Delphi
Patch: Kyle Johnson

The final fix.


Project: http://git-wip-us.apache.org/repos/asf/thrift/repo
Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/ae985dda
Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/ae985dda
Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/ae985dda

Branch: refs/heads/master
Commit: ae985dda55418c6524da5dd7e6a466fc8d1656a8
Parents: 8077883
Author: Jens Geyer <je...@apache.org>
Authored: Wed Apr 20 21:48:35 2016 +0200
Committer: Jens Geyer <je...@apache.org>
Committed: Thu Apr 21 22:54:14 2016 +0200

----------------------------------------------------------------------
 lib/delphi/test/TestClient.pas | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/thrift/blob/ae985dda/lib/delphi/test/TestClient.pas
----------------------------------------------------------------------
diff --git a/lib/delphi/test/TestClient.pas b/lib/delphi/test/TestClient.pas
index 01d9b77..9f45a91 100644
--- a/lib/delphi/test/TestClient.pas
+++ b/lib/delphi/test/TestClient.pas
@@ -323,7 +323,7 @@ begin
 
         trns_NamedPipes: begin
           Console.WriteLine('Using named pipe ('+sPipeName+')');
-          streamtrans := TNamedPipeTransportClientEndImpl.Create( sPipeName, 0, nil, TIMEOUT);
+          streamtrans := TNamedPipeTransportClientEndImpl.Create( sPipeName, 0, nil, TIMEOUT, TIMEOUT);
         end;
 
         trns_AnonPipes: begin


[2/2] thrift git commit: THRIFT-3794 Split Delphi application, protocol and transport exception subtypes into separate exceptions Client: Delphi Patch: Kyle Johnson

Posted by je...@apache.org.
THRIFT-3794 Split Delphi application, protocol and transport exception subtypes into separate exceptions
Client: Delphi
Patch: Kyle Johnson


Project: http://git-wip-us.apache.org/repos/asf/thrift/repo
Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/e0e3240d
Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/e0e3240d
Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/e0e3240d

Branch: refs/heads/master
Commit: e0e3240d6409a3a3f49225db114a3c6914fc682f
Parents: ae985dd
Author: Jens Geyer <je...@apache.org>
Authored: Wed Apr 20 21:50:48 2016 +0200
Committer: Jens Geyer <je...@apache.org>
Committed: Thu Apr 21 22:58:53 2016 +0200

----------------------------------------------------------------------
 compiler/cpp/src/generate/t_delphi_generator.cc |  15 +--
 lib/delphi/src/Thrift.Processor.Multiplex.pas   |  12 +-
 lib/delphi/src/Thrift.Protocol.Compact.pas      |  12 +-
 lib/delphi/src/Thrift.Protocol.JSON.pas         |  26 ++--
 lib/delphi/src/Thrift.Protocol.pas              |  87 +++++++++----
 lib/delphi/src/Thrift.Server.pas                |   2 +-
 lib/delphi/src/Thrift.Transport.Pipes.pas       |  66 ++++------
 lib/delphi/src/Thrift.Transport.pas             | 130 ++++++++++++-------
 lib/delphi/src/Thrift.pas                       | 105 ++++++++++++---
 lib/delphi/test/client.dpr                      |   1 +
 lib/delphi/test/server.dpr                      |   2 +
 11 files changed, 294 insertions(+), 164 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/thrift/blob/e0e3240d/compiler/cpp/src/generate/t_delphi_generator.cc
----------------------------------------------------------------------
diff --git a/compiler/cpp/src/generate/t_delphi_generator.cc b/compiler/cpp/src/generate/t_delphi_generator.cc
index 513bc07..5578501 100644
--- a/compiler/cpp/src/generate/t_delphi_generator.cc
+++ b/compiler/cpp/src/generate/t_delphi_generator.cc
@@ -2131,8 +2131,7 @@ void t_delphi_generator::generate_service_client(t_service* tservice) {
 
       if (!(*f_iter)->get_returntype()->is_void()) {
         indent_impl(s_service_impl)
-            << "raise "
-               "TApplicationException.Create(TApplicationException.TExceptionType.MissingResult, '"
+			<< "raise TApplicationExceptionMissingResult.Create('"
             << (*f_iter)->get_name() << " failed: unknown result');" << endl;
       }
 
@@ -2255,9 +2254,8 @@ void t_delphi_generator::generate_service_server(t_service* tservice) {
   indent_impl(s_service_impl) << "TProtocolUtil.Skip(iprot, TType.Struct);" << endl;
   indent_impl(s_service_impl) << "iprot.ReadMessageEnd();" << endl;
   indent_impl(s_service_impl) << "x := "
-                                 "TApplicationException.Create(TApplicationException."
-                                 "TExceptionType.UnknownMethod, 'Invalid method name: ''' + "
-                                 "msg.Name + '''');" << endl;
+								 "TApplicationExceptionUnknownMethod.Create("
+								 "'Invalid method name: ''' + msg.Name + '''');" << endl;
   indent_impl(s_service_impl)
       << "msg := Thrift.Protocol.TMessageImpl.Create(msg.Name, TMessageType.Exception, msg.SeqID);"
       << endl;
@@ -2444,8 +2442,7 @@ void t_delphi_generator::generate_process_function(t_service* tservice, t_functi
     indent_impl(s_service_impl) << "if events <> nil then events.UnhandledError(E);" << endl;
   }
   if (!tfunction->is_oneway()) {
-    indent_impl(s_service_impl) << "appx := TApplicationException.Create( "
-                                   "TApplicationException.TExceptionType.InternalError, E.Message);"
+	indent_impl(s_service_impl) << "appx := TApplicationExceptionInternalError.Create(E.Message);"
                                 << endl;
     indent_impl(s_service_impl) << "try" << endl;
     indent_up_impl();
@@ -3593,7 +3590,7 @@ void t_delphi_generator::generate_delphi_struct_reader_impl(ostream& out,
     if ((*f_iter)->get_req() == t_field::T_REQUIRED) {
       indent_impl(code_block) << "if not _req_isset_" << prop_name(*f_iter, is_exception) << endl;
       indent_impl(code_block)
-          << "then raise TProtocolException.Create( TProtocolException.INVALID_DATA, "
+          << "then raise TProtocolExceptionInvalidData.Create("
           << "'required field " << prop_name(*f_iter, is_exception) << " not set');" 
           << endl;
     }
@@ -3714,7 +3711,7 @@ void t_delphi_generator::generate_delphi_struct_writer_impl(ostream& out,
     if (is_required && null_allowed) {
       null_allowed = false;
       indent_impl(code_block) << "if (" << fieldname << " = nil)" << endl;
-      indent_impl(code_block) << "then raise TProtocolException.Create( TProtocolException.INVALID_DATA, "
+	  indent_impl(code_block) << "then raise TProtocolExceptionInvalidData.Create("
                               << "'required field " << fieldname << " not set');" 
                               << endl;
     }

http://git-wip-us.apache.org/repos/asf/thrift/blob/e0e3240d/lib/delphi/src/Thrift.Processor.Multiplex.pas
----------------------------------------------------------------------
diff --git a/lib/delphi/src/Thrift.Processor.Multiplex.pas b/lib/delphi/src/Thrift.Processor.Multiplex.pas
index f6d9446..756daa1 100644
--- a/lib/delphi/src/Thrift.Processor.Multiplex.pas
+++ b/lib/delphi/src/Thrift.Processor.Multiplex.pas
@@ -78,7 +78,7 @@ type
     FServiceProcessorMap : TDictionary<String, IProcessor>;
 
     procedure Error( const oprot : IProtocol; const msg : IMessage;
-                     extype : TApplicationException.TExceptionType; const etxt : string);
+                     extype : TApplicationExceptionSpecializedClass; const etxt : string);
 
   public
     constructor Create;
@@ -142,12 +142,12 @@ end;
 
 
 procedure TMultiplexedProcessorImpl.Error( const oprot : IProtocol; const msg : IMessage;
-                                           extype : TApplicationException.TExceptionType;
+                                           extype : TApplicationExceptionSpecializedClass;
                                            const etxt : string);
 var appex  : TApplicationException;
     newMsg : IMessage;
 begin
-  appex := TApplicationException.Create( extype, etxt);
+  appex := extype.Create(etxt);
   try
     newMsg := TMessageImpl.Create( msg.Name, TMessageType.Exception, msg.SeqID);
 
@@ -178,7 +178,7 @@ begin
   msg := iprot.readMessageBegin();
   if not (msg.Type_ in [TMessageType.Call, TMessageType.Oneway]) then begin
     Error( oprot, msg,
-           TApplicationException.TExceptionType.InvalidMessageType,
+           TApplicationExceptionInvalidMessageType,
            ERROR_INVALID_MSGTYPE);
     Exit( FALSE);
   end;
@@ -187,7 +187,7 @@ begin
   idx := Pos( TMultiplexedProtocol.SEPARATOR, msg.Name);
   if idx < 1 then begin
     Error( oprot, msg,
-           TApplicationException.TExceptionType.InvalidProtocol,
+           TApplicationExceptionInvalidProtocol,
            Format(ERROR_INCOMPATIBLE_PROT,[msg.Name]));
     Exit( FALSE);
   end;
@@ -197,7 +197,7 @@ begin
   if not FServiceProcessorMap.TryGetValue( sService, processor)
   then begin
     Error( oprot, msg,
-           TApplicationException.TExceptionType.InternalError,
+           TApplicationExceptionInternalError,
            Format(ERROR_UNKNOWN_SERVICE,[sService]));
     Exit( FALSE);
   end;

http://git-wip-us.apache.org/repos/asf/thrift/blob/e0e3240d/lib/delphi/src/Thrift.Protocol.Compact.pas
----------------------------------------------------------------------
diff --git a/lib/delphi/src/Thrift.Protocol.Compact.pas b/lib/delphi/src/Thrift.Protocol.Compact.pas
index 0355c4e..e9944d6 100644
--- a/lib/delphi/src/Thrift.Protocol.Compact.pas
+++ b/lib/delphi/src/Thrift.Protocol.Compact.pas
@@ -651,14 +651,14 @@ begin
 
   protocolId := Byte( ReadByte);
   if (protocolId <> PROTOCOL_ID)
-  then raise TProtocolException.Create( 'Expected protocol id ' + IntToHex(PROTOCOL_ID,2)
-                                      + ' but got ' + IntToHex(protocolId,2));
+  then raise TProtocolExceptionBadVersion.Create( 'Expected protocol id ' + IntToHex(PROTOCOL_ID,2)
+                                                + ' but got ' + IntToHex(protocolId,2));
 
   versionAndType := Byte( ReadByte);
   version        := Byte( versionAndType and VERSION_MASK);
   if (version <> VERSION)
-  then raise TProtocolException.Create( 'Expected version ' +IntToStr(VERSION)
-                                      + ' but got ' + IntToStr(version));
+  then raise TProtocolExceptionBadVersion.Create( 'Expected version ' +IntToStr(VERSION)
+                                                + ' but got ' + IntToStr(version));
 
   type_ := Byte( (versionAndType shr TYPE_SHIFT_AMOUNT) and TYPE_BITS);
   seqid := Integer( ReadVarint32);
@@ -960,7 +960,7 @@ begin
   tct := Types( type_ and $0F);
   if tct in [Low(Types)..High(Types)]
   then result := tcompactTypeToType[tct]
-  else raise TProtocolException.Create('don''t know what type: '+IntToStr(Ord(tct)));
+  else raise TProtocolExceptionInvalidData.Create('don''t know what type: '+IntToStr(Ord(tct)));
 end;
 
 
@@ -969,7 +969,7 @@ class function TCompactProtocolImpl.getCompactType( const ttype : TType) : Byte;
 begin
   if ttype in VALID_TTYPES
   then result := Byte( ttypeToCompactType[ttype])
-  else raise TProtocolException.Create('don''t know what type: '+IntToStr(Ord(ttype)));
+  else raise TProtocolExceptionInvalidData.Create('don''t know what type: '+IntToStr(Ord(ttype)));
 end;
 
 

http://git-wip-us.apache.org/repos/asf/thrift/blob/e0e3240d/lib/delphi/src/Thrift.Protocol.JSON.pas
----------------------------------------------------------------------
diff --git a/lib/delphi/src/Thrift.Protocol.JSON.pas b/lib/delphi/src/Thrift.Protocol.JSON.pas
index 896dfcc..71ee7ae 100644
--- a/lib/delphi/src/Thrift.Protocol.JSON.pas
+++ b/lib/delphi/src/Thrift.Protocol.JSON.pas
@@ -310,7 +310,7 @@ begin
     TType.Set_:     result := NAME_SET;
     TType.List:     result := NAME_LIST;
   else
-    raise TProtocolException.Create( TProtocolException.NOT_IMPLEMENTED, 'Unrecognized type ('+IntToStr(Ord(typeID))+')');
+    raise TProtocolExceptionNotImplemented.Create('Unrecognized type ('+IntToStr(Ord(typeID))+')');
   end;
 end;
 
@@ -328,7 +328,7 @@ begin
   else if name = NAME_MAP    then result := TType.Map
   else if name = NAME_LIST   then result := TType.List
   else if name = NAME_SET    then result := TType.Set_
-  else raise TProtocolException.Create( TProtocolException.NOT_IMPLEMENTED, 'Unrecognized type ('+name+')');
+  else raise TProtocolExceptionNotImplemented.Create('Unrecognized type ('+name+')');
 end;
 
 
@@ -506,7 +506,7 @@ var ch : Byte;
 begin
   ch := FReader.Read;
   if (ch <> b)
-  then raise TProtocolException.Create( TProtocolException.INVALID_DATA, 'Unexpected character ('+Char(ch)+')');
+  then raise TProtocolExceptionInvalidData.Create('Unexpected character ('+Char(ch)+')');
 end;
 
 
@@ -516,7 +516,7 @@ begin
   i := StrToIntDef( '$0'+Char(ch), -1);
   if (0 <= i) and (i < $10)
   then result := i
-  else raise TProtocolException.Create( TProtocolException.INVALID_DATA, 'Expected hex character ('+Char(ch)+')');
+  else raise TProtocolExceptionInvalidData.Create('Expected hex character ('+Char(ch)+')');
 end;
 
 
@@ -853,7 +853,7 @@ begin
       then begin
         off := Pos( Char(ch), ESCAPE_CHARS);
         if off < 1
-        then raise TProtocolException.Create( TProtocolException.INVALID_DATA, 'Expected control char');
+        then raise TProtocolExceptionInvalidData.Create('Expected control char');
         ch := Byte( ESCAPE_CHAR_VALS[off]);
         buffer.Write( ch, 1);
         Continue;
@@ -870,12 +870,12 @@ begin
       // we need to make UTF8 bytes from it, to be decoded later
       if CharUtils.IsHighSurrogate(char(wch)) then begin
         if highSurogate <> #0
-        then raise TProtocolException.Create( TProtocolException.INVALID_DATA, 'Expected low surrogate char');
+        then raise TProtocolExceptionInvalidData.Create('Expected low surrogate char');
         highSurogate := char(wch);
       end
       else if CharUtils.IsLowSurrogate(char(wch)) then begin
         if highSurogate = #0
-        then TProtocolException.Create( TProtocolException.INVALID_DATA, 'Expected high surrogate char');
+        then TProtocolExceptionInvalidData.Create('Expected high surrogate char');
         surrogatePairs[0] := highSurogate;
         surrogatePairs[1] := char(wch);
         tmp := TEncoding.UTF8.GetBytes(surrogatePairs);
@@ -889,7 +889,7 @@ begin
     end;
 
     if highSurogate <> #0
-    then raise TProtocolException.Create( TProtocolException.INVALID_DATA, 'Expected low surrogate char');
+    then raise TProtocolExceptionInvalidData.Create('Expected low surrogate char');
 
     SetLength( result, buffer.Size);
     if buffer.Size > 0 then Move( buffer.Memory^, result[0], Length(result));
@@ -943,8 +943,7 @@ begin
     result := StrToInt64(str);
   except
     on e:Exception do begin
-      raise TProtocolException.Create( TProtocolException.INVALID_DATA,
-                                       'Bad data encounted in numeric data ('+str+') ('+e.Message+')');
+      raise TProtocolExceptionInvalidData.Create('Bad data encounted in numeric data ('+str+') ('+e.Message+')');
     end;
   end;
 end;
@@ -966,7 +965,7 @@ begin
     and not Math.IsInfinite(dub)
     then begin
       // Throw exception -- we should not be in a string in  Self case
-      raise TProtocolException.Create( TProtocolException.INVALID_DATA, 'Numeric data unexpectedly quoted');
+      raise TProtocolExceptionInvalidData.Create('Numeric data unexpectedly quoted');
     end;
     result := dub;
     Exit;
@@ -981,8 +980,7 @@ begin
     result := StrToFloat( str, INVARIANT_CULTURE);
   except
     on e:Exception
-    do raise TProtocolException.Create( TProtocolException.INVALID_DATA,
-                                       'Bad data encounted in numeric data ('+str+') ('+e.Message+')');
+    do raise TProtocolExceptionInvalidData.Create('Bad data encounted in numeric data ('+str+') ('+e.Message+')');
   end;
 end;
 
@@ -1061,7 +1059,7 @@ begin
   ReadJSONArrayStart;
 
   if ReadJSONInteger <> VERSION
-  then raise TProtocolException.Create( TProtocolException.BAD_VERSION, 'Message contained bad version.');
+  then raise TProtocolExceptionBadVersion.Create('Message contained bad version.');
 
   result.Name  := SysUtils.TEncoding.UTF8.GetString( ReadJSONString( FALSE));
   result.Type_ := TMessageType( ReadJSONInteger);

http://git-wip-us.apache.org/repos/asf/thrift/blob/e0e3240d/lib/delphi/src/Thrift.Protocol.pas
----------------------------------------------------------------------
diff --git a/lib/delphi/src/Thrift.Protocol.pas b/lib/delphi/src/Thrift.Protocol.pas
index 01b11a8..7ff2eae 100644
--- a/lib/delphi/src/Thrift.Protocol.pas
+++ b/lib/delphi/src/Thrift.Protocol.pas
@@ -86,21 +86,37 @@ type
   TProtocolException = class( Exception )
   public
     const // TODO(jensg): change into enum
-      UNKNOWN : Integer = 0;
-      INVALID_DATA : Integer = 1;
-      NEGATIVE_SIZE : Integer = 2;
-      SIZE_LIMIT : Integer = 3;
-      BAD_VERSION : Integer = 4;
-      NOT_IMPLEMENTED : Integer = 5;
-      DEPTH_LIMIT : Integer = 6;
+      UNKNOWN = 0;
+      INVALID_DATA = 1;
+      NEGATIVE_SIZE = 2;
+      SIZE_LIMIT = 3;
+      BAD_VERSION = 4;
+      NOT_IMPLEMENTED = 5;
+      DEPTH_LIMIT = 6;
   protected
-    FType : Integer;
+    constructor HiddenCreate(const Msg: string);
   public
-    constructor Create; overload;
-    constructor Create( type_: Integer ); overload;
-    constructor Create( type_: Integer; const msg: string); overload;
+    // purposefully hide inherited constructor
+    class function Create(const Msg: string): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
+    class function Create: TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
+    class function Create( type_: Integer): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
+    class function Create( type_: Integer; const msg: string): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
   end;
 
+  // Needed to remove deprecation warning
+  TProtocolExceptionSpecialized = class abstract (TProtocolException)
+  public
+    constructor Create(const Msg: string);
+  end;
+
+  TProtocolExceptionUnknown = class (TProtocolExceptionSpecialized);
+  TProtocolExceptionInvalidData = class (TProtocolExceptionSpecialized);
+  TProtocolExceptionNegativeSize = class (TProtocolExceptionSpecialized);
+  TProtocolExceptionSizeLimit = class (TProtocolExceptionSpecialized);
+  TProtocolExceptionBadVersion = class (TProtocolExceptionSpecialized);
+  TProtocolExceptionNotImplemented = class (TProtocolExceptionSpecialized);
+  TProtocolExceptionDepthLimit = class (TProtocolExceptionSpecialized);
+
   IMap = interface
     ['{30531D97-7E06-4233-B800-C3F53CCD23E7}']
     function GetKeyType: TType;
@@ -695,7 +711,7 @@ procedure TProtocolImpl.IncrementRecursionDepth;
 begin
   if FRecursionDepth < FRecursionLimit
   then Inc(FRecursionDepth)
-  else raise TProtocolException.Create( TProtocolException.DEPTH_LIMIT, 'Depth limit exceeded');
+  else raise TProtocolExceptionDepthLimit.Create('Depth limit exceeded');
 end;
 
 procedure TProtocolImpl.DecrementRecursionDepth;
@@ -1143,7 +1159,7 @@ begin
     version := size and Integer( VERSION_MASK);
     if ( version <> Integer( VERSION_1)) then
     begin
-      raise TProtocolException.Create(TProtocolException.BAD_VERSION, 'Bad version in ReadMessageBegin: ' + IntToStr(version) );
+      raise TProtocolExceptionBadVersion.Create('Bad version in ReadMessageBegin: ' + IntToStr(version) );
     end;
     message.Type_ := TMessageType( size and $000000ff);
     message.Name := ReadString;
@@ -1152,7 +1168,7 @@ begin
   begin
     if FStrictRead then
     begin
-      raise TProtocolException.Create( TProtocolException.BAD_VERSION, 'Missing version in readMessageBegin, old client?' );
+      raise TProtocolExceptionBadVersion.Create('Missing version in readMessageBegin, old client?' );
     end;
     message.Name := ReadStringBody( size );
     message.Type_ := TMessageType( ReadByte );
@@ -1358,22 +1374,47 @@ end;
 
 { TProtocolException }
 
-constructor TProtocolException.Create;
+constructor TProtocolException.HiddenCreate(const Msg: string);
+begin
+  inherited Create(Msg);
+end;
+
+class function TProtocolException.Create(const Msg: string): TProtocolException;
+begin
+  Result := TProtocolExceptionUnknown.Create(Msg);
+end;
+
+class function TProtocolException.Create: TProtocolException;
 begin
-  inherited Create('');
-  FType := UNKNOWN;
+  Result := TProtocolExceptionUnknown.Create('');
 end;
 
-constructor TProtocolException.Create(type_: Integer);
+class function TProtocolException.Create(type_: Integer): TProtocolException;
 begin
-  inherited Create('');
-  FType := type_;
+{$WARN SYMBOL_DEPRECATED OFF}
+  Result := Create(type_, '');
+{$WARN SYMBOL_DEPRECATED DEFAULT}
 end;
 
-constructor TProtocolException.Create(type_: Integer; const msg: string);
+class function TProtocolException.Create(type_: Integer; const msg: string): TProtocolException;
+begin
+  case type_ of
+    INVALID_DATA:    Result := TProtocolExceptionInvalidData.Create(msg);
+    NEGATIVE_SIZE:   Result := TProtocolExceptionNegativeSize.Create(msg);
+    SIZE_LIMIT:      Result := TProtocolExceptionSizeLimit.Create(msg);
+    BAD_VERSION:     Result := TProtocolExceptionBadVersion.Create(msg);
+    NOT_IMPLEMENTED: Result := TProtocolExceptionNotImplemented.Create(msg);
+    DEPTH_LIMIT:     Result := TProtocolExceptionDepthLimit.Create(msg);
+  else
+    Result := TProtocolExceptionUnknown.Create(msg);
+  end;
+end;
+
+{ TProtocolExceptionSpecialized }
+
+constructor TProtocolExceptionSpecialized.Create(const Msg: string);
 begin
-  inherited Create( msg );
-  FType := type_;
+  inherited HiddenCreate(Msg);
 end;
 
 { TThriftStringBuilder }

http://git-wip-us.apache.org/repos/asf/thrift/blob/e0e3240d/lib/delphi/src/Thrift.Server.pas
----------------------------------------------------------------------
diff --git a/lib/delphi/src/Thrift.Server.pas b/lib/delphi/src/Thrift.Server.pas
index 6521444..13c5762 100644
--- a/lib/delphi/src/Thrift.Server.pas
+++ b/lib/delphi/src/Thrift.Server.pas
@@ -350,7 +350,7 @@ begin
       if client = nil then begin
         if FStop
         then Abort  // silent exception
-        else raise TTransportException.Create( 'ServerTransport.Accept() may not return NULL' );
+        else raise TTransportExceptionUnknown.Create('ServerTransport.Accept() may not return NULL');
       end;
 
       FLogDelegate( 'Client Connected!');

http://git-wip-us.apache.org/repos/asf/thrift/blob/e0e3240d/lib/delphi/src/Thrift.Transport.Pipes.pas
----------------------------------------------------------------------
diff --git a/lib/delphi/src/Thrift.Transport.Pipes.pas b/lib/delphi/src/Thrift.Transport.Pipes.pas
index fc82bf1..d4f99ab 100644
--- a/lib/delphi/src/Thrift.Transport.Pipes.pas
+++ b/lib/delphi/src/Thrift.Transport.Pipes.pas
@@ -262,8 +262,7 @@ begin
   if not DuplicateHandle( GetCurrentProcess, hSource,
                           GetCurrentProcess, @result,
                           0, FALSE, DUPLICATE_SAME_ACCESS)
-  then raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                         'DuplicateHandle: '+SysErrorMessage(GetLastError));
+  then raise TTransportExceptionNotOpen.Create('DuplicateHandle: '+SysErrorMessage(GetLastError));
 end;
 
 
@@ -331,12 +330,10 @@ procedure TPipeStreamBase.WriteDirect(const buffer: TBytes; offset, count: Integ
 var cbWritten : DWORD;
 begin
   if not IsOpen
-  then raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                         'Called write on non-open pipe');
+  then raise TTransportExceptionNotOpen.Create('Called write on non-open pipe');
 
   if not WriteFile( FPipe, buffer[offset], count, cbWritten, nil)
-  then raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                         'Write to pipe failed');
+  then raise TTransportExceptionNotOpen.Create('Write to pipe failed');
 end;
 
 
@@ -347,8 +344,7 @@ var cbRead, dwErr  : DWORD;
 const INTERVAL = 10;  // ms
 begin
   if not IsOpen
-  then raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                         'Called read on non-open pipe');
+  then raise TTransportExceptionNotOpen.Create('Called read on non-open pipe');
 
   // MSDN: Handle can be a handle to a named pipe instance,
   // or it can be a handle to the read end of an anonymous pipe,
@@ -373,8 +369,7 @@ begin
       Dec( retries);
       if retries > 0
       then Sleep( INTERVAL)
-      else raise TTransportException.Create( TTransportException.TExceptionType.TimedOut,
-                                             'Pipe read timed out');
+      else raise TTransportExceptionTimedOut.Create('Pipe read timed out');
     end;
   end;
 
@@ -391,8 +386,7 @@ var cbWritten, dwWait, dwError : DWORD;
     overlapped : IOverlappedHelper;
 begin
   if not IsOpen
-  then raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                         'Called write on non-open pipe');
+  then raise TTransportExceptionNotOpen.Create('Called write on non-open pipe');
 
   overlapped := TOverlappedHelperImpl.Create;
 
@@ -404,18 +398,15 @@ begin
         dwWait := overlapped.WaitFor(FTimeout);
 
         if (dwWait = WAIT_TIMEOUT)
-        then raise TTransportException.Create( TTransportException.TExceptionType.TimedOut,
-                                               'Pipe write timed out');
+        then raise TTransportExceptionTimedOut.Create('Pipe write timed out');
 
         if (dwWait <> WAIT_OBJECT_0)
         or not GetOverlappedResult( FPipe, overlapped.Overlapped, cbWritten, TRUE)
-        then raise TTransportException.Create( TTransportException.TExceptionType.Unknown,
-                                               'Pipe write error');
+        then raise TTransportExceptionUnknown.Create('Pipe write error');
       end;
 
     else
-      raise TTransportException.Create( TTransportException.TExceptionType.Unknown,
-                                        SysErrorMessage(dwError));
+      raise TTransportExceptionUnknown.Create(SysErrorMessage(dwError));
     end;
   end;
 
@@ -429,8 +420,7 @@ var cbRead, dwWait, dwError  : DWORD;
     overlapped : IOverlappedHelper;
 begin
   if not IsOpen
-  then raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                         'Called read on non-open pipe');
+  then raise TTransportExceptionNotOpen.Create('Called read on non-open pipe');
 
   overlapped := TOverlappedHelperImpl.Create;
 
@@ -443,18 +433,15 @@ begin
         dwWait := overlapped.WaitFor(FTimeout);
 
         if (dwWait = WAIT_TIMEOUT)
-        then raise TTransportException.Create( TTransportException.TExceptionType.TimedOut,
-                                               'Pipe read timed out');
+        then raise TTransportExceptionTimedOut.Create('Pipe read timed out');
 
         if (dwWait <> WAIT_OBJECT_0)
         or not GetOverlappedResult( FPipe, overlapped.Overlapped, cbRead, TRUE)
-        then raise TTransportException.Create( TTransportException.TExceptionType.Unknown,
-                                               'Pipe read error');
+        then raise TTransportExceptionUnknown.Create('Pipe read error');
       end;
 
     else
-      raise TTransportException.Create( TTransportException.TExceptionType.Unknown,
-                                        SysErrorMessage(dwError));
+      raise TTransportExceptionUnknown.Create(SysErrorMessage(dwError));
     end;
   end;
 
@@ -517,14 +504,12 @@ begin
   while not WaitNamedPipe( PChar(FPipeName), INTERVAL) do begin
     dwErr := GetLastError;
     if dwErr <> ERROR_FILE_NOT_FOUND
-    then raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                           'Unable to open pipe, '+SysErrorMessage(dwErr));
+    then raise TTransportExceptionNotOpen.Create('Unable to open pipe, '+SysErrorMessage(dwErr));
 
     if timeout <> INFINITE then begin
       if (retries > 0)
       then Dec(retries)
-      else raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                             'Unable to open pipe, timed out');
+      else raise TTransportExceptionNotOpen.Create('Unable to open pipe, timed out');
     end;
 
     Sleep(INTERVAL)
@@ -540,8 +525,7 @@ begin
                        0);                // no template file
 
   if hPipe = INVALID_HANDLE_VALUE
-  then raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                         'Unable to open pipe, '+SysErrorMessage(GetLastError));
+  then raise TTransportExceptionNotOpen.Create('Unable to open pipe, '+SysErrorMessage(GetLastError));
 
   // everything fine
   FPipe := hPipe;
@@ -725,8 +709,7 @@ begin
   // pass the handles on to the client before the serve (acceptImpl)
   // blocking call.
   if not CreateAnonPipe
-  then raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                         ClassName+'.Create() failed');
+  then raise TTransportExceptionNotOpen.Create(ClassName+'.Create() failed');
 end;
 
 
@@ -740,8 +723,7 @@ begin
   // This 0-byte read serves merely as a blocking call.
   if not ReadFile( FReadHandle, buf, 0, br, nil)
   and (GetLastError() <> ERROR_MORE_DATA)
-  then raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                         'TServerPipe unable to initiate pipe communication');
+  then raise TTransportExceptionNotOpen.Create('TServerPipe unable to initiate pipe communication');
 
   // create the transport impl
   result := TAnonymousPipeTransportImpl.Create( FReadHandle, FWriteHandle, FALSE, FTimeOut);
@@ -798,16 +780,14 @@ begin
     sa.bInheritHandle       := TRUE; //allow passing handle to child
 
     if not CreatePipe( hCAR, hPipeW, @sa, FBufSize) then begin   //create stdin pipe
-      raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                        'TServerPipe CreatePipe (anon) failed, '+SysErrorMessage(GetLastError));
+      raise TTransportExceptionNotOpen.Create('TServerPipe CreatePipe (anon) failed, '+SysErrorMessage(GetLastError));
       Exit;
     end;
 
     if not CreatePipe( hPipe, hCAW, @sa, FBufSize) then begin  //create stdout pipe
       CloseHandle( hCAR);
       CloseHandle( hPipeW);
-      raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                        'TServerPipe CreatePipe (anon) failed, '+SysErrorMessage(GetLastError));
+      raise TTransportExceptionNotOpen.Create('TServerPipe CreatePipe (anon) failed, '+SysErrorMessage(GetLastError));
       Exit;
     end;
 
@@ -888,8 +868,7 @@ begin
 
     else
       InternalClose;
-      raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                        'Client connection failed');
+      raise TTransportExceptionNotOpen.Create('Client connection failed');
     end;
   end;
 
@@ -1001,8 +980,7 @@ begin
 
     if( result <> INVALID_HANDLE_VALUE)
     then InterlockedExchangePointer( Pointer(FHandle), Pointer(result))
-    else raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                           'CreateNamedPipe() failed ' + IntToStr(GetLastError));
+    else raise TTransportExceptionNotOpen.Create('CreateNamedPipe() failed ' + IntToStr(GetLastError));
 
   finally
     if sd <> nil then LocalFree( Cardinal( sd));

http://git-wip-us.apache.org/repos/asf/thrift/blob/e0e3240d/lib/delphi/src/Thrift.Transport.pas
----------------------------------------------------------------------
diff --git a/lib/delphi/src/Thrift.Transport.pas b/lib/delphi/src/Thrift.Transport.pas
index a46fe5c..080cb8c 100644
--- a/lib/delphi/src/Thrift.Transport.pas
+++ b/lib/delphi/src/Thrift.Transport.pas
@@ -84,14 +84,30 @@ type
         Interrupted
       );
   private
-    FType : TExceptionType;
+    function GetType: TExceptionType;
+  protected
+    constructor HiddenCreate(const Msg: string);
   public
-    constructor Create( AType: TExceptionType); overload;
-    constructor Create( const msg: string); overload;
-    constructor Create( AType: TExceptionType; const msg: string); overload;
-    property Type_: TExceptionType read FType;
+    class function Create( AType: TExceptionType): TTransportException; overload; deprecated 'Use specialized TTransportException types (or regenerate from IDL)';
+    class function Create( const msg: string): TTransportException; reintroduce; overload; deprecated 'Use specialized TTransportException types (or regenerate from IDL)';
+    class function Create( AType: TExceptionType; const msg: string): TTransportException; overload; deprecated 'Use specialized TTransportException types (or regenerate from IDL)';
+    property Type_: TExceptionType read GetType;
   end;
 
+  // Needed to remove deprecation warning
+  TTransportExceptionSpecialized = class abstract (TTransportException)
+  public
+    constructor Create(const Msg: string);
+  end;
+
+  TTransportExceptionUnknown = class (TTransportExceptionSpecialized);
+  TTransportExceptionNotOpen = class (TTransportExceptionSpecialized);
+  TTransportExceptionAlreadyOpen = class (TTransportExceptionSpecialized);
+  TTransportExceptionTimedOut = class (TTransportExceptionSpecialized);
+  TTransportExceptionEndOfFile = class (TTransportExceptionSpecialized);
+  TTransportExceptionBadArgs = class (TTransportExceptionSpecialized);
+  TTransportExceptionInterrupted = class (TTransportExceptionSpecialized);
+
   IHTTPClient = interface( ITransport )
     ['{0F5DB8AB-710D-4338-AAC9-46B5734C5057}']
     procedure SetConnectionTimeout(const Value: Integer);
@@ -349,10 +365,10 @@ type
         function GetTransport( const ATrans: ITransport): ITransport; override;
       end;
 
-	  {$IFDEF HAVE_CLASS_CTOR}
+    {$IFDEF HAVE_CLASS_CTOR}
     class constructor Create;
     {$ENDIF}
-	
+
     constructor Create; overload;
     constructor Create( const ATrans: ITransport); overload;
     destructor Destroy; override;
@@ -397,8 +413,8 @@ begin
   while got < len do begin
     ret := Read( buf, off + got, len - got);
     if ret > 0 
-  then Inc( got, ret)
-  else raise TTransportException.Create( 'Cannot read, Remote side has closed' );
+    then Inc( got, ret)
+    else raise TTransportExceptionNotOpen.Create( 'Cannot read, Remote side has closed' );
   end;
   Result := got;
 end;
@@ -488,15 +504,14 @@ end;
 function THTTPClientImpl.Read( var buf: TBytes; off, len: Integer): Integer;
 begin
   if FInputStream = nil then begin
-    raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                      'No request has been sent');
+    raise TTransportExceptionNotOpen.Create('No request has been sent');
   end;
 
   try
     Result := FInputStream.Read( buf, off, len )
   except
     on E: Exception
-    do raise TTransportException.Create( TTransportException.TExceptionType.Unknown, E.Message);
+    do raise TTransportExceptionUnknown.Create(E.Message);
   end;
 end;
 
@@ -542,22 +557,55 @@ end;
 
 { TTransportException }
 
-constructor TTransportException.Create(AType: TExceptionType);
+function TTransportException.GetType: TExceptionType;
+begin
+  if Self is TTransportExceptionNotOpen then Result := TExceptionType.NotOpen
+  else if Self is TTransportExceptionAlreadyOpen then Result := TExceptionType.AlreadyOpen
+  else if Self is TTransportExceptionTimedOut then Result := TExceptionType.TimedOut
+  else if Self is TTransportExceptionEndOfFile then Result := TExceptionType.EndOfFile
+  else if Self is TTransportExceptionBadArgs then Result := TExceptionType.BadArgs
+  else if Self is TTransportExceptionInterrupted then Result := TExceptionType.Interrupted
+  else Result := TExceptionType.Unknown;
+end;
+
+constructor TTransportException.HiddenCreate(const Msg: string);
+begin
+  inherited Create(Msg);
+end;
+
+class function TTransportException.Create(AType: TExceptionType): TTransportException;
 begin
   //no inherited;
-  Create( AType, '' )
+{$WARN SYMBOL_DEPRECATED OFF}
+  Result := Create(AType, '')
+{$WARN SYMBOL_DEPRECATED DEFAULT}
+end;
+
+class function TTransportException.Create(AType: TExceptionType;
+  const msg: string): TTransportException;
+begin
+  case AType of
+    TExceptionType.NotOpen:     Result := TTransportExceptionNotOpen.Create(msg);
+    TExceptionType.AlreadyOpen: Result := TTransportExceptionAlreadyOpen.Create(msg);
+    TExceptionType.TimedOut:    Result := TTransportExceptionTimedOut.Create(msg);
+    TExceptionType.EndOfFile:   Result := TTransportExceptionEndOfFile.Create(msg);
+    TExceptionType.BadArgs:     Result := TTransportExceptionBadArgs.Create(msg);
+    TExceptionType.Interrupted: Result := TTransportExceptionInterrupted.Create(msg);
+  else
+    Result := TTransportExceptionUnknown.Create(msg);
+  end;
 end;
 
-constructor TTransportException.Create(AType: TExceptionType;
-  const msg: string);
+class function TTransportException.Create(const msg: string): TTransportException;
 begin
-  inherited Create(msg);
-  FType := AType;
+  Result := TTransportExceptionUnknown.Create(Msg);
 end;
 
-constructor TTransportException.Create(const msg: string);
+{ TTransportExceptionSpecialized }
+
+constructor TTransportExceptionSpecialized.Create(const Msg: string);
 begin
-  inherited Create(msg);
+  inherited HiddenCreate(Msg);
 end;
 
 { TTransportFactoryImpl }
@@ -629,8 +677,7 @@ var
   trans  : IStreamTransport;
 begin
   if FServer = nil then begin
-    raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                      'No underlying server socket.');
+    raise TTransportExceptionNotOpen.Create('No underlying server socket.');
   end;
 
 {$IFDEF OLD_SOCKETS}
@@ -662,7 +709,7 @@ begin
   except
     on E: Exception do begin
       client.Free;
-      raise TTransportException.Create( E.ToString );
+      raise TTransportExceptionUnknown.Create(E.ToString);
     end;
   end;
 {$ELSE}
@@ -694,7 +741,7 @@ begin
       FServer.Active := True;
     except
       on E: Exception
-	  do raise TTransportException.Create('Could not accept on listening socket: ' + E.Message);
+      do raise TTransportExceptionUnknown.Create('Could not accept on listening socket: ' + E.Message);
     end;
 {$ELSE}
     FServer.Listen;
@@ -710,7 +757,7 @@ begin
       FServer.Active := False;
     except
       on E: Exception
-      do raise TTransportException.Create('Error on closing socket : ' + E.Message);
+      do raise TTransportExceptionUnknown.Create('Error on closing socket : ' + E.Message);
     end;
 {$ELSE}
     FServer.Close;
@@ -800,18 +847,15 @@ end;
 procedure TSocketImpl.Open;
 begin
   if IsOpen then begin
-    raise TTransportException.Create( TTransportException.TExceptionType.AlreadyOpen,
-                                      'Socket already connected');
+    raise TTransportExceptionAlreadyOpen.Create('Socket already connected');
   end;
 
   if FHost = '' then begin
-    raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                      'Cannot open null host');
+    raise TTransportExceptionNotOpen.Create('Cannot open null host');
   end;
 
   if Port <= 0 then begin
-    raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                      'Cannot open without port');
+    raise TTransportExceptionNotOpen.Create('Cannot open without port');
   end;
 
   if FClient = nil
@@ -973,8 +1017,7 @@ end;
 procedure TStreamTransportImpl.Flush;
 begin
   if FOutputStream = nil then begin
-    raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                      'Cannot flush null outputstream' );
+    raise TTransportExceptionNotOpen.Create('Cannot flush null outputstream' );
   end;
 
   FOutputStream.Flush;
@@ -1003,8 +1046,7 @@ end;
 function TStreamTransportImpl.Read(var buf: TBytes; off, len: Integer): Integer;
 begin
   if FInputStream = nil then begin
-    raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                      'Cannot read from null inputstream' );
+    raise TTransportExceptionNotOpen.Create('Cannot read from null inputstream' );
   end;
 
   Result := FInputStream.Read( buf, off, len );
@@ -1013,8 +1055,7 @@ end;
 procedure TStreamTransportImpl.Write(const buf: TBytes; off, len: Integer);
 begin
   if FOutputStream = nil then begin
-    raise TTransportException.Create( TTransportException.TExceptionType.NotOpen,
-                                      'Cannot write to null outputstream' );
+    raise TTransportExceptionNotOpen.Create('Cannot write to null outputstream' );
   end;
 
   FOutputStream.Write( buf, off, len );
@@ -1145,8 +1186,7 @@ begin
 
   data_len := len - FHeaderSize;
   if (data_len < 0) then begin
-    raise TTransportException.Create( TTransportException.TExceptionType.Unknown,
-                                      'TFramedTransport.Flush: data_len < 0' );
+    raise TTransportExceptionUnknown.Create('TFramedTransport.Flush: data_len < 0' );
   end;
 
   InitWriteBuffer;
@@ -1434,8 +1474,7 @@ begin
           if (FTimeout = 0)
           then Exit
           else begin
-            raise TTransportException.Create( TTransportException.TExceptionType.TimedOut,
-                                              SysErrorMessage(Cardinal(wsaError)));
+            raise TTransportExceptionTimedOut.Create(SysErrorMessage(Cardinal(wsaError)));
 
           end;
         end;
@@ -1482,7 +1521,7 @@ begin
   inherited;
 
   if not FTcpClient.Active
-  then raise TTransportException.Create( TTransportException.TExceptionType.NotOpen);
+  then raise TTransportExceptionNotOpen.Create('not open');
 
   // The select function returns the total number of socket handles that are ready
   // and contained in the fd_set structures, zero if the time limit expired,
@@ -1490,14 +1529,13 @@ begin
   // WSAGetLastError can be used to retrieve a specific error code.
   retval := Self.Select( nil, @bCanWrite, @bError, FTimeOut, wsaError);
   if retval = SOCKET_ERROR
-  then raise TTransportException.Create( TTransportException.TExceptionType.Unknown,
-                                         SysErrorMessage(Cardinal(wsaError)));
+  then raise TTransportExceptionUnknown.Create(SysErrorMessage(Cardinal(wsaError)));
 
   if (retval = 0)
-  then raise TTransportException.Create( TTransportException.TExceptionType.TimedOut);
+  then raise TTransportExceptionTimedOut.Create('timed out');
 
   if bError or not bCanWrite
-  then raise TTransportException.Create( TTransportException.TExceptionType.Unknown);
+  then raise TTransportExceptionUnknown.Create('unknown error');
 
   FTcpClient.SendBuf( Pointer(@buffer[offset])^, count);
 end;

http://git-wip-us.apache.org/repos/asf/thrift/blob/e0e3240d/lib/delphi/src/Thrift.pas
----------------------------------------------------------------------
diff --git a/lib/delphi/src/Thrift.pas b/lib/delphi/src/Thrift.pas
index 65f23ab..e969ebf 100644
--- a/lib/delphi/src/Thrift.pas
+++ b/lib/delphi/src/Thrift.pas
@@ -28,6 +28,8 @@ const
   Version = '1.0.0-dev';
 
 type
+  TApplicationExceptionSpecializedClass = class of TApplicationExceptionSpecialized;
+
   TApplicationException = class( SysUtils.Exception )
   public
     type
@@ -47,16 +49,40 @@ type
       );
 {$SCOPEDENUMS OFF}
   private
-    FType : TExceptionType;
+    function GetType: TExceptionType;
+  protected
+    constructor HiddenCreate(const Msg: string);
   public
-    constructor Create; overload;
-    constructor Create( AType: TExceptionType); overload;
-    constructor Create( AType: TExceptionType; const msg: string); overload;
+    // purposefully hide inherited constructor
+    class function Create(const Msg: string): TApplicationException; overload; deprecated 'Use specialized TApplicationException types (or regenerate from IDL)';
+    class function Create: TApplicationException; overload; deprecated 'Use specialized TApplicationException types (or regenerate from IDL)';
+    class function Create( AType: TExceptionType): TApplicationException; overload; deprecated 'Use specialized TApplicationException types (or regenerate from IDL)';
+    class function Create( AType: TExceptionType; const msg: string): TApplicationException; overload; deprecated 'Use specialized TApplicationException types (or regenerate from IDL)';
+
+    class function GetSpecializedExceptionType(AType: TExceptionType): TApplicationExceptionSpecializedClass;
 
     class function Read( const iprot: IProtocol): TApplicationException;
     procedure Write( const oprot: IProtocol );
   end;
 
+  // Needed to remove deprecation warning
+  TApplicationExceptionSpecialized = class abstract (TApplicationException)
+  public
+    constructor Create(const Msg: string);
+  end;
+
+  TApplicationExceptionUnknown = class (TApplicationExceptionSpecialized);
+  TApplicationExceptionUnknownMethod = class (TApplicationExceptionSpecialized);
+  TApplicationExceptionInvalidMessageType = class (TApplicationExceptionSpecialized);
+  TApplicationExceptionWrongMethodName = class (TApplicationExceptionSpecialized);
+  TApplicationExceptionBadSequenceID = class (TApplicationExceptionSpecialized);
+  TApplicationExceptionMissingResult = class (TApplicationExceptionSpecialized);
+  TApplicationExceptionInternalError = class (TApplicationExceptionSpecialized);
+  TApplicationExceptionProtocolError = class (TApplicationExceptionSpecialized);
+  TApplicationExceptionInvalidTransform = class (TApplicationExceptionSpecialized);
+  TApplicationExceptionInvalidProtocol = class (TApplicationExceptionSpecialized);
+  TApplicationExceptionUnsupportedClientType = class (TApplicationExceptionSpecialized);
+
   // base class for IDL-generated exceptions
   TException = class( SysUtils.Exception)
   public
@@ -84,22 +110,64 @@ end;
 
 { TApplicationException }
 
-constructor TApplicationException.Create;
+function TApplicationException.GetType: TExceptionType;
+begin
+  if Self is TApplicationExceptionUnknownMethod then Result := TExceptionType.UnknownMethod
+  else if Self is TApplicationExceptionInvalidMessageType then Result := TExceptionType.InvalidMessageType
+  else if Self is TApplicationExceptionWrongMethodName then Result := TExceptionType.WrongMethodName
+  else if Self is TApplicationExceptionBadSequenceID then Result := TExceptionType.BadSequenceID
+  else if Self is TApplicationExceptionMissingResult then Result := TExceptionType.MissingResult
+  else if Self is TApplicationExceptionInternalError then Result := TExceptionType.InternalError
+  else if Self is TApplicationExceptionProtocolError then Result := TExceptionType.ProtocolError
+  else if Self is TApplicationExceptionInvalidTransform then Result := TExceptionType.InvalidTransform
+  else if Self is TApplicationExceptionInvalidProtocol then Result := TExceptionType.InvalidProtocol
+  else if Self is TApplicationExceptionUnsupportedClientType then Result := TExceptionType.UnsupportedClientType
+  else Result := TExceptionType.Unknown;
+end;
+
+constructor TApplicationException.HiddenCreate(const Msg: string);
+begin
+  inherited Create(Msg);
+end;
+
+class function TApplicationException.Create(const Msg: string): TApplicationException;
 begin
-  inherited Create( '' );
+  Result := TApplicationExceptionUnknown.Create(Msg);
 end;
 
-constructor TApplicationException.Create(AType: TExceptionType;
-  const msg: string);
+class function TApplicationException.Create: TApplicationException;
 begin
-  inherited Create( msg );
-  FType := AType;
+  Result := TApplicationExceptionUnknown.Create('');
 end;
 
-constructor TApplicationException.Create(AType: TExceptionType);
+class function TApplicationException.Create( AType: TExceptionType): TApplicationException;
 begin
-  inherited Create('');
-  FType := AType;
+{$WARN SYMBOL_DEPRECATED OFF}
+  Result := Create(AType, '');
+{$WARN SYMBOL_DEPRECATED DEFAULT}
+end;
+
+class function TApplicationException.Create( AType: TExceptionType; const msg: string): TApplicationException;
+begin
+  Result := GetSpecializedExceptionType(AType).Create(msg);
+end;
+
+class function TApplicationException.GetSpecializedExceptionType(AType: TExceptionType): TApplicationExceptionSpecializedClass;
+begin
+  case AType of
+    TExceptionType.UnknownMethod:         Result := TApplicationExceptionUnknownMethod;
+    TExceptionType.InvalidMessageType:    Result := TApplicationExceptionInvalidMessageType;
+    TExceptionType.WrongMethodName:       Result := TApplicationExceptionWrongMethodName;
+    TExceptionType.BadSequenceID:         Result := TApplicationExceptionBadSequenceID;
+    TExceptionType.MissingResult:         Result := TApplicationExceptionMissingResult;
+    TExceptionType.InternalError:         Result := TApplicationExceptionInternalError;
+    TExceptionType.ProtocolError:         Result := TApplicationExceptionProtocolError;
+    TExceptionType.InvalidTransform:      Result := TApplicationExceptionInvalidTransform;
+    TExceptionType.InvalidProtocol:       Result := TApplicationExceptionInvalidProtocol;
+    TExceptionType.UnsupportedClientType: Result := TApplicationExceptionUnsupportedClientType;
+  else
+    Result := TApplicationExceptionUnknown;
+  end;
 end;
 
 class function TApplicationException.Read( const iprot: IProtocol): TApplicationException;
@@ -147,7 +215,7 @@ begin
     iprot.ReadFieldEnd;
   end;
   iprot.ReadStructEnd;
-  Result := TApplicationException.Create( typ, msg );
+  Result := GetSpecializedExceptionType(typ).Create(msg);
 end;
 
 procedure TApplicationException.Write( const oprot: IProtocol);
@@ -174,10 +242,17 @@ begin
   field.Type_ := TType.I32;
   field.Id := 2;
   oprot.WriteFieldBegin(field);
-  oprot.WriteI32(Integer(FType));
+  oprot.WriteI32(Integer(GetType));
   oprot.WriteFieldEnd();
   oprot.WriteFieldStop();
   oprot.WriteStructEnd();
 end;
 
+{ TApplicationExceptionSpecialized }
+
+constructor TApplicationExceptionSpecialized.Create(const Msg: string);
+begin
+  inherited HiddenCreate(Msg);
+end;
+
 end.

http://git-wip-us.apache.org/repos/asf/thrift/blob/e0e3240d/lib/delphi/test/client.dpr
----------------------------------------------------------------------
diff --git a/lib/delphi/test/client.dpr b/lib/delphi/test/client.dpr
index 88f0fd4..f2e5250 100644
--- a/lib/delphi/test/client.dpr
+++ b/lib/delphi/test/client.dpr
@@ -33,6 +33,7 @@ uses
   Thrift.Protocol in '..\src\Thrift.Protocol.pas',
   Thrift.Protocol.JSON in '..\src\Thrift.Protocol.JSON.pas',
   Thrift.Protocol.Compact in '..\src\Thrift.Protocol.Compact.pas',
+  Thrift.Protocol.Multiplex in '..\src\Thrift.Protocol.Multiplex.pas',
   Thrift.Collections in '..\src\Thrift.Collections.pas',
   Thrift.Server in '..\src\Thrift.Server.pas',
   Thrift.Stream in '..\src\Thrift.Stream.pas',

http://git-wip-us.apache.org/repos/asf/thrift/blob/e0e3240d/lib/delphi/test/server.dpr
----------------------------------------------------------------------
diff --git a/lib/delphi/test/server.dpr b/lib/delphi/test/server.dpr
index 9739f5f..d87a331 100644
--- a/lib/delphi/test/server.dpr
+++ b/lib/delphi/test/server.dpr
@@ -33,6 +33,8 @@ uses
   Thrift.Protocol in '..\src\Thrift.Protocol.pas',
   Thrift.Protocol.JSON in '..\src\Thrift.Protocol.JSON.pas',
   Thrift.Protocol.Compact in '..\src\Thrift.Protocol.Compact.pas',
+  Thrift.Protocol.Multiplex in '..\src\Thrift.Protocol.Multiplex.pas',
+  Thrift.Processor.Multiplex in '..\src\Thrift.Processor.Multiplex.pas',
   Thrift.Collections in '..\src\Thrift.Collections.pas',
   Thrift.Server in '..\src\Thrift.Server.pas',
   Thrift.Console in '..\src\Thrift.Console.pas',