Index: lib/options.dart |
diff --git a/lib/options.dart b/lib/options.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e7e331c9f49b05c6484b533a07e67e4fdf8832ec |
--- /dev/null |
+++ b/lib/options.dart |
@@ -0,0 +1,120 @@ |
+// Copyright (c) 2014, 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. |
+ |
+part of protoc; |
+ |
+/// A function that parses options for the compiler from [request]. If an error |
+/// is detected during parsing, this function should report all errors in |
+/// `response.error` and return `null`. |
+typedef GenerationOptions GenerationOptionsParser( |
+ CodeGeneratorRequest request, CodeGeneratorResponse response); |
+ |
+/// Helper function implementing a generic [GenerationOptionsParser] that reads |
+/// `request.parameters` and treats each token as either a flag ("name") or a |
+/// key-value pair ("name=value"). For each option "name", it looks up whether a |
+/// [SingleOptionParser] exists in [parsers] and delegates the actual parsing of |
+/// the option to it. Finally, it no errors were reported, it will call |
+/// [optionsFactory] to create the resulting [GenerationOptions]. |
+GenerationOptions genericGenerationOptionsParser( |
+ CodeGeneratorRequest request, CodeGeneratorResponse response, |
+ Map<String, SingleOptionParser> parsers, |
+ GenerationOptions optionsFactory(Map<String, SingleOptionParser> parsers)) { |
+ var parameter = request.parameter != null ? request.parameter : ''; |
+ var options = parameter.trim().split(','); |
+ var map = <String, String>{}; |
+ var errors = []; |
+ |
+ for (var option in options) { |
+ option = option.trim(); |
+ if (option.isEmpty) continue; |
+ var reportError = (details) { |
+ errors.add('Error found trying to parse the option: $option.\n$details'); |
+ }; |
+ |
+ var nameValue = option.split('='); |
+ if (nameValue.length != 1 && nameValue.length != 2) { |
+ reportError('Options should be a single token, or a name=value pair'); |
+ continue; |
+ } |
+ var name = nameValue[0].trim(); |
+ var parser = parsers[name]; |
+ if (parser == null) { |
+ reportError('Unknown option ($name).'); |
+ continue; |
+ } |
+ |
+ var value = nameValue.length > 1 ? nameValue[1].trim() : null; |
+ parser.parse(name, value, reportError); |
+ } |
+ |
+ if (errors.length == 0) return optionsFactory(parsers); |
+ |
+ response.error = errors.join('\n'); |
+ return null; |
+} |
+ |
+/// Options expected by the protoc code generation compiler. |
+class GenerationOptions { |
+ /// Maps a fully qualified field name, to the desired name we wish to |
+ /// generate. For example `MyMessage.has_field` to `HasFld`. |
+ final Map<String, String> fieldNameOverrides; |
Chris Bracken
2014/05/16 19:58:45
+1 for the new name
|
+ |
+ GenerationOptions(this.fieldNameOverrides); |
+} |
+ |
+/// A parser for a name-value pair option. Options parsed in |
+/// [genericGenerationOptionsParser] delegate to instances of this class to |
+/// parse the value of a specific option. |
+abstract class SingleOptionParser { |
+ |
+ /// Parse the [name]=[value] value pair and report any errors to [onError]. If |
+ /// the option is a flag, [value] will be null. Note, [name] is commonly |
+ /// unused. It is provided because [SingleOptionParser] can be registered for |
+ /// multiple option names in [genericGenerationOptionsParser]. |
+ void parse(String name, String value, onError(String details)); |
+} |
+ |
+/// Default [GenerationOptionsParser] used by the compiler, which supports |
+/// the `field_name` option. This option overrides the default name given to |
+/// some fields that would otherwise collide with existing field names in Dart |
+/// core objects or in [GeneratedMessage] (see `README.md` for details). |
+GenerationOptions parseDefaultGenerationOptions( |
+ CodeGeneratorRequest request, CodeGeneratorResponse response) { |
+ var fieldNameOptionParser = new FieldNameOptionParser(); |
+ return genericGenerationOptionsParser(request, response, |
+ {'field_name': fieldNameOptionParser}, |
+ (_) => new GenerationOptions(fieldNameOptionParser.mappings)); |
+} |
+ |
+/// A [SingleOptionParser] to parse the `field_name` option. This option |
+/// overrides the default name given to some fields that would otherwise collide |
+/// with existing field names in Dart core objects or in [GeneratedMessage]. |
+class FieldNameOptionParser implements SingleOptionParser { |
+ /// Maps a fully qualified field name, to the desired name we wish to |
+ /// generate. For example `MyMessage.has_field` to `HasFld`. |
+ final Map<String, String> mappings = {}; |
+ |
+ void parse(String name, String value, onError(String message)) { |
+ if (value == null) { |
+ onError('Invalid field_name option, expected a non-emtpy value.'); |
+ return; |
+ } |
+ |
+ List<String> fromTo = value.split('|'); |
+ if (fromTo.length != 2) { |
+ onError('Invalid field_name option, expected a single "|" separator.'); |
+ return; |
+ } |
+ |
+ var fromName = fromTo[0].trim(); |
+ var toName = fromTo[1].trim(); |
+ if (fromName.isEmpty || toName.isEmpty) { |
+ onError('Invalid field_name option, ' |
+ '"from" and "to" names should not be empty.'); |
+ return; |
+ } |
+ |
+ mappings['.$fromName'] = toName; |
+ } |
+} |