From 4018fa893eafb5832cb24f2a6fc58984b0550f68 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Wed, 12 Jul 2023 15:00:31 -0700 Subject: [PATCH 1/6] Add a `raw_features` field to FeatureSet. This will be used for tracking the unresolved feature sets from the original proto file. Notable use-cases for this include: * Code generators that need to validate their own features * Runtimes that need to be able to accurately round-trip the original protos PiperOrigin-RevId: 547610367 --- php/ext/google/protobuf/php-upb.c | 167 +++++++++++------- php/ext/google/protobuf/php-upb.h | 75 +++++--- ruby/ext/google/protobuf_c/ruby-upb.c | 54 +++++- ruby/ext/google/protobuf_c/ruby-upb.h | 75 +++++--- src/google/protobuf/descriptor.pb.cc | 218 +++++++++++++++--------- src/google/protobuf/descriptor.pb.h | 151 +++++++++++++--- src/google/protobuf/descriptor.proto | 2 + src/google/protobuf/feature_resolver.cc | 10 ++ 8 files changed, 528 insertions(+), 224 deletions(-) diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index ca504b2986..8300206a86 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -737,7 +737,7 @@ bool _upb_mapsorter_pushexts(_upb_mapsorter* s, * regenerated. */ -static const char descriptor[10909] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', +static const char descriptor[10979] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', 'M', '\n', '\021', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'S', 'e', 't', '\022', '8', '\n', '\004', 'f', 'i', 'l', 'e', '\030', '\001', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', @@ -1093,7 +1093,7 @@ static const char descriptor[10909] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', 'e', '\032', 'J', '\n', '\010', 'N', 'a', 'm', 'e', 'P', 'a', 'r', 't', '\022', '\033', '\n', '\t', 'n', 'a', 'm', 'e', '_', 'p', 'a', 'r', 't', '\030', '\001', ' ', '\002', '(', '\t', 'R', '\010', 'n', 'a', 'm', 'e', 'P', 'a', 'r', 't', '\022', '!', '\n', '\014', 'i', 's', '_', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\002', ' ', '\002', '(', '\010', 'R', '\013', 'i', 's', 'E', 'x', 't', 'e', 'n', 's', 'i', -'o', 'n', '\"', '\327', '\t', '\n', '\n', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', '\022', 'n', '\n', '\016', 'f', 'i', 'e', 'l', +'o', 'n', '\"', '\235', '\n', '\n', '\n', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', '\022', 'n', '\n', '\016', 'f', 'i', 'e', 'l', 'd', '_', 'p', 'r', 'e', 's', 'e', 'n', 'c', 'e', '\030', '\001', ' ', '\001', '(', '\016', '2', ')', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', '.', 'F', 'i', 'e', 'l', 'd', 'P', 'r', 'e', 's', 'e', 'n', 'c', 'e', 'B', '\034', '\210', '\001', '\001', '\230', '\001', '\004', '\230', '\001', '\001', '\242', '\001', '\020', '\n', '\004', @@ -1122,58 +1122,61 @@ static const char descriptor[10909] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', '.', 'J', 's', 'o', 'n', 'F', 'o', 'r', 'm', 'a', 't', 'B', '\034', '\210', '\001', '\001', '\230', '\001', '\003', '\230', '\001', '\006', '\230', '\001', '\001', '\242', '\001', '\r', '\n', '\004', '2', '0', '2', '3', '\022', '\005', 'A', 'L', 'L', 'O', 'W', 'R', '\n', 'j', 's', 'o', 'n', 'F', 'o', 'r', 'm', 'a', 't', -'\"', '\\', '\n', '\r', 'F', 'i', 'e', 'l', 'd', 'P', 'r', 'e', 's', 'e', 'n', 'c', 'e', '\022', '\032', '\n', '\026', 'F', 'I', 'E', 'L', -'D', '_', 'P', 'R', 'E', 'S', 'E', 'N', 'C', 'E', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\014', '\n', '\010', 'E', -'X', 'P', 'L', 'I', 'C', 'I', 'T', '\020', '\001', '\022', '\014', '\n', '\010', 'I', 'M', 'P', 'L', 'I', 'C', 'I', 'T', '\020', '\002', '\022', '\023', -'\n', '\017', 'L', 'E', 'G', 'A', 'C', 'Y', '_', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D', '\020', '\003', '\"', '7', '\n', '\010', 'E', 'n', -'u', 'm', 'T', 'y', 'p', 'e', '\022', '\025', '\n', '\021', 'E', 'N', 'U', 'M', '_', 'T', 'Y', 'P', 'E', '_', 'U', 'N', 'K', 'N', 'O', -'W', 'N', '\020', '\000', '\022', '\010', '\n', '\004', 'O', 'P', 'E', 'N', '\020', '\001', '\022', '\n', '\n', '\006', 'C', 'L', 'O', 'S', 'E', 'D', '\020', -'\002', '\"', 'V', '\n', '\025', 'R', 'e', 'p', 'e', 'a', 't', 'e', 'd', 'F', 'i', 'e', 'l', 'd', 'E', 'n', 'c', 'o', 'd', 'i', 'n', -'g', '\022', '#', '\n', '\037', 'R', 'E', 'P', 'E', 'A', 'T', 'E', 'D', '_', 'F', 'I', 'E', 'L', 'D', '_', 'E', 'N', 'C', 'O', 'D', -'I', 'N', 'G', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\n', '\n', '\006', 'P', 'A', 'C', 'K', 'E', 'D', '\020', '\001', -'\022', '\014', '\n', '\010', 'E', 'X', 'P', 'A', 'N', 'D', 'E', 'D', '\020', '\002', '\"', '_', '\n', '\025', 'S', 't', 'r', 'i', 'n', 'g', 'F', -'i', 'e', 'l', 'd', 'V', 'a', 'l', 'i', 'd', 'a', 't', 'i', 'o', 'n', '\022', '#', '\n', '\037', 'S', 'T', 'R', 'I', 'N', 'G', '_', -'F', 'I', 'E', 'L', 'D', '_', 'V', 'A', 'L', 'I', 'D', 'A', 'T', 'I', 'O', 'N', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', -'\000', '\022', '\r', '\n', '\t', 'M', 'A', 'N', 'D', 'A', 'T', 'O', 'R', 'Y', '\020', '\001', '\022', '\010', '\n', '\004', 'H', 'I', 'N', 'T', '\020', -'\002', '\022', '\010', '\n', '\004', 'N', 'O', 'N', 'E', '\020', '\003', '\"', 'S', '\n', '\017', 'M', 'e', 's', 's', 'a', 'g', 'e', 'E', 'n', 'c', -'o', 'd', 'i', 'n', 'g', '\022', '\034', '\n', '\030', 'M', 'E', 'S', 'S', 'A', 'G', 'E', '_', 'E', 'N', 'C', 'O', 'D', 'I', 'N', 'G', -'_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\023', '\n', '\017', 'L', 'E', 'N', 'G', 'T', 'H', '_', 'P', 'R', 'E', 'F', -'I', 'X', 'E', 'D', '\020', '\001', '\022', '\r', '\n', '\t', 'D', 'E', 'L', 'I', 'M', 'I', 'T', 'E', 'D', '\020', '\002', '\"', 'H', '\n', '\n', -'J', 's', 'o', 'n', 'F', 'o', 'r', 'm', 'a', 't', '\022', '\027', '\n', '\023', 'J', 'S', 'O', 'N', '_', 'F', 'O', 'R', 'M', 'A', 'T', -'_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\t', '\n', '\005', 'A', 'L', 'L', 'O', 'W', '\020', '\001', '\022', '\026', '\n', '\022', -'L', 'E', 'G', 'A', 'C', 'Y', '_', 'B', 'E', 'S', 'T', '_', 'E', 'F', 'F', 'O', 'R', 'T', '\020', '\002', '*', '\006', '\010', '\350', '\007', -'\020', '\351', '\007', '*', '\006', '\010', '\351', '\007', '\020', '\352', '\007', '*', '\006', '\010', '\213', 'N', '\020', '\220', 'N', '\"', '\247', '\002', '\n', '\016', 'S', -'o', 'u', 'r', 'c', 'e', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'D', '\n', '\010', 'l', 'o', 'c', 'a', 't', 'i', 'o', 'n', -'\030', '\001', ' ', '\003', '(', '\013', '2', '(', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', -'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'L', 'o', 'c', 'a', 't', 'i', 'o', 'n', 'R', '\010', -'l', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\032', '\316', '\001', '\n', '\010', 'L', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\022', '\026', '\n', '\004', -'p', 'a', 't', 'h', '\030', '\001', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', 't', 'h', '\022', '\026', '\n', '\004', 's', -'p', 'a', 'n', '\030', '\002', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 's', 'p', 'a', 'n', '\022', ')', '\n', '\020', 'l', 'e', -'a', 'd', 'i', 'n', 'g', '_', 'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\017', 'l', 'e', 'a', -'d', 'i', 'n', 'g', 'C', 'o', 'm', 'm', 'e', 'n', 't', 's', '\022', '+', '\n', '\021', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', '_', -'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\004', ' ', '\001', '(', '\t', 'R', '\020', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', 'C', -'o', 'm', 'm', 'e', 'n', 't', 's', '\022', ':', '\n', '\031', 'l', 'e', 'a', 'd', 'i', 'n', 'g', '_', 'd', 'e', 't', 'a', 'c', 'h', -'e', 'd', '_', 'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\006', ' ', '\003', '(', '\t', 'R', '\027', 'l', 'e', 'a', 'd', 'i', 'n', -'g', 'D', 'e', 't', 'a', 'c', 'h', 'e', 'd', 'C', 'o', 'm', 'm', 'e', 'n', 't', 's', '\"', '\320', '\002', '\n', '\021', 'G', 'e', 'n', -'e', 'r', 'a', 't', 'e', 'd', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'M', '\n', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', -'i', 'o', 'n', '\030', '\001', ' ', '\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', -'u', 'f', '.', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'A', 'n', 'n', 'o', -'t', 'a', 't', 'i', 'o', 'n', 'R', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\032', '\353', '\001', '\n', '\n', 'A', 'n', -'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', '\030', '\001', ' ', '\003', '(', '\005', 'B', '\002', '\020', -'\001', 'R', '\004', 'p', 'a', 't', 'h', '\022', '\037', '\n', '\013', 's', 'o', 'u', 'r', 'c', 'e', '_', 'f', 'i', 'l', 'e', '\030', '\002', ' ', -'\001', '(', '\t', 'R', '\n', 's', 'o', 'u', 'r', 'c', 'e', 'F', 'i', 'l', 'e', '\022', '\024', '\n', '\005', 'b', 'e', 'g', 'i', 'n', '\030', -'\003', ' ', '\001', '(', '\005', 'R', '\005', 'b', 'e', 'g', 'i', 'n', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\004', ' ', '\001', '(', '\005', -'R', '\003', 'e', 'n', 'd', '\022', 'R', '\n', '\010', 's', 'e', 'm', 'a', 'n', 't', 'i', 'c', '\030', '\005', ' ', '\001', '(', '\016', '2', '6', -'.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', -'d', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '.', 'S', 'e', 'm', 'a', -'n', 't', 'i', 'c', 'R', '\010', 's', 'e', 'm', 'a', 'n', 't', 'i', 'c', '\"', '(', '\n', '\010', 'S', 'e', 'm', 'a', 'n', 't', 'i', -'c', '\022', '\010', '\n', '\004', 'N', 'O', 'N', 'E', '\020', '\000', '\022', '\007', '\n', '\003', 'S', 'E', 'T', '\020', '\001', '\022', '\t', '\n', '\005', 'A', -'L', 'I', 'A', 'S', '\020', '\002', 'B', '~', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', -'o', 'b', 'u', 'f', 'B', '\020', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 's', 'H', '\001', 'Z', -'-', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', -'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'p', 'b', '\370', '\001', '\001', '\242', -'\002', '\003', 'G', 'P', 'B', '\252', '\002', '\032', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'R', -'e', 'f', 'l', 'e', 'c', 't', 'i', 'o', 'n', +'\022', 'D', '\n', '\014', 'r', 'a', 'w', '_', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\030', '\347', '\007', ' ', '\001', '(', '\013', '2', '\033', +'.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', +'e', 't', 'B', '\003', '\230', '\001', '\000', 'R', '\013', 'r', 'a', 'w', 'F', 'e', 'a', 't', 'u', 'r', 'e', 's', '\"', '\\', '\n', '\r', 'F', +'i', 'e', 'l', 'd', 'P', 'r', 'e', 's', 'e', 'n', 'c', 'e', '\022', '\032', '\n', '\026', 'F', 'I', 'E', 'L', 'D', '_', 'P', 'R', 'E', +'S', 'E', 'N', 'C', 'E', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\014', '\n', '\010', 'E', 'X', 'P', 'L', 'I', 'C', +'I', 'T', '\020', '\001', '\022', '\014', '\n', '\010', 'I', 'M', 'P', 'L', 'I', 'C', 'I', 'T', '\020', '\002', '\022', '\023', '\n', '\017', 'L', 'E', 'G', +'A', 'C', 'Y', '_', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D', '\020', '\003', '\"', '7', '\n', '\010', 'E', 'n', 'u', 'm', 'T', 'y', 'p', +'e', '\022', '\025', '\n', '\021', 'E', 'N', 'U', 'M', '_', 'T', 'Y', 'P', 'E', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', +'\010', '\n', '\004', 'O', 'P', 'E', 'N', '\020', '\001', '\022', '\n', '\n', '\006', 'C', 'L', 'O', 'S', 'E', 'D', '\020', '\002', '\"', 'V', '\n', '\025', +'R', 'e', 'p', 'e', 'a', 't', 'e', 'd', 'F', 'i', 'e', 'l', 'd', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', '\022', '#', '\n', '\037', +'R', 'E', 'P', 'E', 'A', 'T', 'E', 'D', '_', 'F', 'I', 'E', 'L', 'D', '_', 'E', 'N', 'C', 'O', 'D', 'I', 'N', 'G', '_', 'U', +'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\n', '\n', '\006', 'P', 'A', 'C', 'K', 'E', 'D', '\020', '\001', '\022', '\014', '\n', '\010', 'E', +'X', 'P', 'A', 'N', 'D', 'E', 'D', '\020', '\002', '\"', '_', '\n', '\025', 'S', 't', 'r', 'i', 'n', 'g', 'F', 'i', 'e', 'l', 'd', 'V', +'a', 'l', 'i', 'd', 'a', 't', 'i', 'o', 'n', '\022', '#', '\n', '\037', 'S', 'T', 'R', 'I', 'N', 'G', '_', 'F', 'I', 'E', 'L', 'D', +'_', 'V', 'A', 'L', 'I', 'D', 'A', 'T', 'I', 'O', 'N', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\r', '\n', '\t', +'M', 'A', 'N', 'D', 'A', 'T', 'O', 'R', 'Y', '\020', '\001', '\022', '\010', '\n', '\004', 'H', 'I', 'N', 'T', '\020', '\002', '\022', '\010', '\n', '\004', +'N', 'O', 'N', 'E', '\020', '\003', '\"', 'S', '\n', '\017', 'M', 'e', 's', 's', 'a', 'g', 'e', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', +'\022', '\034', '\n', '\030', 'M', 'E', 'S', 'S', 'A', 'G', 'E', '_', 'E', 'N', 'C', 'O', 'D', 'I', 'N', 'G', '_', 'U', 'N', 'K', 'N', +'O', 'W', 'N', '\020', '\000', '\022', '\023', '\n', '\017', 'L', 'E', 'N', 'G', 'T', 'H', '_', 'P', 'R', 'E', 'F', 'I', 'X', 'E', 'D', '\020', +'\001', '\022', '\r', '\n', '\t', 'D', 'E', 'L', 'I', 'M', 'I', 'T', 'E', 'D', '\020', '\002', '\"', 'H', '\n', '\n', 'J', 's', 'o', 'n', 'F', +'o', 'r', 'm', 'a', 't', '\022', '\027', '\n', '\023', 'J', 'S', 'O', 'N', '_', 'F', 'O', 'R', 'M', 'A', 'T', '_', 'U', 'N', 'K', 'N', +'O', 'W', 'N', '\020', '\000', '\022', '\t', '\n', '\005', 'A', 'L', 'L', 'O', 'W', '\020', '\001', '\022', '\026', '\n', '\022', 'L', 'E', 'G', 'A', 'C', +'Y', '_', 'B', 'E', 'S', 'T', '_', 'E', 'F', 'F', 'O', 'R', 'T', '\020', '\002', '*', '\006', '\010', '\350', '\007', '\020', '\351', '\007', '*', '\006', +'\010', '\351', '\007', '\020', '\352', '\007', '*', '\006', '\010', '\213', 'N', '\020', '\220', 'N', '\"', '\247', '\002', '\n', '\016', 'S', 'o', 'u', 'r', 'c', 'e', +'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'D', '\n', '\010', 'l', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\030', '\001', ' ', '\003', '(', +'\013', '2', '(', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'o', 'u', 'r', 'c', +'e', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'L', 'o', 'c', 'a', 't', 'i', 'o', 'n', 'R', '\010', 'l', 'o', 'c', 'a', 't', +'i', 'o', 'n', '\032', '\316', '\001', '\n', '\010', 'L', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', '\030', +'\001', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', 't', 'h', '\022', '\026', '\n', '\004', 's', 'p', 'a', 'n', '\030', '\002', +' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 's', 'p', 'a', 'n', '\022', ')', '\n', '\020', 'l', 'e', 'a', 'd', 'i', 'n', 'g', +'_', 'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\017', 'l', 'e', 'a', 'd', 'i', 'n', 'g', 'C', +'o', 'm', 'm', 'e', 'n', 't', 's', '\022', '+', '\n', '\021', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', '_', 'c', 'o', 'm', 'm', 'e', +'n', 't', 's', '\030', '\004', ' ', '\001', '(', '\t', 'R', '\020', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', 'C', 'o', 'm', 'm', 'e', 'n', +'t', 's', '\022', ':', '\n', '\031', 'l', 'e', 'a', 'd', 'i', 'n', 'g', '_', 'd', 'e', 't', 'a', 'c', 'h', 'e', 'd', '_', 'c', 'o', +'m', 'm', 'e', 'n', 't', 's', '\030', '\006', ' ', '\003', '(', '\t', 'R', '\027', 'l', 'e', 'a', 'd', 'i', 'n', 'g', 'D', 'e', 't', 'a', +'c', 'h', 'e', 'd', 'C', 'o', 'm', 'm', 'e', 'n', 't', 's', '\"', '\320', '\002', '\n', '\021', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', +'d', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'M', '\n', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\030', '\001', +' ', '\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'G', 'e', +'n', 'e', 'r', 'a', 't', 'e', 'd', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', +'n', 'R', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\032', '\353', '\001', '\n', '\n', 'A', 'n', 'n', 'o', 't', 'a', 't', +'i', 'o', 'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', '\030', '\001', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', +'t', 'h', '\022', '\037', '\n', '\013', 's', 'o', 'u', 'r', 'c', 'e', '_', 'f', 'i', 'l', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\n', +'s', 'o', 'u', 'r', 'c', 'e', 'F', 'i', 'l', 'e', '\022', '\024', '\n', '\005', 'b', 'e', 'g', 'i', 'n', '\030', '\003', ' ', '\001', '(', '\005', +'R', '\005', 'b', 'e', 'g', 'i', 'n', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\004', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', +'\022', 'R', '\n', '\010', 's', 'e', 'm', 'a', 'n', 't', 'i', 'c', '\030', '\005', ' ', '\001', '(', '\016', '2', '6', '.', 'g', 'o', 'o', 'g', +'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', 'C', 'o', 'd', 'e', +'I', 'n', 'f', 'o', '.', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '.', 'S', 'e', 'm', 'a', 'n', 't', 'i', 'c', 'R', +'\010', 's', 'e', 'm', 'a', 'n', 't', 'i', 'c', '\"', '(', '\n', '\010', 'S', 'e', 'm', 'a', 'n', 't', 'i', 'c', '\022', '\010', '\n', '\004', +'N', 'O', 'N', 'E', '\020', '\000', '\022', '\007', '\n', '\003', 'S', 'E', 'T', '\020', '\001', '\022', '\t', '\n', '\005', 'A', 'L', 'I', 'A', 'S', '\020', +'\002', 'B', '~', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', +'\020', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 's', 'H', '\001', 'Z', '-', 'g', 'o', 'o', 'g', +'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', +'p', 'e', 's', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', +'\252', '\002', '\032', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'R', 'e', 'f', 'l', 'e', 'c', +'t', 'i', 'o', 'n', }; static _upb_DefPool_Init *deps[1] = { @@ -1184,7 +1187,7 @@ _upb_DefPool_Init google_protobuf_descriptor_proto_upbdefinit = { deps, &google_protobuf_descriptor_proto_upb_file_layout, "google/protobuf/descriptor.proto", - UPB_STRINGVIEW_INIT(descriptor, 10909) + UPB_STRINGVIEW_INIT(descriptor, 10979) }; /* This file was generated by upbc (the upb compiler) from the input * file: @@ -2155,7 +2158,8 @@ const upb_MiniTable google_protobuf_UninterpretedOption_NamePart_msg_init = { }) }; -static const upb_MiniTableSub google_protobuf_FeatureSet_submsgs[6] = { +static const upb_MiniTableSub google_protobuf_FeatureSet_submsgs[7] = { + {.submsg = &google_protobuf_FeatureSet_msg_init}, {.subenum = &google_protobuf_FeatureSet_FieldPresence_enum_init}, {.subenum = &google_protobuf_FeatureSet_EnumType_enum_init}, {.subenum = &google_protobuf_FeatureSet_RepeatedFieldEncoding_enum_init}, @@ -2164,19 +2168,54 @@ static const upb_MiniTableSub google_protobuf_FeatureSet_submsgs[6] = { {.subenum = &google_protobuf_FeatureSet_JsonFormat_enum_init}, }; -static const upb_MiniTableField google_protobuf_FeatureSet__fields[6] = { - {1, 4, 1, 0, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, - {2, 8, 2, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, - {3, 12, 3, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, - {4, 16, 4, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, - {5, 20, 5, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, - {6, 24, 6, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, +static const upb_MiniTableField google_protobuf_FeatureSet__fields[7] = { + {1, 4, 1, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, 8, 2, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {3, 12, 3, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {4, 16, 4, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {5, 20, 5, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {6, 24, 6, 6, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(28, 32), 7, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, }; const upb_MiniTable google_protobuf_FeatureSet_msg_init = { &google_protobuf_FeatureSet_submsgs[0], &google_protobuf_FeatureSet__fields[0], - 32, 6, kUpb_ExtMode_Extendable, 6, UPB_FASTTABLE_MASK(255), 0, + UPB_SIZE(32, 40), 7, kUpb_ExtMode_Extendable, 6, UPB_FASTTABLE_MASK(248), 0, + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0020000007003eba, &upb_psm_2bt_max64b}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) }; static const upb_MiniTableSub google_protobuf_SourceCodeInfo_submsgs[1] = { diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h index c888cf9aa1..a434506417 100644 --- a/php/ext/google/protobuf/php-upb.h +++ b/php/ext/google/protobuf/php-upb.h @@ -9164,120 +9164,147 @@ UPB_INLINE char* google_protobuf_FeatureSet_serialize_ex(const google_protobuf_F return ptr; } UPB_INLINE void google_protobuf_FeatureSet_clear_field_presence(google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {1, 4, 1, 0, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {1, 4, 1, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_ClearNonExtensionField(msg, &field); } UPB_INLINE int32_t google_protobuf_FeatureSet_field_presence(const google_protobuf_FeatureSet* msg) { int32_t default_val = 0; int32_t ret; - const upb_MiniTableField field = {1, 4, 1, 0, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {1, 4, 1, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); return ret; } UPB_INLINE bool google_protobuf_FeatureSet_has_field_presence(const google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {1, 4, 1, 0, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {1, 4, 1, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; return _upb_Message_HasNonExtensionField(msg, &field); } UPB_INLINE void google_protobuf_FeatureSet_clear_enum_type(google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {2, 8, 2, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {2, 8, 2, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_ClearNonExtensionField(msg, &field); } UPB_INLINE int32_t google_protobuf_FeatureSet_enum_type(const google_protobuf_FeatureSet* msg) { int32_t default_val = 0; int32_t ret; - const upb_MiniTableField field = {2, 8, 2, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {2, 8, 2, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); return ret; } UPB_INLINE bool google_protobuf_FeatureSet_has_enum_type(const google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {2, 8, 2, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {2, 8, 2, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; return _upb_Message_HasNonExtensionField(msg, &field); } UPB_INLINE void google_protobuf_FeatureSet_clear_repeated_field_encoding(google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {3, 12, 3, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {3, 12, 3, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_ClearNonExtensionField(msg, &field); } UPB_INLINE int32_t google_protobuf_FeatureSet_repeated_field_encoding(const google_protobuf_FeatureSet* msg) { int32_t default_val = 0; int32_t ret; - const upb_MiniTableField field = {3, 12, 3, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {3, 12, 3, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); return ret; } UPB_INLINE bool google_protobuf_FeatureSet_has_repeated_field_encoding(const google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {3, 12, 3, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {3, 12, 3, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; return _upb_Message_HasNonExtensionField(msg, &field); } UPB_INLINE void google_protobuf_FeatureSet_clear_string_field_validation(google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {4, 16, 4, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {4, 16, 4, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_ClearNonExtensionField(msg, &field); } UPB_INLINE int32_t google_protobuf_FeatureSet_string_field_validation(const google_protobuf_FeatureSet* msg) { int32_t default_val = 0; int32_t ret; - const upb_MiniTableField field = {4, 16, 4, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {4, 16, 4, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); return ret; } UPB_INLINE bool google_protobuf_FeatureSet_has_string_field_validation(const google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {4, 16, 4, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {4, 16, 4, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; return _upb_Message_HasNonExtensionField(msg, &field); } UPB_INLINE void google_protobuf_FeatureSet_clear_message_encoding(google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {5, 20, 5, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {5, 20, 5, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_ClearNonExtensionField(msg, &field); } UPB_INLINE int32_t google_protobuf_FeatureSet_message_encoding(const google_protobuf_FeatureSet* msg) { int32_t default_val = 0; int32_t ret; - const upb_MiniTableField field = {5, 20, 5, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {5, 20, 5, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); return ret; } UPB_INLINE bool google_protobuf_FeatureSet_has_message_encoding(const google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {5, 20, 5, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {5, 20, 5, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; return _upb_Message_HasNonExtensionField(msg, &field); } UPB_INLINE void google_protobuf_FeatureSet_clear_json_format(google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {6, 24, 6, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {6, 24, 6, 6, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_ClearNonExtensionField(msg, &field); } UPB_INLINE int32_t google_protobuf_FeatureSet_json_format(const google_protobuf_FeatureSet* msg) { int32_t default_val = 0; int32_t ret; - const upb_MiniTableField field = {6, 24, 6, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {6, 24, 6, 6, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); return ret; } UPB_INLINE bool google_protobuf_FeatureSet_has_json_format(const google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {6, 24, 6, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {6, 24, 6, 6, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} +UPB_INLINE void google_protobuf_FeatureSet_clear_raw_features(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(28, 32), 7, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_FeatureSet_raw_features(const google_protobuf_FeatureSet* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {999, UPB_SIZE(28, 32), 7, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_raw_features(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(28, 32), 7, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; return _upb_Message_HasNonExtensionField(msg, &field); } UPB_INLINE void google_protobuf_FeatureSet_set_field_presence(google_protobuf_FeatureSet *msg, int32_t value) { - const upb_MiniTableField field = {1, 4, 1, 0, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {1, 4, 1, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_SetNonExtensionField(msg, &field, &value); } UPB_INLINE void google_protobuf_FeatureSet_set_enum_type(google_protobuf_FeatureSet *msg, int32_t value) { - const upb_MiniTableField field = {2, 8, 2, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {2, 8, 2, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_SetNonExtensionField(msg, &field, &value); } UPB_INLINE void google_protobuf_FeatureSet_set_repeated_field_encoding(google_protobuf_FeatureSet *msg, int32_t value) { - const upb_MiniTableField field = {3, 12, 3, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {3, 12, 3, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_SetNonExtensionField(msg, &field, &value); } UPB_INLINE void google_protobuf_FeatureSet_set_string_field_validation(google_protobuf_FeatureSet *msg, int32_t value) { - const upb_MiniTableField field = {4, 16, 4, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {4, 16, 4, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_SetNonExtensionField(msg, &field, &value); } UPB_INLINE void google_protobuf_FeatureSet_set_message_encoding(google_protobuf_FeatureSet *msg, int32_t value) { - const upb_MiniTableField field = {5, 20, 5, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {5, 20, 5, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_SetNonExtensionField(msg, &field, &value); } UPB_INLINE void google_protobuf_FeatureSet_set_json_format(google_protobuf_FeatureSet *msg, int32_t value) { - const upb_MiniTableField field = {6, 24, 6, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {6, 24, 6, 6, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSet_set_raw_features(google_protobuf_FeatureSet *msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {999, UPB_SIZE(28, 32), 7, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; _upb_Message_SetNonExtensionField(msg, &field, &value); } +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_FeatureSet_mutable_raw_features(google_protobuf_FeatureSet* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_FeatureSet_raw_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google_protobuf_FeatureSet_msg_init, arena); + if (sub) google_protobuf_FeatureSet_set_raw_features(msg, sub); + } + return sub; +} /* google.protobuf.SourceCodeInfo */ diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c index eaf38cd41c..5ed3c3d3fe 100644 --- a/ruby/ext/google/protobuf_c/ruby-upb.c +++ b/ruby/ext/google/protobuf_c/ruby-upb.c @@ -1697,7 +1697,8 @@ const upb_MiniTable google_protobuf_UninterpretedOption_NamePart_msg_init = { }) }; -static const upb_MiniTableSub google_protobuf_FeatureSet_submsgs[6] = { +static const upb_MiniTableSub google_protobuf_FeatureSet_submsgs[7] = { + {.submsg = &google_protobuf_FeatureSet_msg_init}, {.subenum = &google_protobuf_FeatureSet_FieldPresence_enum_init}, {.subenum = &google_protobuf_FeatureSet_EnumType_enum_init}, {.subenum = &google_protobuf_FeatureSet_RepeatedFieldEncoding_enum_init}, @@ -1706,19 +1707,54 @@ static const upb_MiniTableSub google_protobuf_FeatureSet_submsgs[6] = { {.subenum = &google_protobuf_FeatureSet_JsonFormat_enum_init}, }; -static const upb_MiniTableField google_protobuf_FeatureSet__fields[6] = { - {1, 4, 1, 0, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, - {2, 8, 2, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, - {3, 12, 3, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, - {4, 16, 4, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, - {5, 20, 5, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, - {6, 24, 6, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, +static const upb_MiniTableField google_protobuf_FeatureSet__fields[7] = { + {1, 4, 1, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, 8, 2, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {3, 12, 3, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {4, 16, 4, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {5, 20, 5, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {6, 24, 6, 6, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(28, 32), 7, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, }; const upb_MiniTable google_protobuf_FeatureSet_msg_init = { &google_protobuf_FeatureSet_submsgs[0], &google_protobuf_FeatureSet__fields[0], - 32, 6, kUpb_ExtMode_Extendable, 6, UPB_FASTTABLE_MASK(255), 0, + UPB_SIZE(32, 40), 7, kUpb_ExtMode_Extendable, 6, UPB_FASTTABLE_MASK(248), 0, + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0020000007003eba, &upb_psm_2bt_max64b}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) }; static const upb_MiniTableSub google_protobuf_SourceCodeInfo_submsgs[1] = { diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h index f1ff4ae88d..949d5489f8 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.h +++ b/ruby/ext/google/protobuf_c/ruby-upb.h @@ -9139,120 +9139,147 @@ UPB_INLINE char* google_protobuf_FeatureSet_serialize_ex(const google_protobuf_F return ptr; } UPB_INLINE void google_protobuf_FeatureSet_clear_field_presence(google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {1, 4, 1, 0, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {1, 4, 1, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_ClearNonExtensionField(msg, &field); } UPB_INLINE int32_t google_protobuf_FeatureSet_field_presence(const google_protobuf_FeatureSet* msg) { int32_t default_val = 0; int32_t ret; - const upb_MiniTableField field = {1, 4, 1, 0, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {1, 4, 1, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); return ret; } UPB_INLINE bool google_protobuf_FeatureSet_has_field_presence(const google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {1, 4, 1, 0, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {1, 4, 1, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; return _upb_Message_HasNonExtensionField(msg, &field); } UPB_INLINE void google_protobuf_FeatureSet_clear_enum_type(google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {2, 8, 2, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {2, 8, 2, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_ClearNonExtensionField(msg, &field); } UPB_INLINE int32_t google_protobuf_FeatureSet_enum_type(const google_protobuf_FeatureSet* msg) { int32_t default_val = 0; int32_t ret; - const upb_MiniTableField field = {2, 8, 2, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {2, 8, 2, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); return ret; } UPB_INLINE bool google_protobuf_FeatureSet_has_enum_type(const google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {2, 8, 2, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {2, 8, 2, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; return _upb_Message_HasNonExtensionField(msg, &field); } UPB_INLINE void google_protobuf_FeatureSet_clear_repeated_field_encoding(google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {3, 12, 3, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {3, 12, 3, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_ClearNonExtensionField(msg, &field); } UPB_INLINE int32_t google_protobuf_FeatureSet_repeated_field_encoding(const google_protobuf_FeatureSet* msg) { int32_t default_val = 0; int32_t ret; - const upb_MiniTableField field = {3, 12, 3, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {3, 12, 3, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); return ret; } UPB_INLINE bool google_protobuf_FeatureSet_has_repeated_field_encoding(const google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {3, 12, 3, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {3, 12, 3, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; return _upb_Message_HasNonExtensionField(msg, &field); } UPB_INLINE void google_protobuf_FeatureSet_clear_string_field_validation(google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {4, 16, 4, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {4, 16, 4, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_ClearNonExtensionField(msg, &field); } UPB_INLINE int32_t google_protobuf_FeatureSet_string_field_validation(const google_protobuf_FeatureSet* msg) { int32_t default_val = 0; int32_t ret; - const upb_MiniTableField field = {4, 16, 4, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {4, 16, 4, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); return ret; } UPB_INLINE bool google_protobuf_FeatureSet_has_string_field_validation(const google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {4, 16, 4, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {4, 16, 4, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; return _upb_Message_HasNonExtensionField(msg, &field); } UPB_INLINE void google_protobuf_FeatureSet_clear_message_encoding(google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {5, 20, 5, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {5, 20, 5, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_ClearNonExtensionField(msg, &field); } UPB_INLINE int32_t google_protobuf_FeatureSet_message_encoding(const google_protobuf_FeatureSet* msg) { int32_t default_val = 0; int32_t ret; - const upb_MiniTableField field = {5, 20, 5, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {5, 20, 5, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); return ret; } UPB_INLINE bool google_protobuf_FeatureSet_has_message_encoding(const google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {5, 20, 5, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {5, 20, 5, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; return _upb_Message_HasNonExtensionField(msg, &field); } UPB_INLINE void google_protobuf_FeatureSet_clear_json_format(google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {6, 24, 6, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {6, 24, 6, 6, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_ClearNonExtensionField(msg, &field); } UPB_INLINE int32_t google_protobuf_FeatureSet_json_format(const google_protobuf_FeatureSet* msg) { int32_t default_val = 0; int32_t ret; - const upb_MiniTableField field = {6, 24, 6, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {6, 24, 6, 6, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); return ret; } UPB_INLINE bool google_protobuf_FeatureSet_has_json_format(const google_protobuf_FeatureSet* msg) { - const upb_MiniTableField field = {6, 24, 6, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {6, 24, 6, 6, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return _upb_Message_HasNonExtensionField(msg, &field); +} +UPB_INLINE void google_protobuf_FeatureSet_clear_raw_features(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(28, 32), 7, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_ClearNonExtensionField(msg, &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_FeatureSet_raw_features(const google_protobuf_FeatureSet* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {999, UPB_SIZE(28, 32), 7, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(msg, &field, &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_raw_features(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(28, 32), 7, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; return _upb_Message_HasNonExtensionField(msg, &field); } UPB_INLINE void google_protobuf_FeatureSet_set_field_presence(google_protobuf_FeatureSet *msg, int32_t value) { - const upb_MiniTableField field = {1, 4, 1, 0, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {1, 4, 1, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_SetNonExtensionField(msg, &field, &value); } UPB_INLINE void google_protobuf_FeatureSet_set_enum_type(google_protobuf_FeatureSet *msg, int32_t value) { - const upb_MiniTableField field = {2, 8, 2, 1, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {2, 8, 2, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_SetNonExtensionField(msg, &field, &value); } UPB_INLINE void google_protobuf_FeatureSet_set_repeated_field_encoding(google_protobuf_FeatureSet *msg, int32_t value) { - const upb_MiniTableField field = {3, 12, 3, 2, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {3, 12, 3, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_SetNonExtensionField(msg, &field, &value); } UPB_INLINE void google_protobuf_FeatureSet_set_string_field_validation(google_protobuf_FeatureSet *msg, int32_t value) { - const upb_MiniTableField field = {4, 16, 4, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {4, 16, 4, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_SetNonExtensionField(msg, &field, &value); } UPB_INLINE void google_protobuf_FeatureSet_set_message_encoding(google_protobuf_FeatureSet *msg, int32_t value) { - const upb_MiniTableField field = {5, 20, 5, 4, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {5, 20, 5, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; _upb_Message_SetNonExtensionField(msg, &field, &value); } UPB_INLINE void google_protobuf_FeatureSet_set_json_format(google_protobuf_FeatureSet *msg, int32_t value) { - const upb_MiniTableField field = {6, 24, 6, 5, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + const upb_MiniTableField field = {6, 24, 6, 6, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_SetNonExtensionField(msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSet_set_raw_features(google_protobuf_FeatureSet *msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {999, UPB_SIZE(28, 32), 7, 0, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; _upb_Message_SetNonExtensionField(msg, &field, &value); } +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_FeatureSet_mutable_raw_features(google_protobuf_FeatureSet* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_FeatureSet_raw_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google_protobuf_FeatureSet_msg_init, arena); + if (sub) google_protobuf_FeatureSet_set_raw_features(msg, sub); + } + return sub; +} /* google.protobuf.SourceCodeInfo */ diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index acfe0e4991..f2221a6ea2 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -807,6 +807,7 @@ PROTOBUF_CONSTEXPR FeatureSet::FeatureSet(::_pbi::ConstantInitialized) /*decltype(_impl_._extensions_)*/ {}, /*decltype(_impl_._has_bits_)*/ {}, /*decltype(_impl_._cached_size_)*/ {}, + /*decltype(_impl_.raw_features_)*/ nullptr, /*decltype(_impl_.field_presence_)*/ 0, /*decltype(_impl_.enum_type_)*/ 0, /*decltype(_impl_.repeated_field_encoding_)*/ 0, @@ -1438,12 +1439,14 @@ const ::uint32_t TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets[] P PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_.string_field_validation_), PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_.message_encoding_), PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_.json_format_), - 0, + PROTOBUF_FIELD_OFFSET(::google::protobuf::FeatureSet, _impl_.raw_features_), 1, 2, 3, 4, 5, + 6, + 0, PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _impl_._has_bits_), PROTOBUF_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _internal_metadata_), ~0u, // no _extensions_ @@ -1527,11 +1530,11 @@ static const ::_pbi::MigrationSchema {431, 443, -1, sizeof(::google::protobuf::MethodOptions)}, {447, 457, -1, sizeof(::google::protobuf::UninterpretedOption_NamePart)}, {459, 474, -1, sizeof(::google::protobuf::UninterpretedOption)}, - {481, 495, -1, sizeof(::google::protobuf::FeatureSet)}, - {501, 514, -1, sizeof(::google::protobuf::SourceCodeInfo_Location)}, - {519, -1, -1, sizeof(::google::protobuf::SourceCodeInfo)}, - {528, 541, -1, sizeof(::google::protobuf::GeneratedCodeInfo_Annotation)}, - {546, -1, -1, sizeof(::google::protobuf::GeneratedCodeInfo)}, + {481, 496, -1, sizeof(::google::protobuf::FeatureSet)}, + {503, 516, -1, sizeof(::google::protobuf::SourceCodeInfo_Location)}, + {521, -1, -1, sizeof(::google::protobuf::SourceCodeInfo)}, + {530, 543, -1, sizeof(::google::protobuf::GeneratedCodeInfo_Annotation)}, + {548, -1, -1, sizeof(::google::protobuf::GeneratedCodeInfo)}, }; static const ::_pb::Message* const file_default_instances[] = { @@ -1744,7 +1747,7 @@ const char descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto[] PR "e\030\004 \001(\004\022\032\n\022negative_int_value\030\005 \001(\003\022\024\n\014d" "ouble_value\030\006 \001(\001\022\024\n\014string_value\030\007 \001(\014\022" "\027\n\017aggregate_value\030\010 \001(\t\0323\n\010NamePart\022\021\n\t" - "name_part\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010\"\361\010" + "name_part\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010\"\252\t" "\n\nFeatureSet\022_\n\016field_presence\030\001 \001(\0162).g" "oogle.protobuf.FeatureSet.FieldPresenceB" "\034\210\001\001\230\001\004\230\001\001\242\001\020\n\0042023\022\010EXPLICIT\022Q\n\tenum_ty" @@ -1760,42 +1763,43 @@ const char descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto[] PR "geEncodingB#\210\001\001\230\001\004\230\001\001\242\001\027\n\0042023\022\017LENGTH_P" "REFIXED\022Y\n\013json_format\030\006 \001(\0162&.google.pr" "otobuf.FeatureSet.JsonFormatB\034\210\001\001\230\001\003\230\001\006\230" - "\001\001\242\001\r\n\0042023\022\005ALLOW\"\\\n\rFieldPresence\022\032\n\026F" - "IELD_PRESENCE_UNKNOWN\020\000\022\014\n\010EXPLICIT\020\001\022\014\n" - "\010IMPLICIT\020\002\022\023\n\017LEGACY_REQUIRED\020\003\"7\n\010Enum" - "Type\022\025\n\021ENUM_TYPE_UNKNOWN\020\000\022\010\n\004OPEN\020\001\022\n\n" - "\006CLOSED\020\002\"V\n\025RepeatedFieldEncoding\022#\n\037RE" - "PEATED_FIELD_ENCODING_UNKNOWN\020\000\022\n\n\006PACKE" - "D\020\001\022\014\n\010EXPANDED\020\002\"_\n\025StringFieldValidati" - "on\022#\n\037STRING_FIELD_VALIDATION_UNKNOWN\020\000\022" - "\r\n\tMANDATORY\020\001\022\010\n\004HINT\020\002\022\010\n\004NONE\020\003\"S\n\017Me" - "ssageEncoding\022\034\n\030MESSAGE_ENCODING_UNKNOW" - "N\020\000\022\023\n\017LENGTH_PREFIXED\020\001\022\r\n\tDELIMITED\020\002\"" - "H\n\nJsonFormat\022\027\n\023JSON_FORMAT_UNKNOWN\020\000\022\t" - "\n\005ALLOW\020\001\022\026\n\022LEGACY_BEST_EFFORT\020\002*\006\010\350\007\020\351" - "\007*\006\010\351\007\020\352\007*\006\010\213N\020\220N\"\325\001\n\016SourceCodeInfo\022:\n\010" - "location\030\001 \003(\0132(.google.protobuf.SourceC" - "odeInfo.Location\032\206\001\n\010Location\022\020\n\004path\030\001 " - "\003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020leading_com" - "ments\030\003 \001(\t\022\031\n\021trailing_comments\030\004 \001(\t\022!" - "\n\031leading_detached_comments\030\006 \003(\t\"\234\002\n\021Ge" - "neratedCodeInfo\022A\n\nannotation\030\001 \003(\0132-.go" - "ogle.protobuf.GeneratedCodeInfo.Annotati" - "on\032\303\001\n\nAnnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013s" - "ource_file\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004" - " \001(\005\022H\n\010semantic\030\005 \001(\01626.google.protobuf" - ".GeneratedCodeInfo.Annotation.Semantic\"(" - "\n\010Semantic\022\010\n\004NONE\020\000\022\007\n\003SET\020\001\022\t\n\005ALIAS\020\002" - "B~\n\023com.google.protobufB\020DescriptorProto" - "sH\001Z-google.golang.org/protobuf/types/de" - "scriptorpb\370\001\001\242\002\003GPB\252\002\032Google.Protobuf.Re" - "flection" + "\001\001\242\001\r\n\0042023\022\005ALLOW\0227\n\014raw_features\030\347\007 \001(" + "\0132\033.google.protobuf.FeatureSetB\003\230\001\000\"\\\n\rF" + "ieldPresence\022\032\n\026FIELD_PRESENCE_UNKNOWN\020\000" + "\022\014\n\010EXPLICIT\020\001\022\014\n\010IMPLICIT\020\002\022\023\n\017LEGACY_R" + "EQUIRED\020\003\"7\n\010EnumType\022\025\n\021ENUM_TYPE_UNKNO" + "WN\020\000\022\010\n\004OPEN\020\001\022\n\n\006CLOSED\020\002\"V\n\025RepeatedFi" + "eldEncoding\022#\n\037REPEATED_FIELD_ENCODING_U" + "NKNOWN\020\000\022\n\n\006PACKED\020\001\022\014\n\010EXPANDED\020\002\"_\n\025St" + "ringFieldValidation\022#\n\037STRING_FIELD_VALI" + "DATION_UNKNOWN\020\000\022\r\n\tMANDATORY\020\001\022\010\n\004HINT\020" + "\002\022\010\n\004NONE\020\003\"S\n\017MessageEncoding\022\034\n\030MESSAG" + "E_ENCODING_UNKNOWN\020\000\022\023\n\017LENGTH_PREFIXED\020" + "\001\022\r\n\tDELIMITED\020\002\"H\n\nJsonFormat\022\027\n\023JSON_F" + "ORMAT_UNKNOWN\020\000\022\t\n\005ALLOW\020\001\022\026\n\022LEGACY_BES" + "T_EFFORT\020\002*\006\010\350\007\020\351\007*\006\010\351\007\020\352\007*\006\010\213N\020\220N\"\325\001\n\016S" + "ourceCodeInfo\022:\n\010location\030\001 \003(\0132(.google" + ".protobuf.SourceCodeInfo.Location\032\206\001\n\010Lo" + "cation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005B\002" + "\020\001\022\030\n\020leading_comments\030\003 \001(\t\022\031\n\021trailing" + "_comments\030\004 \001(\t\022!\n\031leading_detached_comm" + "ents\030\006 \003(\t\"\234\002\n\021GeneratedCodeInfo\022A\n\nanno" + "tation\030\001 \003(\0132-.google.protobuf.Generated" + "CodeInfo.Annotation\032\303\001\n\nAnnotation\022\020\n\004pa" + "th\030\001 \003(\005B\002\020\001\022\023\n\013source_file\030\002 \001(\t\022\r\n\005beg" + "in\030\003 \001(\005\022\013\n\003end\030\004 \001(\005\022H\n\010semantic\030\005 \001(\0162" + "6.google.protobuf.GeneratedCodeInfo.Anno" + "tation.Semantic\"(\n\010Semantic\022\010\n\004NONE\020\000\022\007\n" + "\003SET\020\001\022\t\n\005ALIAS\020\002B~\n\023com.google.protobuf" + "B\020DescriptorProtosH\001Z-google.golang.org/" + "protobuf/types/descriptorpb\370\001\001\242\002\003GPB\252\002\032G" + "oogle.Protobuf.Reflection" }; static ::absl::once_flag descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once; const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto = { false, false, - 8888, + 8945, descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto, "google/protobuf/descriptor.proto", &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, @@ -11668,25 +11672,32 @@ class FeatureSet::_Internal { static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_._has_bits_); static void set_has_field_presence(HasBits* has_bits) { - (*has_bits)[0] |= 1u; + (*has_bits)[0] |= 2u; } static void set_has_enum_type(HasBits* has_bits) { - (*has_bits)[0] |= 2u; + (*has_bits)[0] |= 4u; } static void set_has_repeated_field_encoding(HasBits* has_bits) { - (*has_bits)[0] |= 4u; + (*has_bits)[0] |= 8u; } static void set_has_string_field_validation(HasBits* has_bits) { - (*has_bits)[0] |= 8u; + (*has_bits)[0] |= 16u; } static void set_has_message_encoding(HasBits* has_bits) { - (*has_bits)[0] |= 16u; + (*has_bits)[0] |= 32u; } static void set_has_json_format(HasBits* has_bits) { - (*has_bits)[0] |= 32u; + (*has_bits)[0] |= 64u; + } + static const ::google::protobuf::FeatureSet& raw_features(const FeatureSet* msg); + static void set_has_raw_features(HasBits* has_bits) { + (*has_bits)[0] |= 1u; } }; +const ::google::protobuf::FeatureSet& FeatureSet::_Internal::raw_features(const FeatureSet* msg) { + return *msg->_impl_.raw_features_; +} FeatureSet::FeatureSet(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -11699,6 +11710,7 @@ FeatureSet::FeatureSet(const FeatureSet& from) : ::google::protobuf::Message() { /*decltype(_impl_._extensions_)*/ {}, decltype(_impl_._has_bits_){from._impl_._has_bits_}, /*decltype(_impl_._cached_size_)*/ {}, + decltype(_impl_.raw_features_){nullptr}, decltype(_impl_.field_presence_){}, decltype(_impl_.enum_type_){}, decltype(_impl_.repeated_field_encoding_){}, @@ -11710,6 +11722,9 @@ FeatureSet::FeatureSet(const FeatureSet& from) : ::google::protobuf::Message() { from._internal_metadata_); _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_); + if ((from._impl_._has_bits_[0] & 0x00000001u) != 0) { + _this->_impl_.raw_features_ = new ::google::protobuf::FeatureSet(*from._impl_.raw_features_); + } ::memcpy(&_impl_.field_presence_, &from._impl_.field_presence_, static_cast<::size_t>(reinterpret_cast(&_impl_.json_format_) - reinterpret_cast(&_impl_.field_presence_)) + sizeof(_impl_.json_format_)); @@ -11722,6 +11737,7 @@ inline void FeatureSet::SharedCtor(::_pb::Arena* arena) { /*decltype(_impl_._extensions_)*/ {::_pbi::ArenaInitialized(), arena}, decltype(_impl_._has_bits_){}, /*decltype(_impl_._cached_size_)*/ {}, + decltype(_impl_.raw_features_){nullptr}, decltype(_impl_.field_presence_){0}, decltype(_impl_.enum_type_){0}, decltype(_impl_.repeated_field_encoding_){0}, @@ -11738,6 +11754,7 @@ FeatureSet::~FeatureSet() { inline void FeatureSet::SharedDtor() { ABSL_DCHECK(GetArenaForAllocation() == nullptr); _impl_._extensions_.~ExtensionSet(); + if (this != internal_default_instance()) delete _impl_.raw_features_; } void FeatureSet::SetCachedSize(int size) const { _impl_._cached_size_.Set(size); @@ -11751,7 +11768,11 @@ PROTOBUF_NOINLINE void FeatureSet::Clear() { _impl_._extensions_.Clear(); cached_has_bits = _impl_._has_bits_[0]; - if (cached_has_bits & 0x0000003fu) { + if (cached_has_bits & 0x00000001u) { + ABSL_DCHECK(_impl_.raw_features_ != nullptr); + _impl_.raw_features_->Clear(); + } + if (cached_has_bits & 0x0000007eu) { ::memset(&_impl_.field_presence_, 0, static_cast<::size_t>( reinterpret_cast(&_impl_.json_format_) - reinterpret_cast(&_impl_.field_presence_)) + sizeof(_impl_.json_format_)); @@ -11767,16 +11788,16 @@ const char* FeatureSet::_InternalParse( } -constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { +constexpr ::_pbi::TcParseTable<3, 7, 7, 0, 7> FeatureSet::_table_ = { { PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_._has_bits_), PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_._extensions_), - 6, 56, // max_field_number, fast_idx_mask + 999, 56, // max_field_number, fast_idx_mask offsetof(decltype(_table_), field_lookup_table), 4294967232, // skipmap offsetof(decltype(_table_), field_entries), - 6, // num_field_entries - 6, // num_aux_entries + 7, // num_field_entries + 7, // num_aux_entries offsetof(decltype(_table_), aux_entries), &_FeatureSet_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback @@ -11784,44 +11805,51 @@ constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { {::_pbi::TcParser::MiniParse, {}}, // optional .google.protobuf.FeatureSet.FieldPresence field_presence = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { {::_pbi::TcParser::FastEr0S1, - {8, 0, 3, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.field_presence_)}}, + {8, 1, 3, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.field_presence_)}}, // optional .google.protobuf.FeatureSet.EnumType enum_type = 2 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = { {::_pbi::TcParser::FastEr0S1, - {16, 1, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.enum_type_)}}, + {16, 2, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.enum_type_)}}, // optional .google.protobuf.FeatureSet.RepeatedFieldEncoding repeated_field_encoding = 3 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { {::_pbi::TcParser::FastEr0S1, - {24, 2, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.repeated_field_encoding_)}}, + {24, 3, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.repeated_field_encoding_)}}, // optional .google.protobuf.FeatureSet.StringFieldValidation string_field_validation = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { {::_pbi::TcParser::FastEr0S1, - {32, 3, 3, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.string_field_validation_)}}, + {32, 4, 3, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.string_field_validation_)}}, // optional .google.protobuf.FeatureSet.MessageEncoding message_encoding = 5 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { {::_pbi::TcParser::FastEr0S1, - {40, 4, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.message_encoding_)}}, + {40, 5, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.message_encoding_)}}, // optional .google.protobuf.FeatureSet.JsonFormat json_format = 6 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = { {::_pbi::TcParser::FastEr0S1, - {48, 5, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.json_format_)}}, - {::_pbi::TcParser::MiniParse, {}}, + {48, 6, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.json_format_)}}, + // optional .google.protobuf.FeatureSet raw_features = 999 [targets = TARGET_TYPE_UNKNOWN]; + {::_pbi::TcParser::FastMtS2, + {16058, 0, 6, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.raw_features_)}}, }}, {{ + 999, 0, 1, + 65534, 6, 65535, 65535 }}, {{ // optional .google.protobuf.FeatureSet.FieldPresence field_presence = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { - {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.field_presence_), _Internal::kHasBitsOffset + 0, 0, + {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.field_presence_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, // optional .google.protobuf.FeatureSet.EnumType enum_type = 2 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = { - {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.enum_type_), _Internal::kHasBitsOffset + 1, 1, + {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.enum_type_), _Internal::kHasBitsOffset + 2, 1, (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, // optional .google.protobuf.FeatureSet.RepeatedFieldEncoding repeated_field_encoding = 3 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { - {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.repeated_field_encoding_), _Internal::kHasBitsOffset + 2, 2, + {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.repeated_field_encoding_), _Internal::kHasBitsOffset + 3, 2, (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, // optional .google.protobuf.FeatureSet.StringFieldValidation string_field_validation = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { - {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.string_field_validation_), _Internal::kHasBitsOffset + 3, 3, + {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.string_field_validation_), _Internal::kHasBitsOffset + 4, 3, (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, // optional .google.protobuf.FeatureSet.MessageEncoding message_encoding = 5 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { - {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.message_encoding_), _Internal::kHasBitsOffset + 4, 4, + {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.message_encoding_), _Internal::kHasBitsOffset + 5, 4, (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, // optional .google.protobuf.FeatureSet.JsonFormat json_format = 6 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = { - {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.json_format_), _Internal::kHasBitsOffset + 5, 5, + {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.json_format_), _Internal::kHasBitsOffset + 6, 5, (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, + // optional .google.protobuf.FeatureSet raw_features = 999 [targets = TARGET_TYPE_UNKNOWN]; + {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.raw_features_), _Internal::kHasBitsOffset + 0, 6, + (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, }}, {{ {0, 4}, {0, 3}, @@ -11829,6 +11857,7 @@ constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { {0, 4}, {0, 3}, {0, 3}, + {::_pbi::TcParser::GetTable<::google::protobuf::FeatureSet>()}, }}, {{ }}, }; @@ -11842,47 +11871,54 @@ constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { cached_has_bits = _impl_._has_bits_[0]; // optional .google.protobuf.FeatureSet.FieldPresence field_presence = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { - if (cached_has_bits & 0x00000001u) { + if (cached_has_bits & 0x00000002u) { target = stream->EnsureSpace(target); target = ::_pbi::WireFormatLite::WriteEnumToArray( 1, this->_internal_field_presence(), target); } // optional .google.protobuf.FeatureSet.EnumType enum_type = 2 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = { - if (cached_has_bits & 0x00000002u) { + if (cached_has_bits & 0x00000004u) { target = stream->EnsureSpace(target); target = ::_pbi::WireFormatLite::WriteEnumToArray( 2, this->_internal_enum_type(), target); } // optional .google.protobuf.FeatureSet.RepeatedFieldEncoding repeated_field_encoding = 3 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { - if (cached_has_bits & 0x00000004u) { + if (cached_has_bits & 0x00000008u) { target = stream->EnsureSpace(target); target = ::_pbi::WireFormatLite::WriteEnumToArray( 3, this->_internal_repeated_field_encoding(), target); } // optional .google.protobuf.FeatureSet.StringFieldValidation string_field_validation = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { - if (cached_has_bits & 0x00000008u) { + if (cached_has_bits & 0x00000010u) { target = stream->EnsureSpace(target); target = ::_pbi::WireFormatLite::WriteEnumToArray( 4, this->_internal_string_field_validation(), target); } // optional .google.protobuf.FeatureSet.MessageEncoding message_encoding = 5 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { - if (cached_has_bits & 0x00000010u) { + if (cached_has_bits & 0x00000020u) { target = stream->EnsureSpace(target); target = ::_pbi::WireFormatLite::WriteEnumToArray( 5, this->_internal_message_encoding(), target); } // optional .google.protobuf.FeatureSet.JsonFormat json_format = 6 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = { - if (cached_has_bits & 0x00000020u) { + if (cached_has_bits & 0x00000040u) { target = stream->EnsureSpace(target); target = ::_pbi::WireFormatLite::WriteEnumToArray( 6, this->_internal_json_format(), target); } + // optional .google.protobuf.FeatureSet raw_features = 999 [targets = TARGET_TYPE_UNKNOWN]; + if (cached_has_bits & 0x00000001u) { + target = ::google::protobuf::internal::WireFormatLite:: + InternalWriteMessage(999, _Internal::raw_features(this), + _Internal::raw_features(this).GetCachedSize(), target, stream); + } + // Extension range [1000, 10000) target = _impl_._extensions_._InternalSerialize( internal_default_instance(), 1000, 10000, target, stream); @@ -11906,39 +11942,46 @@ constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { (void) cached_has_bits; cached_has_bits = _impl_._has_bits_[0]; - if (cached_has_bits & 0x0000003fu) { - // optional .google.protobuf.FeatureSet.FieldPresence field_presence = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { + if (cached_has_bits & 0x0000007fu) { + // optional .google.protobuf.FeatureSet raw_features = 999 [targets = TARGET_TYPE_UNKNOWN]; if (cached_has_bits & 0x00000001u) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSize( + *_impl_.raw_features_); + } + + // optional .google.protobuf.FeatureSet.FieldPresence field_presence = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { + if (cached_has_bits & 0x00000002u) { total_size += 1 + ::_pbi::WireFormatLite::EnumSize(this->_internal_field_presence()); } // optional .google.protobuf.FeatureSet.EnumType enum_type = 2 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = { - if (cached_has_bits & 0x00000002u) { + if (cached_has_bits & 0x00000004u) { total_size += 1 + ::_pbi::WireFormatLite::EnumSize(this->_internal_enum_type()); } // optional .google.protobuf.FeatureSet.RepeatedFieldEncoding repeated_field_encoding = 3 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { - if (cached_has_bits & 0x00000004u) { + if (cached_has_bits & 0x00000008u) { total_size += 1 + ::_pbi::WireFormatLite::EnumSize(this->_internal_repeated_field_encoding()); } // optional .google.protobuf.FeatureSet.StringFieldValidation string_field_validation = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { - if (cached_has_bits & 0x00000008u) { + if (cached_has_bits & 0x00000010u) { total_size += 1 + ::_pbi::WireFormatLite::EnumSize(this->_internal_string_field_validation()); } // optional .google.protobuf.FeatureSet.MessageEncoding message_encoding = 5 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { - if (cached_has_bits & 0x00000010u) { + if (cached_has_bits & 0x00000020u) { total_size += 1 + ::_pbi::WireFormatLite::EnumSize(this->_internal_message_encoding()); } // optional .google.protobuf.FeatureSet.JsonFormat json_format = 6 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = { - if (cached_has_bits & 0x00000020u) { + if (cached_has_bits & 0x00000040u) { total_size += 1 + ::_pbi::WireFormatLite::EnumSize(this->_internal_json_format()); } @@ -11963,23 +12006,27 @@ void FeatureSet::MergeImpl(::google::protobuf::Message& to_msg, const ::google:: (void) cached_has_bits; cached_has_bits = from._impl_._has_bits_[0]; - if (cached_has_bits & 0x0000003fu) { + if (cached_has_bits & 0x0000007fu) { if (cached_has_bits & 0x00000001u) { - _this->_impl_.field_presence_ = from._impl_.field_presence_; + _this->_internal_mutable_raw_features()->::google::protobuf::FeatureSet::MergeFrom( + from._internal_raw_features()); } if (cached_has_bits & 0x00000002u) { - _this->_impl_.enum_type_ = from._impl_.enum_type_; + _this->_impl_.field_presence_ = from._impl_.field_presence_; } if (cached_has_bits & 0x00000004u) { - _this->_impl_.repeated_field_encoding_ = from._impl_.repeated_field_encoding_; + _this->_impl_.enum_type_ = from._impl_.enum_type_; } if (cached_has_bits & 0x00000008u) { - _this->_impl_.string_field_validation_ = from._impl_.string_field_validation_; + _this->_impl_.repeated_field_encoding_ = from._impl_.repeated_field_encoding_; } if (cached_has_bits & 0x00000010u) { - _this->_impl_.message_encoding_ = from._impl_.message_encoding_; + _this->_impl_.string_field_validation_ = from._impl_.string_field_validation_; } if (cached_has_bits & 0x00000020u) { + _this->_impl_.message_encoding_ = from._impl_.message_encoding_; + } + if (cached_has_bits & 0x00000040u) { _this->_impl_.json_format_ = from._impl_.json_format_; } _this->_impl_._has_bits_[0] |= cached_has_bits; @@ -11999,6 +12046,9 @@ PROTOBUF_NOINLINE bool FeatureSet::IsInitialized() const { if (!_impl_._extensions_.IsInitialized(internal_default_instance())) { return false; } + if ((_impl_._has_bits_[0] & 0x00000001u) != 0) { + if (!_impl_.raw_features_->IsInitialized()) return false; + } return true; } @@ -12010,9 +12060,9 @@ void FeatureSet::InternalSwap(FeatureSet* other) { ::google::protobuf::internal::memswap< PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.json_format_) + sizeof(FeatureSet::_impl_.json_format_) - - PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.field_presence_)>( - reinterpret_cast(&_impl_.field_presence_), - reinterpret_cast(&other->_impl_.field_presence_)); + - PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.raw_features_)>( + reinterpret_cast(&_impl_.raw_features_), + reinterpret_cast(&other->_impl_.raw_features_)); } ::google::protobuf::Metadata FeatureSet::GetMetadata() const { diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index e66401e2d1..68073b97a7 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -8618,6 +8618,7 @@ class PROTOBUF_EXPORT FeatureSet final : // accessors ------------------------------------------------------- enum : int { + kRawFeaturesFieldNumber = 999, kFieldPresenceFieldNumber = 1, kEnumTypeFieldNumber = 2, kRepeatedFieldEncodingFieldNumber = 3, @@ -8625,6 +8626,21 @@ class PROTOBUF_EXPORT FeatureSet final : kMessageEncodingFieldNumber = 5, kJsonFormatFieldNumber = 6, }; + // optional .google.protobuf.FeatureSet raw_features = 999 [targets = TARGET_TYPE_UNKNOWN]; + bool has_raw_features() const; + void clear_raw_features() ; + const ::google::protobuf::FeatureSet& raw_features() const; + PROTOBUF_NODISCARD ::google::protobuf::FeatureSet* release_raw_features(); + ::google::protobuf::FeatureSet* mutable_raw_features(); + void set_allocated_raw_features(::google::protobuf::FeatureSet* value); + void unsafe_arena_set_allocated_raw_features(::google::protobuf::FeatureSet* value); + ::google::protobuf::FeatureSet* unsafe_arena_release_raw_features(); + + private: + const ::google::protobuf::FeatureSet& _internal_raw_features() const; + ::google::protobuf::FeatureSet* _internal_mutable_raw_features(); + + public: // optional .google.protobuf.FeatureSet.FieldPresence field_presence = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { bool has_field_presence() const; void clear_field_presence() ; @@ -8847,7 +8863,7 @@ class PROTOBUF_EXPORT FeatureSet final : class _Internal; friend class ::google::protobuf::internal::TcParser; - static const ::google::protobuf::internal::TcParseTable<3, 6, 6, 0, 2> _table_; + static const ::google::protobuf::internal::TcParseTable<3, 7, 7, 0, 7> _table_; template friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -8856,6 +8872,7 @@ class PROTOBUF_EXPORT FeatureSet final : ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; + ::google::protobuf::FeatureSet* raw_features_; int field_presence_; int enum_type_; int repeated_field_encoding_; @@ -17188,12 +17205,12 @@ inline void UninterpretedOption::set_allocated_aggregate_value(std::string* valu // optional .google.protobuf.FeatureSet.FieldPresence field_presence = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { inline bool FeatureSet::has_field_presence() const { - bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0; + bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0; return value; } inline void FeatureSet::clear_field_presence() { _impl_.field_presence_ = 0; - _impl_._has_bits_[0] &= ~0x00000001u; + _impl_._has_bits_[0] &= ~0x00000002u; } inline ::google::protobuf::FeatureSet_FieldPresence FeatureSet::field_presence() const { // @@protoc_insertion_point(field_get:google.protobuf.FeatureSet.field_presence) @@ -17210,18 +17227,18 @@ inline ::google::protobuf::FeatureSet_FieldPresence FeatureSet::_internal_field_ inline void FeatureSet::_internal_set_field_presence(::google::protobuf::FeatureSet_FieldPresence value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FeatureSet_FieldPresence_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000001u; + _impl_._has_bits_[0] |= 0x00000002u; _impl_.field_presence_ = value; } // optional .google.protobuf.FeatureSet.EnumType enum_type = 2 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = { inline bool FeatureSet::has_enum_type() const { - bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0; + bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0; return value; } inline void FeatureSet::clear_enum_type() { _impl_.enum_type_ = 0; - _impl_._has_bits_[0] &= ~0x00000002u; + _impl_._has_bits_[0] &= ~0x00000004u; } inline ::google::protobuf::FeatureSet_EnumType FeatureSet::enum_type() const { // @@protoc_insertion_point(field_get:google.protobuf.FeatureSet.enum_type) @@ -17238,18 +17255,18 @@ inline ::google::protobuf::FeatureSet_EnumType FeatureSet::_internal_enum_type() inline void FeatureSet::_internal_set_enum_type(::google::protobuf::FeatureSet_EnumType value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FeatureSet_EnumType_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000002u; + _impl_._has_bits_[0] |= 0x00000004u; _impl_.enum_type_ = value; } // optional .google.protobuf.FeatureSet.RepeatedFieldEncoding repeated_field_encoding = 3 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { inline bool FeatureSet::has_repeated_field_encoding() const { - bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0; + bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0; return value; } inline void FeatureSet::clear_repeated_field_encoding() { _impl_.repeated_field_encoding_ = 0; - _impl_._has_bits_[0] &= ~0x00000004u; + _impl_._has_bits_[0] &= ~0x00000008u; } inline ::google::protobuf::FeatureSet_RepeatedFieldEncoding FeatureSet::repeated_field_encoding() const { // @@protoc_insertion_point(field_get:google.protobuf.FeatureSet.repeated_field_encoding) @@ -17266,18 +17283,18 @@ inline ::google::protobuf::FeatureSet_RepeatedFieldEncoding FeatureSet::_interna inline void FeatureSet::_internal_set_repeated_field_encoding(::google::protobuf::FeatureSet_RepeatedFieldEncoding value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FeatureSet_RepeatedFieldEncoding_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000004u; + _impl_._has_bits_[0] |= 0x00000008u; _impl_.repeated_field_encoding_ = value; } // optional .google.protobuf.FeatureSet.StringFieldValidation string_field_validation = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { inline bool FeatureSet::has_string_field_validation() const { - bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0; + bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0; return value; } inline void FeatureSet::clear_string_field_validation() { _impl_.string_field_validation_ = 0; - _impl_._has_bits_[0] &= ~0x00000008u; + _impl_._has_bits_[0] &= ~0x00000010u; } inline ::google::protobuf::FeatureSet_StringFieldValidation FeatureSet::string_field_validation() const { // @@protoc_insertion_point(field_get:google.protobuf.FeatureSet.string_field_validation) @@ -17294,18 +17311,18 @@ inline ::google::protobuf::FeatureSet_StringFieldValidation FeatureSet::_interna inline void FeatureSet::_internal_set_string_field_validation(::google::protobuf::FeatureSet_StringFieldValidation value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FeatureSet_StringFieldValidation_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000008u; + _impl_._has_bits_[0] |= 0x00000010u; _impl_.string_field_validation_ = value; } // optional .google.protobuf.FeatureSet.MessageEncoding message_encoding = 5 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { inline bool FeatureSet::has_message_encoding() const { - bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0; + bool value = (_impl_._has_bits_[0] & 0x00000020u) != 0; return value; } inline void FeatureSet::clear_message_encoding() { _impl_.message_encoding_ = 0; - _impl_._has_bits_[0] &= ~0x00000010u; + _impl_._has_bits_[0] &= ~0x00000020u; } inline ::google::protobuf::FeatureSet_MessageEncoding FeatureSet::message_encoding() const { // @@protoc_insertion_point(field_get:google.protobuf.FeatureSet.message_encoding) @@ -17322,18 +17339,18 @@ inline ::google::protobuf::FeatureSet_MessageEncoding FeatureSet::_internal_mess inline void FeatureSet::_internal_set_message_encoding(::google::protobuf::FeatureSet_MessageEncoding value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FeatureSet_MessageEncoding_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000010u; + _impl_._has_bits_[0] |= 0x00000020u; _impl_.message_encoding_ = value; } // optional .google.protobuf.FeatureSet.JsonFormat json_format = 6 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = { inline bool FeatureSet::has_json_format() const { - bool value = (_impl_._has_bits_[0] & 0x00000020u) != 0; + bool value = (_impl_._has_bits_[0] & 0x00000040u) != 0; return value; } inline void FeatureSet::clear_json_format() { _impl_.json_format_ = 0; - _impl_._has_bits_[0] &= ~0x00000020u; + _impl_._has_bits_[0] &= ~0x00000040u; } inline ::google::protobuf::FeatureSet_JsonFormat FeatureSet::json_format() const { // @@protoc_insertion_point(field_get:google.protobuf.FeatureSet.json_format) @@ -17350,10 +17367,106 @@ inline ::google::protobuf::FeatureSet_JsonFormat FeatureSet::_internal_json_form inline void FeatureSet::_internal_set_json_format(::google::protobuf::FeatureSet_JsonFormat value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FeatureSet_JsonFormat_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000020u; + _impl_._has_bits_[0] |= 0x00000040u; _impl_.json_format_ = value; } +// optional .google.protobuf.FeatureSet raw_features = 999 [targets = TARGET_TYPE_UNKNOWN]; +inline bool FeatureSet::has_raw_features() const { + bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0; + PROTOBUF_ASSUME(!value || _impl_.raw_features_ != nullptr); + return value; +} +inline void FeatureSet::clear_raw_features() { + if (_impl_.raw_features_ != nullptr) _impl_.raw_features_->Clear(); + _impl_._has_bits_[0] &= ~0x00000001u; +} +inline const ::google::protobuf::FeatureSet& FeatureSet::_internal_raw_features() const { + PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race); + const ::google::protobuf::FeatureSet* p = _impl_.raw_features_; + return p != nullptr ? *p : reinterpret_cast(::google::protobuf::_FeatureSet_default_instance_); +} +inline const ::google::protobuf::FeatureSet& FeatureSet::raw_features() const { + // @@protoc_insertion_point(field_get:google.protobuf.FeatureSet.raw_features) + return _internal_raw_features(); +} +inline void FeatureSet::unsafe_arena_set_allocated_raw_features(::google::protobuf::FeatureSet* value) { + PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); + if (GetArenaForAllocation() == nullptr) { + delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.raw_features_); + } + _impl_.raw_features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value); + if (value != nullptr) { + _impl_._has_bits_[0] |= 0x00000001u; + } else { + _impl_._has_bits_[0] &= ~0x00000001u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FeatureSet.raw_features) +} +inline ::google::protobuf::FeatureSet* FeatureSet::release_raw_features() { + PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); + + _impl_._has_bits_[0] &= ~0x00000001u; + ::google::protobuf::FeatureSet* released = _impl_.raw_features_; + _impl_.raw_features_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released); + released = ::google::protobuf::internal::DuplicateIfNonNull(released); + if (GetArenaForAllocation() == nullptr) { + delete old; + } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + if (GetArenaForAllocation() != nullptr) { + released = ::google::protobuf::internal::DuplicateIfNonNull(released); + } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return released; +} +inline ::google::protobuf::FeatureSet* FeatureSet::unsafe_arena_release_raw_features() { + PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); + // @@protoc_insertion_point(field_release:google.protobuf.FeatureSet.raw_features) + + _impl_._has_bits_[0] &= ~0x00000001u; + ::google::protobuf::FeatureSet* temp = _impl_.raw_features_; + _impl_.raw_features_ = nullptr; + return temp; +} +inline ::google::protobuf::FeatureSet* FeatureSet::_internal_mutable_raw_features() { + PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); + _impl_._has_bits_[0] |= 0x00000001u; + if (_impl_.raw_features_ == nullptr) { + auto* p = CreateMaybeMessage<::google::protobuf::FeatureSet>(GetArenaForAllocation()); + _impl_.raw_features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p); + } + return _impl_.raw_features_; +} +inline ::google::protobuf::FeatureSet* FeatureSet::mutable_raw_features() { + ::google::protobuf::FeatureSet* _msg = _internal_mutable_raw_features(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FeatureSet.raw_features) + return _msg; +} +inline void FeatureSet::set_allocated_raw_features(::google::protobuf::FeatureSet* value) { + ::google::protobuf::Arena* message_arena = GetArenaForAllocation(); + PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); + if (message_arena == nullptr) { + delete reinterpret_cast<::google::protobuf::FeatureSet*>(_impl_.raw_features_); + } + + if (value != nullptr) { + ::google::protobuf::Arena* submessage_arena = + ::google::protobuf::Arena::InternalGetOwningArena(reinterpret_cast<::google::protobuf::FeatureSet*>(value)); + if (message_arena != submessage_arena) { + value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena); + } + _impl_._has_bits_[0] |= 0x00000001u; + } else { + _impl_._has_bits_[0] &= ~0x00000001u; + } + + _impl_.raw_features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FeatureSet.raw_features) +} + // ------------------------------------------------------------------- // SourceCodeInfo_Location diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto index d53acc70f7..5f148224c9 100644 --- a/src/google/protobuf/descriptor.proto +++ b/src/google/protobuf/descriptor.proto @@ -974,6 +974,8 @@ message FeatureSet { edition_defaults = { edition: "2023", value: "ALLOW" } ]; + optional FeatureSet raw_features = 999 [targets = TARGET_TYPE_UNKNOWN]; + extensions 1000; // for Protobuf C++ extensions 1001; // for Protobuf Java diff --git a/src/google/protobuf/feature_resolver.cc b/src/google/protobuf/feature_resolver.cc index 9f57d9900e..feda73ed44 100644 --- a/src/google/protobuf/feature_resolver.cc +++ b/src/google/protobuf/feature_resolver.cc @@ -69,6 +69,12 @@ absl::Status Error(Args... args) { return absl::FailedPreconditionError(absl::StrCat(args...)); } +bool IsNonFeatureField(const FieldDescriptor& field) { + return field.containing_type() && + field.containing_type()->full_name() == "google.protobuf.FeatureSet" && + field.name() == "raw_features"; +} + bool EditionsLessThan(absl::string_view a, absl::string_view b) { std::vector as = absl::StrSplit(a, '.'); std::vector bs = absl::StrSplit(b, '.'); @@ -93,6 +99,8 @@ absl::Status ValidateDescriptor(absl::string_view edition, } for (int i = 0; i < descriptor.field_count(); ++i) { const FieldDescriptor& field = *descriptor.field(i); + if (IsNonFeatureField(field)) continue; + if (field.is_required()) { return Error("Feature field ", field.full_name(), " is an unsupported required field."); @@ -122,6 +130,8 @@ absl::Status FillDefaults(absl::string_view edition, Message& msg) { for (int i = 0; i < descriptor.field_count(); ++i) { const FieldDescriptor& field = *descriptor.field(i); + if (IsNonFeatureField(field)) continue; + msg.GetReflection()->ClearField(&msg, &field); ABSL_CHECK(!field.is_repeated()); From b81d2cc8c5c0210414f80c4d4e8883037b613859 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Wed, 12 Jul 2023 16:02:16 -0700 Subject: [PATCH 2/6] Expand VisitDescriptor to support mutable access to the proto. PiperOrigin-RevId: 547625871 --- src/google/protobuf/descriptor_visitor.h | 74 +++++++++++++------ .../protobuf/descriptor_visitor_test.cc | 18 +++++ 2 files changed, 70 insertions(+), 22 deletions(-) diff --git a/src/google/protobuf/descriptor_visitor.h b/src/google/protobuf/descriptor_visitor.h index a8b2f04b04..267ffab703 100644 --- a/src/google/protobuf/descriptor_visitor.h +++ b/src/google/protobuf/descriptor_visitor.h @@ -46,6 +46,10 @@ template void VisitDescriptors(const FileDescriptor& file, const FileDescriptorProto& proto, Visitor visitor); +template +void VisitDescriptors(const FileDescriptor& file, FileDescriptorProto& proto, + Visitor visitor); + // Visit just the descriptors, without a corresponding proto tree. template void VisitDescriptors(const FileDescriptor& file, Visitor visitor); @@ -54,92 +58,111 @@ template struct VisitImpl { Visitor visitor; template - void Visit(const FieldDescriptor& descriptor, const Proto&... proto) { + void Visit(const FieldDescriptor& descriptor, Proto&... proto) { visitor(descriptor, proto...); } template - void Visit(const EnumValueDescriptor& descriptor, const Proto&... proto) { + void Visit(const EnumValueDescriptor& descriptor, Proto&... proto) { visitor(descriptor, proto...); } template - void Visit(const EnumDescriptor& descriptor, const Proto&... proto) { + void Visit(const EnumDescriptor& descriptor, Proto&... proto) { visitor(descriptor, proto...); for (int i = 0; i < descriptor.value_count(); i++) { - Visit(*descriptor.value(i), proto.value(i)...); + Visit(*descriptor.value(i), value(proto, i)...); } } template - void Visit(const Descriptor::ExtensionRange& descriptor, - const Proto&... proto) { + void Visit(const Descriptor::ExtensionRange& descriptor, Proto&... proto) { visitor(descriptor, proto...); } template - void Visit(const OneofDescriptor& descriptor, const Proto&... proto) { + void Visit(const OneofDescriptor& descriptor, Proto&... proto) { visitor(descriptor, proto...); } template - void Visit(const Descriptor& descriptor, const Proto&... proto) { + void Visit(const Descriptor& descriptor, Proto&... proto) { visitor(descriptor, proto...); for (int i = 0; i < descriptor.enum_type_count(); i++) { - Visit(*descriptor.enum_type(i), proto.enum_type(i)...); + Visit(*descriptor.enum_type(i), enum_type(proto, i)...); } for (int i = 0; i < descriptor.oneof_decl_count(); i++) { - Visit(*descriptor.oneof_decl(i), proto.oneof_decl(i)...); + Visit(*descriptor.oneof_decl(i), oneof_decl(proto, i)...); } for (int i = 0; i < descriptor.field_count(); i++) { - Visit(*descriptor.field(i), proto.field(i)...); + Visit(*descriptor.field(i), field(proto, i)...); } for (int i = 0; i < descriptor.nested_type_count(); i++) { - Visit(*descriptor.nested_type(i), proto.nested_type(i)...); + Visit(*descriptor.nested_type(i), nested_type(proto, i)...); } for (int i = 0; i < descriptor.extension_count(); i++) { - Visit(*descriptor.extension(i), proto.extension(i)...); + Visit(*descriptor.extension(i), extension(proto, i)...); } for (int i = 0; i < descriptor.extension_range_count(); i++) { - Visit(*descriptor.extension_range(i), proto.extension_range(i)...); + Visit(*descriptor.extension_range(i), extension_range(proto, i)...); } } template - void Visit(const MethodDescriptor& method, const Proto&... proto) { + void Visit(const MethodDescriptor& method, Proto&... proto) { visitor(method, proto...); } template - void Visit(const ServiceDescriptor& descriptor, const Proto&... proto) { + void Visit(const ServiceDescriptor& descriptor, Proto&... proto) { visitor(descriptor, proto...); for (int i = 0; i < descriptor.method_count(); i++) { - Visit(*descriptor.method(i), proto.method(i)...); + Visit(*descriptor.method(i), method(proto, i)...); } } template - void Visit(const FileDescriptor& descriptor, const Proto&... proto) { + void Visit(const FileDescriptor& descriptor, Proto&... proto) { visitor(descriptor, proto...); for (int i = 0; i < descriptor.message_type_count(); i++) { - Visit(*descriptor.message_type(i), proto.message_type(i)...); + Visit(*descriptor.message_type(i), message_type(proto, i)...); } for (int i = 0; i < descriptor.enum_type_count(); i++) { - Visit(*descriptor.enum_type(i), proto.enum_type(i)...); + Visit(*descriptor.enum_type(i), enum_type(proto, i)...); } for (int i = 0; i < descriptor.extension_count(); i++) { - Visit(*descriptor.extension(i), proto.extension(i)...); + Visit(*descriptor.extension(i), extension(proto, i)...); } for (int i = 0; i < descriptor.service_count(); i++) { - Visit(*descriptor.service(i), proto.service(i)...); + Visit(*descriptor.service(i), service(proto, i)...); } } + + private: +#define CREATE_NESTED_GETTER(TYPE, NESTED) \ + inline auto& NESTED(TYPE& desc, int i) { return *desc.mutable_##NESTED(i); } \ + inline auto& NESTED(const TYPE& desc, int i) { return desc.NESTED(i); } + + CREATE_NESTED_GETTER(DescriptorProto, enum_type); + CREATE_NESTED_GETTER(DescriptorProto, extension); + CREATE_NESTED_GETTER(DescriptorProto, extension_range); + CREATE_NESTED_GETTER(DescriptorProto, field); + CREATE_NESTED_GETTER(DescriptorProto, nested_type); + CREATE_NESTED_GETTER(DescriptorProto, oneof_decl); + CREATE_NESTED_GETTER(EnumDescriptorProto, value); + CREATE_NESTED_GETTER(FileDescriptorProto, enum_type); + CREATE_NESTED_GETTER(FileDescriptorProto, extension); + CREATE_NESTED_GETTER(FileDescriptorProto, message_type); + CREATE_NESTED_GETTER(FileDescriptorProto, service); + CREATE_NESTED_GETTER(ServiceDescriptorProto, method); + +#undef CREATE_NESTED_GETTER }; // Provide a fallback to ignore all the nodes that are not interesting to the @@ -167,6 +190,13 @@ void VisitDescriptors(const FileDescriptor& file, internal::VisitImpl{VisitorImpl(visitor)}.Visit(file, proto); } +template +void VisitDescriptors(const FileDescriptor& file, FileDescriptorProto& proto, + Visitor visitor) { + using VisitorImpl = internal::VisitorImpl; + internal::VisitImpl{VisitorImpl(visitor)}.Visit(file, proto); +} + template void VisitDescriptors(const FileDescriptor& file, Visitor visitor) { using VisitorImpl = internal::VisitorImpl; diff --git a/src/google/protobuf/descriptor_visitor_test.cc b/src/google/protobuf/descriptor_visitor_test.cc index 020c3754d0..2e7bb0165e 100644 --- a/src/google/protobuf/descriptor_visitor_test.cc +++ b/src/google/protobuf/descriptor_visitor_test.cc @@ -78,6 +78,24 @@ TEST(VisitDescriptorsTest, SingleTypeWithProto) { "protobuf_unittest.TestAllTypes.NestedMessage"})); } +TEST(VisitDescriptorsTest, SingleTypeMutableProto) { + const FileDescriptor& file = + *protobuf_unittest::TestAllTypes::GetDescriptor()->file(); + FileDescriptorProto proto; + file.CopyTo(&proto); + std::vector descriptors; + VisitDescriptors(file, proto, + [&](const Descriptor& descriptor, DescriptorProto& proto) { + descriptors.push_back(descriptor.full_name()); + EXPECT_EQ(descriptor.name(), proto.name()); + proto.set_name(""); + }); + EXPECT_THAT(descriptors, + IsSupersetOf({"protobuf_unittest.TestAllTypes", + "protobuf_unittest.TestAllTypes.NestedMessage"})); + EXPECT_EQ(proto.message_type(0).name(), ""); +} + TEST(VisitDescriptorsTest, AllTypesDeduce) { const FileDescriptor& file = *protobuf_unittest::TestAllTypes::GetDescriptor()->file(); From c5a1dbeb1ef46038cd0d749ee103533e7dc4af72 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Thu, 13 Jul 2023 10:48:28 -0700 Subject: [PATCH 3/6] Implement helpers for exporting all FeatureSets to generators. There are 4 different feature sets for every descriptor: * Runtime/resolved - Used to make runtime decisions * Source/resolved - Used to make codegen decisions * Runtime/raw - Used to reason about the original proto file during runtime * Source/raw - Used to validate features during codegen All of these will need to be shipped to code generators. While C++ generators can use the C++ runtime to reconstruct these, they won't end up in the FileDescriptorProtos we send to runtimes. Similarly, non-C++ generators wouldn't be able to get them without duplicating our feature resolution logic. This change adds a helper that allows us to bundle all of these into the protos we send to generators. PiperOrigin-RevId: 547849243 --- src/google/protobuf/compiler/BUILD.bazel | 19 ++ src/google/protobuf/compiler/code_generator.h | 12 + .../compiler/code_generator_unittest.cc | 299 ++++++++++++++++++ src/google/protobuf/compiler/retention.cc | 14 +- src/google/protobuf/compiler/retention.h | 2 + .../protobuf/compiler/retention_unittest.cc | 65 +++- src/google/protobuf/descriptor.cc | 35 +- src/google/protobuf/descriptor.h | 13 +- src/google/protobuf/descriptor_unittest.cc | 41 +++ src/google/protobuf/unittest_features.proto | 28 ++ 10 files changed, 512 insertions(+), 16 deletions(-) create mode 100644 src/google/protobuf/compiler/code_generator_unittest.cc diff --git a/src/google/protobuf/compiler/BUILD.bazel b/src/google/protobuf/compiler/BUILD.bazel index 5898938000..58b8802ff4 100644 --- a/src/google/protobuf/compiler/BUILD.bazel +++ b/src/google/protobuf/compiler/BUILD.bazel @@ -69,6 +69,7 @@ cc_library( visibility = ["//visibility:public"], deps = [ "//src/google/protobuf:protobuf_nowkt", + "//src/google/protobuf/compiler:retention", "//src/google/protobuf/io:io_win32", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/log:absl_check", @@ -248,6 +249,24 @@ cc_binary( ], ) +cc_test( + name = "code_generator_unittest", + srcs = ["code_generator_unittest.cc"], + copts = COPTS, + deps = [ + ":code_generator", + ":importer", + "//src/google/protobuf:cc_test_protos", + "//src/google/protobuf:test_textproto", + "//src/google/protobuf/io", + "//src/google/protobuf/testing", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/strings:str_format", + "@com_google_googletest//:gtest", + "@com_google_googletest//:gtest_main", + ], +) + cc_test( name = "command_line_interface_unittest", srcs = ["command_line_interface_unittest.cc"], diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h index cff469753b..17674c90f2 100644 --- a/src/google/protobuf/compiler/code_generator.h +++ b/src/google/protobuf/compiler/code_generator.h @@ -43,7 +43,9 @@ #include #include "absl/strings/string_view.h" +#include "google/protobuf/compiler/retention.h" #include "google/protobuf/descriptor.h" +#include "google/protobuf/descriptor.pb.h" #include "google/protobuf/port.h" // Must be included last. @@ -143,6 +145,16 @@ class PROTOC_EXPORT CodeGenerator { static const FeatureSet& GetSourceRawFeatures(const DescriptorT& desc) { return ::google::protobuf::internal::InternalFeatureHelper::GetRawFeatures(desc); } + + // Converts a FileDescriptor to a FileDescriptorProto suitable for passing off + // to a runtime. Notably, this strips all source-retention options and + // includes both raw and resolved features. + static FileDescriptorProto GetRuntimeProto(const FileDescriptor& file) { + FileDescriptorProto proto = + ::google::protobuf::internal::InternalFeatureHelper::GetGeneratorProto(file); + StripSourceRetentionOptions(*file.pool(), proto); + return proto; + } #endif // PROTOBUF_FUTURE_EDITIONS }; diff --git a/src/google/protobuf/compiler/code_generator_unittest.cc b/src/google/protobuf/compiler/code_generator_unittest.cc new file mode 100644 index 0000000000..626342d3fe --- /dev/null +++ b/src/google/protobuf/compiler/code_generator_unittest.cc @@ -0,0 +1,299 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "google/protobuf/compiler/code_generator.h" + +#include + +#include "google/protobuf/descriptor.pb.h" +#include +#include +#include "absl/log/absl_log.h" +#include "absl/strings/str_format.h" +#include "absl/strings/str_replace.h" +#include "absl/strings/string_view.h" +#include "google/protobuf/compiler/parser.h" +#include "google/protobuf/io/tokenizer.h" +#include "google/protobuf/io/zero_copy_stream_impl_lite.h" +#include "google/protobuf/test_textproto.h" +#include "google/protobuf/unittest_features.pb.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace { + +using ::testing::NotNull; + +class TestGenerator : public CodeGenerator { + public: + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* generator_context, + std::string* error) const override { + return true; + } + + // Expose the protected methods for testing. + using CodeGenerator::GetRuntimeProto; + using CodeGenerator::GetSourceFeatures; + using CodeGenerator::GetSourceRawFeatures; +}; + +class SimpleErrorCollector : public io::ErrorCollector { + public: + void RecordError(int line, int column, absl::string_view message) override { + ABSL_LOG(ERROR) << absl::StrFormat("%d:%d:%s", line, column, message); + } +}; + +class CodeGeneratorTest : public ::testing::Test { + protected: + void SetUp() override { + ASSERT_THAT(BuildFile(DescriptorProto::descriptor()->file()), NotNull()); + ASSERT_THAT(BuildFile(pb::TestMessage::descriptor()->file()), NotNull()); + } + + const FileDescriptor* BuildFile(absl::string_view schema) { + io::ArrayInputStream input_stream(schema.data(), + static_cast(schema.size())); + SimpleErrorCollector error_collector; + io::Tokenizer tokenizer(&input_stream, &error_collector); + Parser parser; + parser.RecordErrorsTo(&error_collector); + FileDescriptorProto proto; + ABSL_CHECK(parser.Parse(&tokenizer, &proto)) << schema; + proto.set_name("test.proto"); + return pool_.BuildFile(proto); + } + + const FileDescriptor* BuildFile(const FileDescriptor* file) { + FileDescriptorProto proto; + file->CopyTo(&proto); + return pool_.BuildFile(proto); + } + + DescriptorPool pool_; +}; + +TEST_F(CodeGeneratorTest, GetSourceRawFeaturesRoot) { + auto file = BuildFile(R"schema( + edition = "2023"; + package protobuf_unittest; + + import "google/protobuf/unittest_features.proto"; + + option features.field_presence = EXPLICIT; // 2023 default + option features.enum_type = CLOSED; // override + option features.(pb.test).int_file_feature = 8; + option features.(pb.test).string_source_feature = "file"; + )schema"); + ASSERT_THAT(file, NotNull()); + + EXPECT_THAT(TestGenerator::GetSourceRawFeatures(*file), + google::protobuf::EqualsProto(R"pb( + field_presence: EXPLICIT + enum_type: CLOSED + [pb.test] { int_file_feature: 8 string_source_feature: "file" } + )pb")); +} + +TEST_F(CodeGeneratorTest, GetSourceRawFeaturesInherited) { + auto file = BuildFile(R"schema( + edition = "2023"; + package protobuf_unittest; + + import "google/protobuf/unittest_features.proto"; + + option features.enum_type = OPEN; + option features.(pb.test).int_file_feature = 6; + message EditionsMessage { + option features.(pb.test).int_message_feature = 7; + option features.(pb.test).int_multiple_feature = 8; + + string field = 1 [ + features.field_presence = EXPLICIT, + features.(pb.test).int_multiple_feature = 9, + features.(pb.test).string_source_feature = "field" + ]; + } + )schema"); + ASSERT_THAT(file, NotNull()); + + const FieldDescriptor* field = + file->FindMessageTypeByName("EditionsMessage")->FindFieldByName("field"); + ASSERT_THAT(field, NotNull()); + + EXPECT_THAT( + TestGenerator::GetSourceRawFeatures(*field), google::protobuf::EqualsProto(R"pb( + field_presence: EXPLICIT + [pb.test] { int_multiple_feature: 9 string_source_feature: "field" } + )pb")); +} + +TEST_F(CodeGeneratorTest, GetSourceFeaturesRoot) { + auto file = BuildFile(R"schema( + edition = "2023"; + package protobuf_unittest; + + import "google/protobuf/unittest_features.proto"; + + option features.field_presence = EXPLICIT; // 2023 default + option features.enum_type = CLOSED; // override + option features.(pb.test).int_file_feature = 8; + option features.(pb.test).string_source_feature = "file"; + )schema"); + ASSERT_THAT(file, NotNull()); + + const FeatureSet& features = TestGenerator::GetSourceFeatures(*file); + const pb::TestFeatures& ext = features.GetExtension(pb::test); + + EXPECT_TRUE(features.has_repeated_field_encoding()); + EXPECT_TRUE(features.field_presence()); + EXPECT_EQ(features.field_presence(), FeatureSet::EXPLICIT); + EXPECT_EQ(features.enum_type(), FeatureSet::CLOSED); + + EXPECT_TRUE(ext.has_int_message_feature()); + EXPECT_EQ(ext.int_file_feature(), 8); + EXPECT_EQ(ext.string_source_feature(), "file"); +} + +TEST_F(CodeGeneratorTest, GetSourceFeaturesInherited) { + auto file = BuildFile(R"schema( + edition = "2023"; + package protobuf_unittest; + + import "google/protobuf/unittest_features.proto"; + + option features.enum_type = CLOSED; + option features.(pb.test).int_source_feature = 5; + option features.(pb.test).int_file_feature = 6; + message EditionsMessage { + option features.(pb.test).int_message_feature = 7; + option features.(pb.test).int_multiple_feature = 8; + option features.(pb.test).string_source_feature = "message"; + + string field = 1 [ + features.field_presence = IMPLICIT, + features.(pb.test).int_multiple_feature = 9, + features.(pb.test).string_source_feature = "field" + ]; + } + )schema"); + ASSERT_THAT(file, NotNull()); + + const FieldDescriptor* field = + file->FindMessageTypeByName("EditionsMessage")->FindFieldByName("field"); + ASSERT_THAT(field, NotNull()); + const FeatureSet& features = TestGenerator::GetSourceFeatures(*field); + const pb::TestFeatures& ext = features.GetExtension(pb::test); + + EXPECT_EQ(features.enum_type(), FeatureSet::CLOSED); + EXPECT_EQ(features.field_presence(), FeatureSet::IMPLICIT); + + EXPECT_EQ(ext.int_message_feature(), 7); + EXPECT_EQ(ext.int_file_feature(), 6); + EXPECT_EQ(ext.int_multiple_feature(), 9); + EXPECT_EQ(ext.int_source_feature(), 5); + EXPECT_EQ(ext.string_source_feature(), "field"); +} + +TEST_F(CodeGeneratorTest, GetRuntimeProtoRoot) { + auto file = BuildFile(R"schema( + edition = "2023"; + package protobuf_unittest; + + import "google/protobuf/unittest_features.proto"; + + option features.enum_type = CLOSED; + option features.(pb.test).int_source_feature = 5; + option features.(pb.test).int_file_feature = 6; + )schema"); + ASSERT_THAT(file, NotNull()); + + FileDescriptorProto proto = TestGenerator::GetRuntimeProto(*file); + const FeatureSet& features = proto.options().features(); + const pb::TestFeatures& ext = features.GetExtension(pb::test); + + EXPECT_THAT(features.raw_features(), + EqualsProto(R"pb(enum_type: CLOSED + [pb.test] { int_file_feature: 6 })pb")); + EXPECT_EQ(features.enum_type(), FeatureSet::CLOSED); + EXPECT_TRUE(features.has_field_presence()); + EXPECT_EQ(features.field_presence(), FeatureSet::EXPLICIT); + + EXPECT_FALSE(ext.has_int_source_feature()); + EXPECT_EQ(ext.int_file_feature(), 6); +} + +TEST_F(CodeGeneratorTest, GetRuntimeProtoInherited) { + auto file = BuildFile(R"schema( + edition = "2023"; + package protobuf_unittest; + + import "google/protobuf/unittest_features.proto"; + + option features.enum_type = CLOSED; + option features.(pb.test).int_source_feature = 5; + option features.(pb.test).int_file_feature = 6; + message EditionsMessage { + option features.(pb.test).int_message_feature = 7; + option features.(pb.test).int_multiple_feature = 8; + + string field = 1 [ + features.field_presence = IMPLICIT, + features.(pb.test).int_multiple_feature = 9, + features.(pb.test).string_source_feature = "field" + ]; + } + )schema"); + ASSERT_THAT(file, NotNull()); + + FileDescriptorProto proto = TestGenerator::GetRuntimeProto(*file); + const FieldDescriptorProto& field = proto.message_type(0).field(0); + const FeatureSet& features = field.options().features(); + const pb::TestFeatures& ext = features.GetExtension(pb::test); + + EXPECT_THAT(features.raw_features(), google::protobuf::EqualsProto(R"pb( + field_presence: IMPLICIT + [pb.test] { int_multiple_feature: 9 } + )pb")); + EXPECT_EQ(features.enum_type(), FeatureSet::CLOSED); + EXPECT_EQ(features.field_presence(), FeatureSet::IMPLICIT); + EXPECT_EQ(ext.int_multiple_feature(), 9); + EXPECT_EQ(ext.int_message_feature(), 7); + EXPECT_EQ(ext.int_file_feature(), 6); + EXPECT_FALSE(ext.has_int_source_feature()); + EXPECT_FALSE(ext.has_string_source_feature()); +} + +} // namespace +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/retention.cc b/src/google/protobuf/compiler/retention.cc index 822df6096f..38df6210d1 100644 --- a/src/google/protobuf/compiler/retention.cc +++ b/src/google/protobuf/compiler/retention.cc @@ -248,16 +248,22 @@ FileDescriptorProto StripSourceRetentionOptions(const FileDescriptor& file, bool include_source_code_info) { FileDescriptorProto file_proto; file.CopyTo(&file_proto); - std::vector> stripped_paths; - ConvertToDynamicMessageAndStripOptions(file_proto, *file.pool(), - &stripped_paths); if (include_source_code_info) { file.CopySourceCodeInfoTo(&file_proto); - StripSourceCodeInfo(stripped_paths, *file_proto.mutable_source_code_info()); } + StripSourceRetentionOptions(*file.pool(), file_proto); return file_proto; } +void StripSourceRetentionOptions(const DescriptorPool& pool, + FileDescriptorProto& file_proto) { + std::vector> stripped_paths; + ConvertToDynamicMessageAndStripOptions(file_proto, pool, &stripped_paths); + if (file_proto.has_source_code_info()) { + StripSourceCodeInfo(stripped_paths, *file_proto.mutable_source_code_info()); + } +} + DescriptorProto StripSourceRetentionOptions(const Descriptor& message) { DescriptorProto message_proto; message.CopyTo(&message_proto); diff --git a/src/google/protobuf/compiler/retention.h b/src/google/protobuf/compiler/retention.h index bf7fe0e1d6..63353b2c7f 100644 --- a/src/google/protobuf/compiler/retention.h +++ b/src/google/protobuf/compiler/retention.h @@ -47,6 +47,8 @@ namespace compiler { // corresponding to source-retention options. PROTOC_EXPORT FileDescriptorProto StripSourceRetentionOptions( const FileDescriptor& file, bool include_source_code_info = false); +PROTOC_EXPORT void StripSourceRetentionOptions(const DescriptorPool& pool, + FileDescriptorProto& file_proto); PROTOC_EXPORT DescriptorProto StripSourceRetentionOptions(const Descriptor& message); PROTOC_EXPORT DescriptorProto::ExtensionRange StripSourceRetentionOptions( diff --git a/src/google/protobuf/compiler/retention_unittest.cc b/src/google/protobuf/compiler/retention_unittest.cc index fa14e597ae..b0629e01a0 100644 --- a/src/google/protobuf/compiler/retention_unittest.cc +++ b/src/google/protobuf/compiler/retention_unittest.cc @@ -115,16 +115,7 @@ class RetentionStripTest : public testing::Test { DynamicMessageFactory factory; std::unique_ptr dynamic_message( factory.GetPrototype(file_options_descriptor)->New()); - ABSL_CHECK(TextFormat::ParseFromString( - R"([google.protobuf.internal.options] { - i2: 456 - c {} - rc {} - } - [google.protobuf.internal.repeated_options] { - i2: 222 - })", - dynamic_message.get())); + ABSL_CHECK(TextFormat::ParseFromString(data, dynamic_message.get())); ProtoType ret; ABSL_CHECK(ret.ParseFromString(dynamic_message->SerializeAsString())); return ret; @@ -179,6 +170,60 @@ TEST_F(RetentionStripTest, StripSourceRetentionFileOptions) { EqualsProto(expected_options)); } +TEST_F(RetentionStripTest, StripSourceRetentionProtoFileOptions) { + const FileDescriptor* file = ParseSchema(R"schema( + option (source_retention_option) = 123; + option (options) = { + i1: 123 + i2: 456 + c { s: "abc" } + rc { s: "abc" } + }; + option (repeated_options) = { + i1: 111 i2: 222 + }; + + message Options { + optional int32 i1 = 1 [retention = RETENTION_SOURCE]; + optional int32 i2 = 2; + message ChildMessage { + optional string s = 1 [retention = RETENTION_SOURCE]; + } + optional ChildMessage c = 3; + repeated ChildMessage rc = 4; + } + + extend google.protobuf.FileOptions { + optional int32 source_retention_option = 50000 [retention = RETENTION_SOURCE]; + optional Options options = 50001; + repeated Options repeated_options = 50002; + } + )schema"); + + FileDescriptorProto proto; + file->CopyTo(&proto); + + ASSERT_THAT(proto.options(), EqualsProto(BuildDynamicProto(R"pb( + [google.protobuf.internal.source_retention_option]: 123 + [google.protobuf.internal.options] { + i1: 123 + i2: 456 + c { s: "abc" } + rc { s: "abc" } + } + [google.protobuf.internal.repeated_options] { i1: 111 i2: 222 })pb"))); + + StripSourceRetentionOptions(*file->pool(), proto); + + EXPECT_THAT(proto.options(), EqualsProto(BuildDynamicProto(R"pb( + [google.protobuf.internal.options] { + i2: 456 + c {} + rc {} + } + [google.protobuf.internal.repeated_options] { i2: 222 })pb"))); +} + TEST_F(RetentionStripTest, StripSourceRetentionMessageOptions) { const FileDescriptor* file = ParseSchema(R"schema( message TestMessage { diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 1f15e59c88..4531801c6b 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -2759,6 +2759,32 @@ FileDescriptor::FileDescriptor() {} // CopyTo methods ==================================================== +#ifdef PROTOBUF_FUTURE_EDITIONS +namespace internal { +FileDescriptorProto InternalFeatureHelper::GetGeneratorProto( + const FileDescriptor& file) { + FileDescriptorProto file_proto; + file.CopyTo(&file_proto); + + // Insert all the raw features back into the proto. + internal::VisitDescriptors( + file, file_proto, [](const auto& desc, auto& proto) { + const auto& features = GetFeatures(desc); + if (&features != &FeatureSet::default_instance() && + !IsLegacyFeatureSet(features)) { + *proto.mutable_options()->mutable_features() = features; + } + const auto& raw_features = GetRawFeatures(desc); + if (&raw_features != &FeatureSet::default_instance()) { + *proto.mutable_options()->mutable_features()->mutable_raw_features() = + GetRawFeatures(desc); + } + }); + return file_proto; +} +} // namespace internal +#endif // PROTOBUF_FUTURE_EDITIONS + void FileDescriptor::CopyTo(FileDescriptorProto* proto) const { CopyHeadingTo(proto); @@ -5407,7 +5433,14 @@ void DescriptorBuilder::ResolveFeaturesImpl( // internal details. FeatureSet* mutable_features = alloc.AllocateArray(1); descriptor->proto_features_ = mutable_features; - options->mutable_features()->Swap(mutable_features); + if (options->features().has_raw_features()) { + // If the raw features are specified, use those and recalculate the + // resolved features. + options->mutable_features()->mutable_raw_features()->Swap( + mutable_features); + } else { + options->mutable_features()->Swap(mutable_features); + } options->clear_features(); } else if (!force_merge) { // Nothing to merge, and we aren't forcing it. diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index 1bd40c8aff..0c0eccbf29 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -262,7 +262,7 @@ class PROTOBUF_EXPORT SymbolBaseN : public SymbolBase {}; // This class is for internal use only and provides access to the FeatureSets // defined on descriptors. These features are not designed to be stable, and // depending directly on them (vs the public descriptor APIs) is not safe. -class InternalFeatureHelper { +class PROTOBUF_EXPORT InternalFeatureHelper { public: template static const FeatureSet& GetFeatures(const DescriptorT& desc) { @@ -271,10 +271,21 @@ class InternalFeatureHelper { private: friend class ::google::protobuf::compiler::CodeGenerator; + + // Provides a restricted view exclusively to code generators. Raw features + // haven't been resolved, and are virtually meaningless to everyone else. Code + // generators will need them to validate their own features, and runtimes may + // need them internally to be able to properly represent the original proto + // files from generated code. template static const FeatureSet& GetRawFeatures(const DescriptorT& desc) { return *desc.proto_features_; } + + // Provides the full descriptor tree including both resolved features (in the + // `features` fields) and unresolved features (in the `raw_features` fields) + // for every descriptor. + static FileDescriptorProto GetGeneratorProto(const FileDescriptor& file); }; #endif // PROTOBUF_FUTURE_EDITIONS diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index bef2eb1846..cb59fa1645 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -9538,6 +9538,47 @@ TEST_F(FeaturesTest, UninterpretedOptionsMergeExtension) { 9); } +TEST_F(FeaturesTest, RawFeatures) { + BuildDescriptorMessagesInTestPool(); + const FileDescriptor* file = BuildFile(R"pb( + name: "foo.proto" + syntax: "editions" + edition: "2023" + options { features { raw_features { field_presence: IMPLICIT } } } + )pb"); + EXPECT_THAT(file->options(), EqualsProto("")); + EXPECT_THAT(GetFeatures(file), EqualsProto(R"pb( + field_presence: IMPLICIT + enum_type: OPEN + repeated_field_encoding: PACKED + string_field_validation: MANDATORY + message_encoding: LENGTH_PREFIXED + json_format: ALLOW)pb")); +} + +TEST_F(FeaturesTest, RawFeaturesConflict) { + BuildDescriptorMessagesInTestPool(); + const FileDescriptor* file = BuildFile(R"pb( + name: "foo.proto" + syntax: "editions" + edition: "2023" + options { + features { + enum_type: CLOSED + raw_features { field_presence: IMPLICIT } + } + } + )pb"); + EXPECT_THAT(file->options(), EqualsProto("")); + EXPECT_THAT(GetFeatures(file), EqualsProto(R"pb( + field_presence: IMPLICIT + enum_type: OPEN + repeated_field_encoding: PACKED + string_field_validation: MANDATORY + message_encoding: LENGTH_PREFIXED + json_format: ALLOW)pb")); +} + TEST_F(FeaturesTest, InvalidJsonUniquenessDefaultWarning) { BuildFileWithWarnings( R"pb( diff --git a/src/google/protobuf/unittest_features.proto b/src/google/protobuf/unittest_features.proto index 79ac22e951..7ba44b19b2 100644 --- a/src/google/protobuf/unittest_features.proto +++ b/src/google/protobuf/unittest_features.proto @@ -164,4 +164,32 @@ message TestFeatures { edition_defaults = { edition: "2023", value: "ENUM_VALUE1" }, edition_defaults = { edition: "2024", value: "ENUM_VALUE4" } ]; + + optional int32 int_source_feature = 15 [ + retention = RETENTION_SOURCE, + targets = TARGET_TYPE_FILE, + targets = TARGET_TYPE_FIELD, + targets = TARGET_TYPE_MESSAGE, + targets = TARGET_TYPE_ENUM, + targets = TARGET_TYPE_ENUM_ENTRY, + targets = TARGET_TYPE_SERVICE, + targets = TARGET_TYPE_METHOD, + targets = TARGET_TYPE_ONEOF, + targets = TARGET_TYPE_EXTENSION_RANGE, + edition_defaults = { edition: "2023", value: "1" } + ]; + + optional string string_source_feature = 16 [ + retention = RETENTION_SOURCE, + targets = TARGET_TYPE_FILE, + targets = TARGET_TYPE_FIELD, + targets = TARGET_TYPE_MESSAGE, + targets = TARGET_TYPE_ENUM, + targets = TARGET_TYPE_ENUM_ENTRY, + targets = TARGET_TYPE_SERVICE, + targets = TARGET_TYPE_METHOD, + targets = TARGET_TYPE_ONEOF, + targets = TARGET_TYPE_EXTENSION_RANGE, + edition_defaults = { edition: "2023", value: "'2023'" } + ]; } From f1de28a435a68e3fe7e9336a6b681b2004ab5efd Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Thu, 13 Jul 2023 14:36:03 -0700 Subject: [PATCH 4/6] Send full feature sets to plugins. There are 4 different feature sets for every descriptor: * Runtime/resolved - Used to make runtime decisions * Source/resolved - Used to make codegen decisions * Runtime/unresolved - Used to reason about the original proto file during runtime * Source/unresolved - Used to validate features during codegen Plugins will receive all 4 of these. Unresolved features will show up in the `raw_features` fields nested inside `features`. The runtime features will be in the `proto_file` field of the request, while the source features will be in the unstripped `source_file_descriptors` field. PiperOrigin-RevId: 547925275 --- src/google/protobuf/compiler/BUILD.bazel | 1 + .../compiler/command_line_interface.cc | 41 ++-- .../compiler/command_line_interface.h | 22 ++ .../command_line_interface_unittest.cc | 221 +++++++++++++++--- .../compiler/cpp/bootstrap_unittest.cc | 6 +- .../compiler/cpp/generator_unittest.cc | 10 +- src/google/protobuf/compiler/cpp/unittest.cc | 4 +- src/google/protobuf/compiler/cpp/unittest.inc | 6 +- .../java/message_serialization_unittest.cc | 2 +- .../protobuf/compiler/parser_unittest.cc | 5 +- src/google/protobuf/descriptor.h | 1 + src/google/protobuf/extension_set_unittest.cc | 4 +- .../protobuf/io/zero_copy_stream_unittest.cc | 2 +- src/google/protobuf/json/json_test.cc | 2 +- src/google/protobuf/map_test.inc | 8 +- src/google/protobuf/message_unittest.inc | 4 +- src/google/protobuf/test_util2.h | 24 +- src/google/protobuf/text_format_unittest.cc | 4 +- 18 files changed, 257 insertions(+), 110 deletions(-) diff --git a/src/google/protobuf/compiler/BUILD.bazel b/src/google/protobuf/compiler/BUILD.bazel index 58b8802ff4..d5f3a7aecb 100644 --- a/src/google/protobuf/compiler/BUILD.bazel +++ b/src/google/protobuf/compiler/BUILD.bazel @@ -295,6 +295,7 @@ cc_test( ":mock_code_generator", "//:protobuf", "//src/google/protobuf:cc_test_protos", + "//src/google/protobuf:test_textproto", "//src/google/protobuf:test_util2", "//src/google/protobuf/compiler/cpp:names", "//src/google/protobuf/io", diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 0890e6354f..37bf62bcc1 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -302,27 +302,13 @@ std::string PluginName(absl::string_view plugin_prefix, } -// Get all transitive dependencies of the given file (including the file -// itself), adding them to the given list of FileDescriptorProtos. The -// protos will be ordered such that every file is listed before any file that -// depends on it, so that you can call DescriptorPool::BuildFile() on them -// in order. Any files in *already_seen will not be added, and each file -// added will be inserted into *already_seen. If include_source_code_info is -// true then include the source code information in the FileDescriptorProtos. -// If include_json_name is true, populate the json_name field of -// FieldDescriptorProto for all fields. -struct TransitiveDependencyOptions { - bool include_json_name = false; - bool include_source_code_info = false; - bool retain_options = false; -}; +} // namespace -void GetTransitiveDependencies( +void CommandLineInterface::GetTransitiveDependencies( const FileDescriptor* file, absl::flat_hash_set* already_seen, RepeatedPtrField* output, - const TransitiveDependencyOptions& options = - TransitiveDependencyOptions()) { + const TransitiveDependencyOptions& options) { if (!already_seen->insert(file).second) { // Already saw this file. Skip. return; @@ -336,22 +322,19 @@ void GetTransitiveDependencies( // Add this file. FileDescriptorProto* new_descriptor = output->Add(); - if (options.retain_options) { - file->CopyTo(new_descriptor); - if (options.include_source_code_info) { - file->CopySourceCodeInfoTo(new_descriptor); - } - } else { - *new_descriptor = - StripSourceRetentionOptions(*file, options.include_source_code_info); + *new_descriptor = + google::protobuf::internal::InternalFeatureHelper::GetGeneratorProto(*file); + if (options.include_source_code_info) { + file->CopySourceCodeInfoTo(new_descriptor); + } + if (!options.retain_options) { + StripSourceRetentionOptions(*file->pool(), *new_descriptor); } if (options.include_json_name) { file->CopyJsonNameTo(new_descriptor); } } -} // namespace - // A MultiFileErrorCollector that prints errors to stderr. class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector, @@ -2629,9 +2612,11 @@ bool CommandLineInterface::GeneratePluginOutput( if (files_to_generate.contains(file_proto.name())) { const FileDescriptor* file = pool->FindFileByName(file_proto.name()); *request.add_source_file_descriptors() = std::move(file_proto); - file_proto = StripSourceRetentionOptions(*file); + file_proto = + google::protobuf::internal::InternalFeatureHelper::GetGeneratorProto(*file); file->CopySourceCodeInfoTo(&file_proto); file->CopyJsonNameTo(&file_proto); + StripSourceRetentionOptions(*file->pool(), file_proto); } } diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h index 51e2312fc9..c0a606d7c8 100644 --- a/src/google/protobuf/compiler/command_line_interface.h +++ b/src/google/protobuf/compiler/command_line_interface.h @@ -73,6 +73,12 @@ class CodeGenerator; // code_generator.h class GeneratorContext; // code_generator.h class DiskSourceTree; // importer.h +struct TransitiveDependencyOptions { + bool include_json_name = false; + bool include_source_code_info = false; + bool retain_options = false; +}; + // This class implements the command-line interface to the protocol compiler. // It is designed to make it very easy to create a custom protocol compiler // supporting the languages of your choice. For example, if you wanted to @@ -325,6 +331,22 @@ class PROTOC_EXPORT CommandLineInterface { // listed as free numbers in the output. void PrintFreeFieldNumbers(const Descriptor* descriptor); + // Get all transitive dependencies of the given file (including the file + // itself), adding them to the given list of FileDescriptorProtos. The + // protos will be ordered such that every file is listed before any file that + // depends on it, so that you can call DescriptorPool::BuildFile() on them + // in order. Any files in *already_seen will not be added, and each file + // added will be inserted into *already_seen. If include_source_code_info + // (from TransitiveDependencyOptions) is true then include the source code + // information in the FileDescriptorProtos. If include_json_name is true, + // populate the json_name field of FieldDescriptorProto for all fields. + void GetTransitiveDependencies( + const FileDescriptor* file, + absl::flat_hash_set* already_seen, + RepeatedPtrField* output, + const TransitiveDependencyOptions& options = + TransitiveDependencyOptions()); + // ----------------------------------------------------------------- // The name of the executable as invoked (i.e. argv[0]). diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index 07cd76d8e0..edde502c6a 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -43,6 +43,7 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "google/protobuf/compiler/command_line_interface_tester.h" +#include "google/protobuf/unittest_features.pb.h" #ifndef _MSC_VER #include @@ -67,6 +68,7 @@ #include "google/protobuf/compiler/plugin.pb.h" #include "google/protobuf/compiler/subprocess.h" #include "google/protobuf/io/io_win32.h" +#include "google/protobuf/test_textproto.h" #include "google/protobuf/test_util2.h" #include "google/protobuf/unittest.pb.h" #include "google/protobuf/unittest_custom_options.pb.h" @@ -439,7 +441,7 @@ TEST_F(CommandLineInterfaceTest, Plugin_OptionRetention) { std::string plugin_path = GOOGLE_PROTOBUF_FAKE_PLUGIN_PATH; #else std::string plugin_path = absl::StrCat( - TestUtil::TestSourceDir(), "/third_party/protobuf/compiler/fake_plugin"); + TestUtil::TestSourceDir(), "/google/protobuf/compiler/fake_plugin"); #endif // Invoke protoc with fake_plugin to get ahold of the CodeGeneratorRequest @@ -510,7 +512,7 @@ TEST_F(CommandLineInterfaceTest, Plugin_SourceFileDescriptors) { std::string plugin_path = GOOGLE_PROTOBUF_FAKE_PLUGIN_PATH; #else std::string plugin_path = absl::StrCat( - TestUtil::TestSourceDir(), "/third_party/protobuf/compiler/fake_plugin"); + TestUtil::TestSourceDir(), "/google/protobuf/compiler/fake_plugin"); #endif // Invoke protoc with fake_plugin to get ahold of the CodeGeneratorRequest @@ -1384,13 +1386,13 @@ TEST_F(CommandLineInterfaceTest, FeaturesEditionZero) { } TEST_F(CommandLineInterfaceTest, FeatureExtensions) { - CreateTempFile("net/proto2/proto/descriptor.proto", + CreateTempFile("google/protobuf/descriptor.proto", google::protobuf::DescriptorProto::descriptor()->file()->DebugString()); CreateTempFile("features.proto", R"schema( syntax = "proto2"; package pb; - import "net/proto2/proto/descriptor.proto"; + import "google/protobuf/descriptor.proto"; extend google.protobuf.FeatureSet { optional TestFeatures test = 9999; } @@ -1449,13 +1451,13 @@ TEST_F(CommandLineInterfaceTest, FeatureTargetError) { } TEST_F(CommandLineInterfaceTest, FeatureExtensionError) { - CreateTempFile("net/proto2/proto/descriptor.proto", + CreateTempFile("google/protobuf/descriptor.proto", google::protobuf::DescriptorProto::descriptor()->file()->DebugString()); CreateTempFile("features.proto", R"schema( syntax = "proto2"; package pb; - import "net/proto2/proto/descriptor.proto"; + import "google/protobuf/descriptor.proto"; extend google.protobuf.FeatureSet { optional TestFeatures test = 9999; } @@ -1482,6 +1484,165 @@ TEST_F(CommandLineInterfaceTest, FeatureExtensionError) { "repeated field"); } +TEST_F(CommandLineInterfaceTest, Plugin_LegacyFeatures) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto2"; + package foo; + message Foo { + optional int32 b = 1; + })schema"); + +#ifdef GOOGLE_PROTOBUF_FAKE_PLUGIN_PATH + std::string plugin_path = GOOGLE_PROTOBUF_FAKE_PLUGIN_PATH; +#else + std::string plugin_path = absl::StrCat( + TestUtil::TestSourceDir(), "/google/protobuf/compiler/fake_plugin"); +#endif + + // Invoke protoc with fake_plugin to get ahold of the CodeGeneratorRequest + // sent by protoc. + Run(absl::StrCat( + "protocol_compiler --fake_plugin_out=$tmpdir --proto_path=$tmpdir " + "foo.proto --plugin=prefix-gen-fake_plugin=", + plugin_path)); + ExpectNoErrors(); + std::string base64_output = ReadFile("foo.proto.request"); + std::string binary_request; + ASSERT_TRUE(absl::Base64Unescape(base64_output, &binary_request)); + CodeGeneratorRequest request; + ASSERT_TRUE(request.ParseFromString(binary_request)); + + EXPECT_FALSE( + request.proto_file(0).message_type(0).field(0).options().has_features()); + EXPECT_FALSE(request.source_file_descriptors(0) + .message_type(0) + .field(0) + .options() + .has_features()); +} + +TEST_F(CommandLineInterfaceTest, Plugin_RuntimeFeatures) { + CreateTempFile("foo.proto", + R"schema( + edition = "2023"; + package foo; + message Foo { + int32 b = 1 [features.field_presence = IMPLICIT]; + })schema"); + +#ifdef GOOGLE_PROTOBUF_FAKE_PLUGIN_PATH + std::string plugin_path = GOOGLE_PROTOBUF_FAKE_PLUGIN_PATH; +#else + std::string plugin_path = absl::StrCat( + TestUtil::TestSourceDir(), "/google/protobuf/compiler/fake_plugin"); +#endif + + // Invoke protoc with fake_plugin to get ahold of the CodeGeneratorRequest + // sent by protoc. + Run( + absl::StrCat("protocol_compiler --experimental_editions " + "--fake_plugin_out=$tmpdir --proto_path=$tmpdir " + "foo.proto --plugin=prefix-gen-fake_plugin=", + plugin_path)); + ExpectNoErrors(); + std::string base64_output = ReadFile("foo.proto.request"); + std::string binary_request; + ASSERT_TRUE(absl::Base64Unescape(base64_output, &binary_request)); + CodeGeneratorRequest request; + ASSERT_TRUE(request.ParseFromString(binary_request)); + + EXPECT_THAT( + request.proto_file(0).message_type(0).field(0).options().features(), + EqualsProto(R"pb(field_presence: IMPLICIT + enum_type: OPEN + repeated_field_encoding: PACKED + string_field_validation: MANDATORY + message_encoding: LENGTH_PREFIXED + json_format: ALLOW + raw_features { field_presence: IMPLICIT } + )pb")); + EXPECT_THAT(request.source_file_descriptors(0) + .message_type(0) + .field(0) + .options() + .features(), + EqualsProto(R"pb(field_presence: IMPLICIT + enum_type: OPEN + repeated_field_encoding: PACKED + string_field_validation: MANDATORY + message_encoding: LENGTH_PREFIXED + json_format: ALLOW + raw_features { field_presence: IMPLICIT } + )pb")); +} + +TEST_F(CommandLineInterfaceTest, Plugin_SourceFeatures) { + CreateTempFile("google/protobuf/descriptor.proto", + google::protobuf::DescriptorProto::descriptor()->file()->DebugString()); + CreateTempFile("google/protobuf/unittest_features.proto", + pb::TestFeatures::descriptor()->file()->DebugString()); + CreateTempFile("foo.proto", + R"schema( + edition = "2023"; + import "google/protobuf/unittest_features.proto"; + package foo; + message Foo { + int32 b = 1 [ + features.(pb.test).int_field_feature = 99, + features.(pb.test).int_source_feature = 87 + ]; + } + )schema"); + +#ifdef GOOGLE_PROTOBUF_FAKE_PLUGIN_PATH + std::string plugin_path = GOOGLE_PROTOBUF_FAKE_PLUGIN_PATH; +#else + std::string plugin_path = absl::StrCat( + TestUtil::TestSourceDir(), "/google/protobuf/compiler/fake_plugin"); +#endif + + // Invoke protoc with fake_plugin to get ahold of the CodeGeneratorRequest + // sent by protoc. + Run( + absl::StrCat("protocol_compiler --experimental_editions " + "--fake_plugin_out=$tmpdir --proto_path=$tmpdir " + "foo.proto --plugin=prefix-gen-fake_plugin=", + plugin_path)); + ExpectNoErrors(); + std::string base64_output = ReadFile("foo.proto.request"); + std::string binary_request; + ASSERT_TRUE(absl::Base64Unescape(base64_output, &binary_request)); + CodeGeneratorRequest request; + ASSERT_TRUE(request.ParseFromString(binary_request)); + + { + ASSERT_EQ(request.proto_file(2).name(), "foo.proto"); + const FeatureSet& features = + request.proto_file(2).message_type(0).field(0).options().features(); + EXPECT_THAT(features.raw_features(), + EqualsProto(R"pb([pb.test] { int_field_feature: 99 })pb")); + EXPECT_FALSE(features.GetExtension(pb::test).has_int_source_feature()); + EXPECT_EQ(features.GetExtension(pb::test).int_field_feature(), 99); + } + + { + ASSERT_EQ(request.source_file_descriptors(0).name(), "foo.proto"); + const FeatureSet& features = request.source_file_descriptors(0) + .message_type(0) + .field(0) + .options() + .features(); + EXPECT_THAT(features.raw_features(), + EqualsProto(R"pb([pb.test] { + int_field_feature: 99 + int_source_feature: 87 + })pb")); + EXPECT_EQ(features.GetExtension(pb::test).int_field_feature(), 99); + EXPECT_EQ(features.GetExtension(pb::test).int_source_feature(), 87); + } +} + #endif // PROTOBUF_FUTURE_EDITIONS @@ -2766,13 +2927,13 @@ TEST_F(CommandLineInterfaceTest, TargetTypeEnforcement) { // The target option on a field indicates what kind of entity it may apply to // when it is used as an option. This test verifies that the enforcement // works correctly on all entity types. - CreateTempFile("net/proto2/proto/descriptor.proto", + CreateTempFile("google/protobuf/descriptor.proto", google::protobuf::DescriptorProto::descriptor()->file()->DebugString()); CreateTempFile("foo.proto", R"schema( syntax = "proto2"; package protobuf_unittest; - import "net/proto2/proto/descriptor.proto"; + import "google/protobuf/descriptor.proto"; message MyOptions { optional string file_option = 1 [targets = TARGET_TYPE_FILE]; optional string extension_range_option = 2 [targets = @@ -2866,13 +3027,13 @@ TEST_F(CommandLineInterfaceTest, TargetTypeEnforcement) { } TEST_F(CommandLineInterfaceTest, TargetTypeEnforcementMultipleTargetsValid) { - CreateTempFile("net/proto2/proto/descriptor.proto", + CreateTempFile("google/protobuf/descriptor.proto", google::protobuf::DescriptorProto::descriptor()->file()->DebugString()); CreateTempFile("foo.proto", R"schema( syntax = "proto2"; package protobuf_unittest; - import "net/proto2/proto/descriptor.proto"; + import "google/protobuf/descriptor.proto"; message MyOptions { optional string message_or_file_option = 1 [ targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_FILE]; @@ -2894,13 +3055,13 @@ TEST_F(CommandLineInterfaceTest, TargetTypeEnforcementMultipleTargetsValid) { } TEST_F(CommandLineInterfaceTest, TargetTypeEnforcementMultipleTargetsInvalid) { - CreateTempFile("net/proto2/proto/descriptor.proto", + CreateTempFile("google/protobuf/descriptor.proto", google::protobuf::DescriptorProto::descriptor()->file()->DebugString()); CreateTempFile("foo.proto", R"schema( syntax = "proto2"; package protobuf_unittest; - import "net/proto2/proto/descriptor.proto"; + import "google/protobuf/descriptor.proto"; message MyOptions { optional string message_or_file_option = 1 [ targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_FILE]; @@ -2922,13 +3083,13 @@ TEST_F(CommandLineInterfaceTest, TargetTypeEnforcementMultipleTargetsInvalid) { TEST_F(CommandLineInterfaceTest, TargetTypeEnforcementMultipleEdgesWithConstraintsValid) { - CreateTempFile("net/proto2/proto/descriptor.proto", + CreateTempFile("google/protobuf/descriptor.proto", google::protobuf::DescriptorProto::descriptor()->file()->DebugString()); CreateTempFile("foo.proto", R"schema( syntax = "proto2"; package protobuf_unittest; - import "net/proto2/proto/descriptor.proto"; + import "google/protobuf/descriptor.proto"; message A { optional B b = 1 [targets = TARGET_TYPE_FILE, targets = TARGET_TYPE_ENUM]; @@ -2949,13 +3110,13 @@ TEST_F(CommandLineInterfaceTest, TEST_F(CommandLineInterfaceTest, TargetTypeEnforcementMultipleEdgesWithConstraintsInvalid) { - CreateTempFile("net/proto2/proto/descriptor.proto", + CreateTempFile("google/protobuf/descriptor.proto", google::protobuf::DescriptorProto::descriptor()->file()->DebugString()); CreateTempFile("foo.proto", R"schema( syntax = "proto2"; package protobuf_unittest; - import "net/proto2/proto/descriptor.proto"; + import "google/protobuf/descriptor.proto"; message A { optional B b = 1 [targets = TARGET_TYPE_ENUM]; } @@ -3129,28 +3290,27 @@ class EncodeDecodeTest : public testing::TestWithParam { TEST_P(EncodeDecodeTest, Encode) { RedirectStdinFromFile(TestUtil::GetTestDataPath( - "third_party/protobuf/" + "google/protobuf/" "testdata/text_format_unittest_data_oneof_implemented.txt")); std::string args; if (GetParam() != DESCRIPTOR_SET_IN) { - args.append( - TestUtil::MaybeTranslatePath("third_party/protobuf/unittest.proto")); + args.append("google/protobuf/unittest.proto"); } EXPECT_TRUE( Run(absl::StrCat(args, " --encode=protobuf_unittest.TestAllTypes"))); ExpectStdoutMatchesBinaryFile(TestUtil::GetTestDataPath( - "third_party/protobuf/testdata/golden_message_oneof_implemented")); + "google/protobuf/testdata/golden_message_oneof_implemented")); ExpectStderrMatchesText(""); } TEST_P(EncodeDecodeTest, Decode) { RedirectStdinFromFile(TestUtil::GetTestDataPath( - "third_party/protobuf/testdata/golden_message_oneof_implemented")); + "google/protobuf/testdata/golden_message_oneof_implemented")); EXPECT_TRUE( - Run(TestUtil::MaybeTranslatePath("third_party/protobuf/unittest.proto") + + Run("google/protobuf/unittest.proto" " --decode=protobuf_unittest.TestAllTypes")); ExpectStdoutMatchesTextFile(TestUtil::GetTestDataPath( - "third_party/protobuf/" + "google/protobuf/" "testdata/text_format_unittest_data_oneof_implemented.txt")); ExpectStderrMatchesText(""); } @@ -3158,7 +3318,7 @@ TEST_P(EncodeDecodeTest, Decode) { TEST_P(EncodeDecodeTest, Partial) { RedirectStdinFromText(""); EXPECT_TRUE( - Run(TestUtil::MaybeTranslatePath("third_party/protobuf/unittest.proto") + + Run("google/protobuf/unittest.proto" " --encode=protobuf_unittest.TestRequired")); ExpectStdoutMatchesText(""); ExpectStderrMatchesText( @@ -3182,7 +3342,7 @@ TEST_P(EncodeDecodeTest, DecodeRaw) { TEST_P(EncodeDecodeTest, UnknownType) { EXPECT_FALSE( - Run(TestUtil::MaybeTranslatePath("third_party/protobuf/unittest.proto") + + Run("google/protobuf/unittest.proto" " --encode=NoSuchType")); ExpectStdoutMatchesText(""); ExpectStderrMatchesText("Type not defined: NoSuchType\n"); @@ -3199,25 +3359,24 @@ TEST_P(EncodeDecodeTest, ProtoParseError) { TEST_P(EncodeDecodeTest, EncodeDeterministicOutput) { RedirectStdinFromFile(TestUtil::GetTestDataPath( - "third_party/protobuf/" + "google/protobuf/" "testdata/text_format_unittest_data_oneof_implemented.txt")); std::string args; if (GetParam() != DESCRIPTOR_SET_IN) { - args.append( - TestUtil::MaybeTranslatePath("third_party/protobuf/unittest.proto")); + args.append("google/protobuf/unittest.proto"); } EXPECT_TRUE(Run(absl::StrCat( args, " --encode=protobuf_unittest.TestAllTypes --deterministic_output"))); ExpectStdoutMatchesBinaryFile(TestUtil::GetTestDataPath( - "third_party/protobuf/testdata/golden_message_oneof_implemented")); + "google/protobuf/testdata/golden_message_oneof_implemented")); ExpectStderrMatchesText(""); } TEST_P(EncodeDecodeTest, DecodeDeterministicOutput) { RedirectStdinFromFile(TestUtil::GetTestDataPath( - "third_party/protobuf/testdata/golden_message_oneof_implemented")); + "google/protobuf/testdata/golden_message_oneof_implemented")); EXPECT_FALSE( - Run(TestUtil::MaybeTranslatePath("third_party/protobuf/unittest.proto") + + Run("google/protobuf/unittest.proto" " --decode=protobuf_unittest.TestAllTypes --deterministic_output")); ExpectStderrMatchesText( "Can only use --deterministic_output with --encode.\n"); diff --git a/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc index 856a06c689..349eead6fa 100644 --- a/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc @@ -32,7 +32,7 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. // -// This test insures that net/proto2/proto/descriptor.pb.{h,cc} match exactly +// This test insures that google/protobuf/descriptor.pb.{h,cc} match exactly // what would be generated by the protocol compiler. These files are not // generated automatically at build time because they are compiled into the // protocol compiler itself. So, if they were auto-generated, you'd have a @@ -144,9 +144,9 @@ TEST(BootstrapTest, GeneratedFilesMatch) { // of the data to compare to. absl::flat_hash_map vpath_map; absl::flat_hash_map rpath_map; - rpath_map["third_party/protobuf/test_messages_proto2"] = + rpath_map["google/protobuf/test_messages_proto2"] = "net/proto2/z_generated_example/test_messages_proto2"; - rpath_map["third_party/protobuf/test_messages_proto3"] = + rpath_map["google/protobuf/test_messages_proto3"] = "net/proto2/z_generated_example/test_messages_proto3"; rpath_map["net/proto2/internal/proto2_weak"] = "net/proto2/z_generated_example/proto2_weak"; diff --git a/src/google/protobuf/compiler/cpp/generator_unittest.cc b/src/google/protobuf/compiler/cpp/generator_unittest.cc index af3148899d..64efaea4db 100644 --- a/src/google/protobuf/compiler/cpp/generator_unittest.cc +++ b/src/google/protobuf/compiler/cpp/generator_unittest.cc @@ -56,7 +56,7 @@ class CppGeneratorTest : public CommandLineInterfaceTester { "google/protobuf/descriptor.proto", google::protobuf::DescriptorProto::descriptor()->file()->DebugString()); #ifdef PROTOBUF_FUTURE_EDITIONS - CreateTempFile("third_party/protobuf/cpp_features.proto", + CreateTempFile("google/protobuf/cpp_features.proto", pb::CppFeatures::descriptor()->file()->DebugString()); #endif // PROTOBUF_FUTURE_EDITIONS } @@ -97,7 +97,7 @@ TEST_F(CppGeneratorTest, LegacyClosedEnumOnNonEnumField) { CreateTempFile("foo.proto", R"schema( edition = "2023"; - import "third_party/protobuf/cpp_features.proto"; + import "google/protobuf/cpp_features.proto"; message Foo { int32 bar = 1 [features.(pb.cpp).legacy_closed_enum = true]; @@ -116,7 +116,7 @@ TEST_F(CppGeneratorTest, LegacyClosedEnum) { CreateTempFile("foo.proto", R"schema( edition = "2023"; - import "third_party/protobuf/cpp_features.proto"; + import "google/protobuf/cpp_features.proto"; enum TestEnum { TEST_ENUM_UNKNOWN = 0; @@ -136,7 +136,7 @@ TEST_F(CppGeneratorTest, LegacyClosedEnumInherited) { CreateTempFile("foo.proto", R"schema( edition = "2023"; - import "third_party/protobuf/cpp_features.proto"; + import "google/protobuf/cpp_features.proto"; option features.(pb.cpp).legacy_closed_enum = true; enum TestEnum { @@ -158,7 +158,7 @@ TEST_F(CppGeneratorTest, LegacyClosedEnumImplicit) { CreateTempFile("foo.proto", R"schema( edition = "2023"; - import "third_party/protobuf/cpp_features.proto"; + import "google/protobuf/cpp_features.proto"; option features.(pb.cpp).legacy_closed_enum = true; enum TestEnum { diff --git a/src/google/protobuf/compiler/cpp/unittest.cc b/src/google/protobuf/compiler/cpp/unittest.cc index 2d03e6239c..307159e998 100644 --- a/src/google/protobuf/compiler/cpp/unittest.cc +++ b/src/google/protobuf/compiler/cpp/unittest.cc @@ -33,7 +33,7 @@ // Sanjay Ghemawat, Jeff Dean, and others. // // To test the code generator, we actually use it to generate code for -// third_party/protobuf/unittest.proto, then test that. This means that we +// google/protobuf/unittest.proto, then test that. This means that we // are actually testing the parser and other parts of the system at the same // time, and that problems in the generator may show up as compile-time errors // rather than unittest failures, which may be surprising. However, testing @@ -59,7 +59,7 @@ #define HELPERS_TEST_NAME HelpersTest #define DESCRIPTOR_INIT_TEST_NAME DescriptorInitializationTest -#define UNITTEST_PROTO_PATH "third_party/protobuf/unittest.proto" +#define UNITTEST_PROTO_PATH "google/protobuf/unittest.proto" #define UNITTEST ::protobuf_unittest #define UNITTEST_IMPORT ::protobuf_unittest_import diff --git a/src/google/protobuf/compiler/cpp/unittest.inc b/src/google/protobuf/compiler/cpp/unittest.inc index 4be035755e..febda30279 100644 --- a/src/google/protobuf/compiler/cpp/unittest.inc +++ b/src/google/protobuf/compiler/cpp/unittest.inc @@ -34,7 +34,7 @@ // Sanjay Ghemawat, Jeff Dean, and others. // // To test the code generator, we actually use it to generate code for -// third_party/protobuf/unittest.proto, then test that. This means that we +// google/protobuf/unittest.proto, then test that. This means that we // are actually testing the parser and other parts of the system at the same // time, and that problems in the generator may show up as compile-time errors // rather than unittest failures, which may be surprising. However, testing @@ -124,7 +124,7 @@ TEST(GENERATED_DESCRIPTOR_TEST_NAME, IdenticalDescriptors) { // Import (parse) unittest.proto. const FileDescriptor* parsed_descriptor = - importer.Import(TestUtil::MaybeTranslatePath(UNITTEST_PROTO_PATH)); + importer.Import(UNITTEST_PROTO_PATH); EXPECT_EQ("", error_collector.text_); ASSERT_TRUE(parsed_descriptor != nullptr); @@ -2217,7 +2217,7 @@ TEST(DESCRIPTOR_INIT_TEST_NAME, Initialized) { EXPECT_EQ(should_have_descriptors, DescriptorPool::generated_pool()->InternalIsFileLoaded( - TestUtil::MaybeTranslatePath(UNITTEST_PROTO_PATH))); + UNITTEST_PROTO_PATH)); } } // namespace cpp_unittest diff --git a/src/google/protobuf/compiler/java/message_serialization_unittest.cc b/src/google/protobuf/compiler/java/message_serialization_unittest.cc index 9a7a6964fe..60c94ee06c 100644 --- a/src/google/protobuf/compiler/java/message_serialization_unittest.cc +++ b/src/google/protobuf/compiler/java/message_serialization_unittest.cc @@ -63,7 +63,7 @@ int CompileJavaProto(std::string proto_file_name) { std::string proto_path = absl::StrCat( "--proto_path=", - TestUtil::GetTestDataPath("third_party/protobuf/compiler/java")); + TestUtil::GetTestDataPath("google/protobuf/compiler/java")); std::string java_out = absl::StrCat("--java_out=", TestTempDir()); const char* argv[] = { diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc index 9f6f103a3c..0bf2dceb62 100644 --- a/src/google/protobuf/compiler/parser_unittest.cc +++ b/src/google/protobuf/compiler/parser_unittest.cc @@ -2318,7 +2318,7 @@ TEST_F(ParserValidationErrorTest, ResovledUndefinedOptionError) { // base2.proto: // package baz - // import net/proto2/proto/descriptor.proto + // import google/protobuf/descriptor.proto // message Bar { optional int32 foo = 1; } // extend FileOptions { optional Bar bar = 7672757; } FileDescriptorProto other_file; @@ -2461,8 +2461,7 @@ TEST_F(ParseDescriptorDebugTest, TestAllDescriptorTypes) { // We now have a FileDescriptorProto, but to compare with the expected we // need to link to a FileDecriptor, then output back to a proto. We'll // also need to give it the same name as the original. - parsed.set_name( - TestUtil::MaybeTranslatePath("third_party/protobuf/unittest.proto")); + parsed.set_name("google/protobuf/unittest.proto"); // We need the imported dependency before we can build our parsed proto const FileDescriptor* public_import = protobuf_unittest_import::PublicImportMessage::descriptor()->file(); diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index 0c0eccbf29..bebaca08d4 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -271,6 +271,7 @@ class PROTOBUF_EXPORT InternalFeatureHelper { private: friend class ::google::protobuf::compiler::CodeGenerator; + friend class ::google::protobuf::compiler::CommandLineInterface; // Provides a restricted view exclusively to code generators. Raw features // haven't been resolved, and are virtually meaningless to everyone else. Code diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc index 7f6799fa58..c84107a150 100644 --- a/src/google/protobuf/extension_set_unittest.cc +++ b/src/google/protobuf/extension_set_unittest.cc @@ -65,7 +65,7 @@ namespace { using ::google::protobuf::internal::DownCast; using TestUtil::EqualsToSerialized; -// This test closely mirrors third_party/protobuf/compiler/cpp/unittest.cc +// This test closely mirrors google/protobuf/compiler/cpp/unittest.cc // except that it uses extensions rather than regular fields. TEST(ExtensionSetTest, Defaults) { @@ -1368,7 +1368,7 @@ TEST(ExtensionSetTest, Proto3PackedDynamicExtensions) { google::protobuf::FileDescriptorProto file_descriptor_proto; file_descriptor_proto.set_syntax("proto3"); file_descriptor_proto.set_name( - "third_party/protobuf/unittest_proto3_packed_extension.proto"); + "google/protobuf/unittest_proto3_packed_extension.proto"); file_descriptor_proto.set_package("proto3_unittest"); file_descriptor_proto.add_dependency( DescriptorProto::descriptor()->file()->name()); diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc index 5e1859b2af..4472d58460 100644 --- a/src/google/protobuf/io/zero_copy_stream_unittest.cc +++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc @@ -582,7 +582,7 @@ TEST_F(IoTest, CompressionOptions) { // Some ad-hoc testing of compression options. std::string golden_filename = - TestUtil::GetTestDataPath("third_party/protobuf/testdata/golden_message"); + TestUtil::GetTestDataPath("google/protobuf/testdata/golden_message"); std::string golden; ABSL_CHECK_OK(File::GetContents(golden_filename, &golden, true)); diff --git a/src/google/protobuf/json/json_test.cc b/src/google/protobuf/json/json_test.cc index dabd158321..88f7e6d561 100644 --- a/src/google/protobuf/json/json_test.cc +++ b/src/google/protobuf/json/json_test.cc @@ -1165,7 +1165,7 @@ TEST_P(JsonTest, TestDuration) { EXPECT_THAT(ToJson(m5->value()), IsOkAndHolds("\"0.500s\"")); } -// These tests are not exhaustive; tests in //third_party/protobuf/conformance +// These tests are not exhaustive; tests in //google/protobuf/conformance // are more comprehensive. TEST_P(JsonTest, TestTimestamp) { auto m = ToProto(R"json( diff --git a/src/google/protobuf/map_test.inc b/src/google/protobuf/map_test.inc index 1f22bcebb8..55511debf7 100644 --- a/src/google/protobuf/map_test.inc +++ b/src/google/protobuf/map_test.inc @@ -3968,7 +3968,7 @@ TEST(MapSerializationTest, DeterministicSubmessage) { std::string golden; ABSL_CHECK_OK( File::GetContents(TestUtil::GetTestDataPath(absl::StrCat( - "third_party/protobuf/testdata/", filename)), + "google/protobuf/testdata/", filename)), &golden, true)); t.ParseFromString(golden); *(p.mutable_m()) = t; @@ -4010,7 +4010,7 @@ TEST(TextFormatMapTest, DynamicMessage) { std::string expected_text; ABSL_CHECK_OK( - File::GetContents(TestUtil::GetTestDataPath("third_party/protobuf/" + File::GetContents(TestUtil::GetTestDataPath("google/protobuf/" "testdata/map_test_data.txt"), &expected_text, true)); @@ -4026,7 +4026,7 @@ TEST(TextFormatMapTest, Sorted) { std::string expected_text; ABSL_CHECK_OK( - File::GetContents(TestUtil::GetTestDataPath("third_party/protobuf/" + File::GetContents(TestUtil::GetTestDataPath("google/protobuf/" "testdata/map_test_data.txt"), &expected_text, true)); @@ -4047,7 +4047,7 @@ TEST(TextFormatMapTest, ParseCorruptedString) { std::string serialized_message; ABSL_CHECK_OK(File::GetContents( TestUtil::GetTestDataPath( - "third_party/protobuf/testdata/golden_message_maps"), + "google/protobuf/testdata/golden_message_maps"), &serialized_message, true)); UNITTEST::TestMaps message; ABSL_CHECK(message.ParseFromString(serialized_message)); diff --git a/src/google/protobuf/message_unittest.inc b/src/google/protobuf/message_unittest.inc index ec968ccfc4..73a9740acb 100644 --- a/src/google/protobuf/message_unittest.inc +++ b/src/google/protobuf/message_unittest.inc @@ -132,7 +132,7 @@ TEST(MESSAGE_TEST_NAME, SerializeToBrokenOstream) { TEST(MESSAGE_TEST_NAME, ParseFromFileDescriptor) { std::string filename = - TestUtil::GetTestDataPath("third_party/protobuf/testdata/golden_message"); + TestUtil::GetTestDataPath("google/protobuf/testdata/golden_message"); int file = open(filename.c_str(), O_RDONLY | O_BINARY); ASSERT_GE(file, 0); @@ -145,7 +145,7 @@ TEST(MESSAGE_TEST_NAME, ParseFromFileDescriptor) { TEST(MESSAGE_TEST_NAME, ParsePackedFromFileDescriptor) { std::string filename = TestUtil::GetTestDataPath( - "third_party/protobuf/testdata/golden_packed_fields_message"); + "google/protobuf/testdata/golden_packed_fields_message"); int file = open(filename.c_str(), O_RDONLY | O_BINARY); ASSERT_GE(file, 0); diff --git a/src/google/protobuf/test_util2.h b/src/google/protobuf/test_util2.h index 9cc1456ce8..b3549381c8 100644 --- a/src/google/protobuf/test_util2.h +++ b/src/google/protobuf/test_util2.h @@ -45,32 +45,12 @@ namespace google { namespace protobuf { namespace TestUtil { -// Translate net/proto2/* or third_party/protobuf/* to google/protobuf/*. -inline std::string TranslatePathToOpensource(absl::string_view google3_path) { - constexpr absl::string_view net_proto2 = "net/proto2/"; - constexpr absl::string_view third_party_protobuf = "third_party/protobuf/"; - if (!absl::ConsumePrefix(&google3_path, net_proto2)) { - ABSL_CHECK(absl::ConsumePrefix(&google3_path, third_party_protobuf)) - << google3_path; - } - - absl::ConsumePrefix(&google3_path, "internal/"); - absl::ConsumePrefix(&google3_path, "proto/"); - absl::ConsumeSuffix(&google3_path, "public/"); - return absl::StrCat("google/protobuf/", google3_path); -} - -inline std::string MaybeTranslatePath(absl::string_view google3_path) { - return TranslatePathToOpensource(google3_path); - return std::string(google3_path); -} - inline std::string TestSourceDir() { return google::protobuf::TestSourceDir(); } -inline std::string GetTestDataPath(absl::string_view google3_path) { - return absl::StrCat(TestSourceDir(), "/", MaybeTranslatePath(google3_path)); +inline std::string GetTestDataPath(absl::string_view path) { + return absl::StrCat(TestSourceDir(), "/", path); } // Checks the equality of "message" and serialized proto of type "ProtoType". diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index a93ff732f1..471387b082 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -97,7 +97,7 @@ class TextFormatTest : public testing::Test { static void SetUpTestSuite() { ABSL_CHECK_OK(File::GetContents( TestUtil::GetTestDataPath( - "third_party/protobuf/" + "google/protobuf/" "testdata/text_format_unittest_data_oneof_implemented.txt"), &static_proto_text_format_, true)); } @@ -118,7 +118,7 @@ class TextFormatExtensionsTest : public testing::Test { public: static void SetUpTestSuite() { ABSL_CHECK_OK(File::GetContents( - TestUtil::GetTestDataPath("third_party/protobuf/testdata/" + TestUtil::GetTestDataPath("google/protobuf/testdata/" "text_format_unittest_extensions_data.txt"), &static_proto_text_format_, true)); } From e2cec78455769881b9e8c23babeb3fe8effe81fe Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Thu, 13 Jul 2023 16:23:39 -0700 Subject: [PATCH 5/6] Allow code generators to specify whether or not they support editions. Editions are still flag-guarded by the `--experimental_editions` flag for now, but once that's removed in a later release generators will need to explicitly specify that their support. This will avoid cases where generators may happen to work for editions but produce incorrect code. PiperOrigin-RevId: 547959326 --- src/google/protobuf/BUILD.bazel | 34 +----------------- src/google/protobuf/compiler/code_generator.h | 2 ++ .../compiler/code_generator_unittest.cc | 14 ++++++++ .../compiler/command_line_interface.cc | 29 +++++++++++++++ .../command_line_interface_unittest.cc | 35 +++++++++++++++++++ src/google/protobuf/compiler/cpp/generator.h | 2 +- src/google/protobuf/compiler/fake_plugin.cc | 9 +++-- .../protobuf/compiler/mock_code_generator.cc | 14 +++++++- .../protobuf/compiler/mock_code_generator.h | 5 ++- src/google/protobuf/compiler/plugin.pb.cc | 17 +++++---- src/google/protobuf/compiler/plugin.pb.h | 8 +++-- src/google/protobuf/compiler/plugin.proto | 1 + src/google/protobuf/descriptor.cc | 3 -- 13 files changed, 122 insertions(+), 51 deletions(-) diff --git a/src/google/protobuf/BUILD.bazel b/src/google/protobuf/BUILD.bazel index 5dc0a64bf5..6b4f77d5fa 100644 --- a/src/google/protobuf/BUILD.bazel +++ b/src/google/protobuf/BUILD.bazel @@ -739,39 +739,7 @@ proto_library( proto_library( name = "generic_test_protos", - srcs = [ - "map_proto2_unittest.proto", - "map_proto3_unittest.proto", - "map_unittest.proto", - "unittest.proto", - "unittest_arena.proto", - "unittest_custom_options.proto", - "unittest_drop_unknown_fields.proto", - "unittest_embed_optimize_for.proto", - "unittest_empty.proto", - "unittest_enormous_descriptor.proto", - "unittest_import.proto", - "unittest_import_public.proto", - "unittest_lazy_dependencies.proto", - "unittest_lazy_dependencies_custom_option.proto", - "unittest_lazy_dependencies_enum.proto", - "unittest_lite_imports_nonlite.proto", - "unittest_mset.proto", - "unittest_mset_wire_format.proto", - "unittest_no_field_presence.proto", - "unittest_no_generic_services.proto", - "unittest_optimize_for.proto", - "unittest_preserve_unknown_enum.proto", - "unittest_preserve_unknown_enum2.proto", - "unittest_proto3.proto", - "unittest_proto3_arena.proto", - "unittest_proto3_arena_lite.proto", - "unittest_proto3_bad_macros.proto", - "unittest_proto3_lite.proto", - "unittest_proto3_optional.proto", - "unittest_retention.proto", - "unittest_well_known_types.proto", - ], + srcs = [":test_proto_srcs"], strip_import_prefix = "/src", visibility = ["//:__subpackages__"], deps = [ diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h index 17674c90f2..6350ed12c7 100644 --- a/src/google/protobuf/compiler/code_generator.h +++ b/src/google/protobuf/compiler/code_generator.h @@ -113,8 +113,10 @@ class PROTOC_EXPORT CodeGenerator { // This must be kept in sync with plugin.proto. See that file for // documentation on each value. + // TODO(b/291092901) Use CodeGeneratorResponse.Feature here. enum Feature { FEATURE_PROTO3_OPTIONAL = 1, + FEATURE_SUPPORTS_EDITIONS = 2, }; // Implement this to indicate what features this code generator supports. diff --git a/src/google/protobuf/compiler/code_generator_unittest.cc b/src/google/protobuf/compiler/code_generator_unittest.cc index 626342d3fe..bf8b183563 100644 --- a/src/google/protobuf/compiler/code_generator_unittest.cc +++ b/src/google/protobuf/compiler/code_generator_unittest.cc @@ -224,6 +224,20 @@ TEST_F(CodeGeneratorTest, GetSourceFeaturesInherited) { EXPECT_EQ(ext.string_source_feature(), "field"); } +TEST_F(CodeGeneratorTest, GetRuntimeProtoTrivial) { + auto file = BuildFile(R"schema( + edition = "2023"; + package protobuf_unittest; + )schema"); + ASSERT_THAT(file, NotNull()); + + FileDescriptorProto proto = TestGenerator::GetRuntimeProto(*file); + const FeatureSet& features = proto.options().features(); + + EXPECT_TRUE(features.has_raw_features()); + EXPECT_THAT(features.raw_features(), EqualsProto(R"pb()pb")); +} + TEST_F(CodeGeneratorTest, GetRuntimeProtoRoot) { auto file = BuildFile(R"schema( edition = "2023"; diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 37bf62bcc1..f9e966649d 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -302,6 +302,26 @@ std::string PluginName(absl::string_view plugin_prefix, } +bool EnforceEditionsSupport( + const std::string& codegen_name, uint64_t supported_features, + const std::vector& parsed_files) { + if ((supported_features & CodeGenerator::FEATURE_SUPPORTS_EDITIONS) == 0) { + for (const auto fd : parsed_files) { + if (FileDescriptorLegacy(fd).syntax() == + FileDescriptorLegacy::SYNTAX_EDITIONS) { + std::cerr << fd->name() << ": is an editions file, but code generator " + << codegen_name + << " hasn't been updated to support editions yet. Please ask " + "the owner of this code generator to add support or " + "switch back to proto2/proto3." + << std::endl; + return false; + } + } + } + return true; +} + } // namespace void CommandLineInterface::GetTransitiveDependencies( @@ -2490,6 +2510,12 @@ bool CommandLineInterface::GenerateOutput( return false; } + if (!EnforceEditionsSupport( + output_directive.name, + output_directive.generator->GetSupportedFeatures(), parsed_files)) { + return false; + } + if (!output_directive.generator->GenerateAll(parsed_files, parameters, generator_context, &error)) { // Generator returned an error. @@ -2686,6 +2712,9 @@ bool CommandLineInterface::GeneratePluginOutput( } else if (!EnforceProto3OptionalSupport( plugin_name, response.supported_features(), parsed_files)) { return false; + } else if (!EnforceEditionsSupport(plugin_name, response.supported_features(), + parsed_files)) { + return false; } return true; diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index edde502c6a..4fe1211b7c 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -1643,6 +1643,41 @@ TEST_F(CommandLineInterfaceTest, Plugin_SourceFeatures) { } } +TEST_F(CommandLineInterfaceTest, GeneratorNoEditionsSupport) { + CreateTempFile("foo.proto", R"schema( + edition = "2023"; + message Foo { + int32 i = 1; + } + )schema"); + + CreateGeneratorWithMissingFeatures("--no_editions_out", + "Doesn't support editions", + CodeGenerator::FEATURE_SUPPORTS_EDITIONS); + + Run("protocol_compiler --experimental_editions " + "--proto_path=$tmpdir foo.proto --no_editions_out=$tmpdir"); + + ExpectErrorSubstring( + "code generator --no_editions_out hasn't been updated to support " + "editions"); +} + +TEST_F(CommandLineInterfaceTest, PluginNoEditionsSupport) { + CreateTempFile("foo.proto", R"schema( + edition = "2023"; + message Foo { + int32 i = 1; + } + )schema"); + + Run("protocol_compiler --experimental_editions " + "--proto_path=$tmpdir foo.proto --plug_out=no_editions:$tmpdir"); + + ExpectErrorSubstring( + "code generator prefix-gen-plug hasn't been updated to support editions"); +} + #endif // PROTOBUF_FUTURE_EDITIONS diff --git a/src/google/protobuf/compiler/cpp/generator.h b/src/google/protobuf/compiler/cpp/generator.h index 0c1705163e..94bd352346 100644 --- a/src/google/protobuf/compiler/cpp/generator.h +++ b/src/google/protobuf/compiler/cpp/generator.h @@ -89,7 +89,7 @@ class PROTOC_EXPORT CppGenerator : public CodeGenerator { std::string* error) const override; uint64_t GetSupportedFeatures() const override { - return FEATURE_PROTO3_OPTIONAL; + return FEATURE_PROTO3_OPTIONAL | FEATURE_SUPPORTS_EDITIONS; } private: diff --git a/src/google/protobuf/compiler/fake_plugin.cc b/src/google/protobuf/compiler/fake_plugin.cc index 63da6fedba..980f544d42 100644 --- a/src/google/protobuf/compiler/fake_plugin.cc +++ b/src/google/protobuf/compiler/fake_plugin.cc @@ -39,6 +39,9 @@ #include "google/protobuf/compiler/plugin.pb.h" #include "google/protobuf/io/io_win32.h" +using google::protobuf::compiler::CodeGeneratorRequest; +using google::protobuf::compiler::CodeGeneratorResponse; + // This fake protoc plugin does nothing but write out the CodeGeneratorRequest // in base64. This is not very useful except that it gives us a way to make // assertions in tests about the contents of requests that protoc sends to @@ -50,10 +53,12 @@ int main(int argc, char* argv[]) { google::protobuf::io::win32::setmode(STDOUT_FILENO, _O_BINARY); #endif - google::protobuf::compiler::CodeGeneratorRequest request; + CodeGeneratorRequest request; ABSL_CHECK(request.ParseFromFileDescriptor(STDIN_FILENO)); ABSL_CHECK(!request.file_to_generate().empty()); - google::protobuf::compiler::CodeGeneratorResponse response; + CodeGeneratorResponse response; + response.set_supported_features( + CodeGeneratorResponse::FEATURE_SUPPORTS_EDITIONS); response.add_file()->set_name( absl::StrCat(request.file_to_generate(0), ".request")); response.mutable_file(0)->set_content( diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc index d1ff90b61c..8c5366a5a0 100644 --- a/src/google/protobuf/compiler/mock_code_generator.cc +++ b/src/google/protobuf/compiler/mock_code_generator.cc @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "google/protobuf/testing/file.h" @@ -96,7 +97,8 @@ MockCodeGenerator::MockCodeGenerator(absl::string_view name) : name_(name) {} MockCodeGenerator::~MockCodeGenerator() = default; uint64_t MockCodeGenerator::GetSupportedFeatures() const { - uint64_t all_features = CodeGenerator::FEATURE_PROTO3_OPTIONAL; + uint64_t all_features = CodeGenerator::FEATURE_PROTO3_OPTIONAL | + CodeGenerator::FEATURE_SUPPORTS_EDITIONS; return all_features & ~suppressed_features_; } @@ -212,6 +214,16 @@ bool MockCodeGenerator::Generate(const FileDescriptor* file, const std::string& parameter, GeneratorContext* context, std::string* error) const { + std::vector> options; + ParseGeneratorParameter(parameter, &options); + for (const auto& option : options) { + const auto& key = option.first; + + if (key == "no_editions") { + suppressed_features_ |= CodeGenerator::FEATURE_SUPPORTS_EDITIONS; + } + } + bool annotate = false; for (int i = 0; i < file->message_type_count(); i++) { if (absl::StartsWith(file->message_type(i)->name(), "MockCodeGenerator_")) { diff --git a/src/google/protobuf/compiler/mock_code_generator.h b/src/google/protobuf/compiler/mock_code_generator.h index 3987b7e063..bdb30c91c3 100644 --- a/src/google/protobuf/compiler/mock_code_generator.h +++ b/src/google/protobuf/compiler/mock_code_generator.h @@ -118,7 +118,10 @@ class MockCodeGenerator : public CodeGenerator { private: std::string name_; - uint64_t suppressed_features_ = 0; + + // Mark this mutable so that our test plugin can modify it during the Generate + // call via generator flags. + mutable uint64_t suppressed_features_ = 0; static std::string GetOutputFileContent(absl::string_view generator_name, absl::string_view parameter, diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index d0d679e5c4..532469ac9d 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -221,18 +221,19 @@ const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2epro "FileDescriptorProto\022E\n\027source_file_descr" "iptors\030\021 \003(\0132$.google.protobuf.FileDescr" "iptorProto\022;\n\020compiler_version\030\003 \001(\0132!.g" - "oogle.protobuf.compiler.Version\"\301\002\n\025Code" + "oogle.protobuf.compiler.Version\"\340\002\n\025Code" "GeneratorResponse\022\r\n\005error\030\001 \001(\t\022\032\n\022supp" "orted_features\030\002 \001(\004\022B\n\004file\030\017 \003(\01324.goo" "gle.protobuf.compiler.CodeGeneratorRespo" "nse.File\032\177\n\004File\022\014\n\004name\030\001 \001(\t\022\027\n\017insert" "ion_point\030\002 \001(\t\022\017\n\007content\030\017 \001(\t\022\?\n\023gene" "rated_code_info\030\020 \001(\0132\".google.protobuf." - "GeneratedCodeInfo\"8\n\007Feature\022\020\n\014FEATURE_" - "NONE\020\000\022\033\n\027FEATURE_PROTO3_OPTIONAL\020\001Br\n\034c" - "om.google.protobuf.compilerB\014PluginProto" - "sZ)google.golang.org/protobuf/types/plug" - "inpb\252\002\030Google.Protobuf.Compiler" + "GeneratedCodeInfo\"W\n\007Feature\022\020\n\014FEATURE_" + "NONE\020\000\022\033\n\027FEATURE_PROTO3_OPTIONAL\020\001\022\035\n\031F" + "EATURE_SUPPORTS_EDITIONS\020\002Br\n\034com.google" + ".protobuf.compilerB\014PluginProtosZ)google" + ".golang.org/protobuf/types/pluginpb\252\002\030Go" + "ogle.Protobuf.Compiler" }; static const ::_pbi::DescriptorTable* const descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps[1] = { @@ -242,7 +243,7 @@ static ::absl::once_flag descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = { false, false, - 871, + 902, descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto, "google/protobuf/compiler/plugin.proto", &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, @@ -285,6 +286,7 @@ bool CodeGeneratorResponse_Feature_IsValid(int value) { switch (value) { case 0: case 1: + case 2: return true; default: return false; @@ -295,6 +297,7 @@ bool CodeGeneratorResponse_Feature_IsValid(int value) { constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::FEATURE_NONE; constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::FEATURE_PROTO3_OPTIONAL; +constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::FEATURE_SUPPORTS_EDITIONS; constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::Feature_MIN; constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::Feature_MAX; constexpr int CodeGeneratorResponse::Feature_ARRAYSIZE; diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 7cadfa0c4e..ac6a28d33e 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -94,12 +94,13 @@ namespace compiler { enum CodeGeneratorResponse_Feature : int { CodeGeneratorResponse_Feature_FEATURE_NONE = 0, CodeGeneratorResponse_Feature_FEATURE_PROTO3_OPTIONAL = 1, + CodeGeneratorResponse_Feature_FEATURE_SUPPORTS_EDITIONS = 2, }; PROTOC_EXPORT bool CodeGeneratorResponse_Feature_IsValid(int value); constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse_Feature_Feature_MIN = static_cast(0); -constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse_Feature_Feature_MAX = static_cast(1); -constexpr int CodeGeneratorResponse_Feature_Feature_ARRAYSIZE = 1 + 1; +constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse_Feature_Feature_MAX = static_cast(2); +constexpr int CodeGeneratorResponse_Feature_Feature_ARRAYSIZE = 2 + 1; PROTOC_EXPORT const ::google::protobuf::EnumDescriptor* CodeGeneratorResponse_Feature_descriptor(); template @@ -112,7 +113,7 @@ const std::string& CodeGeneratorResponse_Feature_Name(T value) { template <> inline const std::string& CodeGeneratorResponse_Feature_Name(CodeGeneratorResponse_Feature value) { return ::google::protobuf::internal::NameOfDenseEnum( + 0, 2>( static_cast(value)); } inline bool CodeGeneratorResponse_Feature_Parse(absl::string_view name, CodeGeneratorResponse_Feature* value) { @@ -934,6 +935,7 @@ class PROTOC_EXPORT CodeGeneratorResponse final : using Feature = CodeGeneratorResponse_Feature; static constexpr Feature FEATURE_NONE = CodeGeneratorResponse_Feature_FEATURE_NONE; static constexpr Feature FEATURE_PROTO3_OPTIONAL = CodeGeneratorResponse_Feature_FEATURE_PROTO3_OPTIONAL; + static constexpr Feature FEATURE_SUPPORTS_EDITIONS = CodeGeneratorResponse_Feature_FEATURE_SUPPORTS_EDITIONS; static inline bool Feature_IsValid(int value) { return CodeGeneratorResponse_Feature_IsValid(value); } diff --git a/src/google/protobuf/compiler/plugin.proto b/src/google/protobuf/compiler/plugin.proto index ba07c8f6eb..1a8098681b 100644 --- a/src/google/protobuf/compiler/plugin.proto +++ b/src/google/protobuf/compiler/plugin.proto @@ -122,6 +122,7 @@ message CodeGeneratorResponse { enum Feature { FEATURE_NONE = 0; FEATURE_PROTO3_OPTIONAL = 1; + FEATURE_SUPPORTS_EDITIONS = 2; } // Represents a single generated file. diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 4531801c6b..fd5c0ba82f 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -2773,9 +2773,6 @@ FileDescriptorProto InternalFeatureHelper::GetGeneratorProto( if (&features != &FeatureSet::default_instance() && !IsLegacyFeatureSet(features)) { *proto.mutable_options()->mutable_features() = features; - } - const auto& raw_features = GetRawFeatures(desc); - if (&raw_features != &FeatureSet::default_instance()) { *proto.mutable_options()->mutable_features()->mutable_raw_features() = GetRawFeatures(desc); } From 16fbb2bf37dd40ab361b305d8370091cd163be50 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Thu, 13 Jul 2023 17:03:39 -0700 Subject: [PATCH 6/6] Update stale files --- src/file_lists.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/src/file_lists.cmake b/src/file_lists.cmake index 7f5146005b..34111e8c48 100644 --- a/src/file_lists.cmake +++ b/src/file_lists.cmake @@ -737,6 +737,7 @@ set(fake_plugin_files # @//src/google/protobuf/compiler:test_srcs set(compiler_test_files ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/allowlists/allowlist_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/code_generator_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/command_line_interface_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/bootstrap_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/generator_unittest.cc