THRIFT-5004 Make exception implementations more consistent  [ci skip]
Client: Delphi
Patch: Jens Geyer
diff --git a/lib/delphi/src/Thrift.Protocol.pas b/lib/delphi/src/Thrift.Protocol.pas
index 609dfc6..47e88fe 100644
--- a/lib/delphi/src/Thrift.Protocol.pas
+++ b/lib/delphi/src/Thrift.Protocol.pas
@@ -112,24 +112,27 @@
     function GetProtocol( const trans: ITransport): IProtocol;
   end;
 
-  TProtocolException = class( TException)
+  TProtocolException = class abstract( TException)
   public
-    const // TODO(jensg): change into enum
-      UNKNOWN = 0;
-      INVALID_DATA = 1;
-      NEGATIVE_SIZE = 2;
-      SIZE_LIMIT = 3;
-      BAD_VERSION = 4;
-      NOT_IMPLEMENTED = 5;
-      DEPTH_LIMIT = 6;
+    type TExceptionType = (
+      UNKNOWN = 0,
+      INVALID_DATA = 1,
+      NEGATIVE_SIZE = 2,
+      SIZE_LIMIT = 3,
+      BAD_VERSION = 4,
+      NOT_IMPLEMENTED = 5,
+      DEPTH_LIMIT = 6
+    );
   protected
     constructor HiddenCreate(const Msg: string);
+    class function GetType: TExceptionType;  virtual; abstract;
   public
     // 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)';
+    class function Create( aType: TExceptionType): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
+    class function Create( aType: TExceptionType; const msg: string): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)';
+    property Type_: TExceptionType read GetType;
   end;
 
   // Needed to remove deprecation warning
@@ -138,13 +141,41 @@
     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);
+  TProtocolExceptionUnknown = class (TProtocolExceptionSpecialized)
+  protected
+    class function GetType: TProtocolException.TExceptionType;  override;
+  end;
+
+  TProtocolExceptionInvalidData = class (TProtocolExceptionSpecialized)
+  protected
+    class function GetType: TProtocolException.TExceptionType;  override;
+  end;
+
+  TProtocolExceptionNegativeSize = class (TProtocolExceptionSpecialized)
+  protected
+    class function GetType: TProtocolException.TExceptionType;  override;
+  end;
+
+  TProtocolExceptionSizeLimit = class (TProtocolExceptionSpecialized)
+  protected
+    class function GetType: TProtocolException.TExceptionType;  override;
+  end;
+
+  TProtocolExceptionBadVersion = class (TProtocolExceptionSpecialized)
+  protected
+    class function GetType: TProtocolException.TExceptionType;  override;
+  end;
+
+  TProtocolExceptionNotImplemented = class (TProtocolExceptionSpecialized)
+  protected
+    class function GetType: TProtocolException.TExceptionType;  override;
+  end;
+
+  TProtocolExceptionDepthLimit = class (TProtocolExceptionSpecialized)
+  protected
+    class function GetType: TProtocolException.TExceptionType;  override;
+  end;
+
 
 
   TProtocolUtil = class
@@ -1000,23 +1031,24 @@
   Result := TProtocolExceptionUnknown.Create('');
 end;
 
-class function TProtocolException.Create(type_: Integer): TProtocolException;
+class function TProtocolException.Create(aType: TExceptionType): TProtocolException;
 begin
 {$WARN SYMBOL_DEPRECATED OFF}
-  Result := Create(type_, '');
+  Result := Create(aType, '');
 {$WARN SYMBOL_DEPRECATED DEFAULT}
 end;
 
-class function TProtocolException.Create(type_: Integer; const msg: string): TProtocolException;
+class function TProtocolException.Create(aType: TExceptionType; 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);
+  case aType of
+    TExceptionType.INVALID_DATA:    Result := TProtocolExceptionInvalidData.Create(msg);
+    TExceptionType.NEGATIVE_SIZE:   Result := TProtocolExceptionNegativeSize.Create(msg);
+    TExceptionType.SIZE_LIMIT:      Result := TProtocolExceptionSizeLimit.Create(msg);
+    TExceptionType.BAD_VERSION:     Result := TProtocolExceptionBadVersion.Create(msg);
+    TExceptionType.NOT_IMPLEMENTED: Result := TProtocolExceptionNotImplemented.Create(msg);
+    TExceptionType.DEPTH_LIMIT:     Result := TProtocolExceptionDepthLimit.Create(msg);
   else
