googlediscoverytopas.pp 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968
  1. { Base Google API code generator
  2. Copyright (C) 2015 Michael Van Canneyt [email protected]
  3. This library is free software; you can redistribute it and/or modify it
  4. under the terms of the GNU Library General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or (at your
  6. option) any later version with the following modification:
  7. As a special exception, the copyright holders of this library give you
  8. permission to link this library with independent modules to produce an
  9. executable, regardless of the license terms of these independent modules,and
  10. to copy and distribute the resulting executable under terms of your choice,
  11. provided that you also meet, for each linked independent module, the terms
  12. and conditions of the license of that module. An independent module is a
  13. module which is not derived from or based on this library. If you modify
  14. this library, you may extend this exception to your version of the library,
  15. but you are not obligated to do so. If you do not wish to do so, delete this
  16. exception statement from your version.
  17. This program is distributed in the hope that it will be useful, but WITHOUT
  18. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  19. FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
  20. for more details.
  21. You should have received a copy of the GNU Library General Public License
  22. along with this library; if not, write to the Free Software Foundation,
  23. Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  24. }
  25. unit googlediscoverytopas;
  26. {$mode objfpc}{$H+}
  27. interface
  28. uses
  29. typinfo, Classes, SysUtils, fpjson, restcodegen, restbase, googlebase;
  30. Type
  31. TTypeDef = Class;
  32. TSchema = Class;
  33. TSchemas = Array of TSchema;
  34. TPropertyDef = Class;
  35. TProperties = TSchemas;
  36. TRestMethod = Class;
  37. TRestMethods = Array of TRestMethod;
  38. TArrayPropertyDef = Class;
  39. { TIcons }
  40. TGoogleIcons = Class(TGoogleBaseObject)
  41. private
  42. Fx16: String;
  43. Fx32: String;
  44. Published
  45. Property x16 : String Read Fx16 Write fx16;
  46. Property x32 : String Read Fx32 Write fx32;
  47. end;
  48. { TGoogleAuth2 }
  49. TGoogleAuth2 = Class(TGoogleBaseObject)
  50. private
  51. FScopes: TSchemas;
  52. Published
  53. Property Scopes : TSchemas Read Fscopes Write Fscopes;
  54. end;
  55. { TGoogleAuth }
  56. TGoogleAuth = Class(TGoogleBaseObject)
  57. private
  58. Foauth2: TGoogleAuth2;
  59. Published
  60. Property oauth2 : TGoogleAuth2 Read Foauth2 Write Foauth2;
  61. end;
  62. { TDiscoveryJSONToPas }
  63. { TArrayPropertyDef }
  64. { TAnnotations }
  65. TAnnotations = Class(TGoogleBaseObject)
  66. private
  67. FRequired: TStringArray;
  68. Published
  69. Property required : TStringArray Read FRequired Write Frequired;
  70. end;
  71. { TSchema }
  72. TSchema = Class(TGoogleBaseObject)
  73. private
  74. FadditionalProperties: TSchema;
  75. FAnnotations: TAnnotations;
  76. FDefault: String;
  77. Fdescription: string;
  78. fdivisibleby: integer;
  79. FEnum: TJSONSchema;
  80. FenumDescriptions: TStringArray;
  81. fexclusivemaximum: boolean;
  82. fexclusiveminimum: boolean;
  83. Fextends: string;
  84. FFormat: string;
  85. fitems: TSchema;
  86. fmaximum: integer;
  87. fmaxItems: integer;
  88. fmaxlength: integer;
  89. Fmethods: TRestMethods;
  90. fminimum: integer;
  91. fminItems: integer;
  92. fminlength: integer;
  93. FName: String;
  94. FPattern: string;
  95. FProperties: TProperties;
  96. FPropertyName: String;
  97. FreadOnly: Boolean;
  98. Fref: string;
  99. FRefSchema: TSchema;
  100. frequired: Boolean;
  101. FResources: TSchemas;
  102. Fschema: String;
  103. FType: string;
  104. FID: String;
  105. FTypeDef: TTypeDef;
  106. FTypeName: String;
  107. funiqueItems: boolean;
  108. FVariant: TJSONSchema;
  109. function DoGetTypeName(PrependT: Boolean): String;
  110. function GetTypeName: String;
  111. Public
  112. Class function BaseType(ATypeName: String): Boolean;
  113. Class function GetBaseTypeName(AType,AFormat : String) : string;
  114. Function DebugName : String;
  115. function GetBaseTypeName : string;
  116. Function BaseType : Boolean;
  117. Function ClassProperties : TProperties;
  118. Property PropertyName : String Read FPropertyName Write FPropertyName;
  119. Property TypeName : String Read GetTypeName Write FTypeName;
  120. Property Refschema : TSchema Read FRefSchema Write FRefSchema;
  121. Property TypeDef : TTypeDef Read FTypeDef write FTypeDef;
  122. Published
  123. Property id : String Read FID Write FID;
  124. Property description : string read Fdescription Write Fdescription;
  125. Property _type : String Read FType Write FType;
  126. Property ref : String Read FRef Write FRef;
  127. Property schema: String Read Fschema Write Fschema;
  128. Property name : String Read FName Write FName;
  129. Property enum : TJSONSchema Read FEnum Write FEnum;
  130. Property enumDescriptions : TStringArray Read FenumDescriptions Write FenumDescriptions;
  131. Property properties : TProperties Read FProperties Write FProperties;
  132. Property items : TSchema Read fitems write fitems;
  133. Property default : String Read FDefault Write FDefault;
  134. property required : Boolean read frequired write frequired;
  135. Property annotations : TAnnotations Read FAnnotations Write FAnnotations;
  136. Property format : string Read FFormat Write FFormat;
  137. Property additionalProperties : TSchema Read FadditionalProperties Write FadditionalProperties;
  138. Property minLength : integer read fminlength write fminlength;
  139. Property maxLength : integer read fmaxlength write fmaxlength;
  140. Property minItems : integer read fminItems write fminItems;
  141. Property maxItems : integer read fmaxItems write fmaxItems;
  142. Property minimum : integer read fminimum write fminimum;
  143. Property pattern : string read FPattern write fPattern;
  144. Property exclusiveMaximum : boolean read fexclusivemaximum write fexclusivemaximum;
  145. Property exclusiveMinimum : boolean read fexclusiveminimum write fexclusiveminimum;
  146. Property uniqueItems : boolean read funiqueItems write funiqueItems;
  147. Property maximum : integer read fmaximum write fmaximum;
  148. Property divisibleBy : integer read fdivisibleby write fdivisibleby;
  149. Property extends : string Read Fextends Write Fextends;
  150. Property methods : TRestMethods Read Fmethods Write Fmethods;
  151. property readOnly : Boolean Read FreadOnly Write fReadOnly;
  152. Property resources : TSchemas Read FResources write FResources;
  153. Property variant : TJSONSchema Read FVariant Write FVariant;
  154. end;
  155. TArrayPropertyDef = Class(TSchema);
  156. TPropertyDef = Class(TSchema);
  157. TMediaUploadprotocolssimple = Class(TGoogleBaseObject)
  158. Private
  159. Fmultipart : boolean;
  160. Fpath : string;
  161. Published
  162. Property multipart : boolean Read Fmultipart Write Fmultipart;
  163. Property path : string Read Fpath Write Fpath;
  164. end;
  165. TMediaUploadProtocolsSimpleArray = Array of TMediaUploadProtocolsSimple;
  166. TMediaUploadProtocolsResumable = Class(TGoogleBaseObject)
  167. Private
  168. Fmultipart : boolean;
  169. Fpath : string;
  170. Published
  171. Property multipart : boolean Read Fmultipart Write Fmultipart;
  172. Property path : string Read Fpath Write Fpath;
  173. end;
  174. TMediaUploadProtocolsResumableArray = Array of TMediaUploadProtocolsResumable;
  175. { TMediaUploadProtocols }
  176. TMediaUploadProtocols = Class(TGoogleBaseObject)
  177. private
  178. Fresumable: TMediaUploadprotocolsresumable;
  179. Fsimple: TMediaUploadprotocolssimple;
  180. Published
  181. Property resumable : TMediaUploadprotocolsresumable Read Fresumable Write Fresumable;
  182. Property simple : TMediaUploadprotocolssimple Read Fsimple Write Fsimple;
  183. end;
  184. TMediaUploadProtocolsArray = Array of TMediaUploadProtocols;
  185. TMediaUpload = Class(TGoogleBaseObject)
  186. private
  187. FAccept: TStringArray;
  188. FMaxSize: String;
  189. Fprotocols: TMediaUploadProtocols;
  190. Published
  191. Property Accept : TStringArray Read FAccept Write FAccept;
  192. property MaxSize : String Read FMaxSize Write FMaxSize;
  193. Property protocols : TMediaUploadProtocols Read Fprotocols Write Fprotocols;
  194. end;
  195. { TRequest }
  196. TRequest = Class(TGoogleBaseObject)
  197. private
  198. fparameterName: string;
  199. fref: string;
  200. Published
  201. Property ref : string read fref write fref;
  202. Property parameterName : string read fparameterName write fparameterName;
  203. end;
  204. { TResponse }
  205. TResponse = Class(TGoogleBaseObject)
  206. private
  207. fref: string;
  208. Published
  209. Property ref : string read fref write fref;
  210. end;
  211. { TRestMethodParam }
  212. TRestMethodParam = Class(TSchema)
  213. private
  214. FLocation: string;
  215. FRepeated: boolean;
  216. FSourceName: String;
  217. Public
  218. Property SourceName : String Read FSourceName Write FSourceName;
  219. Published
  220. Property location : string Read FLocation Write FLocation;
  221. Property repeated : boolean Read FRepeated write FRepeated;
  222. end;
  223. TRestMethodParams = Array of TRestMethodParam;
  224. { TRestMethod }
  225. TRestMethod = Class(TGoogleBaseObject)
  226. private
  227. FDescription: String;
  228. FeTagrequired: Boolean;
  229. FflatPath: string;
  230. FhttpMethod: string;
  231. Fid: string;
  232. fMediaUpload: TMediaUpload;
  233. fname: string;
  234. FParameterOrder: TStringArray;
  235. fparameters: TRestMethodParams;
  236. fpath: string;
  237. frequest: trequest;
  238. fresponse: tresponse;
  239. Fscopes: TStringArray;
  240. FsupportsMediaDownload: Boolean;
  241. FsupportsMediaUpload: Boolean;
  242. FsupportsSubscription: Boolean;
  243. Published
  244. Property name : string read fname Write fname;
  245. Property description : String Read FDescription Write FDescription;
  246. Property etagRequired: Boolean read FeTagrequired write FeTagrequired;
  247. Property httpMethod: string read FhttpMethod write FhttpMethod;
  248. Property id : string read Fid Write fID;
  249. Property MediaUpload : TMediaUpload Read fMediaUpload Write fmediaUpload;
  250. Property parameterOrder : TStringArray Read FParameterOrder Write FParameterOrder;
  251. Property parameters : TRestMethodParams read fparameters write fparameters;
  252. Property path : string read fpath Write fpath;
  253. Property flatPath : string read FflatPath Write FflatPath;
  254. Property request : trequest read frequest write frequest;
  255. Property response : tresponse read fresponse write fresponse;
  256. property scopes : TStringArray Read Fscopes write Fscopes;
  257. property supportsMediaDownload : Boolean Read FsupportsMediaDownload Write FsupportsMediaDownload;
  258. property supportsMediaUpload : Boolean Read FsupportsMediaUpload Write FsupportsMediaUpload;
  259. property supportsSubscription : Boolean Read FsupportsSubscription Write FsupportsSubscription;
  260. end;
  261. { TGoogleRestDescription }
  262. TGoogleRestDescription = Class(TGoogleBaseObject)
  263. private
  264. Fauth: TGoogleAuth;
  265. fbasePath: string;
  266. fbaseURL: string;
  267. fbatchPath: string;
  268. FCanonicalName: String;
  269. FDescription: string;
  270. FdiscoveryVersion: String;
  271. FdocumentationLink: string;
  272. FEtag: String;
  273. Ffeatures: TstringArray;
  274. Ficons: TGoogleIcons;
  275. fid: String;
  276. FKind: String;
  277. Flabels: TstringArray;
  278. Fmethods: TRestMethods;
  279. Fname: String;
  280. fOwnerDomain: String;
  281. fOwnerName: String;
  282. FpackagePath: String;
  283. Fparameters: TJSONSchema;
  284. Fprotocol: string;
  285. FResources: TSchemas;
  286. FRevision: string;
  287. frootURL: string;
  288. FSchemas: TSchemas;
  289. fservicePath: string;
  290. FTitle: string;
  291. Fversion: String;
  292. Published
  293. property Auth : TGoogleAuth Read Fauth Write Fauth;
  294. property basePath : string read fbasePath write FbasePath;
  295. property baseUrl : string read fbaseURL write FbaseURL;
  296. property batchPath : string read fbatchPath write FbatchPath;
  297. Property canonicalName : String Read FCanonicalName Write FCanonicalName;
  298. Property description : string Read FDescription Write FDescription;
  299. Property discoveryVersion : String Read FdiscoveryVersion Write FdiscoveryVersion;
  300. Property documentationLink : string read FdocumentationLink Write FdocumentationLink;
  301. Property etag : String Read FEtag Write FEtag;
  302. Property features : TstringArray Read Ffeatures Write Ffeatures;
  303. property icons : TGoogleIcons Read Ficons Write Ficons;
  304. Property id: String Read fid Write Fid;
  305. Property kind: String Read FKind Write FKind;
  306. Property labels : TstringArray Read Flabels Write Flabels;
  307. Property methods : TRestMethods Read Fmethods Write Fmethods;
  308. Property name : String Read Fname Write Fname;
  309. Property ownerDomain : String Read fOwnerDomain Write FOwnerDomain;
  310. Property ownerName : String Read fOwnerName Write FOwnerName;
  311. Property packagePath : String Read FpackagePath Write FpackagePath;
  312. Property parameters : TJSONSchema Read Fparameters Write FParameters;
  313. property protocol : string Read Fprotocol write FProtocol;
  314. Property resources : TSchemas Read FResources write FResources;
  315. Property revision : string Read FRevision Write FRevision;
  316. property rootUrl : string read frootURL write FrootURL;
  317. property schemas : TSchemas read FSchemas write fschemas;
  318. property servicePath : string read fservicePath write FservicePath;
  319. Property title : string Read FTitle Write FTitle;
  320. Property version : String Read Fversion Write Fversion;
  321. end;
  322. TParamLocation = (plPath,plQuery);
  323. TParamLocations = Set of TParamLocation;
  324. TDataType = (dtalias,dtClass,dtarray);
  325. { TTypeDef }
  326. TTypeDef = Class(TCollectionItem)
  327. private
  328. FDataType: TDataType;
  329. FItemSchema: TSchema;
  330. FPascalName: String;
  331. FSchema: TSchema;
  332. FTopLevel: Boolean;
  333. Public
  334. Property PascalName : String Read FPascalName Write FPascalName;
  335. Property Schema : TSchema Read FSchema Write FSchema;
  336. Property DataType : TDataType Read FDataType Write FDataType;
  337. Property ItemSchema: TSchema Read FItemSchema Write FItemSchema;
  338. Property TopLevel : Boolean Read FTopLevel Write FTopLevel;
  339. end;
  340. { TTypeDefEnumerator }
  341. TTypeDefEnumerator = Class(TCollectionEnumerator)
  342. Public
  343. Function GetCurrent: TTypeDef;
  344. property Current: TTypeDef read GetCurrent;
  345. end;
  346. { TTypeDefs }
  347. TTypeDefs = Class(TCollection)
  348. private
  349. function GetD(AIndex : Integer): TTypeDef;
  350. Public
  351. Function GetEnumerator: TTypeDefEnumerator;
  352. Function IndexOf(ATypename : String) : Integer;
  353. Function Find(ATypename : String) : TTypeDef;
  354. Function AddTypeDef(ADataType : TDataType; APascalName : String; ASchema : TSchema) : TTypeDef;
  355. Property Defs[AIndex : Integer] : TTypeDef Read GetD; Default;
  356. end;
  357. TGoogleCodeOption = (gcoUseListForArray,gcoFlatResources);
  358. TGoogleCodeOptions = Set of TGoogleCodeOption;
  359. TDiscoveryJSONToPas = Class(TRestCodeGenerator)
  360. private
  361. FArrayItemSuffix: String;
  362. FCodeOptions: TGoogleCodeOptions;
  363. FDescription: TGoogleRestDescription;
  364. FPropertyTypeSuffix: String;
  365. FResourceSuffix: String;
  366. FTypes : TTypeDefs;
  367. Function AddType(ASchema: TSchema; NamePrefix: String; IsTopLevel : Boolean) : TTypeDef;
  368. procedure CollectType(S: TSchema; NamePrefix: String; IsTopLevel : Boolean);
  369. function GetFlat: Boolean;
  370. function GetSchemaDataType(S: TSchema): TDataType;
  371. function GetUseListForArray: Boolean;
  372. function ReservedMethod(ANAme: String): boolean;
  373. Protected
  374. procedure AssignParamNames(Res: TSchema; M: TRestMethod); virtual;
  375. Function BaseUnits : String; override;
  376. // Global functions
  377. Function GetPropertyType(AClassName: String; ASchema: TSchema): String;
  378. Procedure CollectTypes;
  379. Procedure CollectTypes(Schemas: TSchemas; NamePrefix : String);
  380. Procedure ResolveRefs;
  381. Procedure CreateInterface;
  382. Procedure CreateImplementation;
  383. // Schema Classes
  384. procedure CreateSetArrayLength(AClassName: String; ASchema, AItemSchema: TSchema);
  385. procedure CreateExportPropertyName(AClassName: String; ASchema, AItemSchema: TSchema);
  386. Procedure CreateClassDeclaration(AClassName: String; ASchema: TSchema);
  387. Procedure CreateArrayClassDeclaration(AClassName: String; ASchema,AItemSchema: TSchema);
  388. Procedure CreateClassImplementation(AClassName: String; ASchema,AItemSchema: TSchema);
  389. Procedure CreateArrayClassImplementation(AClassName: String; ASchema,AItemSchema: TSchema);
  390. Procedure CreateArrayClassEnumeratorImplementation(AClassName: String; ASchema,AItemSchema: TSchema);
  391. // API class
  392. Function GetAPIClassName: String;
  393. Procedure CreateAPIClassDeclaration;
  394. Procedure CreateAPIClassImplementation;
  395. // Resource classes
  396. Function ConstructResourcePrefix(Const APrefix: String; AResource: TSchema ): String;
  397. // Recursive calls
  398. Procedure CreateResourceClassImplementations(Const APrefix: String; Resources: TSchemas);
  399. Procedure CreateResourceAPIFunctionImplementations(Const AClassName: String; Const APrefix: String; Resources: TSchemas); virtual;
  400. Procedure CreateResourceInstanceFields(Const APrefix: String; Resources: TSchemas);
  401. Procedure CreateResourceInstanceGetters(Const APrefix: String; Resources: TSchemas);
  402. Procedure CreateResourceAPI(Const APrefix: String; Resources: TSchemas);
  403. Procedure CreateResourceProperties(Const APrefix: String; Resources: TSchemas);
  404. Function GetResourceClassName(Const APrefix : String; Res: TSchema): String;
  405. procedure CreateResourceDeclarations(Const APrefix: String; Resources: TSchemas);
  406. Procedure CreateResourceClassDeclaration(Const APrefix: String; Res: TSchema);
  407. Procedure CreateResourceClassImplementation(Const APrefix: String; Res: TSchema);
  408. Procedure CreateResourceClassMethodsImplementation(Res: TSchema; Const AClassName: String);
  409. Procedure CreateResourceMethodImplementation(AClassName: String; Res: TSchema; M: TRestMethod); // Query version
  410. Procedure CreateResourceMethodImplementationOptions(Const APrefix,
  411. AClassName: String; Res: TSchema; M: TRestMethod);// Options record version
  412. Function GetResourceMethodSignature(M: TRestmethod; Out IsFunction: Boolean; QueryOptionType : String; AddTypes : Boolean = True): String;
  413. Function DescribeMethodParams(M: TRestMethod): TParamLocations;
  414. Function HavePathParams(M: TRestMethod): Boolean;
  415. Function HaveQueryParams(M: TRestMethod): Boolean;
  416. Procedure CreateResourceMethodQueryParams(APrefix: String; Res: TSchema;
  417. M: TRestMethod);
  418. Public
  419. Constructor Create(AOwner : TComponent); override;
  420. Destructor Destroy; override;
  421. Procedure LoadFromStream(Const AStream : TStream); override;
  422. Procedure LoadFromJSON(Const JSON : TJSONObject); virtual;
  423. Procedure Execute; override;
  424. Class Procedure RegisterAllObjects;
  425. Property APIClassName: String Read GetAPIClassName;
  426. Property UseListForArray : Boolean Read GetUseListForArray;
  427. Property FlatResources : Boolean Read GetFlat;
  428. Published
  429. Property Description : TGoogleRestDescription Read FDescription;
  430. Property ResourceSuffix : String Read FResourceSuffix Write FResourceSuffix;
  431. Property ArrayItemSuffix : String Read FArrayItemSuffix Write FArrayItemSuffix;
  432. Property PropertyTypeSuffix : String Read FPropertyTypeSuffix Write FPropertyTypeSuffix;
  433. Property CodeOptions : TGoogleCodeOptions Read FCodeOptions Write FCodeOptions;
  434. end;
  435. implementation
  436. { TTypeDefEnumerator }
  437. function TTypeDefEnumerator.GetCurrent: TTypeDef;
  438. begin
  439. Result:=(Inherited GetCurrent) as TTypeDef;
  440. end;
  441. { TTypeDefs }
  442. function TTypeDefs.GetD(AIndex : Integer): TTypeDef;
  443. begin
  444. Result:=Items[AIndex] as TTypeDef;
  445. end;
  446. function TTypeDefs.GetEnumerator: TTypeDefEnumerator;
  447. begin
  448. Result:=TTypeDefEnumerator.Create(Self);
  449. end;
  450. function TTypeDefs.IndexOf(ATypename: String): Integer;
  451. begin
  452. Result:=Count-1;
  453. While (Result>=0) and (CompareText(ATypeName,GetD(Result).PascalName)<>0) do
  454. Dec(Result);
  455. end;
  456. function TTypeDefs.Find(ATypename: String): TTypeDef;
  457. Var
  458. I : Integer;
  459. begin
  460. I:=IndexOf(ATypeName);
  461. if (I=-1) then
  462. Result:=Nil
  463. else
  464. Result:=GetD(I);
  465. end;
  466. function TTypeDefs.AddTypeDef(ADataType: TDataType; APascalName: String;
  467. ASchema: TSchema): TTypeDef;
  468. begin
  469. Result:=Add as TTypeDef;
  470. Result.DataType:=ADataType;
  471. Result.PascalName:=APascalName;
  472. Result.Schema:=ASchema;
  473. end;
  474. { TSchema }
  475. function TSchema.DoGetTypeName(PrependT : Boolean) : String;
  476. begin
  477. Result:=FTypeName;
  478. if (Result='') and Assigned(TypeDef) then
  479. Result:=TypeDef.PascalName;
  480. If Result='' then
  481. begin
  482. If BaseType then
  483. Result:=GetBaseTypeName
  484. else if (_type='array') and Assigned(Items) then
  485. begin
  486. Result:=Items.DoGetTypeName(False);
  487. if (Result<>'') and not Assigned(Items.TypeDef) then
  488. begin
  489. if PrependT and (items._type<>'object') and (items._type<>'array') then
  490. Result:='T'+Result;
  491. Result:=Result+'Array';
  492. end;
  493. end;
  494. end;
  495. end;
  496. function TSchema.GetTypeName: String;
  497. begin
  498. Result:=DoGetTypeName(True);
  499. end;
  500. Function TSchema.ClassProperties: TProperties;
  501. begin
  502. If Length(FProperties)>0 then
  503. Result:=FProperties
  504. //else if Assigned(Items) then
  505. // Result:=Items.properties
  506. else
  507. Result:=Nil
  508. end;
  509. { TGoogleRestDescription }
  510. { TDiscoveryJSONToPas }
  511. Constructor TDiscoveryJSONToPas.Create(AOwner: TComponent);
  512. begin
  513. inherited Create(AOwner);
  514. FDescription:=TGoogleRestDescription.Create;
  515. BaseClassName:='TGoogleBaseObject';
  516. BaseListClassName:='TGoogleBaseObjectList';
  517. FResourceSuffix:='Resource';
  518. ArrayItemSuffix:='Item';
  519. PropertyTypeSuffix:='Type';
  520. // UseListForArray:=True;
  521. end;
  522. Destructor TDiscoveryJSONToPas.Destroy;
  523. begin
  524. FreeAndNil(FDescription);
  525. inherited Destroy;
  526. end;
  527. Procedure TDiscoveryJSONToPas.LoadFromStream(Const AStream: TStream);
  528. Var
  529. D : TJSONData;
  530. begin
  531. D:=GetJSON(AStream,True);
  532. try
  533. if Not (D is TJSONObject) then
  534. Raise EGoogleAPI.Create('Source does not contain a valid JSON object');
  535. LoadFromJSON(D as TJSONObject)
  536. finally
  537. D.Free;
  538. end;
  539. end;
  540. Procedure TDiscoveryJSONToPas.LoadFromJSON(Const JSON: TJSONObject);
  541. begin
  542. Description.LoadFromJSON(JSON);
  543. end;
  544. function TDiscoveryJSONToPas.GetSchemaDataType(S: TSchema): TDataType;
  545. begin
  546. if (S._type='array') then
  547. Result:=dtArray
  548. else if S._type='object' then
  549. Result:=dtClass
  550. else
  551. Result:=dtAlias;
  552. end;
  553. function TDiscoveryJSONToPas.GetUseListForArray: Boolean;
  554. begin
  555. Result:=gcoUseListForArray in CodeOPtions;
  556. end;
  557. Function TDiscoveryJSONToPas.AddType(ASchema: TSchema; NamePrefix: String;
  558. IsTopLevel: Boolean): TTypeDef;
  559. Function DoAdd(DT : TDataType; TCN : String; S,ITS : TSchema) : TTypeDef;
  560. Var
  561. Msg : String;
  562. begin
  563. Result:=Nil;
  564. if (FTypes.IndexOf(TCN)<>-1) then
  565. Raise Exception.CreateFmt('Type already exists : "%s"',[TCN]);
  566. Result:=FTypes.AddTypeDef(dt,TCN,S);
  567. Result.ItemSchema:=ITS;
  568. Result.Toplevel:=isTopLevel;
  569. Str(dt,Msg);
  570. Msg:=Format('[%s] : Adding %s (%s) from ',[NamePrefix,TCN,Msg]);
  571. if Assigned(S) then
  572. Msg:=Msg+S.DebugName;
  573. if Assigned(ItS) then
  574. Msg:=Msg+Format(' (Array item: %s)',[its.DebugName]);
  575. DoLog(Msg);
  576. end;
  577. Var
  578. CN,TCN : String;
  579. Dt : TDataType;
  580. begin
  581. dt:=GetSchemaDataType(ASchema);
  582. CN:=NamePrefix+ASchema.Name;
  583. if (dt=dtArray) and (NamePrefix<>'') then
  584. CN:=CN+'Array';
  585. TCN:='T'+CN;
  586. Result:=doAdd(dt,TCN,ASchema,Aschema.Items);
  587. Aschema.TypeDef:=Result;
  588. if (dt=dtClass) and isToplevel then
  589. doAdd(dtArray,TCN+'Array',Nil,Aschema);
  590. end;
  591. procedure TDiscoveryJSONToPas.CollectType(S: TSchema; NamePrefix: String; IsTopLevel : Boolean);
  592. Var
  593. AE : String;
  594. Dt : TDataType;
  595. BaseArrayElement : Boolean;
  596. begin
  597. if (S.Name='Component') and (NamePrefix='') then
  598. NamePrefix:='_';
  599. dt:=GetSchemaDataType(S);
  600. BaseArrayElement:=(dt=dtArray) and S.Items.BaseType;
  601. DoLog('[%s] Examining : %s (Ref : %s type: %s) Toplevel %s',[NamePrefix,S.Name,S.ref,S._type,BoolToStr(IsTopLevel,'True','False')]);
  602. case dt of
  603. dtArray : if Not BaseArrayElement and (S.Items.Ref='') then
  604. begin
  605. AE:=S.Name;
  606. if S.Items.Name='' then
  607. AE:=AE+ArrayItemSuffix;
  608. DoLog('Array, adding array item type first (%s)',[AE]);
  609. CollectType(S.Items,NamePrefix+AE,isTopLevel);
  610. end;
  611. dtClass :
  612. if (S.Ref='') then
  613. begin
  614. DoLog('Class type, adding properties first');
  615. CollectTypes(S.Properties,NamePrefix+S.Name+PropertyTypeSuffix);
  616. end;
  617. else
  618. //no other cases to handle
  619. end;
  620. if (NamePrefix='') then
  621. AddType(S,'',True)
  622. else if (Not S.BaseType) and (Not BaseArrayElement) and (S.Ref='') then
  623. AddType(S,NamePrefix,IsTopLevel);
  624. end;
  625. function TDiscoveryJSONToPas.GetFlat: Boolean;
  626. begin
  627. Result:=gcoFlatResources in CodeOPtions;
  628. end;
  629. Procedure TDiscoveryJSONToPas.CollectTypes(Schemas: TSchemas; NamePrefix: String
  630. );
  631. Var
  632. S : TSchema;
  633. begin
  634. For S in Schemas do
  635. CollectType(S,NamePrefix,NamePrefix='');
  636. end;
  637. Procedure TDiscoveryJSONToPas.ResolveRefs;
  638. Var
  639. Lookup : TStringList;
  640. Function DoFind (S : TSchema; C : String) : TSchema;
  641. Var
  642. idx : Integer;
  643. begin
  644. Idx:=Lookup.IndexOf(S.Ref);
  645. if idx<>-1 then
  646. Result:=TSchema(Lookup.Objects[idx])
  647. else
  648. Raise Exception.CreateFmt('Could not find reference %s (Context: %s)',[S.Name,C]);
  649. end;
  650. Procedure AddSchema(ASchema : TSchema);
  651. begin
  652. if Assigned(ASchema) then
  653. begin
  654. if (ASchema.Name<>'') then
  655. begin
  656. Lookup.AddObject(ASchema.Name,ASchema)
  657. end;
  658. end
  659. end;
  660. Procedure DoResolve(ASchema : TSchema);
  661. Var
  662. S2 : TSchema;
  663. begin
  664. if Assigned(ASchema) then
  665. begin
  666. if (ASchema.Ref<>'') and (ASchema.Refschema=Nil) then
  667. ASchema.Refschema:=DoFind(ASchema,ASchema.Name);
  668. if Assigned(ASchema.Items) then
  669. DoResolve(ASchema.Items);
  670. if Length(ASchema.Properties)<>0 then
  671. For S2 in ASchema.Properties do
  672. begin
  673. DoResolve(S2);
  674. DoResolve(S2.Items);
  675. end;
  676. end;
  677. end;
  678. Var
  679. T : TTypeDef;
  680. S : TSchema;
  681. begin
  682. Lookup:=TStringList.Create;
  683. try
  684. for S in Description.Schemas do
  685. AddSchema(S);
  686. Lookup.Sorted:=True;
  687. For T in FTypes do
  688. begin
  689. DoResolve(T.Schema);
  690. DoResolve(T.ItemSchema);
  691. end;
  692. finally
  693. Lookup.Free;
  694. end;
  695. end;
  696. Procedure TDiscoveryJSONToPas.CollectTypes;
  697. Var
  698. S : TTypeDef;
  699. Msg : String;
  700. begin
  701. CollectTypes(Description.Schemas,ClassPrefix);
  702. For S in FTypes do
  703. begin
  704. Str(S.DataType,Msg);
  705. DoLog('Created data type %s (%s)',[S.PascalName,Msg]);
  706. end;
  707. ResolveRefs;
  708. end;
  709. Function TDiscoveryJSONToPas.BaseUnits: String;
  710. begin
  711. Result:='sysutils, classes, googleservice, restbase, googlebase';
  712. end;
  713. Class function TSchema.BaseType(ATypeName: String): Boolean;
  714. begin
  715. Result:=(ATypeName='boolean') or (ATypeName='string') or (ATypeName='number') or (ATypeName='any') or (ATypeName='integer');
  716. end;
  717. Class function TSchema.GetBaseTypeName(AType, AFormat: String): string;
  718. begin
  719. Result:=AType;
  720. if Result='any' then
  721. Result:='TJSONSchema'
  722. else if Result='integer' then
  723. begin
  724. if (AFormat='int64') then
  725. Result:='int64'
  726. else
  727. Result:='integer'
  728. end
  729. else if Result='number' then
  730. begin
  731. if (AFormat='double') then
  732. Result:='double'
  733. else
  734. Result:='integer'
  735. end
  736. else if Result='string' then
  737. if Aformat='date-time' then
  738. Result:='TDatetime'
  739. else if Aformat='date' then
  740. Result:='TDate'
  741. else
  742. Result:='String';
  743. end;
  744. Function TSchema.DebugName: String;
  745. begin
  746. Result:=sysutils.Format('(Name: %s, Pascal Type : %s, type : %s, Ref: %s)',[Name,TypeName,_type,Ref]);
  747. end;
  748. function TSchema.GetBaseTypeName: string;
  749. begin
  750. Result:=GetBaseTypeName(_type,Format);
  751. end;
  752. Function TSchema.BaseType: Boolean;
  753. begin
  754. Result:=BaseType(_type)
  755. end;
  756. Function TDiscoveryJSONToPas.GetPropertyType(AClassName: String;
  757. ASchema: TSchema): String;
  758. begin
  759. DoLog('Checking property type "%s" property schema %s',[AClassName,ASchema.DebugName]);
  760. Result:=ASchema.TypeName;
  761. if (Result='') then
  762. begin
  763. Result:=ASchema.ref;
  764. if Result='' then
  765. begin
  766. Result:=ASchema._type;
  767. if TSchema.BaseType(Result) then
  768. Result:=ASchema.GetBaseTypeName;
  769. end
  770. else if Not Assigned(ASchema.Refschema) then
  771. Raise Exception.CreateFmt('%s : Unresolved property schema (%s) type reference : %s',[AClassName,ASchema.Name,ASchema.Ref])
  772. else
  773. Result:=ASchema.Refschema.TypeName;
  774. end;
  775. if Result='array' then
  776. begin
  777. if Aschema.Items.TypeDef<>Nil then
  778. Result:=Aschema.Items.TypeDef.PascalName
  779. else if (ASchema.Items.Ref<>'') then
  780. begin
  781. if not Assigned(ASchema.Items.Refschema) then
  782. Raise Exception.CreateFmt('%s : Unresolved property (%s) type reference : %s',[AClassName,ASchema.Name,ASchema.Ref]);
  783. Result:=Aschema.Items.RefSchema.TypeName+'Array';
  784. end
  785. else
  786. Result:=ASchema.Items.TypeName;
  787. end
  788. else if Result='object' then
  789. if (ASchema.ref<>'') then
  790. Result:='T'+ClassPrefix+ASchema.ref
  791. else
  792. Result:=AClassName+ASchema.Name;
  793. end;
  794. Procedure TDiscoveryJSONToPas.CreateClassDeclaration(AClassName: String;
  795. ASchema: TSchema);
  796. Var
  797. S : TSchema;
  798. N : String;
  799. NeedSetArrayLength, NeedGetWritename : Boolean;
  800. TN : String;
  801. Idx,PropertyIndex,PropertyOptions : Integer;
  802. L : TStringList;
  803. begin
  804. if ASchema=Nil then
  805. Raise Exception.Create(AClassName+' : no Schema');
  806. ClassComment(AClassName);
  807. AddLn('%s = Class(%s)',[AClassName,BaseClassName]);
  808. AddLn('Private');
  809. NeedGetWriteName:=False;
  810. NeedSetArrayLength:=False;
  811. IncIndent;
  812. L:=TStringList.Create;
  813. try
  814. For S in ASchema.Properties do
  815. begin
  816. N:=TBaseObject.CleanPropertyName(S.Name);
  817. Repeat
  818. Idx:=L.IndexOf(N);
  819. if (idx=-1) then
  820. Idx:=L.IndexOf('F'+N);
  821. if (idx<>-1) then
  822. begin
  823. N:='_'+N;
  824. end;
  825. Until Idx=-1;
  826. NeedGetWritename:=NeedGetWritename or (CompareText(N,S.Name)<>0);
  827. NeedSetArrayLength:=NeedSetArrayLength or (S._type='array');
  828. S.PropertyName:=N;
  829. tn:=GetPropertyType(AClassName,S);
  830. AddLn('F%s : %s;',[N,tn]);
  831. L.Add(N);
  832. L.Add('F'+N);
  833. end;
  834. finally
  835. L.Free;
  836. end;
  837. DecIndent;
  838. AddLn('Protected');
  839. IncIndent;
  840. if NeedGetWriteName then
  841. AddLn('Class Function ExportPropertyName(Const AName : String) : string; override;');
  842. Comment('Property setters');
  843. For S in ASchema.ClassProperties do
  844. begin
  845. N:=S.PropertyName;
  846. tn:=GetPropertyType(AClassName,S);
  847. AddLn('Procedure Set%s(AIndex : Integer; const AValue : %s); virtual;',[N,tn]);
  848. end;
  849. DecIndent;
  850. AddLn('Public');
  851. IncIndent;
  852. if Assigned(ASchema.additionalProperties) then
  853. AddLn('Class Function AllowAdditionalProperties : Boolean; override;');
  854. DecIndent;
  855. AddLn('Published');
  856. IncIndent;
  857. PropertyIndex:=0;
  858. For S in ASchema.ClassProperties do
  859. begin
  860. N:=S.PropertyName;
  861. Tn:=GetPropertyType(AClassName,S);
  862. PropertyOptions:=0;
  863. Idx:=(PropertyIndex shl IndexShift) or PropertyOptions;
  864. AddLn('Property %s : %s Index %d Read F%s Write Set%s;',[N,TN,Idx, N,N]);
  865. Inc(PropertyIndex);
  866. end;
  867. DecIndent;
  868. AddLn('end;');
  869. AddLn('%sClass = Class of %s;',[AClassName,AClassName]);
  870. end;
  871. Procedure TDiscoveryJSONToPas.CreateArrayClassDeclaration(AClassName: String;
  872. ASchema, AItemSchema: TSchema);
  873. Var
  874. AEnumeratorName,AItemName : String;
  875. begin
  876. if AItemSchema=Nil then
  877. Raise Exception.Create(AClassName+' : no item Schema');
  878. AItemName:=GetPropertyType('',AItemSchema);
  879. AEnumeratorName:=AClassName+'Enumerator';
  880. ClassComment(AEnumeratorName);
  881. AddLn('%s = Class(%s)',[AEnumeratorName,'TBaseListEnumerator']);
  882. AddLn('Public');
  883. IncIndent;
  884. AddLn('Function GetCurrent : %s; ',[AItemName]);
  885. AddLn('Property Current : %s Read GetCurrent;',[AItemName]);
  886. DecIndent;
  887. AddLn('end;');
  888. AddLn('');
  889. AddLn('');
  890. ClassComment(AClassName);
  891. AddLn('%s = Class(%s)',[AClassName,BaseListClassName]);
  892. AddLn('Private');
  893. IncINdent;
  894. Addln('Function GetI (AIndex : Integer) : %s;',[AItemName]);
  895. Addln('Procedure SetI (AIndex : Integer; Const AValue: %s);',[AItemName]);
  896. DecIndent;
  897. AddLn('Protected');
  898. IncIndent;
  899. AddLn('Class Function ObjectClass : TBaseObjectClass; override;');
  900. DecIndent;
  901. AddLn('Public');
  902. IncIndent;
  903. AddLn('Function GetEnumerator : %s;',[AEnumeratorName]);
  904. AddLn('Property Items[AIndex : Integer] : %s Read GetI Write SetI; default;',[AItemName]);
  905. DecIndent;
  906. AddLn('end;');
  907. AddLn('%sClass = Class of %s;',[AClassName,AClassName]);
  908. end;
  909. procedure TDiscoveryJSONToPas.CreateSetArrayLength(AClassName: String; ASchema, AItemSchema: TSchema);
  910. begin
  911. //not used
  912. end;
  913. procedure TDiscoveryJSONToPas.CreateExportPropertyName(AClassName: String; ASchema, AItemSchema: TSchema);
  914. Var
  915. S : TSchema;
  916. N : String;
  917. begin
  918. begin
  919. Addln('');
  920. AddLn('Class Function %s.ExportPropertyName(Const AName : String) :String;',[AClassName]);
  921. Addln('');
  922. AddLn('begin');
  923. IncIndent;
  924. AddLn('Case AName of');
  925. For S in ASchema.ClassProperties do
  926. begin
  927. N:=S.PropertyName;
  928. if (CompareText(N,S.Name)<>0) then
  929. AddLn('''%s'' : Result:=''%s'';',[N,S.Name]);
  930. end;
  931. AddLn('else');
  932. IncIndent;
  933. AddLn('Result:=Inherited ExportPropertyName(AName);');
  934. DecIndent;
  935. AddLn('end;');
  936. DecIndent;
  937. AddLn('end;');
  938. Addln('');
  939. end;
  940. end;
  941. Procedure TDiscoveryJSONToPas.CreateClassImplementation(AClassName: String;
  942. ASchema, AItemSchema: TSchema);
  943. Var
  944. S : TSchema;
  945. N : String;
  946. NeedSetArrayLength,NeedGetWritename : Boolean;
  947. TN : String;
  948. begin
  949. NeedGetWriteName:=False;
  950. NeedSetArrayLength:=False;
  951. ClassComment(AClassName);
  952. For S in ASchema.ClassProperties do
  953. begin
  954. N:=S.PropertyName;
  955. NeedSetArrayLength:=NeedSetArrayLength or (S._type='array');
  956. NeedGetWritename:=NeedGetWritename or (CompareText(N,S.Name)<>0);
  957. TN:=GetPropertyType(AClassName,S);
  958. Addln('');
  959. AddLn('Procedure %s.Set%s(AIndex : Integer; const AValue : %s); ',[AClassName,N,tn]);
  960. SimpleMethodBody([Format('If (F%s=AValue) then exit;',[N]),
  961. Format('F%s:=AValue;',[N]),
  962. 'MarkPropertyChanged(AIndex);']);
  963. Addln('');
  964. end;
  965. if NeedGetWriteName then
  966. CreateExportPropertyName(AClassName,ASchema, AItemSchema);
  967. if NeedSetArrayLength and not UseListForArray then
  968. CreateSetArrayLength(AClassName,ASchema, AItemSchema);
  969. Addln('');
  970. if Assigned(ASchema.additionalProperties) then
  971. begin
  972. AddLn('Class Function %s.AllowAdditionalProperties : Boolean;',[AClassName]);
  973. SimpleMethodBody(['Result:=True;']);
  974. end;
  975. Addln('');
  976. end;
  977. Procedure TDiscoveryJSONToPas.CreateArrayClassImplementation(
  978. AClassName: String; ASchema, AItemSchema: TSchema);
  979. Var
  980. AEnumeratorName,AItemName : String;
  981. begin
  982. if AItemSchema=Nil then
  983. Raise Exception.Create(AClassName+' : no Schema');
  984. CreateArrayClassEnumeratorImplementation(ACLassName,ASchema,AItemSchema);
  985. AItemName:=GetPropertyType('',AItemSchema);
  986. AEnumeratorName:=AClassName+'Enumerator';
  987. ClassComment(AClassName);
  988. Addln('');
  989. Addln('Function %s.GetI (AIndex : Integer) : %s;',[AClassName,AItemName]);
  990. SimpleMethodBody([Format('Result:=%s(Objects[AIndex]);',[AItemName])]);
  991. Addln('');
  992. Addln('Procedure %s.SetI (AIndex : Integer; Const AValue: %s);',[AClassName,AItemName]);
  993. SimpleMethodBody(['Objects[AIndex]:=AValue;']);
  994. Addln('');
  995. AddLn('Class Function %s.ObjectClass : TBaseObjectClass;',[ACLassName]);
  996. SimpleMethodBody([Format('Result:=%s;',[AItemName])]);
  997. Addln('');
  998. AddLn('Function %S.GetEnumerator : %s;',[ACLassName,AEnumeratorName]);
  999. SimpleMethodBody([Format('Result:=%s(DoCreateEnumerator(%s));',[AEnumeratorName,AEnumeratorName])]);
  1000. Addln('');
  1001. end;
  1002. Procedure TDiscoveryJSONToPas.CreateArrayClassEnumeratorImplementation(
  1003. AClassName: String; ASchema, AItemSchema: TSchema);
  1004. Var
  1005. AEnumeratorName,AItemName : String;
  1006. begin
  1007. if AItemSchema=Nil then
  1008. Raise Exception.Create(AClassName+' : no ItemSchema');
  1009. AItemName:=GetPropertyType('',AItemSchema);
  1010. AEnumeratorName:=AClassName+'Enumerator';
  1011. ClassComment(AEnumeratorName);
  1012. AddLn('Function %s.GetCurrent : %s;',[AEnumeratorName,AItemName]);
  1013. SimpleMethodBody([Format('Result:=%s(Inherited GetCurrent);',[AItemName])]);
  1014. end;
  1015. Function TDiscoveryJSONToPas.GetAPIClassName: String;
  1016. begin
  1017. Result:=Format('T%s%sAPI',[ClassPrefix,PrettyPrint(Description.Name)])
  1018. end;
  1019. Procedure TDiscoveryJSONToPas.CreateInterface;
  1020. procedure AddTypeDecl(S : TTypeDef);
  1021. begin
  1022. Case S.DataType of
  1023. dtAlias : AddLn('%s = %s;',[S.PascalName,S.Schema.GetBaseTypeName]);
  1024. dtArray :
  1025. if UseListForArray then
  1026. AddLn('%s = Class;',[S.PascalName])
  1027. else
  1028. AddLn('%s = Array of %s;',[S.PascalName,GetPropertyType('',S.ItemSchema)]);
  1029. dtClass : AddLn('%s = Class;',[S.PascalName]);
  1030. end;
  1031. end;
  1032. Procedure DoTypeLoops(DoTopLevel : Boolean);
  1033. Var
  1034. S : TTypeDef;
  1035. begin
  1036. For S in FTypes do
  1037. if (S.DataType=dtAlias) and (S.TopLevel=DoTopLevel) then
  1038. AddTypeDecl(S);
  1039. For S in FTypes do
  1040. if (S.DataType=dtClass) and (S.TopLevel=DoTopLevel) then
  1041. AddTypeDecl(S);
  1042. For S in FTypes do
  1043. if (S.DataType=dtArray) and (S.TopLevel=DoTopLevel) then
  1044. AddTypeDecl(S);
  1045. end;
  1046. Var
  1047. S : TTypeDef;
  1048. begin
  1049. Addln('type');
  1050. IncIndent;
  1051. AddLn('');
  1052. Comment('Top-level schema types');
  1053. DoTypeLoops(True);
  1054. Comment('Anonymous types, using auto-generated names');
  1055. DoTypeLoops(False);
  1056. For S in FTypes do
  1057. if S.DataType=dtClass then
  1058. CreateClassDeclaration(S.PascalName,S.Schema)
  1059. else if (S.DataType=dtArray) and UseListForArray then
  1060. CreateArrayClassDeclaration(S.PascalName,S.Schema,S.ItemSchema);
  1061. CreateResourceDeclarations('',Description.Resources);
  1062. CreateAPIClassDeclaration;
  1063. DecIndent;
  1064. end;
  1065. procedure TDiscoveryJSONToPas.CreateResourceDeclarations(Const APrefix : String; Resources : TSchemas);
  1066. var
  1067. R : TSchema;
  1068. begin
  1069. For R in Resources do
  1070. begin
  1071. if Assigned(R.resources) then
  1072. if FlatResources then
  1073. CreateResourceDeclarations(APrefix,R.Resources)
  1074. else
  1075. CreateResourceDeclarations(APrefix+PrettyPrint(R.Name),R.Resources);
  1076. R.TypeName:=GetResourceClassName(APrefix,R);
  1077. CreateResourceClassDeclaration(APrefix,R);
  1078. end;
  1079. end;
  1080. Procedure TDiscoveryJSONToPas.CreateImplementation;
  1081. Var
  1082. S : TTypeDef;
  1083. begin
  1084. For S in FTypes do
  1085. Case S.DataType of
  1086. dtClass: CreateClassImplementation(S.PascalName,S.Schema,S.ItemSchema);
  1087. dtArray: if UseListForArray then
  1088. CreateArrayClassImplementation(S.PascalName,S.Schema,S.ItemSchema);
  1089. else
  1090. //no other cases to handle
  1091. end;
  1092. CreateResourceClassImplementations('',Description.Resources);
  1093. CreateAPIClassImplementation;
  1094. end;
  1095. Procedure TDiscoveryJSONToPas.CreateResourceClassImplementations(Const APrefix : String; Resources : TSchemas);
  1096. var
  1097. R : TSchema;
  1098. begin
  1099. For R in Resources do
  1100. begin
  1101. if Assigned(R.Resources) then
  1102. CreateResourceClassImplementations(ConstructResourcePrefix(APrefix,R),R.Resources);
  1103. CreateResourceClassImplementation(APrefix,R);
  1104. end;
  1105. end;
  1106. Function TDiscoveryJSONToPas.GetResourceMethodSignature(M: TRestmethod; Out
  1107. IsFunction: Boolean; QueryOptionType: String; AddTypes: Boolean): String;
  1108. Const
  1109. Seps : Array[Boolean] of String = (',','; ');
  1110. Procedure AddSep(Var S : String);
  1111. begin
  1112. if (S<>'') then
  1113. S:=S+Seps[AddTypes];
  1114. end;
  1115. Var
  1116. P : TRestMethodParam;
  1117. S : String;
  1118. Q : Boolean; // Was AQuery encountered in options
  1119. begin
  1120. Q:=False;
  1121. S:='';
  1122. For P in M.parameters do
  1123. if (P.Location='path') and P.Required then
  1124. begin
  1125. Q:=Q or (CompareText(p.SourceName,'aquery')=0);
  1126. AddSep(S);
  1127. S:=S+P.SourceName;
  1128. If AddTypes then
  1129. S:=S+': '+P._type;
  1130. end;
  1131. For P in M.parameters do
  1132. if (P.Location='path') and not P.Required then
  1133. begin
  1134. Q:=Q or (CompareText(p.SourceName,'aquery')=0);
  1135. AddSep(S);
  1136. S:=S+P.SourceName;
  1137. if AddTypes then
  1138. begin
  1139. S:=S+': '+P._type + ' = ';
  1140. Case p._type of
  1141. 'string' : S:=S+'''''';
  1142. 'number' : S:=S+'0';
  1143. 'object' : S:=S+'nil';
  1144. end;
  1145. end;
  1146. end;
  1147. if M.Request<>Nil then
  1148. begin
  1149. AddSep(S);
  1150. S:=S+'a'+M.request.ref;
  1151. If AddTypes then
  1152. S:=S+' : T'+ClassPrefix+M.request.ref;
  1153. end;
  1154. if (QueryOptionType<>'') then
  1155. begin
  1156. AddSep(S);
  1157. if AddTypes then
  1158. S:=S+'AQuery : '+QueryOptionType
  1159. else
  1160. S:=S+QueryOptionType; // Will be name instead of type;
  1161. end;
  1162. if (S<>'') then
  1163. S:='('+S+')';
  1164. S:=PrettyPrint(TBaseObject.CleanPropertyName(M.Name))+S;
  1165. isFunction:=M.Response<>Nil;
  1166. if isFunction and AddTypes then
  1167. S:=S+' : T'+ClassPrefix+M.response.ref;
  1168. Result:=S;
  1169. end;
  1170. Function TDiscoveryJSONToPas.DescribeMethodParams(M: TRestMethod
  1171. ): TParamLocations;
  1172. Var
  1173. P : TRestMethodParam;
  1174. begin
  1175. Result:=[];
  1176. For P in M.Parameters do
  1177. Case P.location of
  1178. 'path' : Include(Result,plPath);
  1179. 'query' : Include(Result,plQuery);
  1180. end;
  1181. end;
  1182. Function TDiscoveryJSONToPas.HavePathParams(M: TRestMethod): Boolean;
  1183. begin
  1184. Result:=plPath in DescribeMethodParams(M);
  1185. end;
  1186. Procedure TDiscoveryJSONToPas.CreateResourceMethodQueryParams(APrefix : String; Res: TSchema;
  1187. M: TRestMethod);
  1188. Var
  1189. P : TRestMethodParam;
  1190. RN,RCN,MN : String;
  1191. begin
  1192. RN:=APrefix+PrettyPrint(Res.Name);
  1193. RCN:=Res.TypeName;
  1194. MN:=PrettyPrint(M.Name);
  1195. Addln('');
  1196. Comment(Format('Optional query Options for %s, method %s',[RCN,MN]));
  1197. Addln('');
  1198. Addln('T%s%sOptions = Record',[RN,MN]);
  1199. IncIndent;
  1200. For P in M.parameters do
  1201. begin
  1202. if (P.location='query') then
  1203. if p.format='int64' then
  1204. AddLn('%s : int64;',[P.Sourcename])
  1205. else
  1206. AddLn('%s : %s;',[P.sourcename,P.GetBaseTypeName]);
  1207. end;
  1208. DecIndent;
  1209. Addln('end;');
  1210. Addln('');
  1211. end;
  1212. Function TDiscoveryJSONToPas.HaveQueryParams(M: TRestMethod): Boolean;
  1213. begin
  1214. Result:=plQuery in DescribeMethodParams(M);
  1215. end;
  1216. Function TDiscoveryJSONToPas.GetResourceClassName(Const APrefix: String;
  1217. Res: TSchema): String;
  1218. Var
  1219. Suffix : String;
  1220. begin
  1221. if (Res.TypeName<>'') and (Res.TypeName<>Res.Name) then
  1222. Result:=Res.TypeName
  1223. else
  1224. begin
  1225. Suffix:='Resource';
  1226. Repeat
  1227. Result:=Format('T%s%s%s%s',[ClassPrefix,APrefix,PrettyPrint(Res.Name),Suffix]);
  1228. Suffix:='_'+Suffix;
  1229. Until FTypes.IndexOf(Result)=-1;
  1230. end
  1231. end;
  1232. procedure TDiscoveryJSONToPas.AssignParamNames(Res: TSchema; M: TRestMethod);
  1233. // Google API has case sensitive names. We need to make sure the names are unique in a case insensitive manner.
  1234. // This is done by assigning the 'source name'
  1235. Var
  1236. T : TStringList;
  1237. P : TRestMethodParam;
  1238. N : String;
  1239. begin
  1240. T:=TStringList.Create;
  1241. try
  1242. // The request also has a parameter name
  1243. If Assigned(M.request) then
  1244. T.Add('a'+M.request.ref);
  1245. // Some identifiers that are 'reserved' by the base classes.
  1246. With T do
  1247. begin
  1248. Add('Name');
  1249. Add('ResourceName');
  1250. Add('DefaultAPI');
  1251. Add('API');
  1252. Add('Notification');
  1253. Add('UpdateAction');
  1254. Add('ExecuteAction');
  1255. end;
  1256. // Actual paramters
  1257. For P in M.parameters do
  1258. begin
  1259. N:=P.Name;
  1260. While T.IndexOf(N)<>-1 do
  1261. begin
  1262. N:='_'+N;
  1263. end;
  1264. T.Add(N);
  1265. P.SourceName:=TbaseObject.CleanPropertyName(N);
  1266. end;
  1267. finally
  1268. T.Free;
  1269. end;
  1270. end;
  1271. function TDiscoveryJSONToPas.ReservedMethod(ANAme: String): boolean;
  1272. begin
  1273. AName:=';'+lowerCase(AName)+';';
  1274. Result:=Pos(AName,';create;destroy;free;')<>0;
  1275. end;
  1276. Procedure TDiscoveryJSONToPas.CreateResourceClassDeclaration(
  1277. Const APrefix: String; Res: TSchema);
  1278. Var
  1279. M : TRestMethod;
  1280. CN,S : String;
  1281. HaveOpt : Boolean;
  1282. IsFunc : Boolean;
  1283. begin
  1284. CN:=Res.TypeName;
  1285. ClassComment(CN);
  1286. For M in Res.methods do
  1287. begin
  1288. AssignParamNames(Res,M);
  1289. if HaveQueryParams(M) then
  1290. begin
  1291. CreateResourceMethodQueryParams(APrefix,Res,M);
  1292. end;
  1293. end;
  1294. Addln('%s = Class(TGoogleResource)',[CN]);
  1295. if Assigned(Res.Resources) then
  1296. begin
  1297. Addln('Private');
  1298. IncIndent;
  1299. CreateResourceInstanceFields('',Res.Resources);
  1300. CreateResourceInstanceGetters('',Res.Resources);
  1301. DecIndent;
  1302. end;
  1303. Addln('Public');
  1304. IncIndent;
  1305. AddLn('Class Function ResourceName : String; override;');
  1306. AddLn('Class Function DefaultAPI : TGoogleAPIClass; override;');
  1307. For M in Res.methods do
  1308. begin
  1309. HaveOpt:=HaveQueryParams(M);
  1310. if HaveOpt then
  1311. S:=GetResourceMethodSignature(M,IsFunc,'string = ''''')
  1312. else
  1313. S:=GetResourceMethodSignature(M,IsFunc,'');
  1314. if IsFunc then
  1315. S:='Function '+S
  1316. else
  1317. S:='Procedure '+S;
  1318. if ReservedMethod(M.Name) then
  1319. S:=S+';overload';
  1320. AddLn(S+';');
  1321. if HaveOpt then
  1322. begin
  1323. S:=GetResourceMethodSignature(M,IsFunc,Format('T%s%sOptions',[APrefix+PrettyPrint(Res.Name),M.Name]));
  1324. if IsFunc then
  1325. S:='Function '+S
  1326. else
  1327. S:='Procedure '+S;
  1328. if ReservedMethod(M.Name) then
  1329. S:=S+';overload';
  1330. AddLn(S+';');
  1331. end;
  1332. end;
  1333. if Assigned(Res.Resources) then
  1334. begin
  1335. CreateResourceAPI('',Res.resources);
  1336. CreateResourceProperties('',Res.resources);
  1337. end;
  1338. DecIndent;
  1339. Addln('end;',[Res.name]);
  1340. AddLn('');
  1341. end;
  1342. Procedure TDiscoveryJSONToPas.CreateResourceClassMethodsImplementation(
  1343. Res: TSchema; Const AClassName: String);
  1344. begin
  1345. AddLn('');
  1346. Addln('Class Function %s.ResourceName : String;',[AClassName]);
  1347. AddLn('');
  1348. AddLn('begin');
  1349. IncIndent;
  1350. AddLn('Result:=''%s'';',[Res.name]);
  1351. DecIndent;
  1352. AddLn('end;');
  1353. AddLn('');
  1354. Addln('Class Function %s.DefaultAPI : TGoogleAPIClass;',[AClassName]);
  1355. AddLn('');
  1356. AddLn('begin');
  1357. IncIndent;
  1358. AddLn('Result:=T%s%sAPI;',[ClassPrefix,Description.Name]);
  1359. DecIndent;
  1360. AddLn('end;');
  1361. AddLn('');
  1362. end;
  1363. Procedure TDiscoveryJSONToPas.CreateResourceMethodImplementationOptions(Const APrefix,AClassName: String; Res: TSchema; M: TRestMethod);
  1364. Var
  1365. P : TRestMethodParam;
  1366. S: String;
  1367. IsFunc : Boolean;
  1368. begin
  1369. S:=GetResourceMethodSignature(M,IsFunc,Format('T%s%sOptions',[APrefix+PrettyPrint(Res.Name),M.Name]));
  1370. S:=AClassName+'.'+S;
  1371. if IsFunc then
  1372. S:='Function '+S
  1373. else
  1374. S:='Procedure '+S;
  1375. Addln('');
  1376. AddLn(S+';');
  1377. Addln('');
  1378. AddLn('Var');
  1379. IncIndent;
  1380. Addln('_Q : String;');
  1381. DecIndent;
  1382. Addln('');
  1383. AddLn('begin');
  1384. IncIndent;
  1385. AddLn('_Q:='''';');
  1386. For P in M.parameters do
  1387. begin
  1388. if (P.location='query') then
  1389. AddLn('AddToQuery(_Q,''%s'',AQuery.%s);',[P.name,P.SourceName]);
  1390. end;
  1391. S:=GetResourceMethodSignature(M,IsFunc,'_Q',False);
  1392. if IsFunc then
  1393. S:='Result:='+S;
  1394. AddLn(S+';');
  1395. DecIndent;
  1396. AddLn('end;');
  1397. Addln('');
  1398. end;
  1399. Procedure TDiscoveryJSONToPas.CreateResourceMethodImplementation(
  1400. AClassName: String; Res: TSchema; M: TRestMethod);
  1401. Var
  1402. P : TRestMethodParam;
  1403. Q,RC,O,S,PA : String;
  1404. IsFunc : Boolean;
  1405. PL: TParamLocations;
  1406. begin
  1407. PL:=DescribeMethodParams(M);
  1408. if plQuery in PL then
  1409. S:=GetResourceMethodSignature(M,IsFunc,'string = ''''')
  1410. else
  1411. S:=GetResourceMethodSignature(M,IsFunc,'');
  1412. S:=AClassName+'.'+S;
  1413. if IsFunc then
  1414. S:='Function '+S
  1415. else
  1416. S:='Procedure '+S;
  1417. AddLn(S+';');
  1418. AddLn('');
  1419. AddLn('Const');
  1420. IncIndent;
  1421. AddLn('_HTTPMethod = ''%s'';',[M.httpMethod]);
  1422. AddLn('_Path = ''%s'';',[M.path]);
  1423. AddLn('_Methodid = ''%s'';',[M.id]);
  1424. DecIndent;
  1425. AddLn('');
  1426. if (plPath in PL) then
  1427. begin
  1428. AddLn('Var');
  1429. IncIndent;
  1430. Addln('_P : String;');
  1431. DecIndent;
  1432. Addln('');
  1433. end;
  1434. Addln('begin');
  1435. IncIndent;
  1436. S:='';
  1437. PA:='_Path';
  1438. if (plPath in PL) then
  1439. begin
  1440. for P in M.parameters do
  1441. if P.location='path' then
  1442. begin
  1443. if (S<>'') then
  1444. S:=S+',';
  1445. S:=S+Format('''%s'',%s',[p.name,p.sourcename]);
  1446. end;
  1447. AddLn('_P:=SubstitutePath(_Path,[%s]);',[S]);
  1448. PA:='_P';
  1449. end;
  1450. if M.request<>Nil then
  1451. O:='a'+M.request.ref
  1452. else
  1453. O:='Nil';
  1454. if (M.response<>Nil) then
  1455. RC:='T'+ClassPrefix+M.response.ref
  1456. else
  1457. RC:='Nil';
  1458. if (plQuery in PL) then
  1459. Q:='AQuery'
  1460. else
  1461. Q:='''''';
  1462. S:=Format('ServiceCall(_HTTPMethod,%s,%s,%s,%s)',[PA,Q,O,RC]);
  1463. if isFunc then
  1464. S:='Result:='+S+' as T'+ClassPrefix+M.response.ref;
  1465. AddLn(S+';');
  1466. DecIndent;
  1467. Addln('end;');
  1468. Addln('');
  1469. end;
  1470. Procedure TDiscoveryJSONToPas.CreateResourceClassImplementation(Const APrefix : String; Res: TSchema);
  1471. Var
  1472. CN : String;
  1473. M : TRestMethod;
  1474. PL: TParamLocations;
  1475. begin
  1476. CN:=Res.TypeName;
  1477. ClassComment(CN);
  1478. CreateResourceClassMethodsImplementation(Res,CN);
  1479. For M in Res.methods do
  1480. begin
  1481. PL:=DescribeMethodParams(M);
  1482. CreateResourceMethodImplementation(CN,Res,M);
  1483. if plQuery in PL then
  1484. CreateResourceMethodImplementationOptions(APrefix,CN,Res,M);
  1485. end;
  1486. AddLn('');
  1487. if Assigned(Res.resources) then
  1488. CreateResourceAPIFunctionImplementations(CN,'',Res.resources);
  1489. end;
  1490. Procedure TDiscoveryJSONToPas.CreateResourceInstanceFields(Const APrefix : String;Resources : TSchemas);
  1491. Var
  1492. R : TSchema;
  1493. begin
  1494. For R in Resources do
  1495. begin
  1496. If Assigned(R.Resources) then
  1497. CreateResourceInstanceFields(ConstructResourcePrefix(APrefix,R),R.Resources);
  1498. AddLn('F%sInstance : %s;',[APrefix+PrettyPrint(R.Name),R.TypeName]);
  1499. end;
  1500. end;
  1501. Function TDiscoveryJSONToPas.ConstructResourcePrefix(Const APrefix : String; AResource : TSchema) : String;
  1502. begin
  1503. if FlatResources then
  1504. Result:=APrefix
  1505. else
  1506. Result:=APrefix+PrettyPrint(AResource.Name);
  1507. end;
  1508. Procedure TDiscoveryJSONToPas.CreateResourceInstanceGetters(Const APrefix : String; Resources : TSchemas);
  1509. Var
  1510. R : TSchema;
  1511. begin
  1512. For R in Resources do
  1513. begin
  1514. If Assigned(R.Resources) then
  1515. CreateResourceInstanceGetters(ConstructResourcePrefix(APrefix,R),R.Resources);
  1516. AddLn('Function Get%sInstance : %s;virtual;',[APrefix+PrettyPrint(R.Name),R.TypeName]);
  1517. end;
  1518. end;
  1519. Procedure TDiscoveryJSONToPas.CreateResourceProperties(Const APrefix : String; Resources : TSchemas);
  1520. Var
  1521. R : TSchema;
  1522. begin
  1523. For R in Resources do
  1524. begin
  1525. If Assigned(R.Resources) then
  1526. CreateResourceProperties(ConstructResourcePrefix(APrefix,R),R.Resources);
  1527. AddLn('Property %sResource : %s Read Get%sInstance;',[APrefix+PrettyPrint(R.Name),R.TypeName,APrefix+PrettyPrint(R.Name)]);
  1528. end;
  1529. end;
  1530. Procedure TDiscoveryJSONToPas.CreateResourceAPI(Const APrefix : String; Resources : TSchemas);
  1531. Var
  1532. R : TSchema;
  1533. begin
  1534. For R in Resources do
  1535. begin
  1536. If Assigned(R.Resources) then
  1537. CreateResourceAPI(ConstructResourcePrefix(APrefix,R),R.Resources);
  1538. AddLn('Function Create%sResource(AOwner : TComponent) : %s;virtual;overload;',[APrefix+PrettyPrint(R.Name),R.TypeName]);
  1539. AddLn('Function Create%sResource : %s;virtual;overload;',[APrefix+PrettyPrint(R.Name),R.TypeName]);
  1540. end;
  1541. end;
  1542. Procedure TDiscoveryJSONToPas.CreateAPIClassDeclaration;
  1543. Var
  1544. CN : String;
  1545. begin
  1546. CN:=GetAPIClassName;
  1547. ClassComment(CN);
  1548. AddLn('%s = Class(TGoogleAPI)',[CN]);
  1549. AddLn('Private');
  1550. IncIndent;
  1551. CreateResourceInstanceFields('',Description.resources);
  1552. CreateResourceInstanceGetters('',Description.resources);
  1553. DecINdent;
  1554. AddLn('Public');
  1555. IncIndent;
  1556. Comment('Override class functions with API info');
  1557. AddLn('Class Function APIName : String; override;');
  1558. AddLn('Class Function APIVersion : String; override;');
  1559. AddLn('Class Function APIRevision : String; override;');
  1560. AddLn('Class Function APIID : String; override;');
  1561. AddLn('Class Function APITitle : String; override;');
  1562. AddLn('Class Function APIDescription : String; override;');
  1563. AddLn('Class Function APIOwnerDomain : String; override;');
  1564. AddLn('Class Function APIOwnerName : String; override;');
  1565. AddLn('Class Function APIIcon16 : String; override;');
  1566. AddLn('Class Function APIIcon32 : String; override;');
  1567. AddLn('Class Function APIdocumentationLink : String; override;');
  1568. AddLn('Class Function APIrootUrl : string; override;');
  1569. AddLn('Class Function APIbasePath : string;override;');
  1570. AddLn('Class Function APIbaseURL : String;override;');
  1571. AddLn('Class Function APIProtocol : string;override;');
  1572. AddLn('Class Function APIservicePath : string;override;');
  1573. AddLn('Class Function APIbatchPath : String;override;');
  1574. AddLn('Class Function APIAuthScopes : TScopeInfoArray;override;');
  1575. AddLn('Class Function APINeedsAuth : Boolean;override;');
  1576. AddLn('Class Procedure RegisterAPIResources; override;');
  1577. Comment('Add create function for resources');
  1578. CreateResourceAPI('',Description.resources);
  1579. Comment('Add default on-demand instances for resources');
  1580. CreateResourceProperties('',Description.resources);
  1581. DecIndent;
  1582. AddLn('end;');
  1583. end;
  1584. Procedure TDiscoveryJSONToPas.CreateAPIClassImplementation;
  1585. Procedure StringRes(AValue : String);
  1586. Var
  1587. S : String;
  1588. begin
  1589. S:=MakePascalString(AValue,True);
  1590. S:=StringReplace(S,#13#10,'''#13#10''',[rfReplaceAll]);
  1591. S:=StringReplace(S,#10,'''#10''',[rfReplaceAll]);
  1592. S:=StringReplace(S,#13,'''#13''',[rfReplaceAll]);
  1593. SimpleMethodBody([Format('Result:=%s;',[S])]);
  1594. end;
  1595. Var
  1596. CN : String;
  1597. S : TSchema;
  1598. I : Integer;
  1599. begin
  1600. CN:=GetAPIClassName;
  1601. ClassComment(CN);
  1602. AddLn('Class Function %s.APIName : String;',[CN]);
  1603. StringRes(Description.name);
  1604. AddLn('Class Function %s.APIVersion : String;',[CN]);
  1605. StringRes(Description.version);
  1606. AddLn('Class Function %s.APIRevision : String;',[CN]);
  1607. StringRes(Description.revision);
  1608. AddLn('Class Function %s.APIID : String;',[CN]);
  1609. StringRes(Description.id);
  1610. AddLn('Class Function %s.APITitle : String;',[CN]);
  1611. StringRes(Description.Title);
  1612. AddLn('Class Function %s.APIDescription : String;',[CN]);
  1613. StringRes(Description.Description);
  1614. AddLn('Class Function %s.APIOwnerDomain : String;',[CN]);
  1615. StringRes(Description.ownerDomain);
  1616. AddLn('Class Function %s.APIOwnerName : String;',[CN]);
  1617. StringRes(Description.ownerName);
  1618. AddLn('Class Function %s.APIIcon16 : String;',[CN]);
  1619. StringRes(Description.icons.x16);
  1620. AddLn('Class Function %s.APIIcon32 : String;',[CN]);
  1621. StringRes(Description.icons.x32);
  1622. AddLn('Class Function %s.APIdocumentationLink : String;',[CN]);
  1623. StringRes(Description.documentationLink);
  1624. AddLn('Class Function %s.APIrootUrl : string;',[CN]);
  1625. StringRes(Description.rootUrl);
  1626. AddLn('Class Function %s.APIbasePath : string;',[CN]);
  1627. StringRes(Description.BasePath);
  1628. AddLn('Class Function %s.APIbaseURL : String;',[CN]);
  1629. StringRes(Description.BaseURL);
  1630. AddLn('Class Function %s.APIProtocol : string;',[CN]);
  1631. StringRes(Description.protocol);
  1632. AddLn('Class Function %s.APIservicePath : string;',[CN]);
  1633. StringRes(Description.servicePath);
  1634. AddLn('Class Function %s.APIbatchPath : String;',[CN]);
  1635. StringRes(Description.batchPath);
  1636. AddLn('Class Function %s.APIAuthScopes : TScopeInfoArray;',[CN]);
  1637. Addln('');
  1638. AddLn('begin');
  1639. IncIndent;
  1640. if not (Assigned(Description.Auth) and Assigned(Description.Auth.oauth2)) then
  1641. AddLn('SetLength(Result,0);')
  1642. else
  1643. begin
  1644. AddLn('SetLength(Result,%d);',[Length(Description.Auth.oauth2.Scopes)]);
  1645. For I:=0 to Length(Description.Auth.oauth2.Scopes)-1 do
  1646. begin
  1647. S:=Description.Auth.oauth2.Scopes[i];
  1648. AddLn('Result[%d].Name:=%s;',[I,MakePascalString(S.Name,True)]);
  1649. AddLn('Result[%d].Description:=%s;',[I,MakePascalString(S.Description,True)]);
  1650. end;
  1651. end;
  1652. Addln('');
  1653. DecIndent;
  1654. Addln('end;');
  1655. Addln('');
  1656. AddLn('Class Function %s.APINeedsAuth : Boolean;',[CN]);
  1657. SimpleMethodBody([Format('Result:=%s;',[BoolToStr(Assigned(Description.Auth) and Assigned(Description.Auth.oauth2),'True','False')])]);
  1658. AddLn('Class Procedure %s.RegisterAPIResources;',[CN]);
  1659. Addln('');
  1660. AddLn('begin');
  1661. IncIndent;
  1662. For I:=0 to FTypes.Count-1 do
  1663. if FTypes[i].DataType=dtClass then
  1664. AddLn('%s.RegisterObject;',[FTypes[i].PascalName]);
  1665. DecIndent;
  1666. Addln('end;');
  1667. Addln('');
  1668. CreateResourceAPIFunctionImplementations(GetAPIClassName,'',Description.resources);
  1669. end;
  1670. Procedure TDiscoveryJSONToPas.CreateResourceAPIFunctionImplementations(Const AClassName : String; Const APrefix : String; Resources : TSchemas);
  1671. Var
  1672. RN,CN,RCN : String;
  1673. R : TSchema;
  1674. begin
  1675. CN:=AClassName;
  1676. For R in Resources do
  1677. begin
  1678. if Assigned(R.Resources) then
  1679. CreateResourceAPIFunctionImplementations(CN,ConstructResourcePrefix(APrefix,R),R.Resources);
  1680. RN:=APrefix+PrettyPrint(R.Name);
  1681. RCN:=R.TypeName;
  1682. AddLn('');
  1683. AddLn('Function %s.Get%sInstance : %s;',[CN,RN,RCN]);
  1684. AddLn('');
  1685. AddLn('begin');
  1686. IncIndent;
  1687. AddLn('if (F%sInstance=Nil) then',[RN]);
  1688. IncIndent;
  1689. AddLn('F%sInstance:=Create%sResource;',[RN,RN]);
  1690. DecIndent;
  1691. AddLn('Result:=F%sInstance;',[RN]);
  1692. DecIndent;
  1693. AddLn('end;');
  1694. AddLn('');
  1695. AddLn('Function %s.Create%sResource : %s;',[CN,RN,RCN]);
  1696. SimpleMethodBody([Format('Result:=Create%sResource(Self);',[RN])]);
  1697. AddLn('');
  1698. AddLn('Function %s.Create%sResource(AOwner : TComponent) : %s;',[CN,RN,RCN]);
  1699. SimpleMethodBody([Format('Result:=%s.Create(AOwner);',[RCN]),
  1700. 'Result.API:=Self.API;']);
  1701. AddLn('');
  1702. end;
  1703. end;
  1704. Procedure TDiscoveryJSONToPas.Execute;
  1705. begin
  1706. Source.Clear;
  1707. CreateUnitClause;
  1708. CreateHeader;
  1709. FTypes:=TTypeDefs.Create(TTypeDef);
  1710. try
  1711. CollectTypes;
  1712. CreateInterface;
  1713. AddLn('');
  1714. AddLn('implementation');
  1715. AddLn('');
  1716. CreateImplementation;
  1717. Addln('');
  1718. AddLn('initialization');
  1719. Addln(' %s.RegisterAPI;',[GetAPIClassName]);
  1720. finally
  1721. FTypes.Free;
  1722. end;
  1723. AddLn('end.');
  1724. end;
  1725. Class Procedure TDiscoveryJSONToPas.RegisterAllObjects;
  1726. begin
  1727. TGoogleIcons.RegisterObject;
  1728. TGoogleAuth2.RegisterObject;
  1729. TGoogleAuth.RegisterObject;
  1730. TArrayPropertyDef.RegisterObject;
  1731. TPropertyDef.RegisterObject;
  1732. TSchema.RegisterObject;
  1733. TGoogleRestDescription.RegisterObject;
  1734. TAnnotations.RegisterObject;
  1735. TRestMethod.RegisterObject;
  1736. TRestMethodParam.RegisterObject;
  1737. TMediaUpload.RegisterObject;
  1738. TMediaUploadProtocols.RegisterObject;
  1739. TMediaUploadProtocolsSimple.RegisterObject;
  1740. TMediaUploadProtocolsResumable.RegisterObject;
  1741. TRequest.RegisterObject;
  1742. TResponse.RegisterObject;
  1743. end;
  1744. end.