From f265ab9180915694d17c94556a9baac55f54c288 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Wed, 8 May 2024 13:18:23 -0700 Subject: [PATCH] Add handling for extension range options --- src/parse.js | 19 ++++++- tests/data/google/protobuf/descriptor.proto | 61 ++++++++++++++++++++- tests/data/uncommon.proto | 7 +++ 3 files changed, 85 insertions(+), 2 deletions(-) diff --git a/src/parse.js b/src/parse.js index 739f3265e..ebc464a64 100644 --- a/src/parse.js +++ b/src/parse.js @@ -144,7 +144,24 @@ function parse(source, root, options) { else target.push([ start = parseId(next()), skip("to", true) ? parseId(next()) : start ]); } while (skip(",", true)); - skip(";"); + var dummy = {options: undefined}; + dummy.setOption = function(name, value) { + if (this.options === undefined) this.options = {}; + this.options[name] = value; + }; + ifBlock( + dummy, + function parseRange_block(token) { + /* istanbul ignore else */ + if (token === 'option') { + parseOption(dummy, token); // skip + skip(';'); + } else + throw illegal(token); + }, + function parseRange_line() { + parseInlineOptions(dummy); // skip + }); } function parseNumber(token, insideTryCatch) { diff --git a/tests/data/google/protobuf/descriptor.proto b/tests/data/google/protobuf/descriptor.proto index 747d90cfc..561d9629e 100644 --- a/tests/data/google/protobuf/descriptor.proto +++ b/tests/data/google/protobuf/descriptor.proto @@ -101,6 +101,8 @@ message DescriptorProto { message ExtensionRange { optional int32 start = 1; optional int32 end = 2; + + optional ExtensionRangeOptions options = 3; } repeated ExtensionRange extension_range = 5; @@ -121,6 +123,63 @@ message DescriptorProto { repeated string reserved_name = 10; } + +message ExtensionRangeOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + message Declaration { + // The extension number declared within the extension range. + optional int32 number = 1; + + // The fully-qualified name of the extension field. There must be a leading + // dot in front of the full name. + optional string full_name = 2; + + // The fully-qualified type name of the extension field. Unlike + // Metadata.type, Declaration.type must have a leading dot for messages + // and enums. + optional string type = 3; + + // If true, indicates that the number is reserved in the extension range, + // and any extension field with the number will fail to compile. Set this + // when a declared extension field is deleted. + optional bool reserved = 5; + + // If true, indicates that the extension must be defined as repeated. + // Otherwise the extension must be defined as optional. + optional bool repeated = 6; + + reserved 4; // removed is_repeated + } + + // For external users: DO NOT USE. We are in the process of open sourcing + // extension declaration and executing internal cleanups before it can be + // used externally. + repeated Declaration declaration = 2 [retention = RETENTION_SOURCE]; + + // The verification state of the extension range. + enum VerificationState { + // All the extensions of the range must be declared. + DECLARATION = 0; + UNVERIFIED = 1; + } + + // The verification state of the range. + // TODO(b/278783756): flip the default to DECLARATION once all empty ranges + // are marked as UNVERIFIED. + optional VerificationState verification = 3 + [default = UNVERIFIED, retention = RETENTION_SOURCE]; + + // Clients can define custom options in extensions of this message. See above. + // BEGIN GOOGLE-INTERNAL + // Extension numbers > 530,000,000 must be forward-declared in + // google3/third_party/protobuf/extdecl_extension_range_options.h. See + // go/extension-declaration-reserved-numbers for more information. + // END GOOGLE-INTERNAL + extensions 1000 to max; +} + // Describes a field within a message. message FieldDescriptorProto { enum Type { @@ -813,4 +872,4 @@ message GeneratedCodeInfo { // the last relevant byte (so the length of the text = end - begin). optional int32 end = 4; } -} \ No newline at end of file +} diff --git a/tests/data/uncommon.proto b/tests/data/uncommon.proto index fa9fa037f..1bb9a3d85 100644 --- a/tests/data/uncommon.proto +++ b/tests/data/uncommon.proto @@ -47,6 +47,13 @@ message Test2 { extend Test; extend Test{}; extend Test{required int32 a=1;} // not validated by the parser + extend Test{Test a=1000;} // not validated by the parser + + extensions 1000 to 1999 [declaration = { + number: 1000 + full_name: 'uncommon.Test.a' + type: 'uncommon.Test' + }] }; enum Test3;