blob: dd84cfdfb0f156a93a1fdcebe6e114222be4ec4c [file] [log] [blame]
James Kuszmaul8e62b022022-03-22 09:33:25 -07001#!/usr/bin/env python3
2#
3# Copyright 2021 Google Inc. All rights reserved.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import argparse
18import filecmp
19import glob
20import platform
21import shutil
22import subprocess
Austin Schuh2dd86a92022-09-14 21:19:23 -070023import generate_grpc_examples
James Kuszmaul8e62b022022-03-22 09:33:25 -070024from pathlib import Path
25
26parser = argparse.ArgumentParser()
27parser.add_argument(
28 "--flatc",
29 help="path of the Flat C compiler relative to the root directory",
30)
31parser.add_argument("--cpp-0x", action="store_true", help="use --cpp-std c++ox")
32parser.add_argument(
33 "--skip-monster-extra",
34 action="store_true",
35 help="skip generating tests involving monster_extra.fbs",
36)
37parser.add_argument(
38 "--skip-gen-reflection",
39 action="store_true",
40 help="skip generating the reflection.fbs files",
41)
42args = parser.parse_args()
43
44# Get the path where this script is located so we can invoke the script from
45# any directory and have the paths work correctly.
46script_path = Path(__file__).parent.resolve()
47
48# Get the root path as an absolute path, so all derived paths are absolute.
49root_path = script_path.parent.absolute()
50
51# Get the location of the flatc executable, reading from the first command line
52# argument or defaulting to default names.
53flatc_exe = Path(
54 ("flatc" if not platform.system() == "Windows" else "flatc.exe")
55 if not args.flatc
56 else args.flatc
57)
58
59# Find and assert flatc compiler is present.
60if root_path in flatc_exe.parents:
61 flatc_exe = flatc_exe.relative_to(root_path)
62flatc_path = Path(root_path, flatc_exe)
63assert flatc_path.exists(), "Cannot find the flatc compiler " + str(flatc_path)
64
65# Specify the other paths that will be referenced
66tests_path = Path(root_path, "tests")
Austin Schuh2dd86a92022-09-14 21:19:23 -070067swift_code_gen = Path(root_path, "tests/swift/tests/CodeGenerationTests")
James Kuszmaul8e62b022022-03-22 09:33:25 -070068samples_path = Path(root_path, "samples")
69reflection_path = Path(root_path, "reflection")
70
71# Execute the flatc compiler with the specified parameters
Austin Schuh2dd86a92022-09-14 21:19:23 -070072def flatc(options, schema, prefix=None, include=None, data=None, cwd=tests_path):
James Kuszmaul8e62b022022-03-22 09:33:25 -070073 cmd = [str(flatc_path)] + options
74 if prefix:
75 cmd += ["-o"] + [prefix]
76 if include:
77 cmd += ["-I"] + [include]
78 cmd += [schema] if isinstance(schema, str) else schema
79 if data:
80 cmd += [data] if isinstance(data, str) else data
81 result = subprocess.run(cmd, cwd=str(cwd), check=True)
82
83
84# Generate the code for flatbuffers reflection schema
85def flatc_reflection(options, location, target):
86 full_options = ["--no-prefix"] + options
87 temp_dir = ".tmp"
88 flatc(
89 full_options,
90 prefix=temp_dir,
91 schema="reflection.fbs",
92 cwd=reflection_path,
93 )
94 new_reflection_path = Path(reflection_path, temp_dir, target)
95 original_reflection_path = Path(root_path, location, target)
96 if not filecmp.cmp(str(new_reflection_path), str(original_reflection_path)):
Austin Schuh2dd86a92022-09-14 21:19:23 -070097 shutil.rmtree(str(original_reflection_path), ignore_errors=True)
James Kuszmaul8e62b022022-03-22 09:33:25 -070098 shutil.move(str(new_reflection_path), str(original_reflection_path))
99 shutil.rmtree(str(Path(reflection_path, temp_dir)))
100
Austin Schuh2dd86a92022-09-14 21:19:23 -0700101def flatc_annotate(schema, file, include=None, cwd=tests_path):
102 cmd = [str(flatc_path)]
103 if include:
104 cmd += ["-I"] + [include]
105 cmd += ["--annotate", schema, file]
106 result = subprocess.run(cmd, cwd=str(cwd), check=True)
James Kuszmaul8e62b022022-03-22 09:33:25 -0700107
108# Glob a pattern relative to file path
109def glob(path, pattern):
110 return [str(p) for p in path.glob(pattern)]
111
112
113# flatc options that are shared
114BASE_OPTS = ["--reflect-names", "--gen-mutable", "--gen-object-api"]
115NO_INCL_OPTS = BASE_OPTS + ["--no-includes"]
116
117# Language specific options
118CS_OPTS = ["--csharp", "--cs-gen-json-serializer"]
119CPP_OPTS = [
120 "--cpp",
121 "--gen-compare",
122 "--cpp-ptr-type",
123 "flatbuffers::unique_ptr",
124] + (["--cpp-std", "c++0x"] if args.cpp_0x else [])
125
126CPP_17_OPTS = NO_INCL_OPTS + [
127 "--cpp",
128 "--cpp-std",
129 "c++17",
130 "--cpp-static-reflection",
131 "--gen-object-api",
132]
Austin Schuh2dd86a92022-09-14 21:19:23 -0700133RUST_OPTS = BASE_OPTS + [
134 "--rust",
135 "--gen-all",
136 "--gen-name-strings",
137 "--rust-module-root-file",
138]
James Kuszmaul8e62b022022-03-22 09:33:25 -0700139RUST_SERIALIZE_OPTS = BASE_OPTS + [
140 "--rust",
141 "--gen-all",
142 "--gen-name-strings",
143 "--rust-serialize",
144 "--rust-module-root-file",
145]
146TS_OPTS = ["--ts", "--gen-name-strings"]
147LOBSTER_OPTS = ["--lobster"]
148SWIFT_OPTS = ["--swift", "--gen-json-emit", "--bfbs-filenames", str(tests_path)]
Austin Schuh2dd86a92022-09-14 21:19:23 -0700149SWIFT_OPTS_CODE_GEN = [
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800150 "--swift",
Austin Schuh2dd86a92022-09-14 21:19:23 -0700151 "--gen-json-emit",
152 "--bfbs-filenames",
153 swift_code_gen
154]
James Kuszmaul8e62b022022-03-22 09:33:25 -0700155JAVA_OPTS = ["--java"]
156KOTLIN_OPTS = ["--kotlin"]
157PHP_OPTS = ["--php"]
158DART_OPTS = ["--dart"]
159PYTHON_OPTS = ["--python"]
160BINARY_OPTS = ["-b", "--schema", "--bfbs-comments", "--bfbs-builtins"]
161
162# Basic Usage
163
164flatc(
165 NO_INCL_OPTS
166 + CPP_OPTS
167 + CS_OPTS
James Kuszmaul8e62b022022-03-22 09:33:25 -0700168 + [
169 "--binary",
170 "--java",
171 "--kotlin",
172 "--dart",
173 "--go",
174 "--lobster",
175 "--php",
176 ],
177 schema="monster_test.fbs",
178 include="include_test",
179 data="monsterdata_test.json",
180)
181
182flatc(
Austin Schuh2dd86a92022-09-14 21:19:23 -0700183 NO_INCL_OPTS
184 + TS_OPTS,
185 schema="monster_test.fbs",
186 prefix="ts",
187 include="include_test",
188 data="monsterdata_test.json",
189)
190
191flatc(
James Kuszmaul8e62b022022-03-22 09:33:25 -0700192 ["--lua", "--bfbs-filenames", str(tests_path)],
193 schema="monster_test.fbs",
194 include="include_test",
195)
196
197flatc(
198 NO_INCL_OPTS + CPP_OPTS + ["--grpc"],
199 schema="monster_test.fbs",
200 include="include_test",
201 data="monsterdata_test.json",
202)
203
204flatc(
205 RUST_OPTS,
206 schema="monster_test.fbs",
207 include="include_test",
208 prefix="monster_test",
209 data="monsterdata_test.json",
210)
211
212flatc(
213 RUST_SERIALIZE_OPTS,
214 schema="monster_test.fbs",
215 include="include_test",
216 prefix="monster_test_serialize",
217 data="monsterdata_test.json",
218)
219
220flatc(
221 options=BASE_OPTS + ["--python"],
222 schema="monster_test.fbs",
223 include="include_test",
224 data="monsterdata_test.json",
225)
226
227flatc(
228 options=BASE_OPTS + ["--python", "--gen-onefile"],
229 schema="monster_test.fbs",
230 include="include_test",
231 data="monsterdata_test.json",
232)
233
234# For Rust we currently generate two independent schemas, with namespace_test2
235# duplicating the types in namespace_test1
236flatc(
Austin Schuh2dd86a92022-09-14 21:19:23 -0700237 RUST_OPTS + CS_OPTS,
James Kuszmaul8e62b022022-03-22 09:33:25 -0700238 prefix="namespace_test",
239 schema=[
240 "namespace_test/namespace_test1.fbs",
241 "namespace_test/namespace_test2.fbs",
242 ],
243)
244
245flatc(
Austin Schuh2dd86a92022-09-14 21:19:23 -0700246 BASE_OPTS + CPP_OPTS + CS_OPTS + JAVA_OPTS + KOTLIN_OPTS + PHP_OPTS,
James Kuszmaul8e62b022022-03-22 09:33:25 -0700247 prefix="union_vector",
248 schema="union_vector/union_vector.fbs",
249)
250
251flatc(
Austin Schuh2dd86a92022-09-14 21:19:23 -0700252 BASE_OPTS + TS_OPTS,
253 prefix="ts/union_vector",
254 schema="union_vector/union_vector.fbs",
255)
256
257flatc(
James Kuszmaul8e62b022022-03-22 09:33:25 -0700258 BASE_OPTS + TS_OPTS + ["--gen-name-strings", "--gen-mutable"],
259 include="include_test",
Austin Schuh2dd86a92022-09-14 21:19:23 -0700260 prefix="ts",
James Kuszmaul8e62b022022-03-22 09:33:25 -0700261 schema="monster_test.fbs",
262)
263
Austin Schuh2dd86a92022-09-14 21:19:23 -0700264# Generate the complete flat file TS of monster.
265flatc(
266 ["--ts", "--gen-all", "--ts-flat-files"],
267 include="include_test",
268 schema="monster_test.fbs",
269 prefix="ts/ts-flat-files"
270)
271
James Kuszmaul8e62b022022-03-22 09:33:25 -0700272flatc(
273 BASE_OPTS + TS_OPTS + ["-b"],
274 include="include_test",
Austin Schuh2dd86a92022-09-14 21:19:23 -0700275 prefix="ts",
James Kuszmaul8e62b022022-03-22 09:33:25 -0700276 schema="monster_test.fbs",
277 data="unicode_test.json",
278)
279
280flatc(
281 BASE_OPTS + TS_OPTS + ["--gen-name-strings"],
Austin Schuh2dd86a92022-09-14 21:19:23 -0700282 prefix="ts/union_vector",
James Kuszmaul8e62b022022-03-22 09:33:25 -0700283 schema="union_vector/union_vector.fbs",
284)
285
286flatc(
287 RUST_OPTS,
288 prefix="include_test1",
289 include="include_test",
290 schema="include_test/include_test1.fbs",
291)
292
293flatc(
294 RUST_OPTS,
295 prefix="include_test2",
296 include="include_test",
297 schema="include_test/sub/include_test2.fbs",
298)
299
300flatc(
301 BINARY_OPTS + ["--bfbs-filenames", str(tests_path)],
302 include="include_test",
303 schema="monster_test.fbs",
304)
305
Austin Schuh2dd86a92022-09-14 21:19:23 -0700306# Generate the annotated binary of the monster_test binary schema.
307flatc_annotate(
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800308 schema="../reflection/reflection.fbs",
309 file="monster_test.bfbs",
Austin Schuh2dd86a92022-09-14 21:19:23 -0700310 include="include_test"
311)
312
313flatc_annotate(
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800314 schema="monster_test.fbs",
315 file="monsterdata_test.mon",
Austin Schuh2dd86a92022-09-14 21:19:23 -0700316 include="include_test"
317)
318
James Kuszmaul8e62b022022-03-22 09:33:25 -0700319flatc(
320 CPP_OPTS
321 + NO_INCL_OPTS
322 + [
323 "--bfbs-comments",
324 "--bfbs-builtins",
325 "--bfbs-gen-embed",
326 "--bfbs-filenames",
327 str(tests_path),
328 ],
329 include="include_test",
330 schema="monster_test.fbs",
331)
332
333flatc(
334 BINARY_OPTS + ["--bfbs-filenames", str(tests_path)],
335 include="include_test",
336 schema="arrays_test.fbs",
337)
338
339flatc(
340 ["--jsonschema", "--schema"],
341 include="include_test",
342 schema="monster_test.fbs",
343)
344
345if not args.skip_monster_extra:
346 flatc(
Austin Schuh2dd86a92022-09-14 21:19:23 -0700347 CPP_OPTS + CS_OPTS + NO_INCL_OPTS + JAVA_OPTS + KOTLIN_OPTS + PYTHON_OPTS,
James Kuszmaul8e62b022022-03-22 09:33:25 -0700348 schema="monster_extra.fbs",
349 data="monsterdata_extra.json",
350 )
351
352 flatc(
353 DART_OPTS + ["--gen-object-api"],
354 schema="monster_extra.fbs",
355 )
356
357flatc(
Austin Schuh2dd86a92022-09-14 21:19:23 -0700358 CPP_OPTS + CS_OPTS + NO_INCL_OPTS + JAVA_OPTS + ["--jsonschema", "--scoped-enums"],
James Kuszmaul8e62b022022-03-22 09:33:25 -0700359 schema="arrays_test.fbs",
360)
361
362flatc(
363 RUST_OPTS,
364 prefix="arrays_test",
365 schema="arrays_test.fbs",
366)
367
368flatc(
369 BASE_OPTS + PYTHON_OPTS,
370 schema="arrays_test.fbs",
371)
372
373
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800374flatc(
375 BASE_OPTS + PYTHON_OPTS,
376 schema="nested_union_test.fbs",
377)
378
379
James Kuszmaul8e62b022022-03-22 09:33:25 -0700380# Optional Scalars
381optional_scalars_schema = "optional_scalars.fbs"
Austin Schuh2dd86a92022-09-14 21:19:23 -0700382flatc(["--java", "--kotlin", "--lobster"], schema=optional_scalars_schema)
383flatc(TS_OPTS, schema=optional_scalars_schema, prefix="ts")
James Kuszmaul8e62b022022-03-22 09:33:25 -0700384
Austin Schuh2dd86a92022-09-14 21:19:23 -0700385flatc(["--csharp", "--python", "--gen-object-api"], schema=optional_scalars_schema)
James Kuszmaul8e62b022022-03-22 09:33:25 -0700386
387flatc(RUST_OPTS, prefix="optional_scalars", schema=optional_scalars_schema)
388
389flatc(NO_INCL_OPTS + CPP_OPTS, schema=optional_scalars_schema)
390
Austin Schuh2dd86a92022-09-14 21:19:23 -0700391# Type / field collsion
392type_field_collsion_schema = "type_field_collsion.fbs"
393
394flatc(["--csharp", "--gen-object-api"], schema=type_field_collsion_schema)
395
James Kuszmaul8e62b022022-03-22 09:33:25 -0700396# Generate string/vector default code for tests
397flatc(RUST_OPTS, prefix="more_defaults", schema="more_defaults.fbs")
398
399# Generate the schema evolution tests
400flatc(
401 CPP_OPTS + ["--scoped-enums"],
402 prefix="evolution_test",
403 schema=glob(tests_path, "evolution_test/evolution_v*.fbs"),
404)
405
406# Generate the keywords tests
407flatc(BASE_OPTS + CS_OPTS, schema="keyword_test.fbs")
408flatc(RUST_OPTS, prefix="keyword_test", schema="keyword_test.fbs")
409flatc(
410 BASE_OPTS + CS_OPTS + ["--cs-global-alias", "--gen-onefile"],
411 prefix="nested_namespace_test",
412 schema=glob(tests_path, "nested_namespace_test/nested_namespace_test*.fbs"),
413)
Austin Schuh2dd86a92022-09-14 21:19:23 -0700414flatc(BASE_OPTS + DART_OPTS, prefix="../dart/test/", schema="keyword_test.fbs")
415
416# Field key lookup with default value test
417dictionary_lookup_schema = "dictionary_lookup.fbs"
418flatc(["--java", "--kotlin"], schema=dictionary_lookup_schema)
James Kuszmaul8e62b022022-03-22 09:33:25 -0700419
420# Swift Tests
Austin Schuh2dd86a92022-09-14 21:19:23 -0700421swift_prefix = "swift/tests/Tests/FlatBuffers.Test.SwiftTests"
James Kuszmaul8e62b022022-03-22 09:33:25 -0700422flatc(
Austin Schuh2dd86a92022-09-14 21:19:23 -0700423 SWIFT_OPTS + BASE_OPTS + ["--grpc"],
James Kuszmaul8e62b022022-03-22 09:33:25 -0700424 schema="monster_test.fbs",
425 include="include_test",
426 prefix=swift_prefix,
427)
428flatc(
429 SWIFT_OPTS + BASE_OPTS,
430 schema="union_vector/union_vector.fbs",
431 prefix=swift_prefix,
432)
433flatc(SWIFT_OPTS, schema="optional_scalars.fbs", prefix=swift_prefix)
Austin Schuh2dd86a92022-09-14 21:19:23 -0700434flatc(SWIFT_OPTS, schema="vector_has_test.fbs", prefix=swift_prefix)
James Kuszmaul8e62b022022-03-22 09:33:25 -0700435flatc(
436 SWIFT_OPTS + ["--gen-object-api"],
437 schema="more_defaults.fbs",
438 prefix=swift_prefix,
439)
440flatc(
441 SWIFT_OPTS + BASE_OPTS,
442 schema="MutatingBool.fbs",
443 prefix=swift_prefix,
444)
445
Austin Schuh2dd86a92022-09-14 21:19:23 -0700446flatc(
447 SWIFT_OPTS_CODE_GEN + BASE_OPTS + ["--grpc", "--swift-implementation-only"],
448 schema="test_import.fbs",
449 cwd=swift_code_gen
450)
451
452flatc(
453 SWIFT_OPTS_CODE_GEN + NO_INCL_OPTS + ["--grpc"],
454 schema="test_no_include.fbs",
455 cwd=swift_code_gen
456)
457
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800458# Nim Tests
459NIM_OPTS = BASE_OPTS + ["--nim"]
460flatc(NIM_OPTS, schema="monster_test.fbs", include="include_test")
461flatc(NIM_OPTS, schema="optional_scalars.fbs")
462flatc(NIM_OPTS, schema="more_defaults.fbs")
463flatc(NIM_OPTS, schema="MutatingBool.fbs")
464
James Kuszmaul8e62b022022-03-22 09:33:25 -0700465# --filename-suffix and --filename-ext tests
466flatc(
Austin Schuh2dd86a92022-09-14 21:19:23 -0700467 CPP_OPTS + NO_INCL_OPTS + ["--grpc", "--filename-ext", "hpp"],
James Kuszmaul8e62b022022-03-22 09:33:25 -0700468 include="include_test",
Austin Schuh2dd86a92022-09-14 21:19:23 -0700469 prefix="monster_test_suffix/ext_only",
James Kuszmaul8e62b022022-03-22 09:33:25 -0700470 schema="monster_test.fbs",
471)
Austin Schuh2dd86a92022-09-14 21:19:23 -0700472flatc(
473 CPP_OPTS + NO_INCL_OPTS + ["--grpc", "--filename-suffix", "_suffix"],
474 include="include_test",
475 prefix="monster_test_suffix/filesuffix_only",
476 schema="monster_test.fbs",
477)
478flatc(
479 CPP_OPTS + NO_INCL_OPTS + ["--grpc", "--filename-suffix", "_suffix", "--filename-ext", "hpp"],
480 include="include_test",
481 prefix="monster_test_suffix",
482 schema="monster_test.fbs",
483)
James Kuszmaul8e62b022022-03-22 09:33:25 -0700484
485# Flag c++17 requires Clang6, GCC7, MSVC2017 (_MSC_VER >= 1914) or higher.
486cpp_17_prefix = "cpp17/generated_cpp17"
487flatc(
488 CPP_17_OPTS,
489 schema="monster_test.fbs",
490 include="include_test",
491 prefix=cpp_17_prefix,
492)
493flatc(
494 CPP_17_OPTS,
495 schema="optional_scalars.fbs",
496 prefix=cpp_17_prefix,
497)
498flatc(
499 CPP_17_OPTS,
500 schema="union_vector/union_vector.fbs",
501 prefix=cpp_17_prefix,
502)
503
Austin Schuh2dd86a92022-09-14 21:19:23 -0700504# Private annotations
505annotations_test_schema = "private_annotation_test.fbs"
506
507flatc(RUST_OPTS + ["--no-leak-private-annotation", "--gen-object-api"], prefix="private_annotation_test", schema=annotations_test_schema)
508
James Kuszmaul8e62b022022-03-22 09:33:25 -0700509# Sample files
510samples_schema = "monster.fbs"
Austin Schuh2dd86a92022-09-14 21:19:23 -0700511flatc(BASE_OPTS + CPP_OPTS + LOBSTER_OPTS, schema=samples_schema, cwd=samples_path)
512flatc(RUST_OPTS, prefix="rust_generated", schema=samples_schema, cwd=samples_path)
James Kuszmaul8e62b022022-03-22 09:33:25 -0700513flatc(
514 BINARY_OPTS + ["--bfbs-filenames", str(samples_path)],
515 schema=samples_schema,
516 cwd=samples_path,
517)
518
519# Reflection
520
521# Skip generating the reflection if told too, as we run this script after
522# building flatc which uses the reflection_generated.h itself.
523if not args.skip_gen_reflection:
Austin Schuh2dd86a92022-09-14 21:19:23 -0700524 # C++ Reflection
525 flatc_reflection(
526 ["-c", "--cpp-std", "c++0x"], "include/flatbuffers", "reflection_generated.h"
527 )
James Kuszmaul8e62b022022-03-22 09:33:25 -0700528
529# Python Reflection
530flatc_reflection(["-p"], "python/flatbuffers", "reflection")
Austin Schuh2dd86a92022-09-14 21:19:23 -0700531
532# Annotation
533
534
535def flatc_annotate(schema, include=None, data=None, cwd=tests_path):
536 cmd = [str(flatc_path)]
537 if include:
538 cmd += ["-I"] + [include]
539 cmd += ["--annotate", schema]
540 if data:
541 cmd += [data] if isinstance(data, str) else data
542 subprocess.run(cmd, cwd=str(cwd), check=True)
543
544
545flatc_annotate(
546 schema="monster_test.fbs", include="include_test", data="monsterdata_test.mon"
547)
548
549# Run the generate_grpc_examples script
550generate_grpc_examples.GenerateGRPCExamples()