@@ -32,6 +32,11 @@ const (
32
32
googleDiscoveryURL = "https://www.googleapis.com/discovery/v1/apis"
33
33
googleDefaultUniverse = "googleapis.com"
34
34
universeDomainPlaceholder = "UNIVERSE_DOMAIN"
35
+
36
+ splitFileSeperator = `// =*=*"`
37
+ // Size the buffer so there is room for the header and contents when
38
+ // splitting up large files.
39
+ splitFileHeaderSize = 500
35
40
)
36
41
37
42
var (
@@ -75,6 +80,10 @@ var skipAPIGeneration = map[string]bool{
75
80
"datalineage:v1" : true ,
76
81
}
77
82
83
+ var apisToSplit = map [string ]bool {
84
+ "compute" : true ,
85
+ }
86
+
78
87
// API represents an API to generate, as well as its state while it's
79
88
// generating.
80
89
type API struct {
@@ -226,7 +235,7 @@ func getAPIs() []*API {
226
235
} else {
227
236
bytes = slurpURL (* apisURL )
228
237
if * publicOnly {
229
- if err := writeFile (apiListFile , bytes ); err != nil {
238
+ if err := writeFile (apiListFile , "" , bytes ); err != nil {
230
239
log .Fatal (err )
231
240
}
232
241
}
@@ -300,7 +309,7 @@ func apiFromFile(file string) (*API, error) {
300
309
func checkAndUpdateSpecFile (file string , contents []byte ) error {
301
310
// check if file exists
302
311
if _ , err := os .Stat (file ); os .IsNotExist (err ) {
303
- return writeFile (file , contents )
312
+ return writeFile (file , "" , contents )
304
313
}
305
314
existing , err := os .ReadFile (file )
306
315
if err != nil {
@@ -309,7 +318,7 @@ func checkAndUpdateSpecFile(file string, contents []byte) error {
309
318
if err := isNewerRevision (existing , contents ); err != nil {
310
319
return err
311
320
}
312
- return writeFile (file , contents )
321
+ return writeFile (file , "" , contents )
313
322
}
314
323
315
324
// isNewerRevision returns nil if the contents of new has a newer revision than
@@ -331,7 +340,7 @@ func isNewerRevision(old []byte, new []byte) error {
331
340
return nil
332
341
}
333
342
334
- func writeFile (file string , contents []byte ) error {
343
+ func writeFile (file , pkg string , contents []byte ) error {
335
344
// Don't write it if the contents are identical.
336
345
existing , err := os .ReadFile (file )
337
346
if err == nil && (bytes .Equal (existing , contents ) || basicallyEqual (existing , contents )) {
@@ -341,7 +350,49 @@ func writeFile(file string, contents []byte) error {
341
350
if err = os .MkdirAll (outdir , 0755 ); err != nil {
342
351
return fmt .Errorf ("failed to Mkdir %s: %v" , outdir , err )
343
352
}
344
- return os .WriteFile (file , contents , 0644 )
353
+ // Don't try to split spec files, json or non-allowlisted packages
354
+ if pkg == "" || ! apisToSplit [pkg ] {
355
+ return os .WriteFile (file , contents , 0644 )
356
+ }
357
+
358
+ // Split generated file out into multiple
359
+ bs := bytes .Split (contents , []byte (splitFileSeperator ))
360
+ for i , b := range bs {
361
+ var name string
362
+ var newB []byte
363
+ if i == 0 {
364
+ // For the base case, use the provided inputs as is
365
+ name = file
366
+ var err error
367
+ newB , err = format .Source (b )
368
+ if err != nil {
369
+ return err
370
+ }
371
+ } else {
372
+ // determine the new file name
373
+ base := filepath .Dir (file )
374
+ fileNum := i + 1
375
+ name = filepath .Join (base , fmt .Sprintf ("%s%d-gen.go" , pkg , fileNum ))
376
+
377
+ // prepend file header, package, and imports
378
+ var buf bytes.Buffer
379
+ // Size the buffer so there is room for the header and contents
380
+ buf .Grow (len (b ) + splitFileHeaderSize )
381
+ splitFileHeading (& buf , pkg )
382
+ _ , err := buf .Write (b )
383
+ if err != nil {
384
+ return err
385
+ }
386
+ newB , err = format .Source (buf .Bytes ())
387
+ if err != nil {
388
+ return err
389
+ }
390
+ }
391
+ if err := os .WriteFile (name , newB , 0644 ); err != nil {
392
+ return err
393
+ }
394
+ }
395
+ return nil
345
396
}
346
397
347
398
var ignoreLines = regexp .MustCompile (`(?m)^\s+"(?:etag|revision)": ".+\n` )
@@ -589,7 +640,7 @@ func (a *API) WriteGeneratedCode() error {
589
640
}
590
641
591
642
code , err := a .GenerateCode ()
592
- errw := writeFile (genfilename , code )
643
+ errw := writeFile (genfilename , a . Package (), code )
593
644
if err == nil {
594
645
err = errw
595
646
}
@@ -862,8 +913,12 @@ func (a *API) GenerateCode() ([]byte, error) {
862
913
for _ , meth := range a .APIMethods () {
863
914
meth .generateCode ()
864
915
}
865
-
866
- for _ , res := range a .doc .Resources {
916
+ a .insertSplitFileComment ()
917
+ rCnt := len (a .doc .Resources ) / 2
918
+ for i , res := range a .doc .Resources {
919
+ if i == rCnt {
920
+ a .insertSplitFileComment ()
921
+ }
867
922
a .generateResourceMethods (res )
868
923
}
869
924
@@ -874,6 +929,55 @@ func (a *API) GenerateCode() ([]byte, error) {
874
929
return clean , nil
875
930
}
876
931
932
+ func (a * API ) insertSplitFileComment () {
933
+ if apisToSplit [a .Package ()] {
934
+ a .pn ("" )
935
+ a .pn (splitFileSeperator )
936
+ a .pn ("" )
937
+ }
938
+ }
939
+
940
+ // splitFileHeading writes the file preamble used when generating a split file
941
+ // client like compute.
942
+ func splitFileHeading (w io.Writer , pkg string ) {
943
+ pn := func (format string , args ... interface {}) {
944
+ _ , err := fmt .Fprintf (w , format + "\n " , args ... )
945
+ if err != nil {
946
+ panic (err )
947
+ }
948
+ }
949
+
950
+ pn ("// Copyright %s Google LLC." , * copyrightYear )
951
+ pn ("// Use of this source code is governed by a BSD-style" )
952
+ pn ("// license that can be found in the LICENSE file." )
953
+ pn ("" )
954
+ pn ("// Code generated file. DO NOT EDIT." )
955
+ pn ("" )
956
+ pn ("package %s" , pkg )
957
+ pn ("" )
958
+ pn ("import (" )
959
+ for _ , imp := range []string {
960
+ "context" ,
961
+ "fmt" ,
962
+ "io" ,
963
+ "net/http" ,
964
+ } {
965
+ pn (" %q" , imp )
966
+ }
967
+ pn ("" )
968
+ for _ , imp := range []struct {
969
+ pkg string
970
+ lname string
971
+ }{
972
+ {* gensupportPkg , "gensupport" },
973
+ {* googleapiPkg , "googleapi" },
974
+ } {
975
+ pn (" %s %q" , imp .lname , imp .pkg )
976
+ }
977
+ pn (")" )
978
+ pn ("" )
979
+ }
980
+
877
981
func (a * API ) generateScopeConstants () {
878
982
scopes := a .doc .Auth .OAuth2Scopes
879
983
if len (scopes ) == 0 {
0 commit comments