+    ASSERT( TExceptionType.UNKNOWN = aType);
     Result := TProtocolExceptionUnknown.Create(msg);
   end;
 end;
@@ -1028,6 +1060,43 @@
   inherited HiddenCreate(Msg);
 end;
 
+{ specialized TProtocolExceptions }
+
+class function TProtocolExceptionUnknown.GetType: TProtocolException.TExceptionType;
+begin
+  result := TExceptionType.UNKNOWN;
+end;
+
+class function TProtocolExceptionInvalidData.GetType: TProtocolException.TExceptionType;
+begin
+  result := TExceptionType.INVALID_DATA;
+end;
+
+class function TProtocolExceptionNegativeSize.GetType: TProtocolException.TExceptionType;
+begin
+  result := TExceptionType.NEGATIVE_SIZE;
+end;
+
+class function TProtocolExceptionSizeLimit.GetType: TProtocolException.TExceptionType;
+begin
+  result := TExceptionType.SIZE_LIMIT;
+end;
+
+class function TProtocolExceptionBadVersion.GetType: TProtocolException.TExceptionType;
+begin
+  result := TExceptionType.BAD_VERSION;
+end;
+
+class function TProtocolExceptionNotImplemented.GetType: TProtocolException.TExceptionType;
+begin
+  result := TExceptionType.NOT_IMPLEMENTED;
+end;
+
+class function TProtocolExceptionDepthLimit.GetType: TProtocolException.TExceptionType;
+begin
+  result := TExceptionType.DEPTH_LIMIT;
+end;
+
 { TBinaryProtocolImpl.TFactory }
 
 constructor TBinaryProtocolImpl.TFactory.Create(AStrictRead, AStrictWrite: Boolean);
diff --git a/lib/delphi/src/Thrift.Transport.pas b/lib/delphi/src/Thrift.Transport.pas
index c2071df..df087a1 100644
--- a/lib/delphi/src/Thrift.Transport.pas
+++ b/lib/delphi/src/Thrift.Transport.pas
@@ -81,7 +81,7 @@
     procedure Flush; virtual;
   end;
 
-  TTransportException = class( TException)
+  TTransportException = class abstract( TException)
   public
     type
       TExceptionType = (
@@ -93,10 +93,9 @@
         BadArgs,
         Interrupted
       );
-  private
-    function GetType: TExceptionType;
   protected
     constructor HiddenCreate(const Msg: string);
+    class function GetType: TExceptionType;  virtual; abstract;
   public
     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)';
@@ -110,13 +109,40 @@
     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);
+  TTransportExceptionUnknown = class (TTransportExceptionSpecialized)
+  protected
+    class function GetType: TTransportException.TExceptionType;  override;
+  end;
+
+  TTransportExceptionNotOpen = class (TTransportExceptionSpecialized)
+  protected
+    class function GetType: TTransportException.TExceptionType;  override;
+  end;
+
+  TTransportExceptionAlreadyOpen = class (TTransportExceptionSpecialized)
+  protected
+    class function GetType: TTransportException.TExceptionType;  override;
+  end;
+
+  TTransportExceptionTimedOut = class (TTransportExceptionSpecialized)
+  protected
+    class function GetType: TTransportException.TExceptionType;  override;
+  end;
+
+  TTransportExceptionEndOfFile = class (TTransportExceptionSpecialized)
+  protected
+    class function GetType: TTransportException.TExceptionType;  override;
+  end;
+
+  TTransportExceptionBadArgs = class (TTransportExceptionSpecialized)
+  protected
+    class function GetType: TTransportException.TExceptionType;  override;
+  end;
+
+  TTransportExceptionInterrupted = class (TTransportExceptionSpecialized)
+  protected
+    class function GetType: TTransportException.TExceptionType;  override;
+  end;
 
   TSecureProtocol = (
     SSL_2, SSL_3, TLS_1,   // outdated, for compatibilty only
@@ -446,17 +472,6 @@
 
 { TTransportException }
 
-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);
@@ -470,8 +485,7 @@
 {$WARN SYMBOL_DEPRECATED DEFAULT}
 end;
 
