Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
b6b47ed
Added test for WKT-typed custom field options (Duration/Timestamp)
tom-newotny Feb 21, 2026
7b818f4
Fixed WKT custom option codegen and WKT file filtering
tom-newotny Feb 21, 2026
ff73daf
Added test for unquoted hyphenated json_name keys in custom option ou…
tom-newotny Feb 21, 2026
2389631
Quoted custom option property keys containing non-identifier characters
tom-newotny Feb 21, 2026
717dab0
Added test for vertical tab in custom option string escaping
tom-newotny Feb 21, 2026
ee077ad
Added comprehensive JS string escaping for control characters in cust…
tom-newotny Feb 21, 2026
0926a8d
Added test for integer map key ordering in custom options
tom-newotny Feb 21, 2026
2993948
Sorted integer map keys in custom options to match JS Object.keys() o…
tom-newotny Feb 21, 2026
3bc7a12
Added test for single-element repeated field in custom option not wra…
tom-newotny Feb 21, 2026
8107fbd
Wrapped single-element repeated fields in arrays for custom options
tom-newotny Feb 21, 2026
7b3fe62
Added test for U+2028 LINE SEPARATOR escaping in custom option strings
tom-newotny Feb 21, 2026
d684872
Escaped U+2028 and U+2029 in JS string literals
tom-newotny Feb 21, 2026
5b90b7a
Added test for single-element repeated top-level extension not wrappe…
tom-newotny Feb 21, 2026
5ba1673
Wrapped single-element repeated extension fields in arrays
tom-newotny Feb 21, 2026
f56acbb
Updated RALPH.md with repeated extension fix notes
tom-newotny Feb 21, 2026
0d8748c
Added test for unescaped string map keys in custom options
tom-newotny Feb 21, 2026
8c78fe5
Escaped special characters in string map keys for custom options
tom-newotny Feb 21, 2026
3fab7d1
Added test for U+0085 NEXT LINE escaping in custom option strings
tom-newotny Feb 21, 2026
da0e5f4
Fixed C1 control character and BOM escaping in JS string literals
tom-newotny Feb 21, 2026
5362454
Added test for null byte followed by digit escaping in custom option …
tom-newotny Feb 21, 2026
cfa4b0d
Fixed null byte + digit escaping to use \x00 instead of \0
tom-newotny Feb 21, 2026
574b031
Added test for cross-file extension ordering in custom options
tom-newotny Feb 22, 2026
a90b9b5
Fixed custom option ordering to use registry order instead of field n…
tom-newotny Feb 22, 2026
c7707de
Added test for custom option message field declaration order vs field…
tom-newotny Feb 22, 2026
e41bf60
Fixed custom option field order to match message descriptor declarati…
tom-newotny Feb 22, 2026
61fae1f
Added test for DEL character over-escaping in custom option strings
tom-newotny Feb 22, 2026
626da62
Fixed DEL character escaping — C1 range starts at 0x80 not 0x7F
tom-newotny Feb 22, 2026
5aed91a
Added test for uppercase hex digits in unicode escapes
tom-newotny Feb 22, 2026
6ab6684
Updated NELSON notes with BOM/hex casing findings
tom-newotny Feb 22, 2026
0fd53b0
Fixed uppercase hex in Unicode escape sequences for BOM character
tom-newotny Feb 22, 2026
40554f6
Added test for non-ASCII chars unescaped in custom option strings
tom-newotny Feb 22, 2026
09c8bf1
Escaped all non-ASCII characters (>= 0x80) in JS string literals
tom-newotny Feb 22, 2026
3259ef7
Added test for emoji surrogate pair escaping in custom option strings
tom-newotny Feb 22, 2026
def2774
Updated NELSON notes with emoji surrogate pair attack
tom-newotny Feb 22, 2026
d74f31e
Fixed supplementary character escaping to use surrogate pairs instead…
tom-newotny Feb 22, 2026
32e0cbf
Added test for GROUP field options indexing mismatch in proto2
tom-newotny Feb 22, 2026
55e61b3
Replicated protobuf-ts group field custom options index-shift bug
tom-newotny Feb 22, 2026
9a8deb3
Added test for enum alias resolution in custom option values
tom-newotny Feb 22, 2026
5bc71cd
Fixed enum alias resolution to use last value with matching number
tom-newotny Feb 22, 2026
928713d
Updated RALPH.md with enum alias fix notes
tom-newotny Feb 22, 2026
3951983
Added test for proto2 required fields with default values in custom o…
tom-newotny Feb 22, 2026
32db99f
Filtered default values from custom option message fields
tom-newotny Feb 22, 2026
495793f
Added test for proto2 optional fields with default values incorrectly…
tom-newotny Feb 22, 2026
76d490b
Fixed proto2 optional fields keeping default values in custom options
tom-newotny Feb 22, 2026
b2bf99f
Added failing test for NullValue enum in custom option outputting str…
tom-newotny Feb 22, 2026
76baba4
Fixed google.protobuf.NullValue enum rendering as null in custom options
tom-newotny Feb 22, 2026
4c177cb
Updated RALPH.md with NullValue fix notes
tom-newotny Feb 22, 2026
ed43a73
Added test for map int64 jstype=JS_NORMAL propagation to map value
tom-newotny Feb 22, 2026
79dd256
Propagated jstype option from outer map field to value field
tom-newotny Feb 22, 2026
70c6324
Updated RALPH.md with map jstype fix notes
tom-newotny Feb 22, 2026
c30965a
Added test for proto3 oneof default values filtered in custom options
tom-newotny Feb 22, 2026
9ba8940
Fixed proto3 oneof scalar default values kept in custom options
tom-newotny Feb 22, 2026
efef64e
Added test for optional field named constructor crashing TS plugin
tom-newotny Feb 22, 2026
76fa0cc
Handled TS crash tests in test framework — Go succeeding where TS cra…
tom-newotny Feb 22, 2026
7100bf0
Added test for create() property order with colliding localNames
tom-newotny Feb 22, 2026
b3e71f8
Fixed create() property collision ordering to match JS Object.entries…
tom-newotny Feb 22, 2026
eb0ca64
Updated RALPH.md with create property collision fix notes
tom-newotny Feb 22, 2026
7cd24e6
Added test for ts.client service option not excluded from service opt…
tom-newotny Feb 22, 2026
87842fa
Excluded ts.client and ts.server from generated service options
tom-newotny Feb 22, 2026
971489b
Added test for ts.exclude_options file option not filtering custom op…
tom-newotny Feb 22, 2026
740a1de
Implemented ts.exclude_options file option filtering for custom options
tom-newotny Feb 22, 2026
18edfa1
Added test for ts.exclude_options wildcard substring matching
tom-newotny Feb 22, 2026
ceab93d
Fixed ts.exclude_options wildcard to use regex substring matching
tom-newotny Feb 22, 2026
4134c47
Added test for literal exclude_options pattern using exact match not …
tom-newotny Feb 22, 2026
5f90068
Fixed ts.exclude_options literal patterns to use exact match instead …
tom-newotny Feb 22, 2026
875962b
Added test for ts.server service option not excluded by TS plugin
tom-newotny Feb 22, 2026
8972fa9
Implemented gRPC server file generation and fixed ts.server service o…
tom-newotny Feb 22, 2026
04dcd89
Added test for missing GENERIC_SERVER .server.ts file generation
tom-newotny Feb 22, 2026
349c362
Implemented GENERIC_SERVER .server.ts file generation
tom-newotny Feb 22, 2026
cb1dcdb
Added test for GENERIC_SERVER streaming import ordering mismatch
tom-newotny Feb 22, 2026
7f5ff21
Fixed generic server streaming import order to match TS plugin prepen…
tom-newotny Feb 22, 2026
5327923
Added test for generic server streaming import interleave with differ…
tom-newotny Feb 22, 2026
b090a75
Fixed generic server import interleaving to match TS plugin prepend-a…
tom-newotny Feb 22, 2026
92e14bf
Added test for GENERIC_SERVER bidi streaming import order mismatch
tom-newotny Feb 22, 2026
34daf86
Fixed bidi streaming import order in generic server file
tom-newotny Feb 22, 2026
d96b7a4
Added test for ts.client = NO_CLIENT not suppressing client file gene…
tom-newotny Feb 22, 2026
1c4a04f
Added ts.client = NO_CLIENT support to suppress client file generation
tom-newotny Feb 22, 2026
85c9aa0
Added test for GRPC1_CLIENT generating .grpc-client.ts instead of .cl…
tom-newotny Feb 22, 2026
65e5ae5
Implemented gRPC client file generation for GRPC1_CLIENT option
tom-newotny Feb 22, 2026
2012188
Added test for GRPC1_CLIENT server-streaming optional metadata parame…
tom-newotny Feb 22, 2026
70b7388
Fixed gRPC client server streaming method signatures
tom-newotny Feb 22, 2026
3155146
Updated RALPH.md with test 276 fix notes
tom-newotny Feb 22, 2026
c50531d
Added test for GRPC1_CLIENT bidi streaming optional metadata and opti…
tom-newotny Feb 22, 2026
3b7254c
Fixed gRPC client bidi streaming optional metadata and options casting
tom-newotny Feb 22, 2026
2083004
Added test for grpc-server definition name with underscored service name
tom-newotny Feb 22, 2026
e623329
Fixed gRPC server definition name to lowercase first char instead of …
tom-newotny Feb 22, 2026
4f14de2
Added test for GRPC1_CLIENT client-streaming import order mismatch
tom-newotny Feb 22, 2026
9ba9bd8
Fixed gRPC client streaming import order
tom-newotny Feb 22, 2026
1cdcc87
Added test for service deprecation incorrectly propagated to method J…
tom-newotny Feb 22, 2026
69864a2
Fixed gRPC client method deprecation not to cascade from service
tom-newotny Feb 22, 2026
7617022
Added test for service deprecation incorrectly propagated to method J…
tom-newotny Feb 22, 2026
11d7e9f
Fixed generic server method @deprecated not inheriting from service d…
tom-newotny Feb 22, 2026
9d2e703
Added test for grpc-client import ordering with swapped cross-package…
tom-newotny Feb 22, 2026
70c7703
Fixed gRPC client import ordering to use forward+prepend strategy
tom-newotny Feb 22, 2026
c6052f9
Added grpc-server cross-method import ordering test (283)
tom-newotny Feb 22, 2026
d494e67
Fixed gRPC server import ordering to use forward-iterate+prepend stra…
tom-newotny Feb 22, 2026
d66d32b
Added test for cross-package type alias import ordering in main file
tom-newotny Feb 22, 2026
917c2c7
Fixed service-only import ordering when file has messages
tom-newotny Feb 22, 2026
3fbc21b
Added test for .client.ts including GRPC1_CLIENT-only services
tom-newotny Feb 22, 2026
1a6bd74
Filtered non-generic-client services from .client.ts generation
tom-newotny Feb 22, 2026
8004124
Filter non-generic-client services from .client.ts generation and upd…
tom-newotny Feb 22, 2026
fc6464b
Remove status file from protoc-gen-kaja
wham Feb 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 154 additions & 0 deletions protoc-gen-kaja/NELSON.md

