OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of protoc; | 5 part of protoc; |
6 | 6 |
7 /// Helper function implementing a generic option parser that reads | 7 /// Helper function implementing a generic option parser that reads |
8 /// `request.parameters` and treats each token as either a flag ("name") or a | 8 /// `request.parameters` and treats each token as either a flag ("name") or a |
9 /// key-value pair ("name=value"). For each option "name", it looks up whether a | 9 /// key-value pair ("name=value"). For each option "name", it looks up whether a |
10 /// [SingleOptionParser] exists in [parsers] and delegates the actual parsing of | 10 /// [SingleOptionParser] exists in [parsers] and delegates the actual parsing of |
(...skipping 28 matching lines...) Expand all Loading... |
39 } | 39 } |
40 | 40 |
41 if (errors.length == 0) return true; | 41 if (errors.length == 0) return true; |
42 | 42 |
43 response.error = errors.join('\n'); | 43 response.error = errors.join('\n'); |
44 return false; | 44 return false; |
45 } | 45 } |
46 | 46 |
47 /// Options expected by the protoc code generation compiler. | 47 /// Options expected by the protoc code generation compiler. |
48 class GenerationOptions { | 48 class GenerationOptions { |
49 /// Maps a fully qualified field name, to the desired name we wish to | 49 GenerationOptions(); |
50 /// generate. For example `MyMessage.has_field` to `HasFld`. | |
51 final Map<String, String> fieldNameOverrides; | |
52 | |
53 GenerationOptions([this.fieldNameOverrides = const {}]); | |
54 } | 50 } |
55 | 51 |
56 /// A parser for a name-value pair option. Options parsed in | 52 /// A parser for a name-value pair option. Options parsed in |
57 /// [genericOptionsParser] delegate to instances of this class to | 53 /// [genericOptionsParser] delegate to instances of this class to |
58 /// parse the value of a specific option. | 54 /// parse the value of a specific option. |
59 abstract class SingleOptionParser { | 55 abstract class SingleOptionParser { |
60 /// Parse the [name]=[value] value pair and report any errors to [onError]. If | 56 /// Parse the [name]=[value] value pair and report any errors to [onError]. If |
61 /// the option is a flag, [value] will be null. Note, [name] is commonly | 57 /// the option is a flag, [value] will be null. Note, [name] is commonly |
62 /// unused. It is provided because [SingleOptionParser] can be registered for | 58 /// unused. It is provided because [SingleOptionParser] can be registered for |
63 /// multiple option names in [genericOptionsParser]. | 59 /// multiple option names in [genericOptionsParser]. |
64 void parse(String name, String value, onError(String details)); | 60 void parse(String name, String value, onError(String details)); |
65 } | 61 } |
66 | 62 |
67 /// Parser used by the compiler, which supports the `field_name` option (see | 63 /// Parser used by the compiler, which supports the `field_name` option (see |
68 /// [FieldNameOptionParser]) and any additional option added in [parsers]. If | 64 /// [FieldNameOptionParser]) and any additional option added in [parsers]. If |
69 /// [parsers] has a key for `field_name`, it will be ignored. | 65 /// [parsers] has a key for `field_name`, it will be ignored. |
70 GenerationOptions parseGenerationOptions( | 66 GenerationOptions parseGenerationOptions( |
71 CodeGeneratorRequest request, CodeGeneratorResponse response, | 67 CodeGeneratorRequest request, CodeGeneratorResponse response, |
72 [Map<String, SingleOptionParser> parsers]) { | 68 [Map<String, SingleOptionParser> parsers]) { |
73 var fieldNameOptionParser = new FieldNameOptionParser(); | |
74 | |
75 var newParsers = <String, SingleOptionParser>{}; | 69 var newParsers = <String, SingleOptionParser>{}; |
76 if (parsers != null) newParsers.addAll(parsers); | 70 if (parsers != null) newParsers.addAll(parsers); |
77 newParsers['field_name'] = fieldNameOptionParser; | |
78 | 71 |
79 if (genericOptionsParser(request, response, newParsers)) { | 72 if (genericOptionsParser(request, response, newParsers)) { |
80 return new GenerationOptions(fieldNameOptionParser.mappings); | 73 return new GenerationOptions(); |
81 } | 74 } |
82 return null; | 75 return null; |
83 } | 76 } |
84 | |
85 /// A [SingleOptionParser] to parse the `field_name` option. This option | |
86 /// overrides the default name given to some fields that would otherwise collide | |
87 /// with existing field names in Dart core objects or in [GeneratedMessage]. | |
88 /// (see `README.md` for details). | |
89 class FieldNameOptionParser implements SingleOptionParser { | |
90 /// Maps a fully qualified field name, to the desired name we wish to | |
91 /// generate. For example `MyMessage.has_field` to `HasFld`. | |
92 final Map<String, String> mappings = {}; | |
93 | |
94 void parse(String name, String value, onError(String message)) { | |
95 if (value == null) { | |
96 onError('Invalid field_name option, expected a non-emtpy value.'); | |
97 return; | |
98 } | |
99 | |
100 List<String> fromTo = value.split('|'); | |
101 if (fromTo.length != 2) { | |
102 onError('Invalid field_name option, expected a single "|" separator.'); | |
103 return; | |
104 } | |
105 | |
106 var fromName = fromTo[0].trim(); | |
107 var toName = fromTo[1].trim(); | |
108 if (fromName.isEmpty || toName.isEmpty) { | |
109 onError('Invalid field_name option, ' | |
110 '"from" and "to" names should not be empty.'); | |
111 return; | |
112 } | |
113 | |
114 mappings['.$fromName'] = toName; | |
115 } | |
116 } | |
OLD | NEW |