2212
2212
EXPECT_EQ(1234, options.GetExtension(protobuf_unittest::complex_opt1).foo());
2215
// Check that aggregate options were parsed and saved correctly in
2216
// the appropriate descriptors.
2217
TEST(CustomOptions, AggregateOptions) {
2218
const Descriptor* msg = protobuf_unittest::AggregateMessage::descriptor();
2219
const FileDescriptor* file = msg->file();
2220
const FieldDescriptor* field = msg->FindFieldByName("fieldname");
2221
const EnumDescriptor* enumd = file->FindEnumTypeByName("AggregateEnum");
2222
const EnumValueDescriptor* enumv = enumd->FindValueByName("VALUE");
2223
const ServiceDescriptor* service = file->FindServiceByName(
2224
"AggregateService");
2225
const MethodDescriptor* method = service->FindMethodByName("Method");
2227
// Tests for the different types of data embedded in fileopt
2228
const protobuf_unittest::Aggregate& file_options =
2229
file->options().GetExtension(protobuf_unittest::fileopt);
2230
EXPECT_EQ(100, file_options.i());
2231
EXPECT_EQ("FileAnnotation", file_options.s());
2232
EXPECT_EQ("NestedFileAnnotation", file_options.sub().s());
2233
EXPECT_EQ("FileExtensionAnnotation",
2234
file_options.file().GetExtension(protobuf_unittest::fileopt).s());
2235
EXPECT_EQ("EmbeddedMessageSetElement",
2236
file_options.mset().GetExtension(
2237
protobuf_unittest::AggregateMessageSetElement
2238
::message_set_extension).s());
2240
// Simple tests for all the other types of annotations
2241
EXPECT_EQ("MessageAnnotation",
2242
msg->options().GetExtension(protobuf_unittest::msgopt).s());
2243
EXPECT_EQ("FieldAnnotation",
2244
field->options().GetExtension(protobuf_unittest::fieldopt).s());
2245
EXPECT_EQ("EnumAnnotation",
2246
enumd->options().GetExtension(protobuf_unittest::enumopt).s());
2247
EXPECT_EQ("EnumValueAnnotation",
2248
enumv->options().GetExtension(protobuf_unittest::enumvalopt).s());
2249
EXPECT_EQ("ServiceAnnotation",
2250
service->options().GetExtension(protobuf_unittest::serviceopt).s());
2251
EXPECT_EQ("MethodAnnotation",
2252
method->options().GetExtension(protobuf_unittest::methodopt).s());
2216
2255
// ===================================================================
3425
3464
"string option \"foo\".\n");
3428
TEST_F(ValidationErrorTest, TryingToSetMessageValuedOption) {
3429
BuildDescriptorMessagesInTestPool();
3431
BuildFileWithErrors(
3432
"name: \"foo.proto\" "
3433
"dependency: \"google/protobuf/descriptor.proto\" "
3435
" name: \"TestMessage\" "
3436
" field { name:\"baz\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING }"
3438
"extension { name: \"bar\" number: 7672757 label: LABEL_OPTIONAL "
3439
" type: TYPE_MESSAGE type_name: \"TestMessage\" "
3440
" extendee: \"google.protobuf.FileOptions\" }"
3441
"options { uninterpreted_option { name { name_part: \"bar\" "
3442
" is_extension: true } "
3443
" identifier_value: \"QUUX\" } }",
3445
"foo.proto: foo.proto: OPTION_NAME: Option field \"(bar)\" cannot be of "
3467
// Helper function for tests that check for aggregate value parsing
3468
// errors. The "value" argument is embedded inside the
3469
// "uninterpreted_option" portion of the result.
3470
static string EmbedAggregateValue(const char* value) {
3471
return strings::Substitute(
3472
"name: \"foo.proto\" "
3473
"dependency: \"google/protobuf/descriptor.proto\" "
3474
"message_type { name: \"Foo\" } "
3475
"extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
3476
" type: TYPE_MESSAGE type_name: \"Foo\" "
3477
" extendee: \"google.protobuf.FileOptions\" }"
3478
"options { uninterpreted_option { name { name_part: \"foo\" "
3479
" is_extension: true } "
3484
TEST_F(ValidationErrorTest, AggregateValueNotFound) {
3485
BuildDescriptorMessagesInTestPool();
3487
BuildFileWithErrors(
3488
EmbedAggregateValue("string_value: \"\""),
3489
"foo.proto: foo.proto: OPTION_VALUE: Option \"foo\" is a message. "
3490
"To set the entire message, use syntax like "
3491
"\"foo = { <proto text format> }\". To set fields within it, use "
3492
"syntax like \"foo.foo = value\".\n");
3495
TEST_F(ValidationErrorTest, AggregateValueParseError) {
3496
BuildDescriptorMessagesInTestPool();
3498
BuildFileWithErrors(
3499
EmbedAggregateValue("aggregate_value: \"1+2\""),
3500
"foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
3501
"value for \"foo\": Expected identifier.\n");
3504
TEST_F(ValidationErrorTest, AggregateValueUnknownFields) {
3505
BuildDescriptorMessagesInTestPool();
3507
BuildFileWithErrors(
3508
EmbedAggregateValue("aggregate_value: \"x:100\""),
3509
"foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
3510
"value for \"foo\": Message type \"Foo\" has no field named \"x\".\n");
3449
3513
TEST_F(ValidationErrorTest, NotLiteImportsLite) {
3483
3547
TEST_F(ValidationErrorTest, NoLiteServices) {
3484
3548
BuildFileWithErrors(
3485
3549
"name: \"foo.proto\" "
3486
"options { optimize_for: LITE_RUNTIME } "
3551
" optimize_for: LITE_RUNTIME"
3552
" cc_generic_services: true"
3553
" java_generic_services: true"
3487
3555
"service { name: \"Foo\" }",
3489
3557
"foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot "
3490
"define services.\n");
3558
"define services unless you set both options cc_generic_services and "
3559
"java_generic_sevices to false.\n");
3562
"name: \"bar.proto\" "
3564
" optimize_for: LITE_RUNTIME"
3565
" cc_generic_services: false"
3566
" java_generic_services: false"
3568
"service { name: \"Bar\" }");
3493
3571
TEST_F(ValidationErrorTest, RollbackAfterError) {