Skip to content
This repository has been archived by the owner on Jan 26, 2021. It is now read-only.

Commit

Permalink
Change how to set the Dart name of a field
Browse files Browse the repository at this point in the history
The old way was by passing a --field_name flag to the protoc
generator. (However, it's doubtful whether anyone was using it.)

The new way is to use the field_name option on the .proto file.
For example:

  optional string some_field = 1 [
    (dart_options.dart_name) = "renamedField"
  ];

Based on a patch by Frederik Mutzel.

BUG=
R=frederikmutzel@google.com, sgjesse@google.com

Review URL: https://chromiumcodereview.appspot.com//2043913005 .
  • Loading branch information
Brian Slesinsky committed Jun 9, 2016
1 parent 03fbc43 commit d72f760
Show file tree
Hide file tree
Showing 15 changed files with 515 additions and 337 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ TEST_PROTO_LIST = \
google/protobuf/unittest_import \
google/protobuf/unittest_optimize_for \
google/protobuf/unittest \
dart_name \
dart_options \
descriptor_2_5_opensource \
enum_extension \
Expand Down
27 changes: 0 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,33 +37,6 @@ options `<option 1>` and `<option 2>` like this:

--dart_out="<option 1>,<option 2>:."

#### Option for setting the name of field accessors

The following message definition has the field name `has_field`.

message MyMessage {
optional string has_field = 1;
}

This poses the problem, that the Dart class will have a getter and a
setter called `hasField`. This conflicts with the method `hasField`
which is already defined on the superclass `GeneratedMessage`.

To work around this problem the option `field_name` can be
used. Option `field_name` takes two values separated by the vertical
bar. The first value is the full name of the field and the second
value is the name of the field in the generated Dart code. Passing the
following option:

--dart_out="field_name=MyMessage.has_field|HasFld:."

Will generate the following message field accessors:

String get hasFld => getField(1);
void set hasFld(String v) { setField(1, v); }
bool hasHasFld() => hasField(1);
void clearHasFld() => clearField(1);

Using protocol buffer libraries to build new libraries
------------------------------------------------------

Expand Down
8 changes: 5 additions & 3 deletions lib/extension_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ class ExtensionGenerator {

// populated by resolve()
ProtobufField _field;
String _extensionName;
String _extendedClassName = "";

ExtensionGenerator(this._descriptor, this._parent);

void resolve(GenerationContext ctx) {
_field = new ProtobufField(_descriptor, null, _parent, ctx);
_extensionName = extensionName(_descriptor);
_field = new ProtobufField.extension(_descriptor, _parent, ctx);

ProtobufContainer extendedType = ctx.getFieldType(_descriptor.extendee);
// TODO(skybrian) When would this be null?
Expand All @@ -31,7 +33,7 @@ class ExtensionGenerator {

String get name {
if (_field == null) throw new StateError("resolve not called");
String name = _field.dartFieldName;
String name = _extensionName;
return _parent is MessageGenerator ? '${_parent.classname}.$name' : name;
}

Expand Down Expand Up @@ -72,7 +74,7 @@ class ExtensionGenerator {
void generate(IndentingWriter out) {
if (_field == null) throw new StateError("resolve not called");

String name = _field.dartFieldName;
String name = _extensionName;
var type = _field.baseType;
var dartType = type.getDartType(package);

Expand Down
112 changes: 13 additions & 99 deletions lib/message_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,7 @@

part of protoc;

/// A Dart function called on each item added to a repeated list
/// to check its type and range.
const checkItem = '\$checkItem';

class MessageGenerator extends ProtobufContainer {
// List of Dart language reserved words in names which cannot be used in a
// subclass of GeneratedMessage.
static final List<String> reservedWords = [
'assert',
'break',
'case',
'catch',
'class',
'const',
'continue',
'default',
'do',
'else',
'enum',
'extends',
'false',
'final',
'finally',
'for',
'if',
'in',
'is',
'new',
'null',
'rethrow',
'return',
'super',
'switch',
'this',
'throw',
'true',
'try',
'var',
'void',
'while',
'with'
];

// List of names used in the generated class itself
static final List<String> generatedNames = [
'create',
'createRepeated',
'getDefault',
checkItem
];

// Returns the mixin for this message, or null if none.
static PbMixin _getMixin(DescriptorProto desc, PbMixin defaultValue) {
if (!desc.hasOptions()) return defaultValue;
Expand Down Expand Up @@ -82,9 +32,6 @@ class MessageGenerator extends ProtobufContainer {
// populated by resolve()
List<ProtobufField> _fieldList;

// Used during generation.
final Set<String> _methodNames = new Set<String>();

MessageGenerator(DescriptorProto descriptor, ProtobufContainer parent,
PbMixin defaultMixin)
: _descriptor = descriptor,
Expand Down Expand Up @@ -158,17 +105,12 @@ class MessageGenerator extends ProtobufContainer {
void resolve(GenerationContext ctx) {
if (_fieldList != null) throw new StateError("message already resolved");

var sorted = new List<FieldDescriptorProto>.from(_descriptor.field)
..sort((FieldDescriptorProto a, FieldDescriptorProto b) {
if (a.number < b.number) return -1;
if (a.number > b.number) return 1;
throw "multiple fields defined for tag ${a.number} in $fqname";
});
var reserved = mixin?.findReservedNames() ?? const <String>[];
var fields = messageFieldNames(_descriptor, reserved: reserved);

_fieldList = <ProtobufField>[];
for (FieldDescriptorProto field in sorted) {
int index = _fieldList.length;
_fieldList.add(new ProtobufField(field, index, this, ctx));
for (MemberNames names in fields.values) {
_fieldList.add(new ProtobufField.message(names, this, ctx));
}

for (var m in _messageGenerators) {
Expand Down Expand Up @@ -242,15 +184,6 @@ class MessageGenerator extends ProtobufContainer {
void generate(IndentingWriter out) {
checkResolved();

_methodNames.clear();
_methodNames.addAll(reservedWords);
_methodNames.addAll(GeneratedMessage_reservedNames);
_methodNames.addAll(generatedNames);

if (mixin != null) {
_methodNames.addAll(mixin.findReservedNames());
}

for (MessageGenerator m in _messageGenerators) {
m.generate(out);
}
Expand All @@ -267,7 +200,8 @@ class MessageGenerator extends ProtobufContainer {
'static final BuilderInfo _i = new BuilderInfo(\'${classname}\')',
';', () {
for (ProtobufField field in _fieldList) {
out.println(field.generateBuilderInfoCall(package));
var dartFieldName = field.memberNames.fieldName;
out.println(field.generateBuilderInfoCall(package, dartFieldName));
}

if (_descriptor.extensionRange.length > 0) {
Expand Down Expand Up @@ -366,49 +300,29 @@ class MessageGenerator extends ProtobufContainer {
for (ProtobufField field in _fieldList) {
out.println();

// Choose non-conflicting names.
String identifier = field.dartFieldName;
String hasIdentifier = field.hasMethodName;
String clearIdentifier = field.clearMethodName;
if (!field.isRepeated) {
while (_methodNames.contains(identifier) ||
_methodNames.contains(hasIdentifier) ||
_methodNames.contains(clearIdentifier)) {
identifier += '_' + field.number.toString();
hasIdentifier += '_' + field.number.toString();
clearIdentifier += '_' + field.number.toString();
}
_methodNames.add(identifier);
_methodNames.add(hasIdentifier);
_methodNames.add(clearIdentifier);
} else {
while (_methodNames.contains(identifier)) {
identifier += '_' + field.number.toString();
}
_methodNames.add(identifier);
}

var fieldTypeString = field.getDartType(package);
var defaultExpr = field.getDefaultExpr();
out.println('${fieldTypeString} get ${identifier}'
var names = field.memberNames;

out.println('${fieldTypeString} get ${names.fieldName}'
' => \$_get('
'${field.index}, ${field.number}, $defaultExpr);');
if (!field.isRepeated) {
var fastSetter = field.baseType.setter;
if (fastSetter != null) {
out.println('void set $identifier'
out.println('void set ${names.fieldName}'
'($fieldTypeString v) { '
'$fastSetter(${field.index}, ${field.number}, v);'
' }');
} else {
out.println('void set $identifier'
out.println('void set ${names.fieldName}'
'($fieldTypeString v) { '
'setField(${field.number}, v);'
' }');
}
out.println('bool $hasIdentifier() =>'
out.println('bool ${names.hasMethodName}() =>'
' \$_has(${field.index}, ${field.number});');
out.println('void $clearIdentifier() =>'
out.println('void ${names.clearMethodName}() =>'
' clearField(${field.number});');
}
}
Expand Down

0 comments on commit d72f760

Please sign in to comment.