123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968 |
- { Base Google API code generator
- Copyright (C) 2015 Michael Van Canneyt [email protected]
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version with the following modification:
- As a special exception, the copyright holders of this library give you
- permission to link this library with independent modules to produce an
- executable, regardless of the license terms of these independent modules,and
- to copy and distribute the resulting executable under terms of your choice,
- provided that you also meet, for each linked independent module, the terms
- and conditions of the license of that module. An independent module is a
- module which is not derived from or based on this library. If you modify
- this library, you may extend this exception to your version of the library,
- but you are not obligated to do so. If you do not wish to do so, delete this
- exception statement from your version.
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
- for more details.
- You should have received a copy of the GNU Library General Public License
- along with this library; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- }
- unit googlediscoverytopas;
- {$mode objfpc}{$H+}
- interface
- uses
- typinfo, Classes, SysUtils, fpjson, restcodegen, restbase, googlebase;
- Type
- TTypeDef = Class;
- TSchema = Class;
- TSchemas = Array of TSchema;
- TPropertyDef = Class;
- TProperties = TSchemas;
- TRestMethod = Class;
- TRestMethods = Array of TRestMethod;
- TArrayPropertyDef = Class;
- { TIcons }
- TGoogleIcons = Class(TGoogleBaseObject)
- private
- Fx16: String;
- Fx32: String;
- Published
- Property x16 : String Read Fx16 Write fx16;
- Property x32 : String Read Fx32 Write fx32;
- end;
- { TGoogleAuth2 }
- TGoogleAuth2 = Class(TGoogleBaseObject)
- private
- FScopes: TSchemas;
- Published
- Property Scopes : TSchemas Read Fscopes Write Fscopes;
- end;
- { TGoogleAuth }
- TGoogleAuth = Class(TGoogleBaseObject)
- private
- Foauth2: TGoogleAuth2;
- Published
- Property oauth2 : TGoogleAuth2 Read Foauth2 Write Foauth2;
- end;
- { TDiscoveryJSONToPas }
- { TArrayPropertyDef }
- { TAnnotations }
- TAnnotations = Class(TGoogleBaseObject)
- private
- FRequired: TStringArray;
- Published
- Property required : TStringArray Read FRequired Write Frequired;
- end;
- { TSchema }
- TSchema = Class(TGoogleBaseObject)
- private
- FadditionalProperties: TSchema;
- FAnnotations: TAnnotations;
- FDefault: String;
- Fdescription: string;
- fdivisibleby: integer;
- FEnum: TJSONSchema;
- FenumDescriptions: TStringArray;
- fexclusivemaximum: boolean;
- fexclusiveminimum: boolean;
- Fextends: string;
- FFormat: string;
- fitems: TSchema;
- fmaximum: integer;
- fmaxItems: integer;
- fmaxlength: integer;
- Fmethods: TRestMethods;
- fminimum: integer;
- fminItems: integer;
- fminlength: integer;
- FName: String;
- FPattern: string;
- FProperties: TProperties;
- FPropertyName: String;
- FreadOnly: Boolean;
- Fref: string;
- FRefSchema: TSchema;
- frequired: Boolean;
- FResources: TSchemas;
- Fschema: String;
- FType: string;
- FID: String;
- FTypeDef: TTypeDef;
- FTypeName: String;
- funiqueItems: boolean;
- FVariant: TJSONSchema;
- function DoGetTypeName(PrependT: Boolean): String;
- function GetTypeName: String;
- Public
- Class function BaseType(ATypeName: String): Boolean;
- Class function GetBaseTypeName(AType,AFormat : String) : string;
- Function DebugName : String;
- function GetBaseTypeName : string;
- Function BaseType : Boolean;
- Function ClassProperties : TProperties;
- Property PropertyName : String Read FPropertyName Write FPropertyName;
- Property TypeName : String Read GetTypeName Write FTypeName;
- Property Refschema : TSchema Read FRefSchema Write FRefSchema;
- Property TypeDef : TTypeDef Read FTypeDef write FTypeDef;
- Published
- Property id : String Read FID Write FID;
- Property description : string read Fdescription Write Fdescription;
- Property _type : String Read FType Write FType;
- Property ref : String Read FRef Write FRef;
- Property schema: String Read Fschema Write Fschema;
- Property name : String Read FName Write FName;
- Property enum : TJSONSchema Read FEnum Write FEnum;
- Property enumDescriptions : TStringArray Read FenumDescriptions Write FenumDescriptions;
- Property properties : TProperties Read FProperties Write FProperties;
- Property items : TSchema Read fitems write fitems;
- Property default : String Read FDefault Write FDefault;
- property required : Boolean read frequired write frequired;
- Property annotations : TAnnotations Read FAnnotations Write FAnnotations;
- Property format : string Read FFormat Write FFormat;
- Property additionalProperties : TSchema Read FadditionalProperties Write FadditionalProperties;
- Property minLength : integer read fminlength write fminlength;
- Property maxLength : integer read fmaxlength write fmaxlength;
- Property minItems : integer read fminItems write fminItems;
- Property maxItems : integer read fmaxItems write fmaxItems;
- Property minimum : integer read fminimum write fminimum;
- Property pattern : string read FPattern write fPattern;
- Property exclusiveMaximum : boolean read fexclusivemaximum write fexclusivemaximum;
- Property exclusiveMinimum : boolean read fexclusiveminimum write fexclusiveminimum;
- Property uniqueItems : boolean read funiqueItems write funiqueItems;
- Property maximum : integer read fmaximum write fmaximum;
- Property divisibleBy : integer read fdivisibleby write fdivisibleby;
- Property extends : string Read Fextends Write Fextends;
- Property methods : TRestMethods Read Fmethods Write Fmethods;
- property readOnly : Boolean Read FreadOnly Write fReadOnly;
- Property resources : TSchemas Read FResources write FResources;
- Property variant : TJSONSchema Read FVariant Write FVariant;
- end;
- TArrayPropertyDef = Class(TSchema);
- TPropertyDef = Class(TSchema);
- TMediaUploadprotocolssimple = Class(TGoogleBaseObject)
- Private
- Fmultipart : boolean;
- Fpath : string;
- Published
- Property multipart : boolean Read Fmultipart Write Fmultipart;
- Property path : string Read Fpath Write Fpath;
- end;
- TMediaUploadProtocolsSimpleArray = Array of TMediaUploadProtocolsSimple;
- TMediaUploadProtocolsResumable = Class(TGoogleBaseObject)
- Private
- Fmultipart : boolean;
- Fpath : string;
- Published
- Property multipart : boolean Read Fmultipart Write Fmultipart;
- Property path : string Read Fpath Write Fpath;
- end;
- TMediaUploadProtocolsResumableArray = Array of TMediaUploadProtocolsResumable;
- { TMediaUploadProtocols }
- TMediaUploadProtocols = Class(TGoogleBaseObject)
- private
- Fresumable: TMediaUploadprotocolsresumable;
- Fsimple: TMediaUploadprotocolssimple;
- Published
- Property resumable : TMediaUploadprotocolsresumable Read Fresumable Write Fresumable;
- Property simple : TMediaUploadprotocolssimple Read Fsimple Write Fsimple;
- end;
- TMediaUploadProtocolsArray = Array of TMediaUploadProtocols;
- TMediaUpload = Class(TGoogleBaseObject)
- private
- FAccept: TStringArray;
- FMaxSize: String;
- Fprotocols: TMediaUploadProtocols;
- Published
- Property Accept : TStringArray Read FAccept Write FAccept;
- property MaxSize : String Read FMaxSize Write FMaxSize;
- Property protocols : TMediaUploadProtocols Read Fprotocols Write Fprotocols;
- end;
- { TRequest }
- TRequest = Class(TGoogleBaseObject)
- private
- fparameterName: string;
- fref: string;
- Published
- Property ref : string read fref write fref;
- Property parameterName : string read fparameterName write fparameterName;
- end;
- { TResponse }
- TResponse = Class(TGoogleBaseObject)
- private
- fref: string;
- Published
- Property ref : string read fref write fref;
- end;
- { TRestMethodParam }
- TRestMethodParam = Class(TSchema)
- private
- FLocation: string;
- FRepeated: boolean;
- FSourceName: String;
- Public
- Property SourceName : String Read FSourceName Write FSourceName;
- Published
- Property location : string Read FLocation Write FLocation;
- Property repeated : boolean Read FRepeated write FRepeated;
- end;
- TRestMethodParams = Array of TRestMethodParam;
- { TRestMethod }
- TRestMethod = Class(TGoogleBaseObject)
- private
- FDescription: String;
- FeTagrequired: Boolean;
- FflatPath: string;
- FhttpMethod: string;
- Fid: string;
- fMediaUpload: TMediaUpload;
- fname: string;
- FParameterOrder: TStringArray;
- fparameters: TRestMethodParams;
- fpath: string;
- frequest: trequest;
- fresponse: tresponse;
- Fscopes: TStringArray;
- FsupportsMediaDownload: Boolean;
- FsupportsMediaUpload: Boolean;
- FsupportsSubscription: Boolean;
- Published
- Property name : string read fname Write fname;
- Property description : String Read FDescription Write FDescription;
- Property etagRequired: Boolean read FeTagrequired write FeTagrequired;
- Property httpMethod: string read FhttpMethod write FhttpMethod;
- Property id : string read Fid Write fID;
- Property MediaUpload : TMediaUpload Read fMediaUpload Write fmediaUpload;
- Property parameterOrder : TStringArray Read FParameterOrder Write FParameterOrder;
- Property parameters : TRestMethodParams read fparameters write fparameters;
- Property path : string read fpath Write fpath;
- Property flatPath : string read FflatPath Write FflatPath;
- Property request : trequest read frequest write frequest;
- Property response : tresponse read fresponse write fresponse;
- property scopes : TStringArray Read Fscopes write Fscopes;
- property supportsMediaDownload : Boolean Read FsupportsMediaDownload Write FsupportsMediaDownload;
- property supportsMediaUpload : Boolean Read FsupportsMediaUpload Write FsupportsMediaUpload;
- property supportsSubscription : Boolean Read FsupportsSubscription Write FsupportsSubscription;
- end;
- { TGoogleRestDescription }
- TGoogleRestDescription = Class(TGoogleBaseObject)
- private
- Fauth: TGoogleAuth;
- fbasePath: string;
- fbaseURL: string;
- fbatchPath: string;
- FCanonicalName: String;
- FDescription: string;
- FdiscoveryVersion: String;
- FdocumentationLink: string;
- FEtag: String;
- Ffeatures: TstringArray;
- Ficons: TGoogleIcons;
- fid: String;
- FKind: String;
- Flabels: TstringArray;
- Fmethods: TRestMethods;
- Fname: String;
- fOwnerDomain: String;
- fOwnerName: String;
- FpackagePath: String;
- Fparameters: TJSONSchema;
- Fprotocol: string;
- FResources: TSchemas;
- FRevision: string;
- frootURL: string;
- FSchemas: TSchemas;
- fservicePath: string;
- FTitle: string;
- Fversion: String;
- Published
- property Auth : TGoogleAuth Read Fauth Write Fauth;
- property basePath : string read fbasePath write FbasePath;
- property baseUrl : string read fbaseURL write FbaseURL;
- property batchPath : string read fbatchPath write FbatchPath;
- Property canonicalName : String Read FCanonicalName Write FCanonicalName;
- Property description : string Read FDescription Write FDescription;
- Property discoveryVersion : String Read FdiscoveryVersion Write FdiscoveryVersion;
- Property documentationLink : string read FdocumentationLink Write FdocumentationLink;
- Property etag : String Read FEtag Write FEtag;
- Property features : TstringArray Read Ffeatures Write Ffeatures;
- property icons : TGoogleIcons Read Ficons Write Ficons;
- Property id: String Read fid Write Fid;
- Property kind: String Read FKind Write FKind;
- Property labels : TstringArray Read Flabels Write Flabels;
- Property methods : TRestMethods Read Fmethods Write Fmethods;
- Property name : String Read Fname Write Fname;
- Property ownerDomain : String Read fOwnerDomain Write FOwnerDomain;
- Property ownerName : String Read fOwnerName Write FOwnerName;
- Property packagePath : String Read FpackagePath Write FpackagePath;
- Property parameters : TJSONSchema Read Fparameters Write FParameters;
- property protocol : string Read Fprotocol write FProtocol;
- Property resources : TSchemas Read FResources write FResources;
- Property revision : string Read FRevision Write FRevision;
- property rootUrl : string read frootURL write FrootURL;
- property schemas : TSchemas read FSchemas write fschemas;
- property servicePath : string read fservicePath write FservicePath;
- Property title : string Read FTitle Write FTitle;
- Property version : String Read Fversion Write Fversion;
- end;
- TParamLocation = (plPath,plQuery);
- TParamLocations = Set of TParamLocation;
- TDataType = (dtalias,dtClass,dtarray);
- { TTypeDef }
- TTypeDef = Class(TCollectionItem)
- private
- FDataType: TDataType;
- FItemSchema: TSchema;
- FPascalName: String;
- FSchema: TSchema;
- FTopLevel: Boolean;
- Public
- Property PascalName : String Read FPascalName Write FPascalName;
- Property Schema : TSchema Read FSchema Write FSchema;
- Property DataType : TDataType Read FDataType Write FDataType;
- Property ItemSchema: TSchema Read FItemSchema Write FItemSchema;
- Property TopLevel : Boolean Read FTopLevel Write FTopLevel;
- end;
- { TTypeDefEnumerator }
- TTypeDefEnumerator = Class(TCollectionEnumerator)
- Public
- Function GetCurrent: TTypeDef;
- property Current: TTypeDef read GetCurrent;
- end;
- { TTypeDefs }
- TTypeDefs = Class(TCollection)
- private
- function GetD(AIndex : Integer): TTypeDef;
- Public
- Function GetEnumerator: TTypeDefEnumerator;
- Function IndexOf(ATypename : String) : Integer;
- Function Find(ATypename : String) : TTypeDef;
- Function AddTypeDef(ADataType : TDataType; APascalName : String; ASchema : TSchema) : TTypeDef;
- Property Defs[AIndex : Integer] : TTypeDef Read GetD; Default;
- end;
- TGoogleCodeOption = (gcoUseListForArray,gcoFlatResources);
- TGoogleCodeOptions = Set of TGoogleCodeOption;
- TDiscoveryJSONToPas = Class(TRestCodeGenerator)
- private
- FArrayItemSuffix: String;
- FCodeOptions: TGoogleCodeOptions;
- FDescription: TGoogleRestDescription;
- FPropertyTypeSuffix: String;
- FResourceSuffix: String;
- FTypes : TTypeDefs;
- Function AddType(ASchema: TSchema; NamePrefix: String; IsTopLevel : Boolean) : TTypeDef;
- procedure CollectType(S: TSchema; NamePrefix: String; IsTopLevel : Boolean);
- function GetFlat: Boolean;
- function GetSchemaDataType(S: TSchema): TDataType;
- function GetUseListForArray: Boolean;
- function ReservedMethod(ANAme: String): boolean;
- Protected
- procedure AssignParamNames(Res: TSchema; M: TRestMethod); virtual;
- Function BaseUnits : String; override;
- // Global functions
- Function GetPropertyType(AClassName: String; ASchema: TSchema): String;
- Procedure CollectTypes;
- Procedure CollectTypes(Schemas: TSchemas; NamePrefix : String);
- Procedure ResolveRefs;
- Procedure CreateInterface;
- Procedure CreateImplementation;
- // Schema Classes
- procedure CreateSetArrayLength(AClassName: String; ASchema, AItemSchema: TSchema);
- procedure CreateExportPropertyName(AClassName: String; ASchema, AItemSchema: TSchema);
- Procedure CreateClassDeclaration(AClassName: String; ASchema: TSchema);
- Procedure CreateArrayClassDeclaration(AClassName: String; ASchema,AItemSchema: TSchema);
- Procedure CreateClassImplementation(AClassName: String; ASchema,AItemSchema: TSchema);
- Procedure CreateArrayClassImplementation(AClassName: String; ASchema,AItemSchema: TSchema);
- Procedure CreateArrayClassEnumeratorImplementation(AClassName: String; ASchema,AItemSchema: TSchema);
- // API class
- Function GetAPIClassName: String;
- Procedure CreateAPIClassDeclaration;
- Procedure CreateAPIClassImplementation;
- // Resource classes
- Function ConstructResourcePrefix(Const APrefix: String; AResource: TSchema ): String;
- // Recursive calls
- Procedure CreateResourceClassImplementations(Const APrefix: String; Resources: TSchemas);
- Procedure CreateResourceAPIFunctionImplementations(Const AClassName: String; Const APrefix: String; Resources: TSchemas); virtual;
- Procedure CreateResourceInstanceFields(Const APrefix: String; Resources: TSchemas);
- Procedure CreateResourceInstanceGetters(Const APrefix: String; Resources: TSchemas);
- Procedure CreateResourceAPI(Const APrefix: String; Resources: TSchemas);
- Procedure CreateResourceProperties(Const APrefix: String; Resources: TSchemas);
- Function GetResourceClassName(Const APrefix : String; Res: TSchema): String;
- procedure CreateResourceDeclarations(Const APrefix: String; Resources: TSchemas);
- Procedure CreateResourceClassDeclaration(Const APrefix: String; Res: TSchema);
- Procedure CreateResourceClassImplementation(Const APrefix: String; Res: TSchema);
- Procedure CreateResourceClassMethodsImplementation(Res: TSchema; Const AClassName: String);
- Procedure CreateResourceMethodImplementation(AClassName: String; Res: TSchema; M: TRestMethod); // Query version
- Procedure CreateResourceMethodImplementationOptions(Const APrefix,
- AClassName: String; Res: TSchema; M: TRestMethod);// Options record version
- Function GetResourceMethodSignature(M: TRestmethod; Out IsFunction: Boolean; QueryOptionType : String; AddTypes : Boolean = True): String;
- Function DescribeMethodParams(M: TRestMethod): TParamLocations;
- Function HavePathParams(M: TRestMethod): Boolean;
- Function HaveQueryParams(M: TRestMethod): Boolean;
- Procedure CreateResourceMethodQueryParams(APrefix: String; Res: TSchema;
- M: TRestMethod);
- Public
- Constructor Create(AOwner : TComponent); override;
- Destructor Destroy; override;
- Procedure LoadFromStream(Const AStream : TStream); override;
- Procedure LoadFromJSON(Const JSON : TJSONObject); virtual;
- Procedure Execute; override;
- Class Procedure RegisterAllObjects;
- Property APIClassName: String Read GetAPIClassName;
- Property UseListForArray : Boolean Read GetUseListForArray;
- Property FlatResources : Boolean Read GetFlat;
- Published
- Property Description : TGoogleRestDescription Read FDescription;
- Property ResourceSuffix : String Read FResourceSuffix Write FResourceSuffix;
- Property ArrayItemSuffix : String Read FArrayItemSuffix Write FArrayItemSuffix;
- Property PropertyTypeSuffix : String Read FPropertyTypeSuffix Write FPropertyTypeSuffix;
- Property CodeOptions : TGoogleCodeOptions Read FCodeOptions Write FCodeOptions;
- end;
- implementation
- { TTypeDefEnumerator }
- function TTypeDefEnumerator.GetCurrent: TTypeDef;
- begin
- Result:=(Inherited GetCurrent) as TTypeDef;
- end;
- { TTypeDefs }
- function TTypeDefs.GetD(AIndex : Integer): TTypeDef;
- begin
- Result:=Items[AIndex] as TTypeDef;
- end;
- function TTypeDefs.GetEnumerator: TTypeDefEnumerator;
- begin
- Result:=TTypeDefEnumerator.Create(Self);
- end;
- function TTypeDefs.IndexOf(ATypename: String): Integer;
- begin
- Result:=Count-1;
- While (Result>=0) and (CompareText(ATypeName,GetD(Result).PascalName)<>0) do
- Dec(Result);
- end;
- function TTypeDefs.Find(ATypename: String): TTypeDef;
- Var
- I : Integer;
- begin
- I:=IndexOf(ATypeName);
- if (I=-1) then
- Result:=Nil
- else
- Result:=GetD(I);
- end;
- function TTypeDefs.AddTypeDef(ADataType: TDataType; APascalName: String;
- ASchema: TSchema): TTypeDef;
- begin
- Result:=Add as TTypeDef;
- Result.DataType:=ADataType;
- Result.PascalName:=APascalName;
- Result.Schema:=ASchema;
- end;
- { TSchema }
- function TSchema.DoGetTypeName(PrependT : Boolean) : String;
- begin
- Result:=FTypeName;
- if (Result='') and Assigned(TypeDef) then
- Result:=TypeDef.PascalName;
- If Result='' then
- begin
- If BaseType then
- Result:=GetBaseTypeName
- else if (_type='array') and Assigned(Items) then
- begin
- Result:=Items.DoGetTypeName(False);
- if (Result<>'') and not Assigned(Items.TypeDef) then
- begin
- if PrependT and (items._type<>'object') and (items._type<>'array') then
- Result:='T'+Result;
- Result:=Result+'Array';
- end;
- end;
- end;
- end;
- function TSchema.GetTypeName: String;
- begin
- Result:=DoGetTypeName(True);
- end;
- Function TSchema.ClassProperties: TProperties;
- begin
- If Length(FProperties)>0 then
- Result:=FProperties
- //else if Assigned(Items) then
- // Result:=Items.properties
- else
- Result:=Nil
- end;
- { TGoogleRestDescription }
- { TDiscoveryJSONToPas }
- Constructor TDiscoveryJSONToPas.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FDescription:=TGoogleRestDescription.Create;
- BaseClassName:='TGoogleBaseObject';
- BaseListClassName:='TGoogleBaseObjectList';
- FResourceSuffix:='Resource';
- ArrayItemSuffix:='Item';
- PropertyTypeSuffix:='Type';
- // UseListForArray:=True;
- end;
- Destructor TDiscoveryJSONToPas.Destroy;
- begin
- FreeAndNil(FDescription);
- inherited Destroy;
- end;
- Procedure TDiscoveryJSONToPas.LoadFromStream(Const AStream: TStream);
- Var
- D : TJSONData;
- begin
- D:=GetJSON(AStream,True);
- try
- if Not (D is TJSONObject) then
- Raise EGoogleAPI.Create('Source does not contain a valid JSON object');
- LoadFromJSON(D as TJSONObject)
- finally
- D.Free;
- end;
- end;
- Procedure TDiscoveryJSONToPas.LoadFromJSON(Const JSON: TJSONObject);
- begin
- Description.LoadFromJSON(JSON);
- end;
- function TDiscoveryJSONToPas.GetSchemaDataType(S: TSchema): TDataType;
- begin
- if (S._type='array') then
- Result:=dtArray
- else if S._type='object' then
- Result:=dtClass
- else
- Result:=dtAlias;
- end;
- function TDiscoveryJSONToPas.GetUseListForArray: Boolean;
- begin
- Result:=gcoUseListForArray in CodeOPtions;
- end;
- Function TDiscoveryJSONToPas.AddType(ASchema: TSchema; NamePrefix: String;
- IsTopLevel: Boolean): TTypeDef;
- Function DoAdd(DT : TDataType; TCN : String; S,ITS : TSchema) : TTypeDef;
- Var
- Msg : String;
- begin
- Result:=Nil;
- if (FTypes.IndexOf(TCN)<>-1) then
- Raise Exception.CreateFmt('Type already exists : "%s"',[TCN]);
- Result:=FTypes.AddTypeDef(dt,TCN,S);
- Result.ItemSchema:=ITS;
- Result.Toplevel:=isTopLevel;
- Str(dt,Msg);
- Msg:=Format('[%s] : Adding %s (%s) from ',[NamePrefix,TCN,Msg]);
- if Assigned(S) then
- Msg:=Msg+S.DebugName;
- if Assigned(ItS) then
- Msg:=Msg+Format(' (Array item: %s)',[its.DebugName]);
- DoLog(Msg);
- end;
- Var
- CN,TCN : String;
- Dt : TDataType;
- begin
- dt:=GetSchemaDataType(ASchema);
- CN:=NamePrefix+ASchema.Name;
- if (dt=dtArray) and (NamePrefix<>'') then
- CN:=CN+'Array';
- TCN:='T'+CN;
- Result:=doAdd(dt,TCN,ASchema,Aschema.Items);
- Aschema.TypeDef:=Result;
- if (dt=dtClass) and isToplevel then
- doAdd(dtArray,TCN+'Array',Nil,Aschema);
- end;
- procedure TDiscoveryJSONToPas.CollectType(S: TSchema; NamePrefix: String; IsTopLevel : Boolean);
- Var
- AE : String;
- Dt : TDataType;
- BaseArrayElement : Boolean;
- begin
- if (S.Name='Component') and (NamePrefix='') then
- NamePrefix:='_';
- dt:=GetSchemaDataType(S);
- BaseArrayElement:=(dt=dtArray) and S.Items.BaseType;
- DoLog('[%s] Examining : %s (Ref : %s type: %s) Toplevel %s',[NamePrefix,S.Name,S.ref,S._type,BoolToStr(IsTopLevel,'True','False')]);
- case dt of
- dtArray : if Not BaseArrayElement and (S.Items.Ref='') then
- begin
- AE:=S.Name;
- if S.Items.Name='' then
- AE:=AE+ArrayItemSuffix;
- DoLog('Array, adding array item type first (%s)',[AE]);
- CollectType(S.Items,NamePrefix+AE,isTopLevel);
- end;
- dtClass :
- if (S.Ref='') then
- begin
- DoLog('Class type, adding properties first');
- CollectTypes(S.Properties,NamePrefix+S.Name+PropertyTypeSuffix);
- end;
- else
- //no other cases to handle
- end;
- if (NamePrefix='') then
- AddType(S,'',True)
- else if (Not S.BaseType) and (Not BaseArrayElement) and (S.Ref='') then
- AddType(S,NamePrefix,IsTopLevel);
- end;
- function TDiscoveryJSONToPas.GetFlat: Boolean;
- begin
- Result:=gcoFlatResources in CodeOPtions;
- end;
- Procedure TDiscoveryJSONToPas.CollectTypes(Schemas: TSchemas; NamePrefix: String
- );
- Var
- S : TSchema;
- begin
- For S in Schemas do
- CollectType(S,NamePrefix,NamePrefix='');
- end;
- Procedure TDiscoveryJSONToPas.ResolveRefs;
- Var
- Lookup : TStringList;
- Function DoFind (S : TSchema; C : String) : TSchema;
- Var
- idx : Integer;
- begin
- Idx:=Lookup.IndexOf(S.Ref);
- if idx<>-1 then
- Result:=TSchema(Lookup.Objects[idx])
- else
- Raise Exception.CreateFmt('Could not find reference %s (Context: %s)',[S.Name,C]);
- end;
- Procedure AddSchema(ASchema : TSchema);
- begin
- if Assigned(ASchema) then
- begin
- if (ASchema.Name<>'') then
- begin
- Lookup.AddObject(ASchema.Name,ASchema)
- end;
- end
- end;
- Procedure DoResolve(ASchema : TSchema);
- Var
- S2 : TSchema;
- begin
- if Assigned(ASchema) then
- begin
- if (ASchema.Ref<>'') and (ASchema.Refschema=Nil) then
- ASchema.Refschema:=DoFind(ASchema,ASchema.Name);
- if Assigned(ASchema.Items) then
- DoResolve(ASchema.Items);
- if Length(ASchema.Properties)<>0 then
- For S2 in ASchema.Properties do
- begin
- DoResolve(S2);
- DoResolve(S2.Items);
- end;
- end;
- end;
- Var
- T : TTypeDef;
- S : TSchema;
- begin
- Lookup:=TStringList.Create;
- try
- for S in Description.Schemas do
- AddSchema(S);
- Lookup.Sorted:=True;
- For T in FTypes do
- begin
- DoResolve(T.Schema);
- DoResolve(T.ItemSchema);
- end;
- finally
- Lookup.Free;
- end;
- end;
- Procedure TDiscoveryJSONToPas.CollectTypes;
- Var
- S : TTypeDef;
- Msg : String;
- begin
- CollectTypes(Description.Schemas,ClassPrefix);
- For S in FTypes do
- begin
- Str(S.DataType,Msg);
- DoLog('Created data type %s (%s)',[S.PascalName,Msg]);
- end;
- ResolveRefs;
- end;
- Function TDiscoveryJSONToPas.BaseUnits: String;
- begin
- Result:='sysutils, classes, googleservice, restbase, googlebase';
- end;
- Class function TSchema.BaseType(ATypeName: String): Boolean;
- begin
- Result:=(ATypeName='boolean') or (ATypeName='string') or (ATypeName='number') or (ATypeName='any') or (ATypeName='integer');
- end;
- Class function TSchema.GetBaseTypeName(AType, AFormat: String): string;
- begin
- Result:=AType;
- if Result='any' then
- Result:='TJSONSchema'
- else if Result='integer' then
- begin
- if (AFormat='int64') then
- Result:='int64'
- else
- Result:='integer'
- end
- else if Result='number' then
- begin
- if (AFormat='double') then
- Result:='double'
- else
- Result:='integer'
- end
- else if Result='string' then
- if Aformat='date-time' then
- Result:='TDatetime'
- else if Aformat='date' then
- Result:='TDate'
- else
- Result:='String';
- end;
- Function TSchema.DebugName: String;
- begin
- Result:=sysutils.Format('(Name: %s, Pascal Type : %s, type : %s, Ref: %s)',[Name,TypeName,_type,Ref]);
- end;
- function TSchema.GetBaseTypeName: string;
- begin
- Result:=GetBaseTypeName(_type,Format);
- end;
- Function TSchema.BaseType: Boolean;
- begin
- Result:=BaseType(_type)
- end;
- Function TDiscoveryJSONToPas.GetPropertyType(AClassName: String;
- ASchema: TSchema): String;
- begin
- DoLog('Checking property type "%s" property schema %s',[AClassName,ASchema.DebugName]);
- Result:=ASchema.TypeName;
- if (Result='') then
- begin
- Result:=ASchema.ref;
- if Result='' then
- begin
- Result:=ASchema._type;
- if TSchema.BaseType(Result) then
- Result:=ASchema.GetBaseTypeName;
- end
- else if Not Assigned(ASchema.Refschema) then
- Raise Exception.CreateFmt('%s : Unresolved property schema (%s) type reference : %s',[AClassName,ASchema.Name,ASchema.Ref])
- else
- Result:=ASchema.Refschema.TypeName;
- end;
- if Result='array' then
- begin
- if Aschema.Items.TypeDef<>Nil then
- Result:=Aschema.Items.TypeDef.PascalName
- else if (ASchema.Items.Ref<>'') then
- begin
- if not Assigned(ASchema.Items.Refschema) then
- Raise Exception.CreateFmt('%s : Unresolved property (%s) type reference : %s',[AClassName,ASchema.Name,ASchema.Ref]);
- Result:=Aschema.Items.RefSchema.TypeName+'Array';
- end
- else
- Result:=ASchema.Items.TypeName;
- end
- else if Result='object' then
- if (ASchema.ref<>'') then
- Result:='T'+ClassPrefix+ASchema.ref
- else
- Result:=AClassName+ASchema.Name;
- end;
- Procedure TDiscoveryJSONToPas.CreateClassDeclaration(AClassName: String;
- ASchema: TSchema);
- Var
- S : TSchema;
- N : String;
- NeedSetArrayLength, NeedGetWritename : Boolean;
- TN : String;
- Idx,PropertyIndex,PropertyOptions : Integer;
- L : TStringList;
- begin
- if ASchema=Nil then
- Raise Exception.Create(AClassName+' : no Schema');
- ClassComment(AClassName);
- AddLn('%s = Class(%s)',[AClassName,BaseClassName]);
- AddLn('Private');
- NeedGetWriteName:=False;
- NeedSetArrayLength:=False;
- IncIndent;
- L:=TStringList.Create;
- try
- For S in ASchema.Properties do
- begin
- N:=TBaseObject.CleanPropertyName(S.Name);
- Repeat
- Idx:=L.IndexOf(N);
- if (idx=-1) then
- Idx:=L.IndexOf('F'+N);
- if (idx<>-1) then
- begin
- N:='_'+N;
- end;
- Until Idx=-1;
- NeedGetWritename:=NeedGetWritename or (CompareText(N,S.Name)<>0);
- NeedSetArrayLength:=NeedSetArrayLength or (S._type='array');
- S.PropertyName:=N;
- tn:=GetPropertyType(AClassName,S);
- AddLn('F%s : %s;',[N,tn]);
- L.Add(N);
- L.Add('F'+N);
- end;
- finally
- L.Free;
- end;
- DecIndent;
- AddLn('Protected');
- IncIndent;
- if NeedGetWriteName then
- AddLn('Class Function ExportPropertyName(Const AName : String) : string; override;');
- Comment('Property setters');
- For S in ASchema.ClassProperties do
- begin
- N:=S.PropertyName;
- tn:=GetPropertyType(AClassName,S);
- AddLn('Procedure Set%s(AIndex : Integer; const AValue : %s); virtual;',[N,tn]);
- end;
- DecIndent;
- AddLn('Public');
- IncIndent;
- if Assigned(ASchema.additionalProperties) then
- AddLn('Class Function AllowAdditionalProperties : Boolean; override;');
- DecIndent;
- AddLn('Published');
- IncIndent;
- PropertyIndex:=0;
- For S in ASchema.ClassProperties do
- begin
- N:=S.PropertyName;
- Tn:=GetPropertyType(AClassName,S);
- PropertyOptions:=0;
- Idx:=(PropertyIndex shl IndexShift) or PropertyOptions;
- AddLn('Property %s : %s Index %d Read F%s Write Set%s;',[N,TN,Idx, N,N]);
- Inc(PropertyIndex);
- end;
- DecIndent;
- AddLn('end;');
- AddLn('%sClass = Class of %s;',[AClassName,AClassName]);
- end;
- Procedure TDiscoveryJSONToPas.CreateArrayClassDeclaration(AClassName: String;
- ASchema, AItemSchema: TSchema);
- Var
- AEnumeratorName,AItemName : String;
- begin
- if AItemSchema=Nil then
- Raise Exception.Create(AClassName+' : no item Schema');
- AItemName:=GetPropertyType('',AItemSchema);
- AEnumeratorName:=AClassName+'Enumerator';
- ClassComment(AEnumeratorName);
- AddLn('%s = Class(%s)',[AEnumeratorName,'TBaseListEnumerator']);
- AddLn('Public');
- IncIndent;
- AddLn('Function GetCurrent : %s; ',[AItemName]);
- AddLn('Property Current : %s Read GetCurrent;',[AItemName]);
- DecIndent;
- AddLn('end;');
- AddLn('');
- AddLn('');
- ClassComment(AClassName);
- AddLn('%s = Class(%s)',[AClassName,BaseListClassName]);
- AddLn('Private');
- IncINdent;
- Addln('Function GetI (AIndex : Integer) : %s;',[AItemName]);
- Addln('Procedure SetI (AIndex : Integer; Const AValue: %s);',[AItemName]);
- DecIndent;
- AddLn('Protected');
- IncIndent;
- AddLn('Class Function ObjectClass : TBaseObjectClass; override;');
- DecIndent;
- AddLn('Public');
- IncIndent;
- AddLn('Function GetEnumerator : %s;',[AEnumeratorName]);
- AddLn('Property Items[AIndex : Integer] : %s Read GetI Write SetI; default;',[AItemName]);
- DecIndent;
- AddLn('end;');
- AddLn('%sClass = Class of %s;',[AClassName,AClassName]);
- end;
- procedure TDiscoveryJSONToPas.CreateSetArrayLength(AClassName: String; ASchema, AItemSchema: TSchema);
- begin
- //not used
- end;
- procedure TDiscoveryJSONToPas.CreateExportPropertyName(AClassName: String; ASchema, AItemSchema: TSchema);
- Var
- S : TSchema;
- N : String;
- begin
- begin
- Addln('');
- AddLn('Class Function %s.ExportPropertyName(Const AName : String) :String;',[AClassName]);
- Addln('');
- AddLn('begin');
- IncIndent;
- AddLn('Case AName of');
- For S in ASchema.ClassProperties do
- begin
- N:=S.PropertyName;
- if (CompareText(N,S.Name)<>0) then
- AddLn('''%s'' : Result:=''%s'';',[N,S.Name]);
- end;
- AddLn('else');
- IncIndent;
- AddLn('Result:=Inherited ExportPropertyName(AName);');
- DecIndent;
- AddLn('end;');
- DecIndent;
- AddLn('end;');
- Addln('');
- end;
- end;
- Procedure TDiscoveryJSONToPas.CreateClassImplementation(AClassName: String;
- ASchema, AItemSchema: TSchema);
- Var
- S : TSchema;
- N : String;
- NeedSetArrayLength,NeedGetWritename : Boolean;
- TN : String;
- begin
- NeedGetWriteName:=False;
- NeedSetArrayLength:=False;
- ClassComment(AClassName);
- For S in ASchema.ClassProperties do
- begin
- N:=S.PropertyName;
- NeedSetArrayLength:=NeedSetArrayLength or (S._type='array');
- NeedGetWritename:=NeedGetWritename or (CompareText(N,S.Name)<>0);
- TN:=GetPropertyType(AClassName,S);
- Addln('');
- AddLn('Procedure %s.Set%s(AIndex : Integer; const AValue : %s); ',[AClassName,N,tn]);
- SimpleMethodBody([Format('If (F%s=AValue) then exit;',[N]),
- Format('F%s:=AValue;',[N]),
- 'MarkPropertyChanged(AIndex);']);
- Addln('');
- end;
- if NeedGetWriteName then
- CreateExportPropertyName(AClassName,ASchema, AItemSchema);
- if NeedSetArrayLength and not UseListForArray then
- CreateSetArrayLength(AClassName,ASchema, AItemSchema);
- Addln('');
- if Assigned(ASchema.additionalProperties) then
- begin
- AddLn('Class Function %s.AllowAdditionalProperties : Boolean;',[AClassName]);
- SimpleMethodBody(['Result:=True;']);
- end;
- Addln('');
- end;
- Procedure TDiscoveryJSONToPas.CreateArrayClassImplementation(
- AClassName: String; ASchema, AItemSchema: TSchema);
- Var
- AEnumeratorName,AItemName : String;
- begin
- if AItemSchema=Nil then
- Raise Exception.Create(AClassName+' : no Schema');
- CreateArrayClassEnumeratorImplementation(ACLassName,ASchema,AItemSchema);
- AItemName:=GetPropertyType('',AItemSchema);
- AEnumeratorName:=AClassName+'Enumerator';
- ClassComment(AClassName);
- Addln('');
- Addln('Function %s.GetI (AIndex : Integer) : %s;',[AClassName,AItemName]);
- SimpleMethodBody([Format('Result:=%s(Objects[AIndex]);',[AItemName])]);
- Addln('');
- Addln('Procedure %s.SetI (AIndex : Integer; Const AValue: %s);',[AClassName,AItemName]);
- SimpleMethodBody(['Objects[AIndex]:=AValue;']);
- Addln('');
- AddLn('Class Function %s.ObjectClass : TBaseObjectClass;',[ACLassName]);
- SimpleMethodBody([Format('Result:=%s;',[AItemName])]);
- Addln('');
- AddLn('Function %S.GetEnumerator : %s;',[ACLassName,AEnumeratorName]);
- SimpleMethodBody([Format('Result:=%s(DoCreateEnumerator(%s));',[AEnumeratorName,AEnumeratorName])]);
- Addln('');
- end;
- Procedure TDiscoveryJSONToPas.CreateArrayClassEnumeratorImplementation(
- AClassName: String; ASchema, AItemSchema: TSchema);
- Var
- AEnumeratorName,AItemName : String;
- begin
- if AItemSchema=Nil then
- Raise Exception.Create(AClassName+' : no ItemSchema');
- AItemName:=GetPropertyType('',AItemSchema);
- AEnumeratorName:=AClassName+'Enumerator';
- ClassComment(AEnumeratorName);
- AddLn('Function %s.GetCurrent : %s;',[AEnumeratorName,AItemName]);
- SimpleMethodBody([Format('Result:=%s(Inherited GetCurrent);',[AItemName])]);
- end;
- Function TDiscoveryJSONToPas.GetAPIClassName: String;
- begin
- Result:=Format('T%s%sAPI',[ClassPrefix,PrettyPrint(Description.Name)])
- end;
- Procedure TDiscoveryJSONToPas.CreateInterface;
- procedure AddTypeDecl(S : TTypeDef);
- begin
- Case S.DataType of
- dtAlias : AddLn('%s = %s;',[S.PascalName,S.Schema.GetBaseTypeName]);
- dtArray :
- if UseListForArray then
- AddLn('%s = Class;',[S.PascalName])
- else
- AddLn('%s = Array of %s;',[S.PascalName,GetPropertyType('',S.ItemSchema)]);
- dtClass : AddLn('%s = Class;',[S.PascalName]);
- end;
- end;
- Procedure DoTypeLoops(DoTopLevel : Boolean);
- Var
- S : TTypeDef;
- begin
- For S in FTypes do
- if (S.DataType=dtAlias) and (S.TopLevel=DoTopLevel) then
- AddTypeDecl(S);
- For S in FTypes do
- if (S.DataType=dtClass) and (S.TopLevel=DoTopLevel) then
- AddTypeDecl(S);
- For S in FTypes do
- if (S.DataType=dtArray) and (S.TopLevel=DoTopLevel) then
- AddTypeDecl(S);
- end;
- Var
- S : TTypeDef;
- begin
- Addln('type');
- IncIndent;
- AddLn('');
- Comment('Top-level schema types');
- DoTypeLoops(True);
- Comment('Anonymous types, using auto-generated names');
- DoTypeLoops(False);
- For S in FTypes do
- if S.DataType=dtClass then
- CreateClassDeclaration(S.PascalName,S.Schema)
- else if (S.DataType=dtArray) and UseListForArray then
- CreateArrayClassDeclaration(S.PascalName,S.Schema,S.ItemSchema);
- CreateResourceDeclarations('',Description.Resources);
- CreateAPIClassDeclaration;
- DecIndent;
- end;
- procedure TDiscoveryJSONToPas.CreateResourceDeclarations(Const APrefix : String; Resources : TSchemas);
- var
- R : TSchema;
- begin
- For R in Resources do
- begin
- if Assigned(R.resources) then
- if FlatResources then
- CreateResourceDeclarations(APrefix,R.Resources)
- else
- CreateResourceDeclarations(APrefix+PrettyPrint(R.Name),R.Resources);
- R.TypeName:=GetResourceClassName(APrefix,R);
- CreateResourceClassDeclaration(APrefix,R);
- end;
- end;
- Procedure TDiscoveryJSONToPas.CreateImplementation;
- Var
- S : TTypeDef;
- begin
- For S in FTypes do
- Case S.DataType of
- dtClass: CreateClassImplementation(S.PascalName,S.Schema,S.ItemSchema);
- dtArray: if UseListForArray then
- CreateArrayClassImplementation(S.PascalName,S.Schema,S.ItemSchema);
- else
- //no other cases to handle
- end;
- CreateResourceClassImplementations('',Description.Resources);
- CreateAPIClassImplementation;
- end;
- Procedure TDiscoveryJSONToPas.CreateResourceClassImplementations(Const APrefix : String; Resources : TSchemas);
- var
- R : TSchema;
- begin
- For R in Resources do
- begin
- if Assigned(R.Resources) then
- CreateResourceClassImplementations(ConstructResourcePrefix(APrefix,R),R.Resources);
- CreateResourceClassImplementation(APrefix,R);
- end;
- end;
- Function TDiscoveryJSONToPas.GetResourceMethodSignature(M: TRestmethod; Out
- IsFunction: Boolean; QueryOptionType: String; AddTypes: Boolean): String;
- Const
- Seps : Array[Boolean] of String = (',','; ');
- Procedure AddSep(Var S : String);
- begin
- if (S<>'') then
- S:=S+Seps[AddTypes];
- end;
- Var
- P : TRestMethodParam;
- S : String;
- Q : Boolean; // Was AQuery encountered in options
- begin
- Q:=False;
- S:='';
- For P in M.parameters do
- if (P.Location='path') and P.Required then
- begin
- Q:=Q or (CompareText(p.SourceName,'aquery')=0);
- AddSep(S);
- S:=S+P.SourceName;
- If AddTypes then
- S:=S+': '+P._type;
- end;
- For P in M.parameters do
- if (P.Location='path') and not P.Required then
- begin
- Q:=Q or (CompareText(p.SourceName,'aquery')=0);
- AddSep(S);
- S:=S+P.SourceName;
- if AddTypes then
- begin
- S:=S+': '+P._type + ' = ';
- Case p._type of
- 'string' : S:=S+'''''';
- 'number' : S:=S+'0';
- 'object' : S:=S+'nil';
- end;
- end;
- end;
- if M.Request<>Nil then
- begin
- AddSep(S);
- S:=S+'a'+M.request.ref;
- If AddTypes then
- S:=S+' : T'+ClassPrefix+M.request.ref;
- end;
- if (QueryOptionType<>'') then
- begin
- AddSep(S);
- if AddTypes then
- S:=S+'AQuery : '+QueryOptionType
- else
- S:=S+QueryOptionType; // Will be name instead of type;
- end;
- if (S<>'') then
- S:='('+S+')';
- S:=PrettyPrint(TBaseObject.CleanPropertyName(M.Name))+S;
- isFunction:=M.Response<>Nil;
- if isFunction and AddTypes then
- S:=S+' : T'+ClassPrefix+M.response.ref;
- Result:=S;
- end;
- Function TDiscoveryJSONToPas.DescribeMethodParams(M: TRestMethod
- ): TParamLocations;
- Var
- P : TRestMethodParam;
- begin
- Result:=[];
- For P in M.Parameters do
- Case P.location of
- 'path' : Include(Result,plPath);
- 'query' : Include(Result,plQuery);
- end;
- end;
- Function TDiscoveryJSONToPas.HavePathParams(M: TRestMethod): Boolean;
- begin
- Result:=plPath in DescribeMethodParams(M);
- end;
- Procedure TDiscoveryJSONToPas.CreateResourceMethodQueryParams(APrefix : String; Res: TSchema;
- M: TRestMethod);
- Var
- P : TRestMethodParam;
- RN,RCN,MN : String;
- begin
- RN:=APrefix+PrettyPrint(Res.Name);
- RCN:=Res.TypeName;
- MN:=PrettyPrint(M.Name);
- Addln('');
- Comment(Format('Optional query Options for %s, method %s',[RCN,MN]));
- Addln('');
- Addln('T%s%sOptions = Record',[RN,MN]);
- IncIndent;
- For P in M.parameters do
- begin
- if (P.location='query') then
- if p.format='int64' then
- AddLn('%s : int64;',[P.Sourcename])
- else
- AddLn('%s : %s;',[P.sourcename,P.GetBaseTypeName]);
- end;
- DecIndent;
- Addln('end;');
- Addln('');
- end;
- Function TDiscoveryJSONToPas.HaveQueryParams(M: TRestMethod): Boolean;
- begin
- Result:=plQuery in DescribeMethodParams(M);
- end;
- Function TDiscoveryJSONToPas.GetResourceClassName(Const APrefix: String;
- Res: TSchema): String;
- Var
- Suffix : String;
- begin
- if (Res.TypeName<>'') and (Res.TypeName<>Res.Name) then
- Result:=Res.TypeName
- else
- begin
- Suffix:='Resource';
- Repeat
- Result:=Format('T%s%s%s%s',[ClassPrefix,APrefix,PrettyPrint(Res.Name),Suffix]);
- Suffix:='_'+Suffix;
- Until FTypes.IndexOf(Result)=-1;
- end
- end;
- procedure TDiscoveryJSONToPas.AssignParamNames(Res: TSchema; M: TRestMethod);
- // Google API has case sensitive names. We need to make sure the names are unique in a case insensitive manner.
- // This is done by assigning the 'source name'
- Var
- T : TStringList;
- P : TRestMethodParam;
- N : String;
- begin
- T:=TStringList.Create;
- try
- // The request also has a parameter name
- If Assigned(M.request) then
- T.Add('a'+M.request.ref);
- // Some identifiers that are 'reserved' by the base classes.
- With T do
- begin
- Add('Name');
- Add('ResourceName');
- Add('DefaultAPI');
- Add('API');
- Add('Notification');
- Add('UpdateAction');
- Add('ExecuteAction');
- end;
- // Actual paramters
- For P in M.parameters do
- begin
- N:=P.Name;
- While T.IndexOf(N)<>-1 do
- begin
- N:='_'+N;
- end;
- T.Add(N);
- P.SourceName:=TbaseObject.CleanPropertyName(N);
- end;
- finally
- T.Free;
- end;
- end;
- function TDiscoveryJSONToPas.ReservedMethod(ANAme: String): boolean;
- begin
- AName:=';'+lowerCase(AName)+';';
- Result:=Pos(AName,';create;destroy;free;')<>0;
- end;
- Procedure TDiscoveryJSONToPas.CreateResourceClassDeclaration(
- Const APrefix: String; Res: TSchema);
- Var
- M : TRestMethod;
- CN,S : String;
- HaveOpt : Boolean;
- IsFunc : Boolean;
- begin
- CN:=Res.TypeName;
- ClassComment(CN);
- For M in Res.methods do
- begin
- AssignParamNames(Res,M);
- if HaveQueryParams(M) then
- begin
- CreateResourceMethodQueryParams(APrefix,Res,M);
- end;
- end;
- Addln('%s = Class(TGoogleResource)',[CN]);
- if Assigned(Res.Resources) then
- begin
- Addln('Private');
- IncIndent;
- CreateResourceInstanceFields('',Res.Resources);
- CreateResourceInstanceGetters('',Res.Resources);
- DecIndent;
- end;
- Addln('Public');
- IncIndent;
- AddLn('Class Function ResourceName : String; override;');
- AddLn('Class Function DefaultAPI : TGoogleAPIClass; override;');
- For M in Res.methods do
- begin
- HaveOpt:=HaveQueryParams(M);
- if HaveOpt then
- S:=GetResourceMethodSignature(M,IsFunc,'string = ''''')
- else
- S:=GetResourceMethodSignature(M,IsFunc,'');
- if IsFunc then
- S:='Function '+S
- else
- S:='Procedure '+S;
- if ReservedMethod(M.Name) then
- S:=S+';overload';
- AddLn(S+';');
- if HaveOpt then
- begin
- S:=GetResourceMethodSignature(M,IsFunc,Format('T%s%sOptions',[APrefix+PrettyPrint(Res.Name),M.Name]));
- if IsFunc then
- S:='Function '+S
- else
- S:='Procedure '+S;
- if ReservedMethod(M.Name) then
- S:=S+';overload';
- AddLn(S+';');
- end;
- end;
- if Assigned(Res.Resources) then
- begin
- CreateResourceAPI('',Res.resources);
- CreateResourceProperties('',Res.resources);
- end;
- DecIndent;
- Addln('end;',[Res.name]);
- AddLn('');
- end;
- Procedure TDiscoveryJSONToPas.CreateResourceClassMethodsImplementation(
- Res: TSchema; Const AClassName: String);
- begin
- AddLn('');
- Addln('Class Function %s.ResourceName : String;',[AClassName]);
- AddLn('');
- AddLn('begin');
- IncIndent;
- AddLn('Result:=''%s'';',[Res.name]);
- DecIndent;
- AddLn('end;');
- AddLn('');
- Addln('Class Function %s.DefaultAPI : TGoogleAPIClass;',[AClassName]);
- AddLn('');
- AddLn('begin');
- IncIndent;
- AddLn('Result:=T%s%sAPI;',[ClassPrefix,Description.Name]);
- DecIndent;
- AddLn('end;');
- AddLn('');
- end;
- Procedure TDiscoveryJSONToPas.CreateResourceMethodImplementationOptions(Const APrefix,AClassName: String; Res: TSchema; M: TRestMethod);
- Var
- P : TRestMethodParam;
- S: String;
- IsFunc : Boolean;
- begin
- S:=GetResourceMethodSignature(M,IsFunc,Format('T%s%sOptions',[APrefix+PrettyPrint(Res.Name),M.Name]));
- S:=AClassName+'.'+S;
- if IsFunc then
- S:='Function '+S
- else
- S:='Procedure '+S;
- Addln('');
- AddLn(S+';');
- Addln('');
- AddLn('Var');
- IncIndent;
- Addln('_Q : String;');
- DecIndent;
- Addln('');
- AddLn('begin');
- IncIndent;
- AddLn('_Q:='''';');
- For P in M.parameters do
- begin
- if (P.location='query') then
- AddLn('AddToQuery(_Q,''%s'',AQuery.%s);',[P.name,P.SourceName]);
- end;
- S:=GetResourceMethodSignature(M,IsFunc,'_Q',False);
- if IsFunc then
- S:='Result:='+S;
- AddLn(S+';');
- DecIndent;
- AddLn('end;');
- Addln('');
- end;
- Procedure TDiscoveryJSONToPas.CreateResourceMethodImplementation(
- AClassName: String; Res: TSchema; M: TRestMethod);
- Var
- P : TRestMethodParam;
- Q,RC,O,S,PA : String;
- IsFunc : Boolean;
- PL: TParamLocations;
- begin
- PL:=DescribeMethodParams(M);
- if plQuery in PL then
- S:=GetResourceMethodSignature(M,IsFunc,'string = ''''')
- else
- S:=GetResourceMethodSignature(M,IsFunc,'');
- S:=AClassName+'.'+S;
- if IsFunc then
- S:='Function '+S
- else
- S:='Procedure '+S;
- AddLn(S+';');
- AddLn('');
- AddLn('Const');
- IncIndent;
- AddLn('_HTTPMethod = ''%s'';',[M.httpMethod]);
- AddLn('_Path = ''%s'';',[M.path]);
- AddLn('_Methodid = ''%s'';',[M.id]);
- DecIndent;
- AddLn('');
- if (plPath in PL) then
- begin
- AddLn('Var');
- IncIndent;
- Addln('_P : String;');
- DecIndent;
- Addln('');
- end;
- Addln('begin');
- IncIndent;
- S:='';
- PA:='_Path';
- if (plPath in PL) then
- begin
- for P in M.parameters do
- if P.location='path' then
- begin
- if (S<>'') then
- S:=S+',';
- S:=S+Format('''%s'',%s',[p.name,p.sourcename]);
- end;
- AddLn('_P:=SubstitutePath(_Path,[%s]);',[S]);
- PA:='_P';
- end;
- if M.request<>Nil then
- O:='a'+M.request.ref
- else
- O:='Nil';
- if (M.response<>Nil) then
- RC:='T'+ClassPrefix+M.response.ref
- else
- RC:='Nil';
- if (plQuery in PL) then
- Q:='AQuery'
- else
- Q:='''''';
- S:=Format('ServiceCall(_HTTPMethod,%s,%s,%s,%s)',[PA,Q,O,RC]);
- if isFunc then
- S:='Result:='+S+' as T'+ClassPrefix+M.response.ref;
- AddLn(S+';');
- DecIndent;
- Addln('end;');
- Addln('');
- end;
- Procedure TDiscoveryJSONToPas.CreateResourceClassImplementation(Const APrefix : String; Res: TSchema);
- Var
- CN : String;
- M : TRestMethod;
- PL: TParamLocations;
- begin
- CN:=Res.TypeName;
- ClassComment(CN);
- CreateResourceClassMethodsImplementation(Res,CN);
- For M in Res.methods do
- begin
- PL:=DescribeMethodParams(M);
- CreateResourceMethodImplementation(CN,Res,M);
- if plQuery in PL then
- CreateResourceMethodImplementationOptions(APrefix,CN,Res,M);
- end;
- AddLn('');
- if Assigned(Res.resources) then
- CreateResourceAPIFunctionImplementations(CN,'',Res.resources);
- end;
- Procedure TDiscoveryJSONToPas.CreateResourceInstanceFields(Const APrefix : String;Resources : TSchemas);
- Var
- R : TSchema;
- begin
- For R in Resources do
- begin
- If Assigned(R.Resources) then
- CreateResourceInstanceFields(ConstructResourcePrefix(APrefix,R),R.Resources);
- AddLn('F%sInstance : %s;',[APrefix+PrettyPrint(R.Name),R.TypeName]);
- end;
- end;
- Function TDiscoveryJSONToPas.ConstructResourcePrefix(Const APrefix : String; AResource : TSchema) : String;
- begin
- if FlatResources then
- Result:=APrefix
- else
- Result:=APrefix+PrettyPrint(AResource.Name);
- end;
- Procedure TDiscoveryJSONToPas.CreateResourceInstanceGetters(Const APrefix : String; Resources : TSchemas);
- Var
- R : TSchema;
- begin
- For R in Resources do
- begin
- If Assigned(R.Resources) then
- CreateResourceInstanceGetters(ConstructResourcePrefix(APrefix,R),R.Resources);
- AddLn('Function Get%sInstance : %s;virtual;',[APrefix+PrettyPrint(R.Name),R.TypeName]);
- end;
- end;
- Procedure TDiscoveryJSONToPas.CreateResourceProperties(Const APrefix : String; Resources : TSchemas);
- Var
- R : TSchema;
- begin
- For R in Resources do
- begin
- If Assigned(R.Resources) then
- CreateResourceProperties(ConstructResourcePrefix(APrefix,R),R.Resources);
- AddLn('Property %sResource : %s Read Get%sInstance;',[APrefix+PrettyPrint(R.Name),R.TypeName,APrefix+PrettyPrint(R.Name)]);
- end;
- end;
- Procedure TDiscoveryJSONToPas.CreateResourceAPI(Const APrefix : String; Resources : TSchemas);
- Var
- R : TSchema;
- begin
- For R in Resources do
- begin
- If Assigned(R.Resources) then
- CreateResourceAPI(ConstructResourcePrefix(APrefix,R),R.Resources);
- AddLn('Function Create%sResource(AOwner : TComponent) : %s;virtual;overload;',[APrefix+PrettyPrint(R.Name),R.TypeName]);
- AddLn('Function Create%sResource : %s;virtual;overload;',[APrefix+PrettyPrint(R.Name),R.TypeName]);
- end;
- end;
- Procedure TDiscoveryJSONToPas.CreateAPIClassDeclaration;
- Var
- CN : String;
- begin
- CN:=GetAPIClassName;
- ClassComment(CN);
- AddLn('%s = Class(TGoogleAPI)',[CN]);
- AddLn('Private');
- IncIndent;
- CreateResourceInstanceFields('',Description.resources);
- CreateResourceInstanceGetters('',Description.resources);
- DecINdent;
- AddLn('Public');
- IncIndent;
- Comment('Override class functions with API info');
- AddLn('Class Function APIName : String; override;');
- AddLn('Class Function APIVersion : String; override;');
- AddLn('Class Function APIRevision : String; override;');
- AddLn('Class Function APIID : String; override;');
- AddLn('Class Function APITitle : String; override;');
- AddLn('Class Function APIDescription : String; override;');
- AddLn('Class Function APIOwnerDomain : String; override;');
- AddLn('Class Function APIOwnerName : String; override;');
- AddLn('Class Function APIIcon16 : String; override;');
- AddLn('Class Function APIIcon32 : String; override;');
- AddLn('Class Function APIdocumentationLink : String; override;');
- AddLn('Class Function APIrootUrl : string; override;');
- AddLn('Class Function APIbasePath : string;override;');
- AddLn('Class Function APIbaseURL : String;override;');
- AddLn('Class Function APIProtocol : string;override;');
- AddLn('Class Function APIservicePath : string;override;');
- AddLn('Class Function APIbatchPath : String;override;');
- AddLn('Class Function APIAuthScopes : TScopeInfoArray;override;');
- AddLn('Class Function APINeedsAuth : Boolean;override;');
- AddLn('Class Procedure RegisterAPIResources; override;');
- Comment('Add create function for resources');
- CreateResourceAPI('',Description.resources);
- Comment('Add default on-demand instances for resources');
- CreateResourceProperties('',Description.resources);
- DecIndent;
- AddLn('end;');
- end;
- Procedure TDiscoveryJSONToPas.CreateAPIClassImplementation;
- Procedure StringRes(AValue : String);
- Var
- S : String;
- begin
- S:=MakePascalString(AValue,True);
- S:=StringReplace(S,#13#10,'''#13#10''',[rfReplaceAll]);
- S:=StringReplace(S,#10,'''#10''',[rfReplaceAll]);
- S:=StringReplace(S,#13,'''#13''',[rfReplaceAll]);
- SimpleMethodBody([Format('Result:=%s;',[S])]);
- end;
- Var
- CN : String;
- S : TSchema;
- I : Integer;
- begin
- CN:=GetAPIClassName;
- ClassComment(CN);
- AddLn('Class Function %s.APIName : String;',[CN]);
- StringRes(Description.name);
- AddLn('Class Function %s.APIVersion : String;',[CN]);
- StringRes(Description.version);
- AddLn('Class Function %s.APIRevision : String;',[CN]);
- StringRes(Description.revision);
- AddLn('Class Function %s.APIID : String;',[CN]);
- StringRes(Description.id);
- AddLn('Class Function %s.APITitle : String;',[CN]);
- StringRes(Description.Title);
- AddLn('Class Function %s.APIDescription : String;',[CN]);
- StringRes(Description.Description);
- AddLn('Class Function %s.APIOwnerDomain : String;',[CN]);
- StringRes(Description.ownerDomain);
- AddLn('Class Function %s.APIOwnerName : String;',[CN]);
- StringRes(Description.ownerName);
- AddLn('Class Function %s.APIIcon16 : String;',[CN]);
- StringRes(Description.icons.x16);
- AddLn('Class Function %s.APIIcon32 : String;',[CN]);
- StringRes(Description.icons.x32);
- AddLn('Class Function %s.APIdocumentationLink : String;',[CN]);
- StringRes(Description.documentationLink);
- AddLn('Class Function %s.APIrootUrl : string;',[CN]);
- StringRes(Description.rootUrl);
- AddLn('Class Function %s.APIbasePath : string;',[CN]);
- StringRes(Description.BasePath);
- AddLn('Class Function %s.APIbaseURL : String;',[CN]);
- StringRes(Description.BaseURL);
- AddLn('Class Function %s.APIProtocol : string;',[CN]);
- StringRes(Description.protocol);
- AddLn('Class Function %s.APIservicePath : string;',[CN]);
- StringRes(Description.servicePath);
- AddLn('Class Function %s.APIbatchPath : String;',[CN]);
- StringRes(Description.batchPath);
- AddLn('Class Function %s.APIAuthScopes : TScopeInfoArray;',[CN]);
- Addln('');
- AddLn('begin');
- IncIndent;
- if not (Assigned(Description.Auth) and Assigned(Description.Auth.oauth2)) then
- AddLn('SetLength(Result,0);')
- else
- begin
- AddLn('SetLength(Result,%d);',[Length(Description.Auth.oauth2.Scopes)]);
- For I:=0 to Length(Description.Auth.oauth2.Scopes)-1 do
- begin
- S:=Description.Auth.oauth2.Scopes[i];
- AddLn('Result[%d].Name:=%s;',[I,MakePascalString(S.Name,True)]);
- AddLn('Result[%d].Description:=%s;',[I,MakePascalString(S.Description,True)]);
- end;
- end;
- Addln('');
- DecIndent;
- Addln('end;');
- Addln('');
- AddLn('Class Function %s.APINeedsAuth : Boolean;',[CN]);
- SimpleMethodBody([Format('Result:=%s;',[BoolToStr(Assigned(Description.Auth) and Assigned(Description.Auth.oauth2),'True','False')])]);
- AddLn('Class Procedure %s.RegisterAPIResources;',[CN]);
- Addln('');
- AddLn('begin');
- IncIndent;
- For I:=0 to FTypes.Count-1 do
- if FTypes[i].DataType=dtClass then
- AddLn('%s.RegisterObject;',[FTypes[i].PascalName]);
- DecIndent;
- Addln('end;');
- Addln('');
- CreateResourceAPIFunctionImplementations(GetAPIClassName,'',Description.resources);
- end;
- Procedure TDiscoveryJSONToPas.CreateResourceAPIFunctionImplementations(Const AClassName : String; Const APrefix : String; Resources : TSchemas);
- Var
- RN,CN,RCN : String;
- R : TSchema;
- begin
- CN:=AClassName;
- For R in Resources do
- begin
- if Assigned(R.Resources) then
- CreateResourceAPIFunctionImplementations(CN,ConstructResourcePrefix(APrefix,R),R.Resources);
- RN:=APrefix+PrettyPrint(R.Name);
- RCN:=R.TypeName;
- AddLn('');
- AddLn('Function %s.Get%sInstance : %s;',[CN,RN,RCN]);
- AddLn('');
- AddLn('begin');
- IncIndent;
- AddLn('if (F%sInstance=Nil) then',[RN]);
- IncIndent;
- AddLn('F%sInstance:=Create%sResource;',[RN,RN]);
- DecIndent;
- AddLn('Result:=F%sInstance;',[RN]);
- DecIndent;
- AddLn('end;');
- AddLn('');
- AddLn('Function %s.Create%sResource : %s;',[CN,RN,RCN]);
- SimpleMethodBody([Format('Result:=Create%sResource(Self);',[RN])]);
- AddLn('');
- AddLn('Function %s.Create%sResource(AOwner : TComponent) : %s;',[CN,RN,RCN]);
- SimpleMethodBody([Format('Result:=%s.Create(AOwner);',[RCN]),
- 'Result.API:=Self.API;']);
- AddLn('');
- end;
- end;
- Procedure TDiscoveryJSONToPas.Execute;
- begin
- Source.Clear;
- CreateUnitClause;
- CreateHeader;
- FTypes:=TTypeDefs.Create(TTypeDef);
- try
- CollectTypes;
- CreateInterface;
- AddLn('');
- AddLn('implementation');
- AddLn('');
- CreateImplementation;
- Addln('');
- AddLn('initialization');
- Addln(' %s.RegisterAPI;',[GetAPIClassName]);
- finally
- FTypes.Free;
- end;
- AddLn('end.');
- end;
- Class Procedure TDiscoveryJSONToPas.RegisterAllObjects;
- begin
- TGoogleIcons.RegisterObject;
- TGoogleAuth2.RegisterObject;
- TGoogleAuth.RegisterObject;
- TArrayPropertyDef.RegisterObject;
- TPropertyDef.RegisterObject;
- TSchema.RegisterObject;
- TGoogleRestDescription.RegisterObject;
- TAnnotations.RegisterObject;
- TRestMethod.RegisterObject;
- TRestMethodParam.RegisterObject;
- TMediaUpload.RegisterObject;
- TMediaUploadProtocols.RegisterObject;
- TMediaUploadProtocolsSimple.RegisterObject;
- TMediaUploadProtocolsResumable.RegisterObject;
- TRequest.RegisterObject;
- TResponse.RegisterObject;
- end;
- end.
|