Skip to content

Commit

Permalink
fix: handle type:object with format:google.protobuf.Any (#138)
Browse files Browse the repository at this point in the history
We were not handling the Discovery equivalent of proto `repeated Any`, which shows up in Discovery docs as an `array` of `object` with `format:google.protobuf.Any`. This fixes that, and adds a test.

Note that because we only allow `google.protobuf.Any` when it's nested inside `....error.details`, the test case for this has more structure than other test cases for the `format` field.
  • Loading branch information
vchudnov-g authored Dec 13, 2024
1 parent 4e1c308 commit 285877d
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@ public enum Format {
this.text = text;
}

public String toString() {
return this.text;
}

/**
* @param text the JSON text of the format.
* @return the enum representing the raw JSON format.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -553,8 +553,8 @@ private Field schemaToField(Schema sch, boolean optional, String debugPreviousPa
default:
throw new IllegalStateException(
String.format(
"unexpected 'format' value ('%s') when processing ANY type in schema %s",
sch.format().toString(), debugCurrentPath));
"unexpected 'format' value (%s:'%s') when processing ANY type in schema %s",
sch.format().name(), sch.format().toString(), debugCurrentPath));
}
break;
case ARRAY:
Expand Down Expand Up @@ -631,6 +631,9 @@ private Field schemaToField(Schema sch, boolean optional, String debugPreviousPa
// `additionalProperties' in the schema further specifies the JSON format, but
// "google.protobuf.Struct" is enough for specifying the proto message field type.
break;
case ANY:
valueType = Message.PRIMITIVES.get("google.protobuf.Any");
break;
case EMPTY:
if (sch.additionalProperties() != null) {
repeated = true;
Expand All @@ -643,8 +646,8 @@ private Field schemaToField(Schema sch, boolean optional, String debugPreviousPa
default:
throw new IllegalStateException(
String.format(
"unexpected 'format' value ('%s') when processing OBJECT type in schema %s",
sch.format().toString(), debugCurrentPath));
"unexpected 'format' value (%s:'%s') when processing OBJECT type in schema %s",
sch.format().name(), sch.format().toString(), debugCurrentPath));
}
break;
case STRING:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ message Address {
// This is a field to test that we can create a map whose values are google.protobuf.Value.
map<string, google.protobuf.Value> metadata_map_value = 453356478;

// This is a field to test we can create a repeated google.protobuf.Any
optional MetadataRepeatedAny metadata_repeated_any = 122515127;

// This is a field to test that we can create google.protobuf.Struct.
optional google.protobuf.Struct metadata_struct = 224324325;

Expand Down Expand Up @@ -354,10 +357,9 @@ message DeleteAddressRequest {

}

// [Output Only] If errors are generated during processing of the operation, this field will be populated.
//
message Error {
// [Output Only] The array of errors encountered while processing this operation.
repeated Errors errors = 315977579;
repeated google.protobuf.Any details = 483979842;

}

Expand Down Expand Up @@ -448,6 +450,12 @@ message ListAddressesRequest {

}

// This is a field to test we can create a repeated google.protobuf.Any
message MetadataRepeatedAny {
optional Error error = 96784904;

}

// Represents an Operation resource.
//
// Google Compute Engine has three Operation resources:
Expand Down Expand Up @@ -488,9 +496,6 @@ message Operation {
// [Output Only] The time that this operation was completed. This value is in RFC3339 text format.
optional string end_time = 114938801;

// [Output Only] If errors are generated during processing of the operation, this field will be populated.
optional Error error = 96784904;

// [Output Only] If the operation fails, this field contains the HTTP error message that was returned, such as NOT FOUND.
optional string http_error_message = 202521945 [(google.cloud.operation_field) = ERROR_MESSAGE];

Expand All @@ -509,6 +514,9 @@ message Operation {
// [Output Only] Name of the operation.
optional string name = 3373707 [(google.cloud.operation_field) = NAME];

// [Output Only] If errors are generated during processing of the operation, this field will be populated.
optional OperationError operation_error = 124395824;

// [Output Only] The type of operation, such as insert, update, or delete, and so on.
optional string operation_type = 177650450;

Expand Down Expand Up @@ -550,6 +558,13 @@ message Operation {

}

// [Output Only] If errors are generated during processing of the operation, this field will be populated.
message OperationError {
// [Output Only] The array of errors encountered while processing this operation.
repeated Errors errors = 315977579;

}

//
message SetCommonInstanceMetadataOperationMetadata {
// [Output Only] The client operation id.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
"type": "string",
"description": "[Output Only] The time that this operation was completed. This value is in RFC3339 text format."
},
"error": {
"operationError": {
"type": "object",
"description": "[Output Only] If errors are generated during processing of the operation, this field will be populated.",
"properties": {
Expand Down Expand Up @@ -514,6 +514,28 @@
}
}
},
"metadataRepeatedAny": {
"type": "object",
"description": "This is a field to test we can create a repeated google.protobuf.Any",
"properties": {
"error": {
"type": "object",
"properties": {
"details": {
"type": "array",
"items": {
"format": "google.protobuf.Any",
"type": "object",
"additionalProperties": {
"type": "any",
"description": "Properties of the object. Contains field @type with type URL."
}
}
}
}
}
}
},
"networkTier": {
"type": "string",
"description": "This signifies the networking tier used for configuring this address and can only take the following values: PREMIUM or STANDARD. Global forwarding rules can only be Premium Tier. Regional forwarding rules can be either Premium or Standard Tier. Standard Tier addresses applied to regional forwarding rules can be used with any external load balancer. Regional forwarding rules in Premium Tier can only be used with a network load balancer.\n\nIf this field is not specified, it is assumed to be PREMIUM.",
Expand Down

0 comments on commit 285877d

Please sign in to comment.