Large diffs are not rendered by default.

177 changes: 177 additions & 0 deletions protoc-gen-kaja/RALPH.md

Large diffs are not rendered by default.

2,152 changes: 2,043 additions & 109 deletions protoc-gen-kaja/main.go

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions protoc-gen-kaja/scripts/test
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,16 @@ run_test() {
fi

# If one succeeded and the other failed, it's a failure
# Exception: if protoc-gen-ts crashed (JS stack trace) but protoc-gen-kaja
# succeeded, treat as PASS — Go correctly handles what TS can't.
if [ "$ts_ok" != "$kaja_ok" ]; then
if [ "$ts_ok" = false ] && [ "$kaja_ok" = true ]; then
ts_err=$(cat "$ts_error_file" 2>/dev/null || echo "")
if echo "$ts_err" | grep -q ' at '; then
echo "PASS $ts_elapsed $kaja_elapsed" > "$result_file"
return
fi
fi
echo "FAIL $ts_elapsed $kaja_elapsed" > "$result_file"
if [ "$ts_ok" = true ]; then
{
Expand Down
9 changes: 9 additions & 0 deletions protoc-gen-kaja/tests/239_wkt_custom_option/options.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
syntax = "proto2";
package test;

import "google/protobuf/descriptor.proto";
import "google/protobuf/duration.proto";

extend google.protobuf.FieldOptions {
optional google.protobuf.Duration timeout = 50001;
}
10 changes: 10 additions & 0 deletions protoc-gen-kaja/tests/239_wkt_custom_option/test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
syntax = "proto3";
package test;

import "options.proto";

// Tests that custom field options with WKT message types
// (like google.protobuf.Duration) are correctly emitted.
message TestMsg {
string name = 1 [(timeout) = { seconds: 30 }];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Tests custom message option where nested message has a
// field with json_name containing a hyphen. The property key
// must be quoted in the generated TypeScript.
syntax = "proto3";
package test;

import "google/protobuf/descriptor.proto";

message RuleConfig {
string value = 1 [json_name = "my-value"];
int32 count = 2 [json_name = "item-count"];
}

extend google.protobuf.MessageOptions {
optional RuleConfig rule = 50001;
}

message MyMessage {
option (rule) = { value: "hello", count: 5 };
string name = 1;
}
16 changes: 16 additions & 0 deletions protoc-gen-kaja/tests/241_custom_option_string_vtab/test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Tests that custom string option values containing vertical tab (\v, 0x0B)
// are properly escaped in the generated TypeScript output.
// The TS plugin escapes \v via TypeScript's string literal printer.
// The Go plugin only escapes \, ", \n, \r, \t — missing \v.
syntax = "proto3";
package test;

import "google/protobuf/descriptor.proto";

extend google.protobuf.FieldOptions {
string label = 50001;
}

message TestMsg {
string name = 1 [(label) = "hello\013world"];
}
25 changes: 25 additions & 0 deletions protoc-gen-kaja/tests/242_custom_map_int_key_order/test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Tests that map<int32, string> entries in custom options are ordered by
// ascending numeric key, matching JavaScript's Object.keys() enumeration
// (integer indices come first in numeric order). The Go plugin preserves
// wire order instead of re-sorting, so keys 10,1 stay as {"10","1"}
// while the TS plugin outputs {"1","10"}.
syntax = "proto3";
package test;

import "google/protobuf/descriptor.proto";

message Limits {
map<int32, string> thresholds = 1;
}

extend google.protobuf.MessageOptions {
Limits limits = 50001;
}

message Alert {
option (limits) = {
thresholds: { key: 10, value: "high" }
thresholds: { key: 1, value: "low" }
};
string name = 1;
}
24 changes: 24 additions & 0 deletions protoc-gen-kaja/tests/243_custom_option_repeated_single/test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Tests that a repeated field with a single element in a custom option
// is emitted as an array [42], not a bare scalar 42.
// The TS plugin uses type.toJson() which always produces arrays for
// repeated fields, even with one element. The Go plugin may not wrap
// single repeated values in an array.
syntax = "proto3";
package test;

import "google/protobuf/descriptor.proto";

message Metadata {
repeated string tags = 1;
}

extend google.protobuf.MessageOptions {
Metadata meta = 50001;
}

message Item {
option (meta) = {
tags: "solo"
};
string name = 1;
}
17 changes: 17 additions & 0 deletions protoc-gen-kaja/tests/244_custom_option_string_linesep/test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Tests that U+2028 LINE SEPARATOR in a custom option string value is
// escaped as \u2028. TypeScript's printer escapes U+2028 and U+2029
// because they are not valid unescaped inside JS string literals
// (pre-ES2019). The Go plugin only escapes characters < U+0020,
// so it emits the raw byte sequence instead of \u2028.
syntax = "proto3";
package test;

import "google/protobuf/descriptor.proto";

extend google.protobuf.FieldOptions {
string separator = 50001;
}

message Document {
string content = 1 [(separator) = "line\xe2\x80\xa8sep"];
}
19 changes: 19 additions & 0 deletions protoc-gen-kaja/tests/245_repeated_extension_single/test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Tests that a repeated top-level extension field with a single value
// is emitted as an array ["solo"], not a bare scalar "solo".
// The TS plugin uses type.toJson() which always wraps repeated fields
// in arrays. The Go plugin's parseCustomOptions only wraps repeated
// values when mergeRepeatedOptions finds multiple entries; a single
// repeated entry is left unwrapped.
syntax = "proto3";
package test;

import "google/protobuf/descriptor.proto";

extend google.protobuf.MessageOptions {
repeated string labels = 50001;
}

message Item {
option (labels) = "solo";
string name = 1;
}
25 changes: 25 additions & 0 deletions protoc-gen-kaja/tests/246_custom_map_string_key_escape/test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Tests that map<string, string> keys containing special characters
// (backslash, quotes, newlines) are properly escaped when quoted as
// JS object property keys. The Go plugin wraps keys in quotes via
// needsQuoteAsPropertyKey but does not escape the content, so a key
// like "a\b" becomes "a\b" (backspace escape) instead of "a\\b".
syntax = "proto3";
package test;

import "google/protobuf/descriptor.proto";

message Config {
map<string, string> meta = 1;
}

extend google.protobuf.MessageOptions {
Config cfg = 50001;
}

message Widget {
option (cfg) = {
meta: { key: "back\\slash" value: "val1" }
meta: { key: "has\"quote" value: "val2" }
};
string name = 1;
}
19 changes: 19 additions & 0 deletions protoc-gen-kaja/tests/247_custom_option_string_nextline/test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Tests that U+0085 (NEXT LINE) in a custom option string is escaped as
// \u0085 in the generated TypeScript. The TypeScript compiler's escapeString
// explicitly includes U+0085 in its regex:
// /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g
// The Go plugin's escapeStringForJS only checks r < 0x20, 0x2028, 0x2029,
// missing U+0085 which is 0x85 (above 0x20).
syntax = "proto3";
package test;

import "google/protobuf/descriptor.proto";

extend google.protobuf.MessageOptions {
string note = 50001;
}

message Doc {
option (note) = "line1\302\205line2";
string id = 1;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Tests that null byte (\0) followed by a digit in custom option strings
// is escaped as \x00 (not \0) to avoid ambiguity with octal escape sequences.
// TypeScript's printer uses \x00 when null is followed by 0-9.
// The Go plugin always uses \0, which creates an octal escape when followed by a digit.
syntax = "proto3";
package test;

import "google/protobuf/descriptor.proto";

extend google.protobuf.FieldOptions {
string label = 50001;
}

message TestMsg {
string name = 1 [(label) = "before\0001after"];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Extension with higher field number, in a file sorted first alphabetically.
syntax = "proto2";
package test;

import "google/protobuf/descriptor.proto";

extend google.protobuf.FieldOptions {
optional string alpha_tag = 50002;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Extension with lower field number, in a file sorted second alphabetically.
syntax = "proto2";
package test;

import "google/protobuf/descriptor.proto";

extend google.protobuf.FieldOptions {
optional string beta_tag = 50001;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Tests ordering of custom options from different files.
// a_options.proto defines alpha_tag at field 50002.
// b_options.proto defines beta_tag at field 50001.
//
// The TS plugin builds a synthetic type with extensions in registry
// order (= file processing order). Since a_options.proto is imported
// first, alpha_tag (50002) appears before beta_tag (50001) in the
// field list and therefore in the toJson() output.
//
// The Go plugin reads the binary data in wire order (field-number
// order), so beta_tag (50001) comes before alpha_tag (50002).
syntax = "proto3";
package test;

import "a_options.proto";
import "b_options.proto";

message TestMsg {
string name = 1 [(alpha_tag) = "aaa", (beta_tag) = "bbb"];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
syntax = "proto3";

package fieldorder;

import "google/protobuf/descriptor.proto";

// Message with fields declared in REVERSE field-number order.
// protoc serializes by field number (alpha=1 first, beta=2 second),
// but the TS plugin emits JSON keys in declaration order (beta first, alpha second).
message StyleOption {
string beta = 2;
string alpha = 1;
}

extend google.protobuf.FieldOptions {
StyleOption style = 50001;
}

message StyledMessage {
string value = 1 [(style) = { beta: "round", alpha: "bold" }];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
syntax = "proto2";
package test;

import "google/protobuf/descriptor.proto";

extend google.protobuf.FieldOptions {
optional string annotation = 50001;
}
11 changes: 11 additions & 0 deletions protoc-gen-kaja/tests/251_custom_option_string_del/test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
syntax = "proto3";
package test;

import "options.proto";

// Tests that the DEL character (U+007F) in a custom option string
// is NOT escaped — the TS compiler's escapeString only covers U+0000-U+001F,
// not DEL. The Go plugin incorrectly escapes it as \u007f.
message TestMsg {
string name = 1 [(annotation) = "hello\x7fworld"];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
syntax = "proto2";
package test;

import "google/protobuf/descriptor.proto";

extend google.protobuf.FieldOptions {
optional string annotation = 50001;
}
11 changes: 11 additions & 0 deletions protoc-gen-kaja/tests/252_custom_option_string_bom/test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
syntax = "proto3";
package test;

import "options.proto";

// Tests that U+FEFF (BOM) in a custom option string is escaped with
// UPPERCASE hex digits. The TS compiler emits \uFEFF but the Go plugin
// emits \ufeff because it uses fmt %04x (lowercase) instead of %04X.
message TestMsg {
string name = 1 [(annotation) = "hello\xEF\xBB\xBFworld"];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
syntax = "proto2";
package test;

import "google/protobuf/descriptor.proto";

extend google.protobuf.FieldOptions {
optional string label = 50001;
}
10 changes: 10 additions & 0 deletions protoc-gen-kaja/tests/253_custom_option_string_nonascii/test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
syntax = "proto3";
package test;

import "options.proto";

// Tests that non-ASCII characters in custom option string values
// are escaped as \uXXXX (matching TypeScript printer's escapeNonAsciiString).
message TestMsg {
string name = 1 [(label) = "café"];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
syntax = "proto2";
package test;

import "google/protobuf/descriptor.proto";

extend google.protobuf.FieldOptions {
optional string emoji_label = 50001;
}
11 changes: 11 additions & 0 deletions protoc-gen-kaja/tests/254_custom_option_string_emoji/test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
syntax = "proto3";
package test;

import "options.proto";

// Tests that supplementary plane characters (above U+FFFF) in custom option
// strings are escaped as surrogate pairs (\uD83C\uDF89) matching the TS
// compiler, not as ES2015 \u{1F389} which the Go plugin produces.
message TestMsg {
string name = 1 [(emoji_label) = "🎉"];
}
16 changes: 16 additions & 0 deletions protoc-gen-kaja/tests/255_group_field_options/test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
syntax = "proto2";
package test;

import "google/protobuf/descriptor.proto";

extend google.protobuf.FieldOptions {
optional int32 my_tag = 50000;
}

message Foo {
optional int32 before = 1 [(my_tag) = 111];
optional group MyGroup = 2 {
optional int32 inner = 3;
}
optional int32 after = 4 [(my_tag) = 444];
}
Loading