-class function TTransportException.Create(AType: TExceptionType;
-  const msg: string): TTransportException;
+class function TTransportException.Create(aType: TExceptionType; const msg: string): TTransportException;
 begin
   case AType of
     TExceptionType.NotOpen:     Result := TTransportExceptionNotOpen.Create(msg);
@@ -481,6 +495,7 @@
     TExceptionType.BadArgs:     Result := TTransportExceptionBadArgs.Create(msg);
     TExceptionType.Interrupted: Result := TTransportExceptionInterrupted.Create(msg);
   else
+    ASSERT( TExceptionType.Unknown = aType);
     Result := TTransportExceptionUnknown.Create(msg);
   end;
 end;
@@ -497,6 +512,43 @@
   inherited HiddenCreate(Msg);
 end;
 
+{ specialized TTransportExceptions }
+
+class function TTransportExceptionUnknown.GetType: TTransportException.TExceptionType;
+begin
+  result := TExceptionType.Unknown;
+end;
+
+class function TTransportExceptionNotOpen.GetType: TTransportException.TExceptionType;
+begin
+  result := TExceptionType.NotOpen;
+end;
+
+class function TTransportExceptionAlreadyOpen.GetType: TTransportException.TExceptionType;
+begin
+  result := TExceptionType.AlreadyOpen;
+end;
+
+class function TTransportExceptionTimedOut.GetType: TTransportException.TExceptionType;
+begin
+  result := TExceptionType.TimedOut;
+end;
+
+class function TTransportExceptionEndOfFile.GetType: TTransportException.TExceptionType;
+begin
+  result := TExceptionType.EndOfFile;
+end;
+
+class function TTransportExceptionBadArgs.GetType: TTransportException.TExceptionType;
+begin
+  result := TExceptionType.BadArgs;
+end;
+
+class function TTransportExceptionInterrupted.GetType: TTransportException.TExceptionType;
+begin
+  result := TExceptionType.Interrupted;
+end;
+
 { TTransportFactoryImpl }
 
 function TTransportFactoryImpl.GetTransport( const ATrans: ITransport): ITransport;
diff --git a/lib/delphi/src/Thrift.pas b/lib/delphi/src/Thrift.pas
index e127380..abc0c1e 100644
--- a/lib/delphi/src/Thrift.pas
+++ b/lib/delphi/src/Thrift.pas
@@ -34,7 +34,7 @@
 
   TApplicationExceptionSpecializedClass = class of TApplicationExceptionSpecialized;
 
-  TApplicationException = class( TException)
+  TApplicationException = class abstract( TException)
   public
     type
 {$SCOPEDENUMS ON}
@@ -52,10 +52,10 @@
         UnsupportedClientType
       );
 {$SCOPEDENUMS OFF}
-  private
-    function GetType: TExceptionType;
   protected
     constructor HiddenCreate(const Msg: string);
+    class function GetType: TExceptionType;  virtual; abstract;
+    class function GetSpecializedExceptionType(AType: TExceptionType): TApplicationExceptionSpecializedClass;
   public
     // purposefully hide inherited constructor
     class function Create(const Msg: string): TApplicationException; overload; deprecated 'Use specialized TApplicationException types (or regenerate from IDL)';
@@ -63,7 +63,7 @@
     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;
+    property Type_: TExceptionType read GetType;
 
     class function Read( const iprot: IProtocol): TApplicationException;
     procedure Write( const oprot: IProtocol );
@@ -75,38 +75,67 @@
     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);
