| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'ast.dart'; |
| import 'generator_tools.dart'; |
| |
| /// An abstract base class of generators. |
| /// |
| /// This provides the structure that is common across generators for different languages. |
| abstract class Generator<T> { |
| /// Constructor. |
| const Generator(); |
| |
| /// Generates files for specified language with specified [generatorOptions] |
| void generate( |
| T generatorOptions, |
| Root root, |
| StringSink sink, { |
| required String dartPackageName, |
| }); |
| } |
| |
| /// An abstract base class that enforces code generation across platforms. |
| abstract class StructuredGenerator<T> extends Generator<T> { |
| /// Constructor. |
| const StructuredGenerator(); |
| |
| @override |
| void generate( |
| T generatorOptions, |
| Root root, |
| StringSink sink, { |
| required String dartPackageName, |
| }) { |
| final Indent indent = Indent(sink); |
| |
| writeFilePrologue( |
| generatorOptions, |
| root, |
| indent, |
| dartPackageName: dartPackageName, |
| ); |
| |
| writeFileImports( |
| generatorOptions, |
| root, |
| indent, |
| dartPackageName: dartPackageName, |
| ); |
| |
| writeOpenNamespace( |
| generatorOptions, |
| root, |
| indent, |
| dartPackageName: dartPackageName, |
| ); |
| |
| writeGeneralUtilities( |
| generatorOptions, |
| root, |
| indent, |
| dartPackageName: dartPackageName, |
| ); |
| |
| if (root.apis.any((Api api) => api is AstProxyApi)) { |
| writeInstanceManager( |
| generatorOptions, |
| root, |
| indent, |
| dartPackageName: dartPackageName, |
| ); |
| |
| writeInstanceManagerApi( |
| generatorOptions, |
| root, |
| indent, |
| dartPackageName: dartPackageName, |
| ); |
| |
| writeProxyApiBaseCodec(generatorOptions, root, indent); |
| } |
| |
| writeEnums( |
| generatorOptions, |
| root, |
| indent, |
| dartPackageName: dartPackageName, |
| ); |
| |
| writeDataClasses( |
| generatorOptions, |
| root, |
| indent, |
| dartPackageName: dartPackageName, |
| ); |
| |
| writeApis( |
| generatorOptions, |
| root, |
| indent, |
| dartPackageName: dartPackageName, |
| ); |
| |
| writeCloseNamespace( |
| generatorOptions, |
| root, |
| indent, |
| dartPackageName: dartPackageName, |
| ); |
| } |
| |
| /// Adds specified headers to [indent]. |
| void writeFilePrologue( |
| T generatorOptions, |
| Root root, |
| Indent indent, { |
| required String dartPackageName, |
| }); |
| |
| /// Writes specified imports to [indent]. |
| void writeFileImports( |
| T generatorOptions, |
| Root root, |
| Indent indent, { |
| required String dartPackageName, |
| }); |
| |
| /// Writes code to [indent] that opens file namespace if needed. |
| /// |
| /// This method is not required, and does not need to be overridden. |
| void writeOpenNamespace( |
| T generatorOptions, |
| Root root, |
| Indent indent, { |
| required String dartPackageName, |
| }) {} |
| |
| /// Writes code to [indent] that closes file namespace if needed. |
| /// |
| /// This method is not required, and does not need to be overridden. |
| void writeCloseNamespace( |
| T generatorOptions, |
| Root root, |
| Indent indent, { |
| required String dartPackageName, |
| }) {} |
| |
| /// Writes any necessary helper utilities to [indent] if needed. |
| /// |
| /// This method is not required, and does not need to be overridden. |
| void writeGeneralUtilities( |
| T generatorOptions, |
| Root root, |
| Indent indent, { |
| required String dartPackageName, |
| }) {} |
| |
| /// Writes all enums to [indent]. |
| /// |
| /// Can be overridden to add extra code before/after enums. |
| void writeEnums( |
| T generatorOptions, |
| Root root, |
| Indent indent, { |
| required String dartPackageName, |
| }) { |
| for (final Enum anEnum in root.enums) { |
| writeEnum( |
| generatorOptions, |
| root, |
| indent, |
| anEnum, |
| dartPackageName: dartPackageName, |
| ); |
| } |
| } |
| |
| /// Writes a single Enum to [indent]. This is needed in most generators. |
| void writeEnum( |
| T generatorOptions, |
| Root root, |
| Indent indent, |
| Enum anEnum, { |
| required String dartPackageName, |
| }) {} |
| |
| /// Writes all data classes to [indent]. |
| /// |
| /// Can be overridden to add extra code before/after apis. |
| void writeDataClasses( |
| T generatorOptions, |
| Root root, |
| Indent indent, { |
| required String dartPackageName, |
| }) { |
| for (final Class classDefinition in root.classes) { |
| writeDataClass( |
| generatorOptions, |
| root, |
| indent, |
| classDefinition, |
| dartPackageName: dartPackageName, |
| ); |
| } |
| } |
| |
| /// Writes a single data class to [indent]. |
| void writeDataClass( |
| T generatorOptions, |
| Root root, |
| Indent indent, |
| Class classDefinition, { |
| required String dartPackageName, |
| }); |
| |
| /// Writes a single class encode method to [indent]. |
| void writeClassEncode( |
| T generatorOptions, |
| Root root, |
| Indent indent, |
| Class classDefinition, { |
| required String dartPackageName, |
| }) {} |
| |
| /// Writes a single class decode method to [indent]. |
| void writeClassDecode( |
| T generatorOptions, |
| Root root, |
| Indent indent, |
| Class classDefinition, { |
| required String dartPackageName, |
| }) {} |
| |
| /// Writes all apis to [indent]. |
| /// |
| /// Can be overridden to add extra code before/after classes. |
| void writeApis( |
| T generatorOptions, |
| Root root, |
| Indent indent, { |
| required String dartPackageName, |
| }) { |
| for (final Api api in root.apis) { |
| switch (api) { |
| case AstHostApi(): |
| writeHostApi( |
| generatorOptions, |
| root, |
| indent, |
| api, |
| dartPackageName: dartPackageName, |
| ); |
| case AstFlutterApi(): |
| writeFlutterApi( |
| generatorOptions, |
| root, |
| indent, |
| api, |
| dartPackageName: dartPackageName, |
| ); |
| case AstProxyApi(): |
| writeProxyApi( |
| generatorOptions, |
| root, |
| indent, |
| api, |
| dartPackageName: dartPackageName, |
| ); |
| } |
| } |
| } |
| |
| /// Writes a single Flutter Api to [indent]. |
| void writeFlutterApi( |
| T generatorOptions, |
| Root root, |
| Indent indent, |
| AstFlutterApi api, { |
| required String dartPackageName, |
| }); |
| |
| /// Writes a single Host Api to [indent]. |
| void writeHostApi( |
| T generatorOptions, |
| Root root, |
| Indent indent, |
| AstHostApi api, { |
| required String dartPackageName, |
| }); |
| |
| /// Writes the implementation of an `InstanceManager` to [indent]. |
| void writeInstanceManager( |
| T generatorOptions, |
| Root root, |
| Indent indent, { |
| required String dartPackageName, |
| }) {} |
| |
| /// Writes the implementation of the API for the `InstanceManager` to |
| /// [indent]. |
| void writeInstanceManagerApi( |
| T generatorOptions, |
| Root root, |
| Indent indent, { |
| required String dartPackageName, |
| }) {} |
| |
| /// Writes the base codec to be used by all ProxyApis. |
| /// |
| /// This codec should use `128` as the identifier for objects that exist in |
| /// an `InstanceManager`. The write implementation should convert an instance |
| /// to an identifier. The read implementation should covert the identifier |
| /// to an instance. |
| /// |
| /// This will serve as the default codec for all ProxyApis. If a ProxyApi |
| /// needs to create its own codec (it has methods/fields/constructor that use |
| /// a data class) it should extend this codec and not `StandardMessageCodec`. |
| void writeProxyApiBaseCodec( |
| T generatorOptions, |
| Root root, |
| Indent indent, |
| ) {} |
| |
| /// Writes a single Proxy Api to [indent]. |
| void writeProxyApi( |
| T generatorOptions, |
| Root root, |
| Indent indent, |
| AstProxyApi api, { |
| required String dartPackageName, |
| }) {} |
| } |