blob: 00455e657e47ed4a76b29975819a6236ea48d5d0 [file] [log] [blame]
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
/// Provides metadata about mixins to dart-protoc-plugin.
/// (Experimental API; subject to change.)
import 'indenting_writer.dart';
/// Finds [name] in the exported mixins.
PbMixin findMixin(String name) {
const _exportedMixins = {
'PbMapMixin': _pbMapMixin,
'PbEventMixin': _pbEventMixin,
};
return _exportedMixins[name];
}
/// PbMixin contains metadata needed by dart-protoc-plugin to apply a mixin.
///
/// The mixin can be applied to a message using options in dart_options.proto.
/// Only one mixin can be applied to each message, but that mixin can depend
/// on another mixin, recursively, similar to single inheritance.
class PbMixin {
/// The name of the mixin class to import into the .pb.dart file.
final String name;
/// The file that the .pb.dart file should import the symbol from.
final String importFrom;
/// Another mixin to apply ahead of this one, or null for none.
final PbMixin parent;
/// Names that shouldn't be used by properties in the generated child class.
/// May be null if the mixin doesn't reserve any new names.
final List<String> reservedNames;
/// Code to inject into the class using the mixin.
///
/// Typically used for static helpers since you cannot mix in static members.
final List<String> injectedHelpers;
/// If `True` the mixin should have static methods for converting to and from
/// proto3 Json.
final bool hasProto3JsonHelpers;
const PbMixin(
this.name, {
this.importFrom,
this.parent,
this.reservedNames,
this.injectedHelpers,
this.hasProto3JsonHelpers = false,
});
/// Returns the mixin and its ancestors, in the order they should be applied.
Iterable<PbMixin> findMixinsToApply() {
var result = [this];
for (var p = parent; p != null; p = p.parent) {
result.add(p);
}
return result.reversed;
}
/// Returns all the reserved names, including from ancestor mixins.
Iterable<String> findReservedNames() {
var names = <String>{};
for (var m = this; m != null; m = m.parent) {
names.add(m.name);
if (m.reservedNames != null) {
names.addAll(m.reservedNames);
}
}
return names;
}
void injectHelpers(IndentingWriter out) {
if (injectedHelpers != null && injectedHelpers.isNotEmpty) {
out.println(injectedHelpers.join('\n'));
}
}
}
const _pbMapMixin = PbMixin("PbMapMixin",
importFrom: "package:protobuf/src/protobuf/mixins/map_mixin.dart",
parent: _mapMixin);
const _pbEventMixin = PbMixin("PbEventMixin",
importFrom: "package:protobuf/src/protobuf/mixins/event_mixin.dart",
reservedNames: ["changes", "deliverChanges"]);
const List<String> _reservedNamesForMap = [
'[]',
'[]=',
'addAll',
'addEntries',
'cast',
'containsKey',
'containsValue',
'entries',
'forEach',
'isEmpty',
'isNotEmpty',
'keys',
'length',
'map',
'putIfAbsent',
'remove',
'removeWhere',
'retype',
'update',
'updateAll',
'values',
];
const _mapMixin = PbMixin("MapMixin",
importFrom: "dart:collection", reservedNames: _reservedNamesForMap);