+  TApplicationExceptionUnknown = class (TApplicationExceptionSpecialized)
+  protected
+    class function GetType: TApplicationException.TExceptionType;  override;
+  end;
+
+  TApplicationExceptionUnknownMethod = class (TApplicationExceptionSpecialized)
+  protected
+    class function GetType: TApplicationException.TExceptionType;  override;
+  end;
+
+  TApplicationExceptionInvalidMessageType = class (TApplicationExceptionSpecialized)
+  protected
+    class function GetType: TApplicationException.TExceptionType;  override;
+  end;
+
+  TApplicationExceptionWrongMethodName = class (TApplicationExceptionSpecialized)
+  protected
+    class function GetType: TApplicationException.TExceptionType;  override;
+  end;
+
+  TApplicationExceptionBadSequenceID = class (TApplicationExceptionSpecialized)
+  protected
+    class function GetType: TApplicationException.TExceptionType;  override;
+  end;
+
+  TApplicationExceptionMissingResult = class (TApplicationExceptionSpecialized)
+  protected
+    class function GetType: TApplicationException.TExceptionType;  override;
+  end;
+
+  TApplicationExceptionInternalError = class (TApplicationExceptionSpecialized)
+  protected
+    class function GetType: TApplicationException.TExceptionType;  override;
+  end;
+
+  TApplicationExceptionProtocolError = class (TApplicationExceptionSpecialized)
+  protected
+    class function GetType: TApplicationException.TExceptionType;  override;
+  end;
+
+  TApplicationExceptionInvalidTransform = class (TApplicationExceptionSpecialized)
+  protected
+    class function GetType: TApplicationException.TExceptionType;  override;
+  end;
+
+  TApplicationExceptionInvalidProtocol = class (TApplicationExceptionSpecialized)
+  protected
+    class function GetType: TApplicationException.TExceptionType;  override;
+  end;
+
+  TApplicationExceptionUnsupportedClientType = class (TApplicationExceptionSpecialized)
+  protected
+    class function GetType: TApplicationException.TExceptionType;  override;
+  end;
+
 
 
 implementation
 
 { TApplicationException }
 
-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);
@@ -148,10 +177,12 @@
     TExceptionType.InvalidProtocol:       Result := TApplicationExceptionInvalidProtocol;
     TExceptionType.UnsupportedClientType: Result := TApplicationExceptionUnsupportedClientType;
   else
+    ASSERT( TExceptionType.Unknown = aType);
     Result := TApplicationExceptionUnknown;
   end;
 end;
 
+
 class function TApplicationException.Read( const iprot: IProtocol): TApplicationException;
 var
   field : TThriftField;
@@ -236,4 +267,62 @@
   inherited HiddenCreate(Msg);
 end;
 
+{ specialized TApplicationExceptions }
+
+class function TApplicationExceptionUnknownMethod.GetType : TApplicationException.TExceptionType;
+begin
+  result := TExceptionType.UnknownMethod;
+end;
+
+class function TApplicationExceptionInvalidMessageType.GetType : TApplicationException.TExceptionType;
+begin
+  result := TExceptionType.InvalidMessageType;
+end;
+
+class function TApplicationExceptionWrongMethodName.GetType : TApplicationException.TExceptionType;
+begin
+  result := TExceptionType.WrongMethodName;
+end;
+
+class function TApplicationExceptionBadSequenceID.GetType : TApplicationException.TExceptionType;
+begin
+  result := TExceptionType.BadSequenceID;
+end;
+
+class function TApplicationExceptionMissingResult.GetType : TApplicationException.TExceptionType;
+begin
+  result := TExceptionType.MissingResult;
+end;
+
+class function TApplicationExceptionInternalError.GetType : TApplicationException.TExceptionType;
+begin
+  result := TExceptionType.InternalError;
+end;
+
+class function TApplicationExceptionProtocolError.GetType : TApplicationException.TExceptionType;
+begin
+  result := TExceptionType.ProtocolError;
+end;
+
+class function TApplicationExceptionInvalidTransform.GetType : TApplicationException.TExceptionType;
+begin
+  result := TExceptionType.InvalidTransform;
+end;
+
+class function TApplicationExceptionInvalidProtocol.GetType : TApplicationException.TExceptionType;
+begin
+  result := TExceptionType.InvalidProtocol;
+end;
+
+class function TApplicationExceptionUnsupportedClientType.GetType : TApplicationException.TExceptionType;
+begin
+  result := TExceptionType.UnsupportedClientType;
+end;
+
+class function TApplicationExceptionUnknown.GetType : TApplicationException.TExceptionType;
+begin
+  result := TExceptionType.Unknown;
+end;
+
+
 end.