| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282 |
- {******************************************************************************}
- { }
- { Library: Fundamentals 4.00 }
- { File name: cProtoBufProtoNodes.pas }
- { File version: 0.02 }
- { Description: Protocol Buffer proto file nodes. }
- { }
- { Copyright: Copyright (c) 2012-2013, David J Butler }
- { All rights reserved. }
- { This file is licensed under the BSD License. }
- { See http://www.opensource.org/licenses/bsd-license.php }
- { Redistribution and use in source and binary forms, with }
- { or without modification, are permitted provided that }
- { the following conditions are met: }
- { Redistributions of source code must retain the above }
- { copyright notice, this list of conditions and the }
- { following disclaimer. }
- { THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND }
- { CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED }
- { WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED }
- { WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A }
- { PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL }
- { THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, }
- { INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR }
- { CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, }
- { PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF }
- { USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) }
- { HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER }
- { IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING }
- { NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE }
- { USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE }
- { POSSIBILITY OF SUCH DAMAGE. }
- { }
- { Home page: http://fundementals.sourceforge.net }
- { Forum: http://sourceforge.net/forum/forum.php?forum_id=2117 }
- { E-mail: fundamentals.library@gmail.com }
- { }
- { Revision history: }
- { }
- { 2012/04/15 0.01 Initial development: Proto nodes. }
- { 2012/04/26 0.02 Resolve delimited identifiers. }
- { }
- {******************************************************************************}
- {$INCLUDE cProtoBuf.inc}
- unit cProtoBufProtoNodes;
- interface
- uses
- { System }
- SysUtils;
- type
- TpbProtoNodeFactory = class;
- TpbProtoNode = class
- protected
- public
- function ResolveValue(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode; virtual;
- function ResolveType(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode; virtual;
- function ExpectResolvedValue(const AIdentifier: AnsiString): TpbProtoNode;
- function ExpectResolvedType(const AIdentifier: AnsiString): TpbProtoNode;
- function GetAsProtoString: AnsiString; virtual;
- end;
- EpbProtoNode = class(Exception);
- TpbProtoEnum = class; // forward
- TpbProtoEnumValue = class(TpbProtoNode)
- protected
- FParentEnum : TpbProtoEnum;
- FName : AnsiString;
- FValue : LongInt;
- public
- constructor Create(const AParentEnum: TpbProtoEnum);
- property Name: AnsiString read FName write FName;
- property Value: LongInt read FValue write FValue;
- function GetAsProtoString: AnsiString; override;
- end;
- TpbProtoMessage = class; // forward
- TpbProtoEnum = class(TpbProtoNode)
- protected
- FName : AnsiString;
- FValues : array of TpbProtoEnumValue;
- public
- constructor Create(const AParentNode: TpbProtoNode);
- property Name: AnsiString read FName write FName;
- procedure Add(const V: TpbProtoEnumValue);
- function GetValueCount: Integer;
- function GetValue(const Idx: Integer): TpbProtoEnumValue;
- function GetValueByName(const AName: AnsiString): TpbProtoEnumValue;
- function ResolveValue(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode; override;
- function GetAsProtoString: AnsiString; override;
- end;
- TpbProtoLiteralType = (
- pltNone,
- pltInteger,
- pltFloat,
- pltString,
- pltBoolean,
- pltIdentifier
- );
- TpbProtoLiteral = class(TpbProtoNode)
- protected
- FParentNode : TpbProtoNode;
- FLiteralType : TpbProtoLiteralType;
- FLiteralInt : Int64;
- FLiteralFloat : Extended;
- FLiteralStr : AnsiString;
- FLiteralBool : Boolean;
- FLiteralIden : AnsiString;
- public
- constructor Create(const AParentNode: TpbProtoNode);
- property LiteralType: TpbProtoLiteralType read FLiteralType write FLiteralType;
- property LiteralInt: Int64 read FLiteralInt write FLiteralInt;
- property LiteralFloat: Extended read FLiteralFloat write FLiteralFloat;
- property LiteralStr: AnsiString read FLiteralStr write FLiteralStr;
- property LiteralBool: Boolean read FLiteralBool write FLiteralBool;
- property LiteralIden: AnsiString read FLiteralIden write FLiteralIden;
- function ResolveValue(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode; override;
- function GetAsProtoString: AnsiString; override;
- function LiteralIdenValue: TpbProtoNode;
- end;
- TpbProtoOption = class(TpbProtoNode)
- protected
- FCustom : Boolean;
- FName : AnsiString;
- FValue : TpbProtoLiteral;
- procedure SetValue(const Value: TpbProtoLiteral);
- public
- constructor Create(const AFactory: TpbProtoNodeFactory);
- destructor Destroy; override;
- property Custom: Boolean read FCustom write FCustom;
- property Name: AnsiString read FName write FName;
- property Value: TpbProtoLiteral read FValue write FValue;
- end;
- TpbProtoFieldCardinality = (
- pfcNone,
- pfcRequired,
- pfcOptional,
- pfcRepeated
- );
- TpbProtoFieldBaseType = (
- pftNone,
- pftDouble,
- pftFloat,
- pftInt32,
- pftInt64,
- pftUInt32,
- pftUInt64,
- pftSInt32,
- pftSInt64,
- pftFixed32,
- pftFixed64,
- pftSFixed32,
- pftSFixed64,
- pftBool,
- pftString,
- pftBytes,
- pftIdentifier
- );
- TpbProtoField = class; // forward
- TpbProtoFieldType = class(TpbProtoNode)
- protected
- FParentField : TpbProtoField;
- FBaseType : TpbProtoFieldBaseType;
- FIdenStr : AnsiString;
- public
- constructor Create(const AParentField: TpbProtoField);
- property ParentField: TpbProtoField read FParentField;
- property BaseType: TpbProtoFieldBaseType read FBaseType write FBaseType;
- property IdenStr: AnsiString read FIdenStr write FIdenStr;
- function ResolveType(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode; override;
- function GetAsProtoString: AnsiString; override;
- function IsSimpleType: Boolean;
- function IsIdenType: Boolean;
- function IdenType: TpbProtoNode;
- end;
- TpbProtoField = class(TpbProtoNode)
- protected
- FParentMessage : TpbProtoMessage;
- FName : AnsiString;
- FFieldType : TpbProtoFieldType;
- FCardinality : TpbProtoFieldCardinality;
- FTagID : LongInt;
- FDefaultValue : TpbProtoLiteral;
- FOptionPacked : Boolean;
- FOptions : array of TpbProtoOption;
- procedure SetFieldType(const Value: TpbProtoFieldType);
- procedure SetDefaultValue(const Value: TpbProtoLiteral);
- public
- constructor Create(const AParentMessage: TpbProtoMessage; const AFactory: TpbProtoNodeFactory);
- destructor Destroy; override;
- property ParentMessage: TpbProtoMessage read FParentMessage;
- property Name: AnsiString read FName write FName;
- property FieldType: TpbProtoFieldType read FFieldType write SetFieldType;
- property Cardinality: TpbProtoFieldCardinality read FCardinality write FCardinality;
- property TagID: LongInt read FTagID write FTagID;
- property DefaultValue: TpbProtoLiteral read FDefaultValue write SetDefaultValue;
- property OptionPacked: Boolean read FOptionPacked write FOptionPacked;
- procedure AddOption(const Option: TpbProtoOption);
- function GetOptionCount: Integer;
- function GetOption(const Idx: Integer): TpbProtoOption;
- function ResolveValue(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode; override;
- function ResolveType(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode; override;
- function GetAsProtoString: AnsiString; override;
- end;
- TpbProtoMessage = class(TpbProtoNode)
- protected
- FParentNode : TpbProtoNode;
- FName : AnsiString;
- FMessages : array of TpbProtoMessage;
- FFields : array of TpbProtoField;
- FEnums : array of TpbProtoEnum;
- FExtensionsMin : LongInt;
- FExtensionsMax : LongInt;
- function GetFieldCount: Integer;
- function GetField(const Idx: Integer): TpbProtoField;
- function GetEnumCount: Integer;
- function GetEnum(const Idx: Integer): TpbProtoEnum;
- function GetEnumByName(const AName: AnsiString): TpbProtoEnum;
- function GetMessageCount: Integer;
- function GetMessage(const Idx: Integer): TpbProtoMessage;
- function GetMessageByName(const AName: AnsiString): TpbProtoMessage;
- public
- constructor Create(const AParentNode: TpbProtoNode);
- destructor Destroy; override;
- property ParentNode: TpbProtoNode read FParentNode;
- property Name: AnsiString read FName write FName;
- procedure AddField(const F: TpbProtoField);
- property FieldCount: Integer read GetFieldCount;
- property Field[const Idx: Integer]: TpbProtoField read GetField;
- function GetFieldByTagID(const ATagID: Integer): TpbProtoField;
- procedure AddEnum(const E: TpbProtoEnum);
- property EnumCount: Integer read GetEnumCount;
- property Enum[const Idx: Integer]: TpbProtoEnum read GetEnum;
- procedure AddMessage(const M: TpbProtoMessage);
- property MessageCount: Integer read GetMessageCount;
- property Msg[const Idx: Integer]: TpbProtoMessage read GetMessage;
- property ExtensionsMin: LongInt read FExtensionsMin write FExtensionsMin;
- property ExtensionsMax: LongInt read FExtensionsMax write FExtensionsMax;
- function ResolveValue(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode; override;
- function ResolveType(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode; override;
- function GetAsProtoString: AnsiString; override;
- end;
- TpbProtoPackage = class(TpbProtoNode)
- protected
- FFileName : AnsiString;
- FName : AnsiString;
- FMessages : array of TpbProtoMessage;
- FImports : array of AnsiString;
- FImportedPackages : array of TpbProtoPackage;
- FOptions : array of TpbProtoOption;
- FEnums : array of TpbProtoEnum;
- function GetEnumCount: Integer;
- function GetEnum(const Idx: Integer): TpbProtoEnum;
- function GetEnumByName(const AName: AnsiString): TpbProtoEnum;
- public
- constructor Create;
- destructor Destroy; override;
- property FileName: AnsiString read FFileName write FFileName;
- property Name: AnsiString read FName write FName;
- procedure AddMessage(const M: TpbProtoMessage);
- function GetMessageCount: Integer;
- function GetMessage(const Idx: Integer): TpbProtoMessage;
- function GetMessageByName(const AName: AnsiString): TpbProtoMessage;
- procedure AddImport(const Path: AnsiString);
- function GetImportCount: Integer;
- function GetImport(const Idx: Integer): AnsiString;
- procedure AddImportedPackage(const Package: TpbProtoPackage);
- function GetImportedPackageCount: Integer;
- function GetImportedPackage(const Idx: Integer): TpbProtoPackage;
- function GetImportedPackageByName(const AName: AnsiString): TpbProtoPackage;
- procedure AddOption(const Option: TpbProtoOption);
- function GetOptionCount: Integer;
- function GetOption(const Idx: Integer): TpbProtoOption;
- procedure AddEnum(const E: TpbProtoEnum);
- property EnumCount: Integer read GetEnumCount;
- property Enum[const Idx: Integer]: TpbProtoEnum read GetEnum;
- function ResolveValue(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode; override;
- function ResolveType(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode; override;
- function GetAsProtoString: AnsiString; override;
- end;
- TpbProtoNodeFactory = class
- public
- function CreatePackage: TpbProtoPackage; virtual;
- function CreateMessage(const AParentNode: TpbProtoNode): TpbProtoMessage; virtual;
- function CreateField(const AParentMessage: TpbProtoMessage): TpbProtoField; virtual;
- function CreateFieldType(const AParentField: TpbProtoField): TpbProtoFieldType; virtual;
- function CreateLiteral(const AParentNode: TpbProtoNode): TpbProtoLiteral; virtual;
- function CreateEnum(const AParentNode: TpbProtoNode): TpbProtoEnum; virtual;
- function CreateEnumValue(const AParentEnum: TpbProtoEnum): TpbProtoEnumValue; virtual;
- end;
- { Default ProtoNode factory }
- function GetDefaultProtoNodeFactory: TpbProtoNodeFactory;
- implementation
- uses
- { Fundamentals }
- cUtils,
- cStrings;
- const
- pbCRLF = AnsiString(#13#10);
- ProtoFieldCardinalityStr : array[TpbProtoFieldCardinality] of AnsiString = (
- '',
- 'required',
- 'optional',
- 'repeated'
- );
- ProtoFieldTypeStr : array[TpbProtoFieldBaseType] of AnsiString = (
- '',
- 'double',
- 'float',
- 'int32',
- 'int64',
- 'uint32',
- 'uint64',
- 'sint32',
- 'sint64',
- 'fixed32',
- 'fixed64',
- 'sfixed32',
- 'sfixed64',
- 'bool',
- 'string',
- 'bytes',
- ''
- );
- SErr_IdentifierNotDefined = 'Identifier not defined (%s)';
- SErr_IdentifierNotAValue = 'Identifier not a value (%s)';
- { Helper functions }
- procedure pbSplitIdentifier(const AIdentifier: AnsiString;
- var ALeftName, ARightIdentifier: AnsiString);
- begin
- StrSplitAtCharA(AIdentifier, '.', ALeftName, ARightIdentifier, True);
- end;
- { TpbProtoNode }
- function TpbProtoNode.ResolveValue(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode;
- begin
- raise EpbProtoNode.CreateFmt('%s.ResolveValue not implemented', [ClassName]);
- end;
- function TpbProtoNode.ResolveType(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode;
- begin
- raise EpbProtoNode.CreateFmt('%s.ResolveType not implemented', [ClassName]);
- end;
- function TpbProtoNode.ExpectResolvedValue(const AIdentifier: AnsiString): TpbProtoNode;
- begin
- Result := ResolveValue(AIdentifier, False);
- if not Assigned(Result) then
- raise EpbProtoNode.CreateFmt(SErr_IdentifierNotDefined, [AIdentifier]);
- end;
- function TpbProtoNode.ExpectResolvedType(const AIdentifier: AnsiString): TpbProtoNode;
- begin
- Result := ResolveType(AIdentifier, False);
- if not Assigned(Result) then
- raise EpbProtoNode.CreateFmt(SErr_IdentifierNotDefined, [AIdentifier]);
- end;
- function TpbProtoNode.GetAsProtoString: AnsiString;
- begin
- raise EpbProtoNode.CreateFmt('%s.GetAsProtoString not implemented', [ClassName]);
- end;
- { TpbProtoEnumValue }
- constructor TpbProtoEnumValue.Create(const AParentEnum: TpbProtoEnum);
- begin
- Assert(Assigned(AParentEnum));
- inherited Create;
- FParentEnum := AParentEnum;
- end;
- function TpbProtoEnumValue.GetAsProtoString: AnsiString;
- begin
- Result := FName + ' = ' + IntToStringA(FValue) + ';';
- end;
- { TpbProtoEnum }
- constructor TpbProtoEnum.Create(const AParentNode: TpbProtoNode);
- begin
- Assert(Assigned(AParentNode));
- inherited Create;
- end;
- procedure TpbProtoEnum.Add(const V: TpbProtoEnumValue);
- var L : Integer;
- begin
- L := Length(FValues);
- SetLength(FValues, L + 1);
- FValues[L] := V;
- end;
- function TpbProtoEnum.GetValueCount: Integer;
- begin
- Result := Length(FValues);
- end;
- function TpbProtoEnum.GetValue(const Idx: Integer): TpbProtoEnumValue;
- begin
- Assert((Idx >= 0) and (Idx < Length(FValues)));
- Result := FValues[Idx];
- end;
- function TpbProtoEnum.GetValueByName(const AName: AnsiString): TpbProtoEnumValue;
- var
- I : Integer;
- V : TpbProtoEnumValue;
- begin
- for I := 0 to Length(FValues) - 1 do
- begin
- V := FValues[I];
- if V.FName = AName then
- begin
- Result := V;
- exit;
- end;
- end;
- Result := nil;
- end;
- function TpbProtoEnum.ResolveValue(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode;
- begin
- Result := GetValueByName(AIdentifier);
- end;
- function TpbProtoEnum.GetAsProtoString: AnsiString;
- var I, L : Integer;
- begin
- Result := 'enum ' + FName + ' {' + pbCRLF;
- L := Length(FValues);
- for I := 0 to L - 1 do
- Result := Result + FValues[I].GetAsProtoString + pbCRLF;
- Result := Result + '}';
- end;
- { TpbProtoLiteral }
- constructor TpbProtoLiteral.Create(const AParentNode: TpbProtoNode);
- begin
- Assert(Assigned(AParentNode));
- inherited Create;
- FParentNode := AParentNode;
- end;
- function TpbProtoLiteral.ResolveValue(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode;
- begin
- if AChildrenOnly then
- Result := nil
- else
- Result := FParentNode.ResolveValue(AIdentifier, False);
- end;
- function TpbProtoLiteral.GetAsProtoString: AnsiString;
- begin
- case FLiteralType of
- pltNone : Result := '';
- pltInteger : Result := IntToStringA(FLiteralInt);
- pltFloat : Result := FloatToStringA(FLiteralFloat);
- pltString : Result := StrQuoteA(FLiteralStr, '"');
- pltBoolean : Result := iifA(FLiteralBool, 'true', 'false');
- pltIdentifier : Result := FLiteralIden;
- else
- raise EpbProtoNode.Create('Invalid literal type');
- end;
- end;
- function TpbProtoLiteral.LiteralIdenValue: TpbProtoNode;
- begin
- if FLiteralType <> pltIdentifier then
- raise EpbProtoNode.Create('Not a identifier type');
- Result := ResolveValue(FLiteralIden, False);
- end;
- { TpbProtoFieldType }
- constructor TpbProtoFieldType.Create(const AParentField: TpbProtoField);
- begin
- Assert(Assigned(AParentField));
- inherited Create;
- FParentField := AParentField;
- end;
- function TpbProtoFieldType.ResolveType(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode;
- begin
- if AChildrenOnly then
- Result := nil
- else
- Result := FParentField.ResolveType(AIdentifier, False);
- end;
- function TpbProtoFieldType.GetAsProtoString: AnsiString;
- begin
- if FBaseType = pftIdentifier then
- Result := FIdenStr
- else
- Result := ProtoFieldTypeStr[FBaseType];
- end;
- function TpbProtoFieldType.IsSimpleType: Boolean;
- begin
- Result := not (FBaseType in [pftNone, pftIdentifier]);
- end;
- function TpbProtoFieldType.IsIdenType: Boolean;
- begin
- Result := FBaseType = pftIdentifier;
- end;
- function TpbProtoFieldType.IdenType: TpbProtoNode;
- begin
- if not IsIdenType then
- raise EpbProtoNode.Create('Not an identifier type');
- Result := ExpectResolvedType(FIdenStr);
- end;
- { TpbProtoField }
- constructor TpbProtoField.Create(const AParentMessage: TpbProtoMessage; const AFactory: TpbProtoNodeFactory);
- begin
- Assert(Assigned(AParentMessage));
- Assert(Assigned(AFactory));
- inherited Create;
- FParentMessage := AParentMessage;
- FDefaultValue := AFactory.CreateLiteral(self);
- FFieldType := AFactory.CreateFieldType(self);
- end;
- destructor TpbProtoField.Destroy;
- var I : Integer;
- begin
- for I := Length(FOptions) - 1 downto 0 do
- FreeAndNil(FOptions);
- FreeAndNil(FFieldType);
- FreeAndNil(FDefaultValue);
- inherited Destroy;
- end;
- procedure TpbProtoField.SetFieldType(const Value: TpbProtoFieldType);
- begin
- FreeAndNil(FFieldType);
- FFieldType := Value;
- end;
- procedure TpbProtoField.SetDefaultValue(const Value: TpbProtoLiteral);
- begin
- FreeAndNil(FDefaultValue);
- FDefaultValue := Value;
- end;
- procedure TpbProtoField.AddOption(const Option: TpbProtoOption);
- var
- L : Integer;
- begin
- L := Length(FOptions);
- SetLength(FOptions, L + 1);
- FOptions[L] := Option;
- end;
- function TpbProtoField.GetOptionCount: Integer;
- begin
- Result := Length(FOptions);
- end;
- function TpbProtoField.GetOption(const Idx: Integer): TpbProtoOption;
- begin
- Assert((Idx >= 0) and (Idx < Length(FOptions)));
- Result := FOptions[Idx];
- end;
- function TpbProtoField.ResolveValue(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode;
- begin
- if AChildrenOnly then
- Result := nil
- else
- Result := FParentMessage.ResolveValue(AIdentifier, False);
- end;
- function TpbProtoField.ResolveType(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode;
- begin
- if AChildrenOnly then
- Result := nil
- else
- Result := FParentMessage.ResolveType(AIdentifier, False);
- end;
- function TpbProtoField.GetAsProtoString: AnsiString;
- begin
- Result :=
- ProtoFieldCardinalityStr[FCardinality] + ' ' +
- FFieldType.GetAsProtoString + ' ' +
- FName + ' = ' +
- IntToStringA(FTagID) + ';';
- end;
- { TpbProtoMessage }
- constructor TpbProtoMessage.Create(const AParentNode: TpbProtoNode);
- begin
- Assert(Assigned(AParentNode));
- inherited Create;
- FParentNode := AParentNode;
- end;
- destructor TpbProtoMessage.Destroy;
- var I : Integer;
- begin
- for I := Length(FEnums) - 1 downto 0 do
- FreeAndNil(FEnums[I]);
- for I := Length(FFields) - 1 downto 0 do
- FreeAndNil(FFields[I]);
- for I := Length(FMessages) - 1 downto 0 do
- FreeAndNil(FMessages[I]);
- inherited Destroy;
- end;
- procedure TpbProtoMessage.AddField(const F: TpbProtoField);
- var L : Integer;
- begin
- L := Length(FFields);
- SetLength(FFields, L + 1);
- FFields[L] := F;
- end;
- function TpbProtoMessage.GetFieldCount: Integer;
- begin
- Result := Length(FFields);
- end;
- function TpbProtoMessage.GetField(const Idx: Integer): TpbProtoField;
- begin
- Assert((Idx >= 0) and (Idx < Length(FFields)));
- Result := FFields[Idx];
- end;
- function TpbProtoMessage.GetFieldByTagID(const ATagID: Integer): TpbProtoField;
- var
- I : Integer;
- F : TpbProtoField;
- begin
- for I := 0 to Length(FFields) - 1 do
- begin
- F := GetField(I);
- if F.FTagID = ATagID then
- begin
- Result := F;
- exit;
- end;
- end;
- Result := nil;
- end;
- procedure TpbProtoMessage.AddEnum(const E: TpbProtoEnum);
- var L : Integer;
- begin
- L := Length(FEnums);
- SetLength(FEnums, L + 1);
- FEnums[L] := E;
- end;
- function TpbProtoMessage.GetEnumCount: Integer;
- begin
- Result := Length(FEnums);
- end;
- function TpbProtoMessage.GetEnum(const Idx: Integer): TpbProtoEnum;
- begin
- Assert((Idx >= 0) and (Idx < Length(FEnums)));
- Result := FEnums[Idx];
- end;
- function TpbProtoMessage.GetEnumByName(const AName: AnsiString): TpbProtoEnum;
- var
- I : Integer;
- E : TpbProtoEnum;
- begin
- for I := 0 to GetEnumCount - 1 do
- begin
- E := GetEnum(I);
- if E.FName = AName then
- begin
- Result := E;
- exit;
- end;
- end;
- Result := nil;
- end;
- procedure TpbProtoMessage.AddMessage(const M: TpbProtoMessage);
- var L : Integer;
- begin
- L := Length(FMessages);
- SetLength(FMessages, L + 1);
- FMessages[L] := M;
- end;
- function TpbProtoMessage.GetMessageCount: Integer;
- begin
- Result := Length(FMessages);
- end;
- function TpbProtoMessage.GetMessage(const Idx: Integer): TpbProtoMessage;
- begin
- Assert((Idx >= 0) and (Idx < Length(FMessages)));
- Result := FMessages[Idx];
- end;
- function TpbProtoMessage.GetMessageByName(const AName: AnsiString): TpbProtoMessage;
- var
- I : Integer;
- M : TpbProtoMessage;
- begin
- for I := 0 to GetMessageCount - 1 do
- begin
- M := GetMessage(I);
- if M.FName = AName then
- begin
- Result := M;
- exit;
- end;
- end;
- Result := nil;
- end;
- function TpbProtoMessage.ResolveValue(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode;
- var
- I : Integer;
- E : TpbProtoEnum;
- M : TpbProtoMessage;
- N, S : AnsiString;
- begin
- for I := 0 to GetEnumCount - 1 do
- begin
- E := GetEnum(I);
- Result := E.ResolveValue(AIdentifier, True);
- if Assigned(Result) then
- exit;
- end;
- pbSplitIdentifier(AIdentifier, N, S);
- M := GetMessageByName(N);
- if Assigned(M) then
- begin
- if S = '' then
- raise EpbProtoNode.CreateFmt(SErr_IdentifierNotAValue, [AIdentifier]);
- Result := M.ResolveValue(S, True);
- if Assigned(Result) then
- exit
- else
- raise EpbProtoNode.CreateFmt(SErr_IdentifierNotDefined, [AIdentifier]);
- end;
- if AChildrenOnly then
- Result := nil
- else
- Result := FParentNode.ResolveValue(AIdentifier, False);
- end;
- function TpbProtoMessage.ResolveType(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode;
- var
- M : TpbProtoMessage;
- E : TpbProtoEnum;
- N, S : AnsiString;
- begin
- pbSplitIdentifier(AIdentifier, N, S);
- M := GetMessageByName(N);
- if Assigned(M) then
- begin
- if S = '' then
- Result := M
- else
- begin
- Result := M.ResolveType(S, True);
- if not Assigned(Result) then
- raise EpbProtoNode.CreateFmt(SErr_IdentifierNotDefined, [AIdentifier]);
- end;
- exit;
- end;
- E := GetEnumByName(AIdentifier);
- if Assigned(E) then
- begin
- Result := E;
- exit;
- end;
- if AChildrenOnly then
- Result := nil
- else
- Result := FParentNode.ResolveType(AIdentifier, False);
- end;
- function TpbProtoMessage.GetAsProtoString: AnsiString;
- var
- S : AnsiString;
- I : Integer;
- begin
- S := 'message ' + FName + ' {' + pbCRLF;
- for I := 0 to GetMessageCount - 1 do
- S := S + GetMessage(I).GetAsProtoString;
- for I := 0 to GetEnumCount - 1 do
- S := S + GetEnum(I).GetAsProtoString;
- for I := 0 to GetFieldCount - 1 do
- S := S + GetField(I).GetAsProtoString;
- S := S + '}' + pbCRLF;
- Result := S;
- end;
- { TpbProtoOption }
- constructor TpbProtoOption.Create(const AFactory: TpbProtoNodeFactory);
- begin
- Assert(Assigned(AFactory));
- inherited Create;
- FValue := AFactory.CreateLiteral(self);
- end;
- destructor TpbProtoOption.Destroy;
- begin
- FreeAndNil(FValue);
- inherited Destroy;
- end;
- procedure TpbProtoOption.SetValue(const Value: TpbProtoLiteral);
- begin
- FreeAndNil(FValue);
- FValue := Value;
- end;
- { TpbProtoPackage }
- constructor TpbProtoPackage.Create;
- begin
- inherited Create;
- end;
- destructor TpbProtoPackage.Destroy;
- var I : Integer;
- begin
- for I := Length(FImportedPackages) - 1 downto 0 do
- FreeAndNil(FImportedPackages[I]);
- for I := Length(FOptions) - 1 downto 0 do
- FreeAndNil(FOptions[I]);
- for I := Length(FMessages) - 1 downto 0 do
- FreeAndNil(FMessages[I]);
- inherited Destroy;
- end;
- procedure TpbProtoPackage.AddMessage(const M: TpbProtoMessage);
- var
- L : Integer;
- begin
- L := Length(FMessages);
- SetLength(FMessages, L + 1);
- FMessages[L] := M;
- end;
- function TpbProtoPackage.GetMessageCount: Integer;
- begin
- Result := Length(FMessages);
- end;
- function TpbProtoPackage.GetMessage(const Idx: Integer): TpbProtoMessage;
- begin
- Assert((Idx >= 0) and (Idx < Length(FMessages)));
- Result := FMessages[Idx];
- end;
- function TpbProtoPackage.GetMessageByName(const AName: AnsiString): TpbProtoMessage;
- var
- I : Integer;
- M : TpbProtoMessage;
- begin
- for I := 0 to GetMessageCount - 1 do
- begin
- M := GetMessage(I);
- if M.FName = AName then
- begin
- Result := M;
- exit;
- end;
- end;
- Result := nil;
- end;
- procedure TpbProtoPackage.AddImport(const Path: AnsiString);
- var
- L : Integer;
- begin
- L := Length(FImports);
- SetLength(FImports, L + 1);
- FImports[L] := Path;
- end;
- function TpbProtoPackage.GetImportCount: Integer;
- begin
- Result := Length(FImports);
- end;
- function TpbProtoPackage.GetImport(const Idx: Integer): AnsiString;
- begin
- Assert((Idx >= 0) and (Idx < Length(FImports)));
- Result := FImports[Idx];
- end;
- procedure TpbProtoPackage.AddImportedPackage(const Package: TpbProtoPackage);
- var
- L : Integer;
- begin
- L := Length(FImportedPackages);
- SetLength(FImportedPackages, L + 1);
- FImportedPackages[L] := Package;
- end;
- function TpbProtoPackage.GetImportedPackageCount: Integer;
- begin
- Result := Length(FImportedPackages);
- end;
- function TpbProtoPackage.GetImportedPackage(const Idx: Integer): TpbProtoPackage;
- begin
- Assert((Idx >= 0) and (Idx < Length(FImportedPackages)));
- Result := FImportedPackages[Idx];
- end;
- function TpbProtoPackage.GetImportedPackageByName(const AName: AnsiString): TpbProtoPackage;
- var
- I : Integer;
- P : TpbProtoPackage;
- begin
- for I := 0 to GetImportedPackageCount - 1 do
- begin
- P := GetImportedPackage(I);
- if P.FName = AName then
- begin
- Result := P;
- exit;
- end;
- end;
- Result := nil;
- end;
- procedure TpbProtoPackage.AddOption(const Option: TpbProtoOption);
- var
- L : Integer;
- begin
- L := Length(FOptions);
- SetLength(FOptions, L + 1);
- FOptions[L] := Option;
- end;
- function TpbProtoPackage.GetOptionCount: Integer;
- begin
- Result := Length(FOptions);
- end;
- function TpbProtoPackage.GetOption(const Idx: Integer): TpbProtoOption;
- begin
- Assert((Idx >= 0) and (Idx < Length(FOptions)));
- Result := FOptions[Idx];
- end;
- procedure TpbProtoPackage.AddEnum(const E: TpbProtoEnum);
- var L : Integer;
- begin
- L := Length(FEnums);
- SetLength(FEnums, L + 1);
- FEnums[L] := E;
- end;
- function TpbProtoPackage.GetEnumCount: Integer;
- begin
- Result := Length(FEnums);
- end;
- function TpbProtoPackage.GetEnum(const Idx: Integer): TpbProtoEnum;
- begin
- Assert((Idx >= 0) and (Idx < Length(FEnums)));
- Result := FEnums[Idx];
- end;
- function TpbProtoPackage.GetEnumByName(const AName: AnsiString): TpbProtoEnum;
- var
- I : Integer;
- E : TpbProtoEnum;
- begin
- for I := 0 to GetEnumCount - 1 do
- begin
- E := GetEnum(I);
- if E.FName = AName then
- begin
- Result := E;
- exit;
- end;
- end;
- Result := nil;
- end;
- function TpbProtoPackage.ResolveValue(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode;
- var
- I : Integer;
- E : TpbProtoEnum;
- M : TpbProtoMessage;
- P : TpbProtoPackage;
- N, S : AnsiString;
- begin
- for I := 0 to GetEnumCount - 1 do
- begin
- E := GetEnum(I);
- Result := E.ResolveValue(AIdentifier, True);
- if Assigned(Result) then
- exit;
- end;
- pbSplitIdentifier(AIdentifier, N, S);
- M := GetMessageByName(N);
- if Assigned(M) then
- begin
- if S = '' then
- raise EpbProtoNode.CreateFmt(SErr_IdentifierNotAValue, [AIdentifier]);
- Result := M.ResolveValue(S, True);
- if Assigned(Result) then
- exit
- else
- raise EpbProtoNode.CreateFmt(SErr_IdentifierNotDefined, [AIdentifier]);
- end;
- for I := 0 to GetMessageCount - 1 do
- begin
- M := GetMessage(I);
- Result := M.ResolveValue(AIdentifier, True);
- if Assigned(Result) then
- exit;
- end;
- P := GetImportedPackageByName(N);
- if Assigned(P) then
- begin
- if S = '' then
- raise EpbProtoNode.CreateFmt(SErr_IdentifierNotAValue, [AIdentifier]);
- Result := P.ResolveValue(S, True);
- if Assigned(Result) then
- exit
- else
- raise EpbProtoNode.CreateFmt(SErr_IdentifierNotDefined, [AIdentifier]);
- end;
- for I := 0 to GetImportedPackageCount - 1 do
- begin
- P := GetImportedPackage(I);
- Result := P.ResolveValue(AIdentifier, True);
- if Assigned(Result) then
- exit;
- end;
- Result := nil;
- end;
- function TpbProtoPackage.ResolveType(const AIdentifier: AnsiString; const AChildrenOnly: Boolean): TpbProtoNode;
- var
- M : TpbProtoMessage;
- E : TpbProtoEnum;
- P : TpbProtoPackage;
- N, S : AnsiString;
- I : Integer;
- begin
- pbSplitIdentifier(AIdentifier, N, S);
- M := GetMessageByName(N);
- if Assigned(M) then
- begin
- if S = '' then
- Result := M
- else
- begin
- Result := M.ResolveType(S, True);
- if not Assigned(Result) then
- raise EpbProtoNode.CreateFmt(SErr_IdentifierNotDefined, [AIdentifier]);
- end;
- exit;
- end;
- E := GetEnumByName(AIdentifier);
- if Assigned(E) then
- begin
- Result := E;
- exit;
- end;
- P := GetImportedPackageByName(N);
- if Assigned(P) then
- begin
- if S = '' then
- Result := P
- else
- begin
- Result := P.ResolveType(S, True);
- if not Assigned(Result) then
- raise EpbProtoNode.CreateFmt(SErr_IdentifierNotDefined, [AIdentifier]);
- end;
- exit;
- end;
- for I := 0 to GetImportedPackageCount - 1 do
- begin
- Result := GetImportedPackage(I).ResolveType(AIdentifier, True);
- if Assigned(Result) then
- exit;
- end;
- Result := nil;
- end;
- function TpbProtoPackage.GetAsProtoString: AnsiString;
- var
- I : Integer;
- S : AnsiString;
- begin
- S := '';
- if FName <> '' then
- S := S + 'package ' + FName + ';' + pbCRLF + pbCRLF;
- for I := 0 to GetMessageCount - 1 do
- S := S + GetMessage(I).GetAsProtoString;
- Result := S;
- end;
- { TpbProtoNodeFactory }
- function TpbProtoNodeFactory.CreatePackage: TpbProtoPackage;
- begin
- Result := TpbProtoPackage.Create;
- end;
- function TpbProtoNodeFactory.CreateMessage(const AParentNode: TpbProtoNode): TpbProtoMessage;
- begin
- Result := TpbProtoMessage.Create(AParentNode);
- end;
- function TpbProtoNodeFactory.CreateField(const AParentMessage: TpbProtoMessage): TpbProtoField;
- begin
- Result := TpbProtoField.Create(AParentMessage, self);
- end;
- function TpbProtoNodeFactory.CreateFieldType(const AParentField: TpbProtoField): TpbProtoFieldType;
- begin
- Result := TpbProtoFieldType.Create(AParentField);
- end;
- function TpbProtoNodeFactory.CreateLiteral(const AParentNode: TpbProtoNode): TpbProtoLiteral;
- begin
- Result := TpbProtoLiteral.Create(AParentNode);
- end;
- function TpbProtoNodeFactory.CreateEnum(const AParentNode: TpbProtoNode): TpbProtoEnum;
- begin
- Result := TpbProtoEnum.Create(AParentNode);
- end;
- function TpbProtoNodeFactory.CreateEnumValue(const AParentEnum: TpbProtoEnum): TpbProtoEnumValue;
- begin
- Result := TpbProtoEnumValue.Create(AParentEnum);
- end;
- { Default ProtoNode factory }
- var
- DefaultProtoNodeFactory: TpbProtoNodeFactory = nil;
- function GetDefaultProtoNodeFactory: TpbProtoNodeFactory;
- begin
- if not Assigned(DefaultProtoNodeFactory) then
- DefaultProtoNodeFactory := TpbProtoNodeFactory.Create;
- Result := DefaultProtoNodeFactory;
- end;
- initialization
- finalization
- FreeAndNil(DefaultProtoNodeFactory);
- end.
|