diff --git a/execution/engine/execution_engine_grpc_test.go b/execution/engine/execution_engine_grpc_test.go index 0799edaaf6..94bf2f3f6b 100644 --- a/execution/engine/execution_engine_grpc_test.go +++ b/execution/engine/execution_engine_grpc_test.go @@ -6,6 +6,7 @@ package engine import ( "context" "fmt" + "math" "os" "os/exec" "path/filepath" @@ -534,7 +535,7 @@ func TestGRPCSubgraphExecution(t *testing.T) { response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) require.NoError(t, err) - require.Equal(t, `{"data":{"nullableFieldsTypeById":{"id":"full-data","name":"Full Data by ID","optionalString":"All fields populated","optionalInt":123,"optionalFloat":12.34000015258789,"optionalBoolean":false,"requiredString":"Required by ID","requiredInt":456}}}`, response) + require.Equal(t, `{"data":{"nullableFieldsTypeById":{"id":"full-data","name":"Full Data by ID","optionalString":"All fields populated","optionalInt":123,"optionalFloat":12.34,"optionalBoolean":false,"requiredString":"Required by ID","requiredInt":456}}}`, response) }) t.Run("should handle nullable fields query by ID with partial data", func(t *testing.T) { @@ -631,7 +632,7 @@ func TestGRPCSubgraphExecution(t *testing.T) { response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) require.NoError(t, err) - require.Equal(t, `{"data":{"allNullableFieldsTypes":[{"id":"nullable-1","name":"Full Data Entry","optionalString":"Optional String Value","optionalInt":42,"optionalFloat":3.140000104904175,"optionalBoolean":true,"requiredString":"Required String 1","requiredInt":100},{"id":"nullable-2","name":"Partial Data Entry","optionalString":"Only string is set","optionalInt":null,"optionalFloat":null,"optionalBoolean":false,"requiredString":"Required String 2","requiredInt":200},{"id":"nullable-3","name":"Minimal Data Entry","optionalString":null,"optionalInt":null,"optionalFloat":null,"optionalBoolean":null,"requiredString":"Required String 3","requiredInt":300}]}}`, response) + require.Equal(t, `{"data":{"allNullableFieldsTypes":[{"id":"nullable-1","name":"Full Data Entry","optionalString":"Optional String Value","optionalInt":42,"optionalFloat":1.7976931348623157e+308,"optionalBoolean":true,"requiredString":"Required String 1","requiredInt":100},{"id":"nullable-2","name":"Partial Data Entry","optionalString":"Only string is set","optionalInt":null,"optionalFloat":null,"optionalBoolean":false,"requiredString":"Required String 2","requiredInt":200},{"id":"nullable-3","name":"Minimal Data Entry","optionalString":null,"optionalInt":null,"optionalFloat":null,"optionalBoolean":null,"requiredString":"Required String 3","requiredInt":300}]}}`, response) }) t.Run("should handle nullable fields query with filter", func(t *testing.T) { @@ -677,8 +678,8 @@ func TestGRPCSubgraphExecution(t *testing.T) { "input": map[string]any{ "name": "Created Type", "optionalString": "Optional Value", - "optionalInt": 42, - "optionalFloat": 3.14, + "optionalInt": math.MaxInt32, + "optionalFloat": math.MaxFloat64, "optionalBoolean": true, "requiredString": "Required Value", "requiredInt": 100, @@ -703,8 +704,8 @@ func TestGRPCSubgraphExecution(t *testing.T) { require.NoError(t, err) require.Contains(t, response, `"name":"Created Type"`) require.Contains(t, response, `"optionalString":"Optional Value"`) - require.Contains(t, response, `"optionalInt":42`) - require.Contains(t, response, `"optionalFloat":3.14`) + require.Contains(t, response, `"optionalInt":2147483647`) + require.Contains(t, response, `"optionalFloat":1.7976931348623157e+308`) require.Contains(t, response, `"optionalBoolean":true`) require.Contains(t, response, `"requiredString":"Required Value"`) require.Contains(t, response, `"requiredInt":100`) @@ -809,4 +810,626 @@ func TestGRPCSubgraphExecution(t *testing.T) { require.NoError(t, err) require.Equal(t, `{"data":{"updateNullableFieldsType":null}}`, response) }) + + // BlogPost and Author list tests + t.Run("should handle BlogPost query with scalar lists", func(t *testing.T) { + operation := graphql.Request{ + OperationName: "BlogPostScalarListsQuery", + Query: `query BlogPostScalarListsQuery { + blogPost { + id + title + content + tags + optionalTags + categories + keywords + viewCounts + ratings + isPublished + } + }`, + } + + response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) + + require.NoError(t, err) + require.Contains(t, response, `"tags":`) + require.Contains(t, response, `"optionalTags":`) + require.Contains(t, response, `"categories":`) + require.Contains(t, response, `"keywords":`) + require.Contains(t, response, `"viewCounts":`) + require.Contains(t, response, `"ratings":`) + require.Contains(t, response, `"isPublished":`) + }) + + t.Run("should handle BlogPost query with nested scalar lists", func(t *testing.T) { + operation := graphql.Request{ + OperationName: "BlogPostNestedScalarListsQuery", + Query: `query BlogPostNestedScalarListsQuery { + blogPost { + id + title + tagGroups + relatedTopics + commentThreads + suggestions + } + }`, + } + + response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) + + require.NoError(t, err) + require.Equal(t, `{"data":{"blogPost":{"id":"blog-default","title":"Default Blog Post","tagGroups":[["tech","programming"],["golang","backend"]],"relatedTopics":[["microservices","api"],["databases","performance"]],"commentThreads":[["Great post!","Very helpful"],["Could use more examples","Thanks for sharing"]],"suggestions":[["Add code examples","Include diagrams"]]}}}`, response) + }) + + t.Run("should handle BlogPost query with complex lists", func(t *testing.T) { + operation := graphql.Request{ + OperationName: "BlogPostComplexListsQuery", + Query: `query BlogPostComplexListsQuery { + blogPost { + id + title + relatedCategories { + id + name + kind + } + contributors { + id + name + } + mentionedProducts { + id + name + price + } + mentionedUsers { + id + name + } + } + }`, + } + + response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) + + require.NoError(t, err) + require.Contains(t, response, `"relatedCategories":`) + require.Contains(t, response, `"contributors":`) + require.Contains(t, response, `"mentionedProducts":`) + require.Contains(t, response, `"mentionedUsers":`) + // Verify complex objects within lists + require.Contains(t, response, `"kind":`) + require.Contains(t, response, `"price":`) + }) + + t.Run("should handle BlogPost query with nested complex lists", func(t *testing.T) { + operation := graphql.Request{ + OperationName: "BlogPostNestedComplexListsQuery", + Query: `query BlogPostNestedComplexListsQuery { + blogPost { + id + title + categoryGroups { + id + name + kind + } + contributorTeams { + id + name + } + } + }`, + } + + response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) + + require.NoError(t, err) + require.Contains(t, response, `"categoryGroups":`) + require.Contains(t, response, `"contributorTeams":`) + // Verify nested complex objects + require.Contains(t, response, `"kind":`) + }) + + t.Run("should handle BlogPost query by ID", func(t *testing.T) { + operation := graphql.Request{ + OperationName: "BlogPostByIdQuery", + Variables: stringify(map[string]any{ + "id": "test-blog-1", + }), + Query: `query BlogPostByIdQuery($id: ID!) { + blogPostById(id: $id) { + id + title + content + tags + tagGroups + relatedCategories { + id + name + kind + } + } + }`, + } + + response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) + + require.NoError(t, err) + require.Contains(t, response, `"id":"test-blog-1"`) + require.Contains(t, response, `"title":"Blog Post test-blog-1"`) + require.Contains(t, response, `"tags":`) + require.Contains(t, response, `"tagGroups":`) + require.Contains(t, response, `"relatedCategories":`) + }) + + t.Run("should handle BlogPost filtered query", func(t *testing.T) { + operation := graphql.Request{ + OperationName: "BlogPostFilteredQuery", + Variables: stringify(map[string]any{ + "filter": map[string]any{ + "title": "Test", + "hasCategories": true, + "minTags": 2, + }, + }), + Query: `query BlogPostFilteredQuery($filter: BlogPostFilter!) { + blogPostsWithFilter(filter: $filter) { + id + title + tags + categories + tagGroups + relatedCategories { + id + name + kind + } + } + }`, + } + + response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) + + require.NoError(t, err) + require.Contains(t, response, `"blogPostsWithFilter":`) + require.Contains(t, response, `"tags":`) + require.Contains(t, response, `"categories":`) + require.Contains(t, response, `"tagGroups":`) + require.Contains(t, response, `"relatedCategories":`) + }) + + t.Run("should handle Author query with scalar lists", func(t *testing.T) { + operation := graphql.Request{ + OperationName: "AuthorScalarListsQuery", + Query: `query AuthorScalarListsQuery { + author { + id + name + email + skills + languages + socialLinks + } + }`, + } + + response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) + + require.NoError(t, err) + require.Contains(t, response, `"skills":`) + require.Contains(t, response, `"languages":`) + require.Contains(t, response, `"socialLinks":`) + }) + + t.Run("should handle Author query with nested scalar lists", func(t *testing.T) { + operation := graphql.Request{ + OperationName: "AuthorNestedScalarListsQuery", + Query: `query AuthorNestedScalarListsQuery { + author { + id + name + teamsByProject + collaborations + } + }`, + } + + response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) + + require.NoError(t, err) + require.Equal(t, `{"data":{"author":{"id":"author-default","name":"Default Author","teamsByProject":[["Alice","Bob","Charlie"],["David","Eve"]],"collaborations":[["Open Source Project A","Research Paper B"],["Conference Talk C"]]}}}`, response) + }) + + t.Run("should handle Author query with complex lists", func(t *testing.T) { + operation := graphql.Request{ + OperationName: "AuthorComplexListsQuery", + Query: `query AuthorComplexListsQuery { + author { + id + name + writtenPosts { + id + title + content + } + favoriteCategories { + id + name + kind + } + relatedAuthors { + id + name + } + productReviews { + id + name + price + } + } + }`, + } + + response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) + + require.NoError(t, err) + require.Contains(t, response, `"writtenPosts":`) + require.Contains(t, response, `"favoriteCategories":`) + require.Contains(t, response, `"relatedAuthors":`) + require.Contains(t, response, `"productReviews":`) + // Verify complex objects within lists + require.Contains(t, response, `"title":`) + require.Contains(t, response, `"kind":`) + require.Contains(t, response, `"price":`) + }) + + t.Run("should handle Author query with nested complex lists", func(t *testing.T) { + operation := graphql.Request{ + OperationName: "AuthorNestedComplexListsQuery", + Query: `query AuthorNestedComplexListsQuery { + author { + id + name + authorGroups { + id + name + } + categoryPreferences { + id + name + kind + } + projectTeams { + id + name + } + } + }`, + } + + response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) + + require.NoError(t, err) + require.Contains(t, response, `"authorGroups":`) + require.Contains(t, response, `"categoryPreferences":`) + require.Contains(t, response, `"projectTeams":`) + // Verify nested complex objects + require.Contains(t, response, `"kind":`) + }) + + t.Run("should handle Author query by ID", func(t *testing.T) { + operation := graphql.Request{ + OperationName: "AuthorByIdQuery", + Variables: stringify(map[string]any{ + "id": "test-author-1", + }), + Query: `query AuthorByIdQuery($id: ID!) { + authorById(id: $id) { + id + name + skills + teamsByProject + favoriteCategories { + id + name + kind + } + } + }`, + } + + response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) + + require.NoError(t, err) + require.Contains(t, response, `"id":"test-author-1"`) + require.Contains(t, response, `"name":"Author test-author-1"`) + require.Contains(t, response, `"skills":`) + require.Contains(t, response, `"teamsByProject":`) + require.Contains(t, response, `"favoriteCategories":`) + }) + + t.Run("should handle Author filtered query", func(t *testing.T) { + operation := graphql.Request{ + OperationName: "AuthorFilteredQuery", + Variables: stringify(map[string]any{ + "filter": map[string]any{ + "name": "Test", + "hasTeams": true, + "skillCount": 3, + }, + }), + Query: `query AuthorFilteredQuery($filter: AuthorFilter!) { + authorsWithFilter(filter: $filter) { + id + name + skills + teamsByProject + favoriteCategories { + id + name + kind + } + } + }`, + } + + response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) + + require.NoError(t, err) + require.Contains(t, response, `"authorsWithFilter":`) + require.Contains(t, response, `"skills":`) + require.Contains(t, response, `"teamsByProject":`) + require.Contains(t, response, `"favoriteCategories":`) + }) + + t.Run("should handle BlogPost creation mutation with complex input lists", func(t *testing.T) { + operation := graphql.Request{ + OperationName: "CreateBlogPostMutation", + Variables: stringify(map[string]any{ + "input": map[string]any{ + "title": "Complex Lists Blog Post", + "content": "Testing complex input lists", + "tags": []string{"graphql", "grpc", "lists"}, + "optionalTags": []string{"optional1", "optional2"}, + "categories": []string{"Technology", "Programming"}, + "keywords": []string{"nested", "complex", "types"}, + "viewCounts": []int{150, 250, 350}, + "ratings": []float64{4.2, 4.8, 3.9}, + "isPublished": []bool{true, false, true}, + "tagGroups": [][]string{ + {"graphql", "schema"}, + {"grpc", "protobuf"}, + {"lists", "arrays"}, + }, + "relatedTopics": [][]string{ + {"backend", "api"}, + {"frontend", "ui"}, + }, + "commentThreads": [][]string{ + {"Great post!", "Thanks for sharing"}, + {"Very helpful", "Keep it up"}, + }, + "suggestions": [][]string{ + {"Add examples"}, + {"More details", "Better formatting"}, + }, + "relatedCategories": []map[string]any{ + {"name": "Web Development", "kind": "ELECTRONICS"}, + {"name": "API Design", "kind": "OTHER"}, + }, + "contributors": []map[string]any{ + {"name": "Alice Developer"}, + {"name": "Bob Engineer"}, + }, + "categoryGroups": [][]map[string]any{ + { + {"name": "Backend", "kind": "ELECTRONICS"}, + {"name": "Database", "kind": "OTHER"}, + }, + { + {"name": "Frontend", "kind": "ELECTRONICS"}, + }, + }, + }, + }), + Query: `mutation CreateBlogPostMutation($input: BlogPostInput!) { + createBlogPost(input: $input) { + id + title + content + tags + optionalTags + categories + keywords + viewCounts + ratings + isPublished + tagGroups + relatedTopics + commentThreads + suggestions + relatedCategories { + id + name + kind + } + contributors { + id + name + } + categoryGroups { + id + name + kind + } + } + }`, + } + + response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) + + require.NoError(t, err) + require.Contains(t, response, `"title":"Complex Lists Blog Post"`) + require.Contains(t, response, `"content":"Testing complex input lists"`) + require.Contains(t, response, `"tags":["graphql","grpc","lists"]`) + require.Contains(t, response, `"optionalTags":["optional1","optional2"]`) + require.Contains(t, response, `"categories":["Technology","Programming"]`) + require.Contains(t, response, `"keywords":["nested","complex","types"]`) + require.Contains(t, response, `"viewCounts":[150,250,350]`) + require.Contains(t, response, `"ratings":[4.2,4.8,3.9]`) + require.Contains(t, response, `"isPublished":[true,false,true]`) + require.Contains(t, response, `"tagGroups":[["graphql","schema"],["grpc","protobuf"],["lists","arrays"]]`) + require.Contains(t, response, `"relatedTopics":[["backend","api"],["frontend","ui"]]`) + require.Contains(t, response, `"relatedCategories":`) + require.Contains(t, response, `"contributors":`) + require.Contains(t, response, `"categoryGroups":`) + require.Contains(t, response, `"name":"Web Development"`) + require.Contains(t, response, `"name":"Alice Developer"`) + require.Contains(t, response, `"name":"Backend"`) + }) + + t.Run("should handle Author creation mutation with complex input lists", func(t *testing.T) { + operation := graphql.Request{ + OperationName: "CreateAuthorMutation", + Variables: stringify(map[string]any{ + "input": map[string]any{ + "name": "New Author", + "email": "author@example.com", + "skills": []string{"Go", "GraphQL", "gRPC"}, + "languages": []string{"English", "Spanish"}, + "socialLinks": []string{"twitter.com/author", "github.com/author"}, + "teamsByProject": [][]string{ + {"Alice", "Bob"}, + {"Charlie", "David", "Eve"}, + }, + "collaborations": [][]string{ + {"Project1", "Project2"}, + {"Project3"}, + }, + "favoriteCategories": []map[string]any{ + {"name": "Backend Development", "kind": "ELECTRONICS"}, + {"name": "API Design", "kind": "OTHER"}, + }, + "authorGroups": [][]map[string]any{ + { + {"name": "Go Team"}, + {"name": "GraphQL Team"}, + }, + }, + "projectTeams": [][]map[string]any{ + { + {"name": "Team Lead"}, + {"name": "Senior Dev"}, + }, + { + {"name": "Junior Dev"}, + }, + }, + }, + }), + Query: `mutation CreateAuthorMutation($input: AuthorInput!) { + createAuthor(input: $input) { + id + name + email + skills + languages + socialLinks + teamsByProject + collaborations + favoriteCategories { + id + name + kind + } + authorGroups { + id + name + } + projectTeams { + id + name + } + } + }`, + } + + response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) + + require.NoError(t, err) + require.Contains(t, response, `"name":"New Author"`) + require.Contains(t, response, `"email":"author@example.com"`) + require.Contains(t, response, `"skills":["Go","GraphQL","gRPC"]`) + require.Contains(t, response, `"languages":["English","Spanish"]`) + require.Contains(t, response, `"socialLinks":["twitter.com/author","github.com/author"]`) + require.Contains(t, response, `"teamsByProject":[["Alice","Bob"],["Charlie","David","Eve"]]`) + require.Contains(t, response, `"collaborations":[["Project1","Project2"],["Project3"]]`) + require.Contains(t, response, `"favoriteCategories":`) + require.Contains(t, response, `"authorGroups":`) + require.Contains(t, response, `"projectTeams":`) + require.Contains(t, response, `"name":"Backend Development"`) + require.Contains(t, response, `"name":"Go Team"`) + }) + + t.Run("should handle all BlogPosts query with lists", func(t *testing.T) { + operation := graphql.Request{ + OperationName: "AllBlogPostsQuery", + Query: `query AllBlogPostsQuery { + allBlogPosts { + id + title + tags + tagGroups + viewCounts + ratings + relatedCategories { + id + name + kind + } + } + }`, + } + + response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) + + require.NoError(t, err) + require.Contains(t, response, `"allBlogPosts":`) + require.Contains(t, response, `"tags":`) + require.Contains(t, response, `"tagGroups":`) + require.Contains(t, response, `"viewCounts":`) + require.Contains(t, response, `"ratings":`) + require.Contains(t, response, `"relatedCategories":`) + }) + + t.Run("should handle all Authors query with lists", func(t *testing.T) { + operation := graphql.Request{ + OperationName: "AllAuthorsQuery", + Query: `query AllAuthorsQuery { + allAuthors { + id + name + skills + teamsByProject + favoriteCategories { + id + name + kind + } + } + }`, + } + + response, err := executeOperation(t, conn, operation, withGRPCMapping(mapping.DefaultGRPCMapping())) + + require.NoError(t, err) + require.Contains(t, response, `"allAuthors":`) + require.Contains(t, response, `"skills":`) + require.Contains(t, response, `"teamsByProject":`) + require.Contains(t, response, `"favoriteCategories":`) + }) } diff --git a/v2/pkg/ast/ast_type.go b/v2/pkg/ast/ast_type.go index 001cd36547..6c22f33fe3 100644 --- a/v2/pkg/ast/ast_type.go +++ b/v2/pkg/ast/ast_type.go @@ -180,6 +180,16 @@ func (d *Document) TypeIsList(ref int) bool { } } +// TypeIsNonNullList checks if the type is a non-nullable list. +// e.g.: +// * [String!]! -> true +// * [String]! -> true +// * [String!] -> false +// * [String] -> false +func (d *Document) TypeIsNonNullList(ref int) bool { + return d.Types[ref].TypeKind == TypeKindNonNull && d.TypeIsList(d.Types[ref].OfType) +} + func (d *Document) TypeNumberOfListWraps(ref int) int { count := 0 for { @@ -260,3 +270,27 @@ func (d *Document) ResolveListOrNameType(ref int) (typeRef int) { } return } + +// ResolveNestedListOrListType returns the underlying type of a list. +// In contrast to ResolveListOrNameType, this function does not unwrap a non-null type. +// e.g.: +// * [[String]] -> [String] +// * [[String]!] -> [String]! +// * [String!]! -> String! +// * [String]! -> String +func (d *Document) ResolveNestedListOrListType(ref int) int { + if !d.TypeIsList(ref) { + return InvalidRef + } + + graphqlType := d.Types[ref] + if graphqlType.TypeKind == TypeKindNonNull { + graphqlType = d.Types[graphqlType.OfType] + } + + if graphqlType.TypeKind == TypeKindList { + return graphqlType.OfType + } + + return ref +} diff --git a/v2/pkg/engine/datasource/grpc_datasource/compiler.go b/v2/pkg/engine/datasource/grpc_datasource/compiler.go index 5726126399..ee49e8176c 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/compiler.go +++ b/v2/pkg/engine/datasource/grpc_datasource/compiler.go @@ -212,14 +212,16 @@ func (d *Document) ServiceByRef(ref int) Service { // MessageByName returns a Message by its name. // Returns an empty Message if no message with the given name exists. -func (d *Document) MessageByName(name string) Message { +// We only expect this function to return false if either the message name was provided incorrectly, +// or the schema and mapping was not properly configured. +func (d *Document) MessageByName(name string) (Message, bool) { for _, m := range d.Messages { if m.Name == name { - return m + return m, true } } - return Message{} + return Message{}, false } // MessageRefByName returns the index of a Message in the Messages slice by its name. @@ -336,13 +338,13 @@ func (p *RPCCompiler) Compile(executionPlan *RPCExecutionPlan, inputData gjson.R invocations := make([]Invocation, 0, len(executionPlan.Calls)) for _, call := range executionPlan.Calls { - inputMessage := p.doc.MessageByName(call.Request.Name) - if inputMessage.Name == "" { + inputMessage, ok := p.doc.MessageByName(call.Request.Name) + if !ok { return nil, fmt.Errorf("input message %s not found in document", call.Request.Name) } - outputMessage := p.doc.MessageByName(call.Response.Name) - if outputMessage.Name == "" { + outputMessage, ok := p.doc.MessageByName(call.Response.Name) + if !ok { return nil, fmt.Errorf("output message %s not found in document", call.Response.Name) } @@ -445,11 +447,39 @@ func (p *RPCCompiler) buildProtoMessage(inputMessage Message, rpcMessage *RPCMes if field.MessageRef >= 0 { var fieldMsg *dynamicpb.Message - // If the field is optional, we are handling a scalar value that is wrapped in a message - // as protobuf scalar types are not nullable. - if rpcField.Optional { - // If we don't have a value for an optional field, we skip it to provide a null message. + switch { + + case rpcField.IsListType: + // Nested and nullable lists are wrapped in a message, therefore we need to handle them differently + // than repeated fields. We need to do this because protobuf repeated fields are not nullable and cannot be nested. + // + // message BlogPost { + // ListOfBoolean is_published = 1; + // ListOfListOfString related_topics = 2; + // } if !data.Get(rpcField.JSONPath).Exists() { + if !rpcField.Optional { + p.report.AddInternalError(fmt.Errorf("field %s is required but has no value", rpcField.JSONPath)) + } + + continue + } + + if rpcField.ListMetadata == nil { + p.report.AddInternalError(fmt.Errorf("list metadata not found for field %s", rpcField.JSONPath)) + continue + } + + fieldMsg = p.buildListMessage(inputMessage.Desc, field, rpcField, data) + if fieldMsg == nil { + continue + } + case rpcField.IsOptionalScalar(): + // If the field is optional, we are handling a scalar value that is wrapped in a message + // as protobuf scalar types are not nullable. + + if !data.Get(rpcField.JSONPath).Exists() { + // If we don't have a value for an optional field, we skip it to provide a null message. continue } @@ -459,7 +489,7 @@ func (p *RPCCompiler) buildProtoMessage(inputMessage Message, rpcMessage *RPCMes rpcField.ToOptionalTypeMessage(p.doc.Messages[field.MessageRef].Name), data, ) - } else { + default: fieldMsg = p.buildProtoMessage(p.doc.Messages[field.MessageRef], rpcField.Message, data.Get(rpcField.JSONPath)) } @@ -468,28 +498,17 @@ func (p *RPCCompiler) buildProtoMessage(inputMessage Message, rpcMessage *RPCMes } if field.Type == DataTypeEnum { - enum, ok := p.doc.EnumByName(rpcField.EnumName) - if !ok { - p.report.AddInternalError(fmt.Errorf("enum %s not found in document", rpcField.EnumName)) - continue - } - - for _, enumValue := range enum.Values { - if enumValue.GraphqlValue == data.Get(rpcField.JSONPath).String() { - message.Set( - fd.ByName(protoref.Name(field.Name)), - protoref.ValueOfEnum(protoref.EnumNumber(enumValue.Number)), - ) - - break - } + if val := p.getEnumValue(rpcField.EnumName, data.Get(rpcField.JSONPath)); val != nil { + message.Set( + fd.ByName(protoref.Name(field.Name)), + *val, + ) } continue } // Handle scalar fields - // TODO handle optional fields value := data.Get(rpcField.JSONPath) message.Set(fd.ByName(protoref.Name(field.Name)), p.setValueForKind(field.Type, value)) } @@ -497,6 +516,118 @@ func (p *RPCCompiler) buildProtoMessage(inputMessage Message, rpcMessage *RPCMes return message } +// buildListMessage creates a new protobuf message, which reflects a wrapper type to work with a list in GraphQL. +// A list wrapper type has an inner message type, which contains a repeated field. +// We need this to make sure we can differentiate between a null list and an empty list, as repeated fields are not nullable. +// +// message ListOfFloat { +// message List { +// repeated double items = 1; +// } +// List list = 1; +// } +func (p *RPCCompiler) buildListMessage(desc protoref.MessageDescriptor, field Field, rpcField *RPCField, data gjson.Result) *dynamicpb.Message { + rootMsg := dynamicpb.NewMessage(desc.Fields().ByName(protoref.Name(field.Name)).Message()) + p.traverseList(rootMsg, 1, field, rpcField, data.Get(rpcField.JSONPath)) + return rootMsg +} + +// traverseList makes sure we can handle nested lists properly. +// A nested list follows the same structure as a regular list, but references the lower nested message list wrapper. +// +// message ListOfListOfString { +// message List { +// repeated ListOfString items = 1; +// } +// List list = 1; +// } +func (p *RPCCompiler) traverseList(rootMsg protoref.Message, level int, field Field, rpcField *RPCField, data gjson.Result) protoref.Message { + listFieldDesc := rootMsg.Descriptor().Fields().ByNumber(1) + if listFieldDesc == nil { + p.report.AddInternalError(fmt.Errorf("field with number %d not found in message %s", 1, rootMsg.Descriptor().Name())) + return nil + } + + elements := data.Array() + newListField := rootMsg.NewField(listFieldDesc) + if len(elements) == 0 { + if rpcField.ListMetadata.LevelInfo[level-1].Optional { + return nil + } + + rootMsg.Set(listFieldDesc, newListField) + return rootMsg + } + + // Inside of a List message type we expect a repeated "items" field with field number 1 + itemsFieldMsg := newListField.Message() + itemsFieldDesc := itemsFieldMsg.Descriptor().Fields().ByNumber(1) + if itemsFieldDesc == nil { + p.report.AddInternalError(fmt.Errorf("field with number %d not found in message %s", 1, itemsFieldMsg.Descriptor().Name())) + return nil + } + + itemsField := itemsFieldMsg.Mutable(itemsFieldDesc).List() + + if level >= rpcField.ListMetadata.NestingLevel { + switch DataType(rpcField.TypeName) { + case DataTypeMessage: + itemsFieldMsg, ok := p.doc.MessageByName(rpcField.Message.Name) + if !ok { + p.report.AddInternalError(fmt.Errorf("message %s not found in document", rpcField.Message.Name)) + return nil + } + + for _, element := range elements { + if msg := p.buildProtoMessage(itemsFieldMsg, rpcField.Message, element); msg != nil { + itemsField.Append(protoref.ValueOfMessage(msg)) + } + } + case DataTypeEnum: + for _, element := range elements { + if val := p.getEnumValue(rpcField.EnumName, element); val != nil { + itemsField.Append(*val) + } + } + default: + for _, element := range elements { + itemsField.Append(p.setValueForKind(DataType(itemsFieldDesc.Kind().String()), element)) + } + } + + itemsFieldMsg.Set(itemsFieldDesc, protoref.ValueOfList(itemsField)) + rootMsg.Set(listFieldDesc, newListField) + return rootMsg + } + + for _, element := range elements { + newElement := itemsField.NewElement() + if val := p.traverseList(newElement.Message(), level+1, field, rpcField, element); val != nil { + itemsField.Append(protoref.ValueOfMessage(val)) + } + } + + rootMsg.Set(listFieldDesc, newListField) + return rootMsg +} + +func (p *RPCCompiler) getEnumValue(enumName string, data gjson.Result) *protoref.Value { + enum, ok := p.doc.EnumByName(enumName) + if !ok { + p.report.AddInternalError(fmt.Errorf("enum %s not found in document", enumName)) + return nil + } + + for _, enumValue := range enum.Values { + if enumValue.GraphqlValue == data.String() { + v := protoref.ValueOfEnum(protoref.EnumNumber(enumValue.Number)) + return &v + } + } + + return nil +} + // setValueForKind converts a gjson.Result value to the appropriate protobuf value // based on its kind/type. func (p *RPCCompiler) setValueForKind(kind DataType, data gjson.Result) protoref.Value { @@ -599,18 +730,20 @@ func (p *RPCCompiler) parseMethod(m protoref.MethodDescriptor) Method { // parseMessageDefinitions extracts information from a protobuf message descriptor. // It returns a slice of Message objects with the name and descriptor. func (p *RPCCompiler) parseMessageDefinitions(messages protoref.MessageDescriptors) []Message { - extractedMessage := make([]Message, 0, messages.Len()) + extractedMessages := make([]Message, 0, messages.Len()) for i := 0; i < messages.Len(); i++ { protoMessage := messages.Get(i) - extractedMessage = append(extractedMessage, Message{ + message := Message{ Name: string(protoMessage.Name()), Desc: protoMessage, - }) + } + + extractedMessages = append(extractedMessages, message) } - return extractedMessage + return extractedMessages } // enrichMessageData enriches the message data with the field information. diff --git a/v2/pkg/engine/datasource/grpc_datasource/compiler_test.go b/v2/pkg/engine/datasource/grpc_datasource/compiler_test.go index 5e098c3035..4859896124 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/compiler_test.go +++ b/v2/pkg/engine/datasource/grpc_datasource/compiler_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/require" "github.com/tidwall/gjson" "github.com/wundergraph/graphql-go-tools/v2/pkg/grpctest" + "google.golang.org/protobuf/reflect/protoreflect" ) // Complete valid protobuf definition with service and message definitions @@ -291,3 +292,160 @@ func TestBuildProtoMessage(t *testing.T) { require.Equal(t, 1, len(invocations)) } + +func TestCompileNestedLists(t *testing.T) { + compiler, err := NewProtoCompiler(grpctest.MustProtoSchema(t), testMapping()) + require.NoError(t, err) + + plan := &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryCalculateTotals", + Request: RPCMessage{ + Name: "QueryCalculateTotalsRequest", + Fields: []RPCField{ + { + Name: "orders", + TypeName: string(DataTypeMessage), + JSONPath: "orders", + Repeated: true, + Message: &RPCMessage{ + Name: "OrderInput", + Fields: []RPCField{ + { + Name: "order_id", + TypeName: string(DataTypeString), + JSONPath: "orderId", + }, + { + Name: "customer_name", + TypeName: string(DataTypeString), + JSONPath: "customerName", + }, + { + Name: "lines", + TypeName: string(DataTypeMessage), + JSONPath: "lines", + Repeated: true, + Message: &RPCMessage{ + Name: "OrderLineInput", + Fields: []RPCField{ + { + Name: "product_id", + TypeName: string(DataTypeString), + JSONPath: "productId", + }, + { + Name: "quantity", + TypeName: string(DataTypeInt32), + JSONPath: "quantity", + }, + { + Name: "modifiers", + TypeName: string(DataTypeString), + JSONPath: "modifiers", + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 1, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "QueryCalculateTotalsResponse", + Fields: []RPCField{ + { + Name: "calculate_totals", + TypeName: string(DataTypeMessage), + JSONPath: "calculateTotals", + Repeated: true, + Message: &RPCMessage{ + Name: "Order", + Fields: []RPCField{ + { + Name: "order_id", + TypeName: string(DataTypeString), + JSONPath: "orderId", + }, + { + Name: "customer_name", + TypeName: string(DataTypeString), + JSONPath: "customerName", + }, + { + Name: "total_items", + TypeName: string(DataTypeInt32), + JSONPath: "totalItems", + }, + }, + }, + }, + }, + }, + }, + }, + } + + invocations, err := compiler.Compile(plan, gjson.ParseBytes([]byte(`{"orders":[{"orderId":"123","customerName":"John Doe","lines":[{"productId":"123","quantity":1, "modifiers":["modifier1", "modifier2"]}]}]}`))) + require.NoError(t, err) + require.Equal(t, 1, len(invocations)) + + proto := invocations[0].Input.ProtoReflect() + + msgDesc := proto.Descriptor() + + ordersDesc := msgDesc.Fields().ByName("orders") + require.True(t, proto.Has(ordersDesc)) + orders := proto.Get(ordersDesc) + require.True(t, orders.IsValid()) + + require.True(t, ordersDesc.IsList()) + ordersList := orders.List() + + orderMsg := ordersList.Get(0).Message() + orderDesc := orderMsg.Descriptor() + require.True(t, ordersList.Get(0).Message().Has(orderDesc.Fields().ByName("order_id"))) + require.True(t, ordersList.Get(0).Message().Has(orderDesc.Fields().ByName("customer_name"))) + require.True(t, ordersList.Get(0).Message().Has(orderDesc.Fields().ByName("lines"))) + + linesList := ordersList.Get(0).Message().Get(orderDesc.Fields().ByName("lines")).List() + require.True(t, linesList.IsValid()) + + require.Equal(t, 1, linesList.Len()) + + for i := 0; i < linesList.Len(); i++ { + linesMsg := linesList.Get(i).Message() + + linesDesc := linesMsg.Descriptor().Fields() + + require.True(t, linesMsg.Has(linesDesc.ByName("product_id"))) + require.True(t, linesMsg.Has(linesDesc.ByName("quantity"))) + require.True(t, linesMsg.Has(linesDesc.ByName("modifiers"))) + + modifiersDesc := linesDesc.ByName("modifiers") + require.True(t, modifiersDesc.Kind() == protoreflect.MessageKind) + + modifiersMsg := linesMsg.Get(modifiersDesc).Message() + require.True(t, modifiersMsg.IsValid(), "expected modifiers message to be valid") + modifiersListMsg := modifiersMsg.Get(modifiersMsg.Descriptor().Fields().ByName("list")).Message() + modifiersList := modifiersListMsg.Get(modifiersListMsg.Descriptor().Fields().ByName("items")).List() + + require.True(t, modifiersList.IsValid(), "expected modifiers list to be valid") + require.Equal(t, 2, modifiersList.Len()) + require.Equal(t, "modifier1", modifiersList.Get(0).String()) + require.Equal(t, "modifier2", modifiersList.Get(1).String()) + } +} diff --git a/v2/pkg/engine/datasource/grpc_datasource/execution_plan.go b/v2/pkg/engine/datasource/grpc_datasource/execution_plan.go index 90c19b2280..ad41e4baf8 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/execution_plan.go +++ b/v2/pkg/engine/datasource/grpc_datasource/execution_plan.go @@ -168,11 +168,29 @@ type RPCField struct { StaticValue string // Optional indicates if the field is optional Optional bool + // IsListType indicates if the field is a list wrapper type + IsListType bool + // ListMetadata contains the metadata for the list type + ListMetadata *ListMetadata // Message represents the nested message type definition for complex fields. // This enables recursive construction of nested protobuf message structures. Message *RPCMessage } +// ListMetadata contains the metadata for the list type +type ListMetadata struct { + // NestingLevel is the nesting level of the list type + NestingLevel int + // LevelInfo contains the metadata for each nesting level of the list + LevelInfo []LevelInfo +} + +// LevelInfo contains the metadata for the list type +type LevelInfo struct { + // Optional indicates if the field is optional + Optional bool +} + // ToOptionalTypeMessage returns a message that wraps the scalar value in a message // as protobuf scalar types are not nullable. func (r *RPCField) ToOptionalTypeMessage(protoName string) *RPCMessage { @@ -192,7 +210,6 @@ func (r *RPCField) ToOptionalTypeMessage(protoName string) *RPCMessage { }, }, } - } // AliasOrPath returns the alias of the field if it exists, otherwise it returns the JSONPath. @@ -204,6 +221,11 @@ func (r *RPCField) AliasOrPath() string { return r.JSONPath } +// IsOptionalScalar checks if the field is an optional scalar value. +func (r *RPCField) IsOptionalScalar() bool { + return r.Optional && r.TypeName != string(DataTypeMessage) +} + // RPCFields is a list of RPCFields that provides helper methods // for working with collections of fields. type RPCFields []RPCField diff --git a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_composite_test.go b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_composite_test.go new file mode 100644 index 0000000000..30ae95163e --- /dev/null +++ b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_composite_test.go @@ -0,0 +1,896 @@ +package grpcdatasource + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" + "github.com/wundergraph/graphql-go-tools/v2/pkg/astparser" + "github.com/wundergraph/graphql-go-tools/v2/pkg/astvisitor" + grpctest "github.com/wundergraph/graphql-go-tools/v2/pkg/grpctest" +) + +func TestCompositeTypeExecutionPlan(t *testing.T) { + tests := []struct { + name string + query string + expectedPlan *RPCExecutionPlan + expectedError string + }{ + { + name: "Should create an execution plan for a query with a random cat", + query: "query RandomCatQuery { randomPet { id name kind ... on Cat { meowVolume } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryRandomPet", + Request: RPCMessage{ + Name: "QueryRandomPetRequest", + }, + Response: RPCMessage{ + Name: "QueryRandomPetResponse", + Fields: []RPCField{ + { + Name: "random_pet", + TypeName: string(DataTypeMessage), + JSONPath: "randomPet", + Message: &RPCMessage{ + Name: "Animal", + OneOfType: OneOfTypeInterface, + MemberTypes: []string{ + "Cat", + "Dog", + }, + FieldSelectionSet: RPCFieldSelectionSet{ + "Cat": { + { + Name: "meow_volume", + TypeName: string(DataTypeInt32), + JSONPath: "meowVolume", + }, + }, + }, + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "kind", + TypeName: string(DataTypeString), + JSONPath: "kind", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for a query with a random cat and dog", + query: "query CatAndDogQuery { randomPet { id name kind ... on Cat { meowVolume } ... on Dog { barkVolume } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryRandomPet", + Request: RPCMessage{ + Name: "QueryRandomPetRequest", + }, + Response: RPCMessage{ + Name: "QueryRandomPetResponse", + Fields: []RPCField{ + { + Name: "random_pet", + TypeName: string(DataTypeMessage), + JSONPath: "randomPet", + Message: &RPCMessage{ + Name: "Animal", + OneOfType: OneOfTypeInterface, + MemberTypes: []string{ + "Cat", + "Dog", + }, + FieldSelectionSet: RPCFieldSelectionSet{ + "Cat": { + { + Name: "meow_volume", + TypeName: string(DataTypeInt32), + JSONPath: "meowVolume", + }, + }, + "Dog": { + { + Name: "bark_volume", + TypeName: string(DataTypeInt32), + JSONPath: "barkVolume", + }, + }, + }, + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "kind", + TypeName: string(DataTypeString), + JSONPath: "kind", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for a query with all pets (interface list)", + query: "query AllPetsQuery { allPets { id name kind ... on Cat { meowVolume } ... on Dog { barkVolume } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryAllPets", + Request: RPCMessage{ + Name: "QueryAllPetsRequest", + }, + Response: RPCMessage{ + Name: "QueryAllPetsResponse", + Fields: []RPCField{ + { + Name: "all_pets", + TypeName: string(DataTypeMessage), + JSONPath: "allPets", + Repeated: true, + Message: &RPCMessage{ + Name: "Animal", + OneOfType: OneOfTypeInterface, + MemberTypes: []string{ + "Cat", + "Dog", + }, + FieldSelectionSet: RPCFieldSelectionSet{ + "Cat": { + { + Name: "meow_volume", + TypeName: string(DataTypeInt32), + JSONPath: "meowVolume", + }, + }, + "Dog": { + { + Name: "bark_volume", + TypeName: string(DataTypeInt32), + JSONPath: "barkVolume", + }, + }, + }, + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "kind", + TypeName: string(DataTypeString), + JSONPath: "kind", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for a query with all pets using an interface fragment", + query: "query AllPetsQuery { allPets { ... on Animal { id name kind } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryAllPets", + Request: RPCMessage{ + Name: "QueryAllPetsRequest", + }, + Response: RPCMessage{ + Name: "QueryAllPetsResponse", + Fields: []RPCField{ + { + Name: "all_pets", + TypeName: string(DataTypeMessage), + JSONPath: "allPets", + Repeated: true, + Message: &RPCMessage{ + Name: "Animal", + OneOfType: OneOfTypeInterface, + MemberTypes: []string{ + "Cat", + "Dog", + }, + Fields: RPCFields{}, + FieldSelectionSet: RPCFieldSelectionSet{ + "Animal": { + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "kind", + TypeName: string(DataTypeString), + JSONPath: "kind", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for a query with interface selecting only common fields", + query: "query CommonFieldsQuery { randomPet { id name kind } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryRandomPet", + Request: RPCMessage{ + Name: "QueryRandomPetRequest", + }, + Response: RPCMessage{ + Name: "QueryRandomPetResponse", + Fields: []RPCField{ + { + Name: "random_pet", + TypeName: string(DataTypeMessage), + JSONPath: "randomPet", + Message: &RPCMessage{ + Name: "Animal", + OneOfType: OneOfTypeInterface, + MemberTypes: []string{ + "Cat", + "Dog", + }, + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "kind", + TypeName: string(DataTypeString), + JSONPath: "kind", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for a SearchResult union query", + query: "query SearchQuery($input: SearchInput!) { search(input: $input) { ... on Product { id name price } ... on User { id name } ... on Category { id name kind } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QuerySearch", + Request: RPCMessage{ + Name: "QuerySearchRequest", + Fields: []RPCField{ + { + Name: "input", + TypeName: string(DataTypeMessage), + JSONPath: "input", + Message: &RPCMessage{ + Name: "SearchInput", + Fields: []RPCField{ + { + Name: "query", + TypeName: string(DataTypeString), + JSONPath: "query", + }, + { + Name: "limit", + TypeName: string(DataTypeInt32), + JSONPath: "limit", + Optional: true, + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "QuerySearchResponse", + Fields: []RPCField{ + { + Name: "search", + TypeName: string(DataTypeMessage), + JSONPath: "search", + Repeated: true, + Message: &RPCMessage{ + Name: "SearchResult", + OneOfType: OneOfTypeUnion, + MemberTypes: []string{ + "Product", + "User", + "Category", + }, + Fields: RPCFields{}, + FieldSelectionSet: RPCFieldSelectionSet{ + "Product": { + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "price", + TypeName: string(DataTypeDouble), + JSONPath: "price", + }, + }, + "User": { + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + }, + "Category": { + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "kind", + TypeName: string(DataTypeEnum), + JSONPath: "kind", + EnumName: "CategoryKind", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for a single SearchResult union query", + query: "query RandomSearchQuery { randomSearchResult { ... on Product { id name price } ... on User { id name } ... on Category { id name kind } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryRandomSearchResult", + Request: RPCMessage{ + Name: "QueryRandomSearchResultRequest", + }, + Response: RPCMessage{ + Name: "QueryRandomSearchResultResponse", + Fields: []RPCField{ + { + Name: "random_search_result", + TypeName: string(DataTypeMessage), + JSONPath: "randomSearchResult", + Message: &RPCMessage{ + Name: "SearchResult", + OneOfType: OneOfTypeUnion, + MemberTypes: []string{ + "Product", + "User", + "Category", + }, + Fields: RPCFields{}, + FieldSelectionSet: RPCFieldSelectionSet{ + "Product": { + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "price", + TypeName: string(DataTypeDouble), + JSONPath: "price", + }, + }, + "User": { + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + }, + "Category": { + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "kind", + TypeName: string(DataTypeEnum), + JSONPath: "kind", + EnumName: "CategoryKind", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for a SearchResult union with partial selection", + query: "query PartialSearchQuery($input: SearchInput!) { search(input: $input) { ... on Product { id name } ... on User { id name } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QuerySearch", + Request: RPCMessage{ + Name: "QuerySearchRequest", + Fields: []RPCField{ + { + Name: "input", + TypeName: string(DataTypeMessage), + JSONPath: "input", + Message: &RPCMessage{ + Name: "SearchInput", + Fields: []RPCField{ + { + Name: "query", + TypeName: string(DataTypeString), + JSONPath: "query", + }, + { + Name: "limit", + TypeName: string(DataTypeInt32), + JSONPath: "limit", + Optional: true, + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "QuerySearchResponse", + Fields: []RPCField{ + { + Name: "search", + TypeName: string(DataTypeMessage), + JSONPath: "search", + Repeated: true, + Message: &RPCMessage{ + Name: "SearchResult", + OneOfType: OneOfTypeUnion, + MemberTypes: []string{ + "Product", + "User", + "Category", + }, + Fields: RPCFields{}, + FieldSelectionSet: RPCFieldSelectionSet{ + "Product": { + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + }, + "User": { + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + // Parse the GraphQL schema + schemaDoc := grpctest.MustGraphQLSchema(t) + + // Parse the GraphQL query + queryDoc, report := astparser.ParseGraphqlDocumentString(tt.query) + if report.HasErrors() { + t.Fatalf("failed to parse query: %s", report.Error()) + } + + walker := astvisitor.NewWalker(48) + + rpcPlanVisitor := newRPCPlanVisitor(&walker, rpcPlanVisitorConfig{ + subgraphName: "Products", + mapping: testMapping(), + }) + + walker.Walk(&queryDoc, &schemaDoc, &report) + + if report.HasErrors() { + require.NotEmpty(t, tt.expectedError) + require.Contains(t, report.Error(), tt.expectedError) + return + } + + require.Empty(t, tt.expectedError) + diff := cmp.Diff(tt.expectedPlan, rpcPlanVisitor.plan) + if diff != "" { + t.Fatalf("execution plan mismatch: %s", diff) + } + }) + } +} + +func TestMutationUnionExecutionPlan(t *testing.T) { + tests := []struct { + name string + query string + expectedPlan *RPCExecutionPlan + expectedError string + }{ + { + name: "Should create an execution plan for ActionResult union mutation", + query: "mutation PerformActionMutation($input: ActionInput!) { performAction(input: $input) { ... on ActionSuccess { message timestamp } ... on ActionError { message code } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "MutationPerformAction", + Request: RPCMessage{ + Name: "MutationPerformActionRequest", + Fields: []RPCField{ + { + Name: "input", + TypeName: string(DataTypeMessage), + JSONPath: "input", + Message: &RPCMessage{ + Name: "ActionInput", + Fields: []RPCField{ + { + Name: "type", + TypeName: string(DataTypeString), + JSONPath: "type", + }, + { + Name: "payload", + TypeName: string(DataTypeString), + JSONPath: "payload", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "MutationPerformActionResponse", + Fields: []RPCField{ + { + Name: "perform_action", + TypeName: string(DataTypeMessage), + JSONPath: "performAction", + Message: &RPCMessage{ + Name: "ActionResult", + OneOfType: OneOfTypeUnion, + MemberTypes: []string{ + "ActionSuccess", + "ActionError", + }, + Fields: RPCFields{}, + FieldSelectionSet: RPCFieldSelectionSet{ + "ActionSuccess": { + { + Name: "message", + TypeName: string(DataTypeString), + JSONPath: "message", + }, + { + Name: "timestamp", + TypeName: string(DataTypeString), + JSONPath: "timestamp", + }, + }, + "ActionError": { + { + Name: "message", + TypeName: string(DataTypeString), + JSONPath: "message", + }, + { + Name: "code", + TypeName: string(DataTypeString), + JSONPath: "code", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for ActionResult union with only success case", + query: "mutation PerformSuccessActionMutation($input: ActionInput!) { performAction(input: $input) { ... on ActionSuccess { message timestamp } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "MutationPerformAction", + Request: RPCMessage{ + Name: "MutationPerformActionRequest", + Fields: []RPCField{ + { + Name: "input", + TypeName: string(DataTypeMessage), + JSONPath: "input", + Message: &RPCMessage{ + Name: "ActionInput", + Fields: []RPCField{ + { + Name: "type", + TypeName: string(DataTypeString), + JSONPath: "type", + }, + { + Name: "payload", + TypeName: string(DataTypeString), + JSONPath: "payload", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "MutationPerformActionResponse", + Fields: []RPCField{ + { + Name: "perform_action", + TypeName: string(DataTypeMessage), + JSONPath: "performAction", + Message: &RPCMessage{ + Name: "ActionResult", + OneOfType: OneOfTypeUnion, + MemberTypes: []string{ + "ActionSuccess", + "ActionError", + }, + Fields: RPCFields{}, + FieldSelectionSet: RPCFieldSelectionSet{ + "ActionSuccess": { + { + Name: "message", + TypeName: string(DataTypeString), + JSONPath: "message", + }, + { + Name: "timestamp", + TypeName: string(DataTypeString), + JSONPath: "timestamp", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for ActionResult union with only error case", + query: "mutation PerformErrorActionMutation($input: ActionInput!) { performAction(input: $input) { ... on ActionError { message code } } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "MutationPerformAction", + Request: RPCMessage{ + Name: "MutationPerformActionRequest", + Fields: []RPCField{ + { + Name: "input", + TypeName: string(DataTypeMessage), + JSONPath: "input", + Message: &RPCMessage{ + Name: "ActionInput", + Fields: []RPCField{ + { + Name: "type", + TypeName: string(DataTypeString), + JSONPath: "type", + }, + { + Name: "payload", + TypeName: string(DataTypeString), + JSONPath: "payload", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "MutationPerformActionResponse", + Fields: []RPCField{ + { + Name: "perform_action", + TypeName: string(DataTypeMessage), + JSONPath: "performAction", + Message: &RPCMessage{ + Name: "ActionResult", + OneOfType: OneOfTypeUnion, + MemberTypes: []string{ + "ActionSuccess", + "ActionError", + }, + Fields: RPCFields{}, + FieldSelectionSet: RPCFieldSelectionSet{ + "ActionError": { + { + Name: "message", + TypeName: string(DataTypeString), + JSONPath: "message", + }, + { + Name: "code", + TypeName: string(DataTypeString), + JSONPath: "code", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + // Parse the GraphQL schema + schemaDoc := grpctest.MustGraphQLSchema(t) + + // Parse the GraphQL query + queryDoc, report := astparser.ParseGraphqlDocumentString(tt.query) + if report.HasErrors() { + t.Fatalf("failed to parse query: %s", report.Error()) + } + + walker := astvisitor.NewWalker(48) + + rpcPlanVisitor := newRPCPlanVisitor(&walker, rpcPlanVisitorConfig{ + subgraphName: "Products", + mapping: testMapping(), + }) + + walker.Walk(&queryDoc, &schemaDoc, &report) + + if report.HasErrors() { + require.NotEmpty(t, tt.expectedError) + require.Contains(t, report.Error(), tt.expectedError) + return + } + + require.Empty(t, tt.expectedError) + diff := cmp.Diff(tt.expectedPlan, rpcPlanVisitor.plan) + if diff != "" { + t.Fatalf("execution plan mismatch: %s", diff) + } + }) + } +} diff --git a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_federation_test.go b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_federation_test.go new file mode 100644 index 0000000000..5756d9d167 --- /dev/null +++ b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_federation_test.go @@ -0,0 +1,326 @@ +package grpcdatasource + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/wundergraph/graphql-go-tools/v2/pkg/astparser" + "github.com/wundergraph/graphql-go-tools/v2/pkg/astvisitor" + grpctest "github.com/wundergraph/graphql-go-tools/v2/pkg/grpctest" +) + +func TestEntityLookup(t *testing.T) { + tests := []struct { + name string + query string + expectedPlan *RPCExecutionPlan + mapping *GRPCMapping + }{ + { + name: "Should create an execution plan for an entity lookup with one key field", + query: `query EntityLookup($representations: [_Any!]!) { _entities(representations: $representations) { ... on Product { __typename id name price } } }`, + mapping: &GRPCMapping{ + Service: "Products", + EntityRPCs: map[string]EntityRPCConfig{ + "Product": { + Key: "id", + RPCConfig: RPCConfig{ + RPC: "LookupProductById", + Request: "LookupProductByIdRequest", + Response: "LookupProductByIdResponse", + }, + }, + }, + }, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "LookupProductById", + // Define the structure of the request message + Request: RPCMessage{ + Name: "LookupProductByIdRequest", + Fields: []RPCField{ + { + Name: "keys", + TypeName: string(DataTypeMessage), + Repeated: true, + JSONPath: "representations", + Message: &RPCMessage{ + Name: "LookupProductByIdKey", + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + }, + }, + }, + }, + }, + // Define the structure of the response message + Response: RPCMessage{ + Name: "LookupProductByIdResponse", + Fields: []RPCField{ + { + Name: "result", + TypeName: string(DataTypeMessage), + Repeated: true, + JSONPath: "_entities", + Message: &RPCMessage{ + Name: "Product", + Fields: []RPCField{ + { + Name: "__typename", + TypeName: string(DataTypeString), + JSONPath: "__typename", + StaticValue: "Product", + }, + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "price", + TypeName: string(DataTypeDouble), + JSONPath: "price", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + + // TODO implement multiple entity lookup types + // { + // name: "Should create an execution plan for an entity lookup multiple types", + // query: ` + // query EntityLookup($representations: [_Any!]!) { + // _entities(representations: $representations) { + // ... on Product { + // id + // name + // price + // } + // ... on Storage { + // id + // name + // location + // } + // } + // } + // `, + // expectedPlan: &RPCExecutionPlan{ + // Groups: []RPCCallGroup{ + // { + // Calls: []RPCCall{ + // { + // ServiceName: "Products", + // MethodName: "LookupProductById", + // // Define the structure of the request message + // Request: RPCMessage{ + // Name: "LookupProductByIdRequest", + // Fields: []RPCField{ + // { + // Name: "inputs", + // TypeName: string(DataTypeMessage), + // Repeated: true, + // JSONPath: "representations", // Path to extract data from GraphQL variables + // + + // Message: &RPCMessage{ + // Name: "LookupProductByIdInput", + // Fields: []RPCField{ + // { + // Name: "key", + // TypeName: string(DataTypeMessage), + // + + // Message: &RPCMessage{ + // Name: "ProductByIdKey", + // Fields: []RPCField{ + // { + // Name: "id", + // TypeName: string(DataTypeString), + // JSONPath: "id", // Extract 'id' from each representation + // + + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // // Define the structure of the response message + // Response: RPCMessage{ + // Name: "LookupProductByIdResponse", + // Fields: []RPCField{ + // { + // Name: "results", + // TypeName: string(DataTypeMessage), + // Repeated: true, + // + + // JSONPath: "results", + // Message: &RPCMessage{ + // Name: "LookupProductByIdResult", + // Fields: []RPCField{ + // { + // Name: "product", + // TypeName: string(DataTypeMessage), + // + + // Message: &RPCMessage{ + // Name: "Product", + // Fields: []RPCField{ + // { + // Name: "id", + // TypeName: string(DataTypeString), + // JSONPath: "id", + // }, + // { + // Name: "name", + // TypeName: string(DataTypeString), + // JSONPath: "name", + // }, + // { + // Name: "price", + // TypeName: string(DataTypeFloat), + // JSONPath: "price", + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // { + // ServiceName: "Products", + // MethodName: "LookupStorageById", + // Request: RPCMessage{ + // Name: "LookupStorageByIdRequest", + // Fields: []RPCField{ + // { + // Name: "inputs", + // TypeName: string(DataTypeMessage), + // Repeated: true, + // JSONPath: "representations", + // Message: &RPCMessage{ + // Name: "LookupStorageByIdInput", + // Fields: []RPCField{ + // { + // Name: "key", + // TypeName: string(DataTypeMessage), + // Message: &RPCMessage{ + // Name: "StorageByIdKey", + // Fields: []RPCField{ + // { + // Name: "id", + // TypeName: string(DataTypeString), + // JSONPath: "id", + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // Response: RPCMessage{ + // Name: "LookupStorageByIdResponse", + // Fields: []RPCField{ + // { + // Name: "results", + // TypeName: string(DataTypeMessage), + // Repeated: true, + // JSONPath: "results", + // Message: &RPCMessage{ + // Name: "LookupStorageByIdResult", + // Fields: []RPCField{ + // { + // Name: "storage", + // TypeName: string(DataTypeMessage), + // Message: &RPCMessage{ + // Name: "Storage", + // Fields: []RPCField{ + // { + // Name: "id", + // TypeName: string(DataTypeString), + // JSONPath: "id", + // }, + // { + // Name: "name", + // TypeName: string(DataTypeString), + // JSONPath: "name", + // }, + // { + // Name: "location", + // TypeName: string(DataTypeString), + // JSONPath: "location", + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + // Parse the GraphQL schema + schemaDoc := grpctest.MustGraphQLSchema(t) + + // Parse the GraphQL query + queryDoc, report := astparser.ParseGraphqlDocumentString(tt.query) + if report.HasErrors() { + t.Fatalf("failed to parse query: %s", report.Error()) + } + + walker := astvisitor.NewWalker(48) + + rpcPlanVisitor := newRPCPlanVisitor(&walker, rpcPlanVisitorConfig{ + subgraphName: "Products", + mapping: tt.mapping, + }) + + walker.Walk(&queryDoc, &schemaDoc, &report) + + if report.HasErrors() { + t.Fatalf("failed to walk AST: %s", report.Error()) + } + + diff := cmp.Diff(tt.expectedPlan, rpcPlanVisitor.plan) + if diff != "" { + t.Fatalf("execution plan mismatch: %s", diff) + } + }) + } +} diff --git a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_list_test.go b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_list_test.go new file mode 100644 index 0000000000..e85e58d6c9 --- /dev/null +++ b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_list_test.go @@ -0,0 +1,1012 @@ +package grpcdatasource + +import "testing" + +func TestListExecutionPlan(t *testing.T) { + tests := []struct { + name string + query string + expectedPlan *RPCExecutionPlan + expectedError string + }{ + { + name: "Should create an execution plan for a blog post with a non-nullable list", + query: `query GetBlogPost { blogPost { title tags } }`, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryBlogPost", + Request: RPCMessage{ + Name: "QueryBlogPostRequest", + }, + Response: RPCMessage{ + Name: "QueryBlogPostResponse", + Fields: RPCFields{ + { + Name: "blog_post", + TypeName: string(DataTypeMessage), + JSONPath: "blogPost", + Message: &RPCMessage{ + Name: "BlogPost", + Fields: RPCFields{ + { + Name: "title", + TypeName: string(DataTypeString), + JSONPath: "title", + }, + { + Name: "tags", + TypeName: string(DataTypeString), + Repeated: true, + JSONPath: "tags", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for a blog post with a nullable list", + query: `query GetBlogPost { blogPost { title optionalTags } }`, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryBlogPost", + Request: RPCMessage{ + Name: "QueryBlogPostRequest", + }, + Response: RPCMessage{ + Name: "QueryBlogPostResponse", + Fields: RPCFields{ + { + Name: "blog_post", + TypeName: string(DataTypeMessage), + JSONPath: "blogPost", + Message: &RPCMessage{ + Name: "BlogPost", + Fields: RPCFields{ + { + Name: "title", + TypeName: string(DataTypeString), + JSONPath: "title", + }, + { + Name: "optional_tags", + TypeName: string(DataTypeString), + Optional: true, + JSONPath: "optionalTags", + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 1, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for a blog post with a nested list", + query: `query GetBlogPost { blogPost { tagGroups } }`, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryBlogPost", + Request: RPCMessage{ + Name: "QueryBlogPostRequest", + }, + Response: RPCMessage{ + Name: "QueryBlogPostResponse", + Fields: RPCFields{ + { + Name: "blog_post", + TypeName: string(DataTypeMessage), + JSONPath: "blogPost", + Message: &RPCMessage{ + Name: "BlogPost", + Fields: RPCFields{ + { + Name: "tag_groups", + TypeName: string(DataTypeString), + Repeated: false, + JSONPath: "tagGroups", + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 2, + LevelInfo: []LevelInfo{ + { + Optional: false, + }, + { + Optional: false, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + runTest(t, testCase{ + query: tt.query, + expectedPlan: tt.expectedPlan, + expectedError: tt.expectedError, + }) + }) + } +} + +func TestListParametersExecutionPlan(t *testing.T) { + tests := []struct { + name string + query string + expectedPlan *RPCExecutionPlan + expectedError string + }{ + { + name: "Should create an execution plan for query with required list of required enums parameter", + query: `query GetCategoriesByKinds($kinds: [CategoryKind!]!) { categoriesByKinds(kinds: $kinds) { id name kind } }`, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryCategoriesByKinds", + Request: RPCMessage{ + Name: "QueryCategoriesByKindsRequest", + Fields: []RPCField{ + { + Name: "kinds", + TypeName: string(DataTypeEnum), + JSONPath: "kinds", + EnumName: "CategoryKind", + Repeated: true, + }, + }, + }, + Response: RPCMessage{ + Name: "QueryCategoriesByKindsResponse", + Fields: []RPCField{ + { + Name: "categories_by_kinds", + TypeName: string(DataTypeMessage), + JSONPath: "categoriesByKinds", + Repeated: true, + Message: &RPCMessage{ + Name: "Category", + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "kind", + TypeName: string(DataTypeEnum), + JSONPath: "kind", + EnumName: "CategoryKind", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for query with required list of required input objects parameter", + query: `query CalculateTotals($orders: [OrderInput!]!) { calculateTotals(orders: $orders) { orderId customerName totalItems } }`, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryCalculateTotals", + Request: RPCMessage{ + Name: "QueryCalculateTotalsRequest", + Fields: []RPCField{ + { + Name: "orders", + TypeName: string(DataTypeMessage), + JSONPath: "orders", + Repeated: true, + Message: &RPCMessage{ + Name: "OrderInput", + Fields: []RPCField{ + { + Name: "order_id", + TypeName: string(DataTypeString), + JSONPath: "orderId", + }, + { + Name: "customer_name", + TypeName: string(DataTypeString), + JSONPath: "customerName", + }, + { + Name: "lines", + TypeName: string(DataTypeMessage), + JSONPath: "lines", + Repeated: true, + Message: &RPCMessage{ + Name: "OrderLineInput", + Fields: []RPCField{ + { + Name: "product_id", + TypeName: string(DataTypeString), + JSONPath: "productId", + }, + { + Name: "quantity", + TypeName: string(DataTypeInt32), + JSONPath: "quantity", + }, + { + Name: "modifiers", + TypeName: string(DataTypeString), + JSONPath: "modifiers", + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 1, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "QueryCalculateTotalsResponse", + Fields: []RPCField{ + { + Name: "calculate_totals", + TypeName: string(DataTypeMessage), + JSONPath: "calculateTotals", + Repeated: true, + Message: &RPCMessage{ + Name: "Order", + Fields: []RPCField{ + { + Name: "order_id", + TypeName: string(DataTypeString), + JSONPath: "orderId", + }, + { + Name: "customer_name", + TypeName: string(DataTypeString), + JSONPath: "customerName", + }, + { + Name: "total_items", + TypeName: string(DataTypeInt32), + JSONPath: "totalItems", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for BlogPost mutation with single list parameters", + query: `mutation CreateBlogPost($input: BlogPostInput!) { createBlogPost(input: $input) { id title tags optionalTags categories keywords } }`, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "MutationCreateBlogPost", + Request: RPCMessage{ + Name: "MutationCreateBlogPostRequest", + Fields: []RPCField{ + { + Name: "input", + TypeName: string(DataTypeMessage), + JSONPath: "input", + Message: &RPCMessage{ + Name: "BlogPostInput", + Fields: []RPCField{ + { + Name: "title", + TypeName: string(DataTypeString), + JSONPath: "title", + }, + { + Name: "content", + TypeName: string(DataTypeString), + JSONPath: "content", + }, + { + Name: "tags", + TypeName: string(DataTypeString), + JSONPath: "tags", + Repeated: true, + }, + { + Name: "optional_tags", + TypeName: string(DataTypeString), + JSONPath: "optionalTags", + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 1, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + }, + }, + }, + { + Name: "categories", + TypeName: string(DataTypeString), + JSONPath: "categories", + Repeated: true, + }, + { + Name: "keywords", + TypeName: string(DataTypeString), + JSONPath: "keywords", + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 1, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + }, + }, + }, + { + Name: "view_counts", + TypeName: string(DataTypeInt32), + JSONPath: "viewCounts", + Repeated: true, + }, + { + Name: "ratings", + TypeName: string(DataTypeDouble), + JSONPath: "ratings", + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 1, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + }, + }, + }, + { + Name: "is_published", + TypeName: string(DataTypeBool), + JSONPath: "isPublished", + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 1, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + }, + }, + }, + { + Name: "tag_groups", + TypeName: string(DataTypeString), + JSONPath: "tagGroups", + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 2, + LevelInfo: []LevelInfo{ + { + Optional: false, + }, + { + Optional: false, + }, + }, + }, + }, + { + Name: "related_topics", + TypeName: string(DataTypeString), + JSONPath: "relatedTopics", + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 2, + LevelInfo: []LevelInfo{ + { + Optional: false, + }, + { + Optional: true, + }, + }, + }, + }, + { + Name: "comment_threads", + TypeName: string(DataTypeString), + JSONPath: "commentThreads", + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 2, + LevelInfo: []LevelInfo{ + { + Optional: false, + }, + { + Optional: false, + }, + }, + }, + }, + { + Name: "suggestions", + TypeName: string(DataTypeString), + JSONPath: "suggestions", + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 2, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + { + Optional: true, + }, + }, + }, + }, + { + Name: "related_categories", + TypeName: string(DataTypeMessage), + JSONPath: "relatedCategories", + Repeated: false, + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 1, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + }, + }, + Message: &RPCMessage{ + Name: "CategoryInput", + Fields: []RPCField{ + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "kind", + TypeName: string(DataTypeEnum), + JSONPath: "kind", + EnumName: "CategoryKind", + }, + }, + }, + }, + { + Name: "contributors", + TypeName: string(DataTypeMessage), + JSONPath: "contributors", + Repeated: false, + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 1, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + }, + }, + Message: &RPCMessage{ + Name: "UserInput", + Fields: []RPCField{ + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + }, + }, + }, + { + Name: "category_groups", + TypeName: string(DataTypeMessage), + JSONPath: "categoryGroups", + Repeated: false, + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 2, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + { + Optional: true, + }, + }, + }, + Message: &RPCMessage{ + Name: "CategoryInput", + Fields: []RPCField{ + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "kind", + TypeName: string(DataTypeEnum), + JSONPath: "kind", + EnumName: "CategoryKind", + }, + }, + }, + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "MutationCreateBlogPostResponse", + Fields: []RPCField{ + { + Name: "create_blog_post", + TypeName: string(DataTypeMessage), + JSONPath: "createBlogPost", + Message: &RPCMessage{ + Name: "BlogPost", + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "title", + TypeName: string(DataTypeString), + JSONPath: "title", + }, + { + Name: "tags", + TypeName: string(DataTypeString), + JSONPath: "tags", + Repeated: true, + }, + { + Name: "optional_tags", + TypeName: string(DataTypeString), + JSONPath: "optionalTags", + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 1, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + }, + }, + }, + { + Name: "categories", + TypeName: string(DataTypeString), + JSONPath: "categories", + Repeated: true, + }, + { + Name: "keywords", + TypeName: string(DataTypeString), + JSONPath: "keywords", + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 1, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for Author mutation with nested list parameters", + query: `mutation CreateAuthor($input: AuthorInput!) { createAuthor(input: $input) { id name skills teamsByProject collaborations } }`, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "MutationCreateAuthor", + Request: RPCMessage{ + Name: "MutationCreateAuthorRequest", + Fields: []RPCField{ + { + Name: "input", + TypeName: string(DataTypeMessage), + JSONPath: "input", + Message: &RPCMessage{ + Name: "AuthorInput", + Fields: []RPCField{ + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "email", + TypeName: string(DataTypeString), + JSONPath: "email", + Optional: true, + }, + { + Name: "skills", + TypeName: string(DataTypeString), + JSONPath: "skills", + Repeated: true, + }, + { + Name: "languages", + TypeName: string(DataTypeString), + JSONPath: "languages", + Repeated: true, + }, + { + Name: "social_links", + TypeName: string(DataTypeString), + JSONPath: "socialLinks", + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 1, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + }, + }, + }, + { + Name: "teams_by_project", + TypeName: string(DataTypeString), + JSONPath: "teamsByProject", + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 2, + LevelInfo: []LevelInfo{ + { + Optional: false, + }, + { + Optional: false, + }, + }, + }, + }, + { + Name: "collaborations", + TypeName: string(DataTypeString), + JSONPath: "collaborations", + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 2, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + { + Optional: true, + }, + }, + }, + }, + { + Name: "favorite_categories", + TypeName: string(DataTypeMessage), + JSONPath: "favoriteCategories", + Repeated: true, + Message: &RPCMessage{ + Name: "CategoryInput", + Fields: []RPCField{ + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "kind", + TypeName: string(DataTypeEnum), + JSONPath: "kind", + EnumName: "CategoryKind", + }, + }, + }, + }, + { + Name: "author_groups", + TypeName: string(DataTypeMessage), + JSONPath: "authorGroups", + Repeated: false, + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 2, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + { + Optional: true, + }, + }, + }, + Message: &RPCMessage{ + Name: "UserInput", + Fields: []RPCField{ + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + }, + }, + }, + { + Name: "project_teams", + TypeName: string(DataTypeMessage), + JSONPath: "projectTeams", + Repeated: false, + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 2, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + { + Optional: true, + }, + }, + }, + Message: &RPCMessage{ + Name: "UserInput", + Fields: []RPCField{ + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + }, + }, + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "MutationCreateAuthorResponse", + Fields: []RPCField{ + { + Name: "create_author", + TypeName: string(DataTypeMessage), + JSONPath: "createAuthor", + Message: &RPCMessage{ + Name: "Author", + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "skills", + TypeName: string(DataTypeString), + JSONPath: "skills", + Repeated: true, + }, + { + Name: "teams_by_project", + TypeName: string(DataTypeString), + JSONPath: "teamsByProject", + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 2, + LevelInfo: []LevelInfo{ + { + Optional: false, + }, + { + Optional: false, + }, + }, + }, + }, + { + Name: "collaborations", + TypeName: string(DataTypeString), + JSONPath: "collaborations", + Optional: true, + IsListType: true, + ListMetadata: &ListMetadata{ + NestingLevel: 2, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + { + Optional: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for filtered BlogPost query with simple parameters", + query: `query FilteredBlogPosts($filter: BlogPostFilter!) { blogPostsWithFilter(filter: $filter) { id title tags } }`, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryBlogPostsWithFilter", + Request: RPCMessage{ + Name: "QueryBlogPostsWithFilterRequest", + Fields: []RPCField{ + { + Name: "filter", + TypeName: string(DataTypeMessage), + JSONPath: "filter", + Message: &RPCMessage{ + Name: "BlogPostFilter", + Fields: []RPCField{ + { + Name: "title", + TypeName: string(DataTypeString), + JSONPath: "title", + Optional: true, + }, + { + Name: "has_categories", + TypeName: string(DataTypeBool), + JSONPath: "hasCategories", + Optional: true, + }, + { + Name: "min_tags", + TypeName: string(DataTypeInt32), + JSONPath: "minTags", + Optional: true, + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "QueryBlogPostsWithFilterResponse", + Fields: []RPCField{ + { + Name: "blog_posts_with_filter", + TypeName: string(DataTypeMessage), + JSONPath: "blogPostsWithFilter", + Repeated: true, + Message: &RPCMessage{ + Name: "BlogPost", + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "title", + TypeName: string(DataTypeString), + JSONPath: "title", + }, + { + Name: "tags", + TypeName: string(DataTypeString), + JSONPath: "tags", + Repeated: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + runTest(t, testCase{ + query: tt.query, + expectedPlan: tt.expectedPlan, + expectedError: tt.expectedError, + }) + }) + } +} diff --git a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_nullable_test.go b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_nullable_test.go new file mode 100644 index 0000000000..14eb1218e0 --- /dev/null +++ b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_nullable_test.go @@ -0,0 +1,645 @@ +package grpcdatasource + +import ( + "testing" +) + +func TestNullableFieldsExecutionPlan(t *testing.T) { + tests := []struct { + name string + query string + expectedPlan *RPCExecutionPlan + expectedError string + }{ + { + name: "Should create an execution plan for a query with nullable fields type", + query: "query NullableFieldsTypeQuery { nullableFieldsType { id name optionalString optionalInt optionalFloat optionalBoolean requiredString requiredInt } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryNullableFieldsType", + Request: RPCMessage{ + Name: "QueryNullableFieldsTypeRequest", + }, + Response: RPCMessage{ + Name: "QueryNullableFieldsTypeResponse", + Fields: []RPCField{ + { + Name: "nullable_fields_type", + TypeName: string(DataTypeMessage), + JSONPath: "nullableFieldsType", + Message: &RPCMessage{ + Name: "NullableFieldsType", + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "optional_string", + TypeName: string(DataTypeString), + JSONPath: "optionalString", + Optional: true, + }, + { + Name: "optional_int", + TypeName: string(DataTypeInt32), + JSONPath: "optionalInt", + Optional: true, + }, + { + Name: "optional_float", + TypeName: string(DataTypeDouble), + JSONPath: "optionalFloat", + Optional: true, + }, + { + Name: "optional_boolean", + TypeName: string(DataTypeBool), + JSONPath: "optionalBoolean", + Optional: true, + }, + { + Name: "required_string", + TypeName: string(DataTypeString), + JSONPath: "requiredString", + }, + { + Name: "required_int", + TypeName: string(DataTypeInt32), + JSONPath: "requiredInt", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for a query with nullable fields in the request", + query: `query NullableFieldsTypeWithFilterQuery($filter: NullableFieldsFilter!) { nullableFieldsTypeWithFilter(filter: $filter) { id name optionalString optionalInt optionalFloat optionalBoolean } }`, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryNullableFieldsTypeWithFilter", + Request: RPCMessage{ + Name: "QueryNullableFieldsTypeWithFilterRequest", + Fields: []RPCField{ + { + Name: "filter", + TypeName: string(DataTypeMessage), + JSONPath: "filter", + Message: &RPCMessage{ + Name: "NullableFieldsFilter", + Fields: []RPCField{ + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + Optional: true, + }, + { + Name: "optional_string", + TypeName: string(DataTypeString), + JSONPath: "optionalString", + Optional: true, + }, + { + Name: "include_nulls", + TypeName: string(DataTypeBool), + JSONPath: "includeNulls", + Optional: true, + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "QueryNullableFieldsTypeWithFilterResponse", + Fields: []RPCField{ + { + Name: "nullable_fields_type_with_filter", + TypeName: string(DataTypeMessage), + JSONPath: "nullableFieldsTypeWithFilter", + Repeated: true, + Message: &RPCMessage{ + Name: "NullableFieldsType", + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "optional_string", + TypeName: string(DataTypeString), + JSONPath: "optionalString", + Optional: true, + }, + { + Name: "optional_int", + TypeName: string(DataTypeInt32), + JSONPath: "optionalInt", + Optional: true, + }, + { + Name: "optional_float", + TypeName: string(DataTypeDouble), + JSONPath: "optionalFloat", + Optional: true, + }, + { + Name: "optional_boolean", + TypeName: string(DataTypeBool), + JSONPath: "optionalBoolean", + Optional: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for nullable fields type by ID query", + query: `query NullableFieldsTypeByIdQuery($id: ID!) { nullableFieldsTypeById(id: $id) { id name optionalString requiredString } }`, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryNullableFieldsTypeById", + Request: RPCMessage{ + Name: "QueryNullableFieldsTypeByIdRequest", + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + }, + }, + Response: RPCMessage{ + Name: "QueryNullableFieldsTypeByIdResponse", + Fields: []RPCField{ + { + Name: "nullable_fields_type_by_id", + TypeName: string(DataTypeMessage), + JSONPath: "nullableFieldsTypeById", + Optional: true, + Message: &RPCMessage{ + Name: "NullableFieldsType", + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "optional_string", + TypeName: string(DataTypeString), + JSONPath: "optionalString", + Optional: true, + }, + { + Name: "required_string", + TypeName: string(DataTypeString), + JSONPath: "requiredString", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for all nullable fields types query", + query: "query AllNullableFieldsTypesQuery { allNullableFieldsTypes { id name optionalString optionalInt requiredString requiredInt } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryAllNullableFieldsTypes", + Request: RPCMessage{ + Name: "QueryAllNullableFieldsTypesRequest", + }, + Response: RPCMessage{ + Name: "QueryAllNullableFieldsTypesResponse", + Fields: []RPCField{ + { + Name: "all_nullable_fields_types", + TypeName: string(DataTypeMessage), + JSONPath: "allNullableFieldsTypes", + Repeated: true, + Message: &RPCMessage{ + Name: "NullableFieldsType", + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "optional_string", + TypeName: string(DataTypeString), + JSONPath: "optionalString", + Optional: true, + }, + { + Name: "optional_int", + TypeName: string(DataTypeInt32), + JSONPath: "optionalInt", + Optional: true, + }, + { + Name: "required_string", + TypeName: string(DataTypeString), + JSONPath: "requiredString", + }, + { + Name: "required_int", + TypeName: string(DataTypeInt32), + JSONPath: "requiredInt", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for create nullable fields type mutation", + query: `mutation CreateNullableFieldsType($input: NullableFieldsInput!) { createNullableFieldsType(input: $input) { id name optionalString optionalInt optionalFloat optionalBoolean requiredString requiredInt } }`, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "MutationCreateNullableFieldsType", + Request: RPCMessage{ + Name: "MutationCreateNullableFieldsTypeRequest", + Fields: []RPCField{ + { + Name: "input", + TypeName: string(DataTypeMessage), + JSONPath: "input", + Message: &RPCMessage{ + Name: "NullableFieldsInput", + Fields: []RPCField{ + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "optional_string", + TypeName: string(DataTypeString), + JSONPath: "optionalString", + Optional: true, + }, + { + Name: "optional_int", + TypeName: string(DataTypeInt32), + JSONPath: "optionalInt", + Optional: true, + }, + { + Name: "optional_float", + TypeName: string(DataTypeDouble), + JSONPath: "optionalFloat", + Optional: true, + }, + { + Name: "optional_boolean", + TypeName: string(DataTypeBool), + JSONPath: "optionalBoolean", + Optional: true, + }, + { + Name: "required_string", + TypeName: string(DataTypeString), + JSONPath: "requiredString", + }, + { + Name: "required_int", + TypeName: string(DataTypeInt32), + JSONPath: "requiredInt", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "MutationCreateNullableFieldsTypeResponse", + Fields: []RPCField{ + { + Name: "create_nullable_fields_type", + TypeName: string(DataTypeMessage), + JSONPath: "createNullableFieldsType", + Message: &RPCMessage{ + Name: "NullableFieldsType", + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "optional_string", + TypeName: string(DataTypeString), + JSONPath: "optionalString", + Optional: true, + }, + { + Name: "optional_int", + TypeName: string(DataTypeInt32), + JSONPath: "optionalInt", + Optional: true, + }, + { + Name: "optional_float", + TypeName: string(DataTypeDouble), + JSONPath: "optionalFloat", + Optional: true, + }, + { + Name: "optional_boolean", + TypeName: string(DataTypeBool), + JSONPath: "optionalBoolean", + Optional: true, + }, + { + Name: "required_string", + TypeName: string(DataTypeString), + JSONPath: "requiredString", + }, + { + Name: "required_int", + TypeName: string(DataTypeInt32), + JSONPath: "requiredInt", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for update nullable fields type mutation", + query: `mutation UpdateNullableFieldsType($id: ID!, $input: NullableFieldsInput!) { updateNullableFieldsType(id: $id, input: $input) { id name optionalString requiredString } }`, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "MutationUpdateNullableFieldsType", + Request: RPCMessage{ + Name: "MutationUpdateNullableFieldsTypeRequest", + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "input", + TypeName: string(DataTypeMessage), + JSONPath: "input", + Message: &RPCMessage{ + Name: "NullableFieldsInput", + Fields: []RPCField{ + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "optional_string", + TypeName: string(DataTypeString), + JSONPath: "optionalString", + Optional: true, + }, + { + Name: "optional_int", + TypeName: string(DataTypeInt32), + JSONPath: "optionalInt", + Optional: true, + }, + { + Name: "optional_float", + TypeName: string(DataTypeDouble), + JSONPath: "optionalFloat", + Optional: true, + }, + { + Name: "optional_boolean", + TypeName: string(DataTypeBool), + JSONPath: "optionalBoolean", + Optional: true, + }, + { + Name: "required_string", + TypeName: string(DataTypeString), + JSONPath: "requiredString", + }, + { + Name: "required_int", + TypeName: string(DataTypeInt32), + JSONPath: "requiredInt", + }, + }, + }, + }, + }, + }, + Response: RPCMessage{ + Name: "MutationUpdateNullableFieldsTypeResponse", + Fields: []RPCField{ + { + Name: "update_nullable_fields_type", + TypeName: string(DataTypeMessage), + JSONPath: "updateNullableFieldsType", + Optional: true, + Message: &RPCMessage{ + Name: "NullableFieldsType", + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + }, + { + Name: "optional_string", + TypeName: string(DataTypeString), + JSONPath: "optionalString", + Optional: true, + }, + { + Name: "required_string", + TypeName: string(DataTypeString), + JSONPath: "requiredString", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for nullable fields with partial field selection", + query: "query PartialNullableFieldsQuery { nullableFieldsType { id optionalString } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryNullableFieldsType", + Request: RPCMessage{ + Name: "QueryNullableFieldsTypeRequest", + }, + Response: RPCMessage{ + Name: "QueryNullableFieldsTypeResponse", + Fields: []RPCField{ + { + Name: "nullable_fields_type", + TypeName: string(DataTypeMessage), + JSONPath: "nullableFieldsType", + Message: &RPCMessage{ + Name: "NullableFieldsType", + Fields: []RPCField{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "optional_string", + TypeName: string(DataTypeString), + JSONPath: "optionalString", + Optional: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Should create an execution plan for nullable fields with only optional fields", + query: "query OptionalFieldsOnlyQuery { nullableFieldsType { optionalString optionalInt optionalFloat optionalBoolean } }", + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryNullableFieldsType", + Request: RPCMessage{ + Name: "QueryNullableFieldsTypeRequest", + }, + Response: RPCMessage{ + Name: "QueryNullableFieldsTypeResponse", + Fields: []RPCField{ + { + Name: "nullable_fields_type", + TypeName: string(DataTypeMessage), + JSONPath: "nullableFieldsType", + Message: &RPCMessage{ + Name: "NullableFieldsType", + Fields: []RPCField{ + { + Name: "optional_string", + TypeName: string(DataTypeString), + JSONPath: "optionalString", + Optional: true, + }, + { + Name: "optional_int", + TypeName: string(DataTypeInt32), + JSONPath: "optionalInt", + Optional: true, + }, + { + Name: "optional_float", + TypeName: string(DataTypeDouble), + JSONPath: "optionalFloat", + Optional: true, + }, + { + Name: "optional_boolean", + TypeName: string(DataTypeBool), + JSONPath: "optionalBoolean", + Optional: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + runTest(t, testCase{ + query: tt.query, + expectedPlan: tt.expectedPlan, + expectedError: tt.expectedError, + }) + }) + } +} diff --git a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_test.go b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_test.go index 5cc3e89230..a104ac585f 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_test.go +++ b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_test.go @@ -52,322 +52,6 @@ func runTest(t *testing.T, testCase testCase) { } } -func TestEntityLookup(t *testing.T) { - tests := []struct { - name string - query string - expectedPlan *RPCExecutionPlan - mapping *GRPCMapping - }{ - { - name: "Should create an execution plan for an entity lookup with one key field", - query: `query EntityLookup($representations: [_Any!]!) { _entities(representations: $representations) { ... on Product { __typename id name price } } }`, - mapping: &GRPCMapping{ - Service: "Products", - EntityRPCs: map[string]EntityRPCConfig{ - "Product": { - Key: "id", - RPCConfig: RPCConfig{ - RPC: "LookupProductById", - Request: "LookupProductByIdRequest", - Response: "LookupProductByIdResponse", - }, - }, - }, - }, - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "LookupProductById", - // Define the structure of the request message - Request: RPCMessage{ - Name: "LookupProductByIdRequest", - Fields: []RPCField{ - { - Name: "keys", - TypeName: string(DataTypeMessage), - Repeated: true, - JSONPath: "representations", - Message: &RPCMessage{ - Name: "LookupProductByIdKey", - Fields: []RPCField{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - }, - }, - }, - }, - }, - // Define the structure of the response message - Response: RPCMessage{ - Name: "LookupProductByIdResponse", - Fields: []RPCField{ - { - Name: "result", - TypeName: string(DataTypeMessage), - Repeated: true, - JSONPath: "_entities", - Message: &RPCMessage{ - Name: "Product", - Fields: []RPCField{ - { - Name: "__typename", - TypeName: string(DataTypeString), - JSONPath: "__typename", - StaticValue: "Product", - }, - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - { - Name: "price", - TypeName: string(DataTypeDouble), - JSONPath: "price", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - - // TODO implement multiple entity lookup types - // { - // name: "Should create an execution plan for an entity lookup multiple types", - // query: ` - // query EntityLookup($representations: [_Any!]!) { - // _entities(representations: $representations) { - // ... on Product { - // id - // name - // price - // } - // ... on Storage { - // id - // name - // location - // } - // } - // } - // `, - // expectedPlan: &RPCExecutionPlan{ - // Groups: []RPCCallGroup{ - // { - // Calls: []RPCCall{ - // { - // ServiceName: "Products", - // MethodName: "LookupProductById", - // // Define the structure of the request message - // Request: RPCMessage{ - // Name: "LookupProductByIdRequest", - // Fields: []RPCField{ - // { - // Name: "inputs", - // TypeName: string(DataTypeMessage), - // Repeated: true, - // JSONPath: "representations", // Path to extract data from GraphQL variables - // - - // Message: &RPCMessage{ - // Name: "LookupProductByIdInput", - // Fields: []RPCField{ - // { - // Name: "key", - // TypeName: string(DataTypeMessage), - // - - // Message: &RPCMessage{ - // Name: "ProductByIdKey", - // Fields: []RPCField{ - // { - // Name: "id", - // TypeName: string(DataTypeString), - // JSONPath: "id", // Extract 'id' from each representation - // - - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // // Define the structure of the response message - // Response: RPCMessage{ - // Name: "LookupProductByIdResponse", - // Fields: []RPCField{ - // { - // Name: "results", - // TypeName: string(DataTypeMessage), - // Repeated: true, - // - - // JSONPath: "results", - // Message: &RPCMessage{ - // Name: "LookupProductByIdResult", - // Fields: []RPCField{ - // { - // Name: "product", - // TypeName: string(DataTypeMessage), - // - - // Message: &RPCMessage{ - // Name: "Product", - // Fields: []RPCField{ - // { - // Name: "id", - // TypeName: string(DataTypeString), - // JSONPath: "id", - // }, - // { - // Name: "name", - // TypeName: string(DataTypeString), - // JSONPath: "name", - // }, - // { - // Name: "price", - // TypeName: string(DataTypeFloat), - // JSONPath: "price", - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // { - // ServiceName: "Products", - // MethodName: "LookupStorageById", - // Request: RPCMessage{ - // Name: "LookupStorageByIdRequest", - // Fields: []RPCField{ - // { - // Name: "inputs", - // TypeName: string(DataTypeMessage), - // Repeated: true, - // JSONPath: "representations", - // Message: &RPCMessage{ - // Name: "LookupStorageByIdInput", - // Fields: []RPCField{ - // { - // Name: "key", - // TypeName: string(DataTypeMessage), - // Message: &RPCMessage{ - // Name: "StorageByIdKey", - // Fields: []RPCField{ - // { - // Name: "id", - // TypeName: string(DataTypeString), - // JSONPath: "id", - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // Response: RPCMessage{ - // Name: "LookupStorageByIdResponse", - // Fields: []RPCField{ - // { - // Name: "results", - // TypeName: string(DataTypeMessage), - // Repeated: true, - // JSONPath: "results", - // Message: &RPCMessage{ - // Name: "LookupStorageByIdResult", - // Fields: []RPCField{ - // { - // Name: "storage", - // TypeName: string(DataTypeMessage), - // Message: &RPCMessage{ - // Name: "Storage", - // Fields: []RPCField{ - // { - // Name: "id", - // TypeName: string(DataTypeString), - // JSONPath: "id", - // }, - // { - // Name: "name", - // TypeName: string(DataTypeString), - // JSONPath: "name", - // }, - // { - // Name: "location", - // TypeName: string(DataTypeString), - // JSONPath: "location", - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - // Parse the GraphQL schema - schemaDoc := grpctest.MustGraphQLSchema(t) - - // Parse the GraphQL query - queryDoc, report := astparser.ParseGraphqlDocumentString(tt.query) - if report.HasErrors() { - t.Fatalf("failed to parse query: %s", report.Error()) - } - - walker := astvisitor.NewWalker(48) - - rpcPlanVisitor := newRPCPlanVisitor(&walker, rpcPlanVisitorConfig{ - subgraphName: "Products", - mapping: tt.mapping, - }) - - walker.Walk(&queryDoc, &schemaDoc, &report) - - if report.HasErrors() { - t.Fatalf("failed to walk AST: %s", report.Error()) - } - - diff := cmp.Diff(tt.expectedPlan, rpcPlanVisitor.plan) - if diff != "" { - t.Fatalf("execution plan mismatch: %s", diff) - } - }) - } -} - func TestQueryExecutionPlans(t *testing.T) { tests := []struct { name string @@ -487,6 +171,7 @@ func TestQueryExecutionPlans(t *testing.T) { Name: "user", TypeName: string(DataTypeMessage), JSONPath: "user", + Optional: true, Message: &RPCMessage{ Name: "User", Fields: []RPCField{ @@ -618,6 +303,7 @@ func TestQueryExecutionPlans(t *testing.T) { Name: "pagination", TypeName: string(DataTypeMessage), JSONPath: "pagination", + Optional: true, Message: &RPCMessage{ Name: "Pagination", Fields: []RPCField{ @@ -716,6 +402,7 @@ func TestQueryExecutionPlans(t *testing.T) { Name: "pagination", TypeName: string(DataTypeMessage), JSONPath: "pagination", + Optional: true, Message: &RPCMessage{ Name: "Pagination", Fields: []RPCField{ @@ -815,6 +502,7 @@ func TestQueryExecutionPlans(t *testing.T) { Name: "pagination", TypeName: string(DataTypeMessage), JSONPath: "pagination", + Optional: true, Message: &RPCMessage{ Name: "Pagination", Fields: []RPCField{ @@ -1014,6 +702,7 @@ func TestQueryExecutionPlans(t *testing.T) { Name: "user", TypeName: string(DataTypeMessage), JSONPath: "user", + Optional: true, Message: &RPCMessage{ Name: "User", Fields: []RPCField{ @@ -1327,10 +1016,20 @@ func TestQueryExecutionPlans(t *testing.T) { JSONPath: "quantity", }, { - Name: "modifiers", - TypeName: string(DataTypeString), - JSONPath: "modifiers", - Repeated: true, + Name: "modifiers", + TypeName: string(DataTypeString), + Repeated: false, + Optional: true, + IsListType: true, + JSONPath: "modifiers", + ListMetadata: &ListMetadata{ + NestingLevel: 1, + LevelInfo: []LevelInfo{ + { + Optional: true, + }, + }, + }, }, }, }, @@ -1412,7 +1111,7 @@ func TestQueryExecutionPlans(t *testing.T) { } } -func TestCompositeTypeExecutionPlan(t *testing.T) { +func TestProductExecutionPlan(t *testing.T) { tests := []struct { name string query string @@ -1420,105 +1119,34 @@ func TestCompositeTypeExecutionPlan(t *testing.T) { expectedError string }{ { - name: "Should create an execution plan for a query with a random cat", - query: "query RandomCatQuery { randomPet { id name kind ... on Cat { meowVolume } } }", + name: "Should create an execution plan for a query with categories by kind", + query: "query CategoriesQuery($kind: CategoryKind!) { categoriesByKind(kind: $kind) { id name kind } }", expectedPlan: &RPCExecutionPlan{ Calls: []RPCCall{ { ServiceName: "Products", - MethodName: "QueryRandomPet", + MethodName: "QueryCategoriesByKind", Request: RPCMessage{ - Name: "QueryRandomPetRequest", - }, - Response: RPCMessage{ - Name: "QueryRandomPetResponse", + Name: "QueryCategoriesByKindRequest", Fields: []RPCField{ { - Name: "random_pet", - TypeName: string(DataTypeMessage), - JSONPath: "randomPet", - Message: &RPCMessage{ - Name: "Animal", - OneOfType: OneOfTypeInterface, - MemberTypes: []string{ - "Cat", - "Dog", - }, - FieldSelectionSet: RPCFieldSelectionSet{ - "Cat": { - { - Name: "meow_volume", - TypeName: string(DataTypeInt32), - JSONPath: "meowVolume", - }, - }, - }, - Fields: []RPCField{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - { - Name: "kind", - TypeName: string(DataTypeString), - JSONPath: "kind", - }, - }, - }, + Name: "kind", + TypeName: string(DataTypeEnum), + JSONPath: "kind", + EnumName: "CategoryKind", }, }, }, - }, - }, - }, - }, - { - name: "Should create an execution plan for a query with a random cat and dog", - query: "query CatAndDogQuery { randomPet { id name kind ... on Cat { meowVolume } ... on Dog { barkVolume } } }", - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "QueryRandomPet", - Request: RPCMessage{ - Name: "QueryRandomPetRequest", - }, Response: RPCMessage{ - Name: "QueryRandomPetResponse", + Name: "QueryCategoriesByKindResponse", Fields: []RPCField{ { - Name: "random_pet", + Name: "categories_by_kind", TypeName: string(DataTypeMessage), - JSONPath: "randomPet", + JSONPath: "categoriesByKind", + Repeated: true, Message: &RPCMessage{ - Name: "Animal", - OneOfType: OneOfTypeInterface, - MemberTypes: []string{ - "Cat", - "Dog", - }, - FieldSelectionSet: RPCFieldSelectionSet{ - "Cat": { - { - Name: "meow_volume", - TypeName: string(DataTypeInt32), - JSONPath: "meowVolume", - }, - }, - "Dog": { - { - Name: "bark_volume", - TypeName: string(DataTypeInt32), - JSONPath: "barkVolume", - }, - }, - }, + Name: "Category", Fields: []RPCField{ { Name: "id", @@ -1532,8 +1160,9 @@ func TestCompositeTypeExecutionPlan(t *testing.T) { }, { Name: "kind", - TypeName: string(DataTypeString), + TypeName: string(DataTypeEnum), JSONPath: "kind", + EnumName: "CategoryKind", }, }, }, @@ -1545,47 +1174,35 @@ func TestCompositeTypeExecutionPlan(t *testing.T) { }, }, { - name: "Should create an execution plan for a query with all pets (interface list)", - query: "query AllPetsQuery { allPets { id name kind ... on Cat { meowVolume } ... on Dog { barkVolume } } }", + name: "Should create an execution plan for a query with categories by kinds", + query: "query CategoriesQuery($kinds: [CategoryKind!]!) { categoriesByKinds(kinds: $kinds) { id name kind } }", expectedPlan: &RPCExecutionPlan{ Calls: []RPCCall{ { ServiceName: "Products", - MethodName: "QueryAllPets", + MethodName: "QueryCategoriesByKinds", Request: RPCMessage{ - Name: "QueryAllPetsRequest", + Name: "QueryCategoriesByKindsRequest", + Fields: []RPCField{ + { + Name: "kinds", + TypeName: string(DataTypeEnum), + JSONPath: "kinds", + EnumName: "CategoryKind", + Repeated: true, + }, + }, }, Response: RPCMessage{ - Name: "QueryAllPetsResponse", + Name: "QueryCategoriesByKindsResponse", Fields: []RPCField{ { - Name: "all_pets", + Name: "categories_by_kinds", TypeName: string(DataTypeMessage), - JSONPath: "allPets", + JSONPath: "categoriesByKinds", Repeated: true, Message: &RPCMessage{ - Name: "Animal", - OneOfType: OneOfTypeInterface, - MemberTypes: []string{ - "Cat", - "Dog", - }, - FieldSelectionSet: RPCFieldSelectionSet{ - "Cat": { - { - Name: "meow_volume", - TypeName: string(DataTypeInt32), - JSONPath: "meowVolume", - }, - }, - "Dog": { - { - Name: "bark_volume", - TypeName: string(DataTypeInt32), - JSONPath: "barkVolume", - }, - }, - }, + Name: "Category", Fields: []RPCField{ { Name: "id", @@ -1599,8 +1216,9 @@ func TestCompositeTypeExecutionPlan(t *testing.T) { }, { Name: "kind", - TypeName: string(DataTypeString), + TypeName: string(DataTypeEnum), JSONPath: "kind", + EnumName: "CategoryKind", }, }, }, @@ -1612,48 +1230,48 @@ func TestCompositeTypeExecutionPlan(t *testing.T) { }, }, { - name: "Should create an execution plan for a query with all pets using an interface fragment", - query: "query AllPetsQuery { allPets { ... on Animal { id name kind } } }", + name: "Should create an execution plan for a query with filtered categories", + query: "query FilterCategoriesQuery($filter: CategoryFilter!) { filterCategories(filter: $filter) { id name kind } }", expectedPlan: &RPCExecutionPlan{ Calls: []RPCCall{ { ServiceName: "Products", - MethodName: "QueryAllPets", + MethodName: "QueryFilterCategories", Request: RPCMessage{ - Name: "QueryAllPetsRequest", - }, - Response: RPCMessage{ - Name: "QueryAllPetsResponse", + Name: "QueryFilterCategoriesRequest", Fields: []RPCField{ { - Name: "all_pets", + Name: "filter", TypeName: string(DataTypeMessage), - JSONPath: "allPets", - Repeated: true, + JSONPath: "filter", Message: &RPCMessage{ - Name: "Animal", - OneOfType: OneOfTypeInterface, - MemberTypes: []string{ - "Cat", - "Dog", - }, - Fields: RPCFields{}, - FieldSelectionSet: RPCFieldSelectionSet{ - "Animal": { - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - { - Name: "kind", - TypeName: string(DataTypeString), - JSONPath: "kind", + Name: "CategoryFilter", + Fields: []RPCField{ + { + Name: "category", + TypeName: string(DataTypeEnum), + JSONPath: "category", + EnumName: "CategoryKind", + }, + { + Name: "pagination", + TypeName: string(DataTypeMessage), + JSONPath: "pagination", + Optional: true, + Message: &RPCMessage{ + Name: "Pagination", + Fields: []RPCField{ + { + Name: "page", + TypeName: string(DataTypeInt32), + JSONPath: "page", + }, + { + Name: "per_page", + TypeName: string(DataTypeInt32), + JSONPath: "perPage", + }, + }, }, }, }, @@ -1661,35 +1279,16 @@ func TestCompositeTypeExecutionPlan(t *testing.T) { }, }, }, - }, - }, - }, - }, - { - name: "Should create an execution plan for a query with interface selecting only common fields", - query: "query CommonFieldsQuery { randomPet { id name kind } }", - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "QueryRandomPet", - Request: RPCMessage{ - Name: "QueryRandomPetRequest", - }, Response: RPCMessage{ - Name: "QueryRandomPetResponse", + Name: "QueryFilterCategoriesResponse", Fields: []RPCField{ { - Name: "random_pet", + Name: "filter_categories", TypeName: string(DataTypeMessage), - JSONPath: "randomPet", + JSONPath: "filterCategories", + Repeated: true, Message: &RPCMessage{ - Name: "Animal", - OneOfType: OneOfTypeInterface, - MemberTypes: []string{ - "Cat", - "Dog", - }, + Name: "Category", Fields: []RPCField{ { Name: "id", @@ -1703,8 +1302,9 @@ func TestCompositeTypeExecutionPlan(t *testing.T) { }, { Name: "kind", - TypeName: string(DataTypeString), + TypeName: string(DataTypeEnum), JSONPath: "kind", + EnumName: "CategoryKind", }, }, }, @@ -1715,104 +1315,146 @@ func TestCompositeTypeExecutionPlan(t *testing.T) { }, }, }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + report := &operationreport.Report{} + // Parse the GraphQL schema + schemaDoc := grpctest.MustGraphQLSchema(t) + + astvalidation.DefaultDefinitionValidator().Validate(&schemaDoc, report) + if report.HasErrors() { + t.Fatalf("failed to validate schema: %s", report.Error()) + } + + // Parse the GraphQL query + queryDoc, queryReport := astparser.ParseGraphqlDocumentString(tt.query) + if queryReport.HasErrors() { + t.Fatalf("failed to parse query: %s", queryReport.Error()) + } + + astvalidation.DefaultOperationValidator().Validate(&queryDoc, &schemaDoc, report) + if report.HasErrors() { + t.Fatalf("failed to validate query: %s", report.Error()) + } + + planner := NewPlanner("Products", testMapping()) + outPlan, err := planner.PlanOperation(&queryDoc, &schemaDoc) + + if tt.expectedError != "" { + if err == nil { + t.Fatalf("expected error, got nil") + } + if !strings.Contains(err.Error(), tt.expectedError) { + t.Fatalf("expected error to contain %q, got %q", tt.expectedError, err.Error()) + } + return + } + + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + + diff := cmp.Diff(tt.expectedPlan, outPlan) + if diff != "" { + t.Fatalf("execution plan mismatch: %s", diff) + } + }) + } +} + +func TestProductExecutionPlanWithAliases(t *testing.T) { + tests := []struct { + name string + query string + expectedPlan *RPCExecutionPlan + expectedError string + }{ { - name: "Should create an execution plan for a SearchResult union query", - query: "query SearchQuery($input: SearchInput!) { search(input: $input) { ... on Product { id name price } ... on User { id name } ... on Category { id name kind } } }", + name: "Should create an execution plan for a query with an alias on the users root field", + query: "query { foo: users { id name } }", expectedPlan: &RPCExecutionPlan{ Calls: []RPCCall{ { ServiceName: "Products", - MethodName: "QuerySearch", + MethodName: "QueryUsers", Request: RPCMessage{ - Name: "QuerySearchRequest", - Fields: []RPCField{ + Name: "QueryUsersRequest", + }, + Response: RPCMessage{ + Name: "QueryUsersResponse", + Fields: RPCFields{ { - Name: "input", + Name: "users", TypeName: string(DataTypeMessage), - JSONPath: "input", + JSONPath: "users", + Alias: "foo", + Repeated: true, Message: &RPCMessage{ - Name: "SearchInput", - Fields: []RPCField{ + Name: "User", + Fields: RPCFields{ { - Name: "query", + Name: "id", TypeName: string(DataTypeString), - JSONPath: "query", + JSONPath: "id", }, { - Name: "limit", - TypeName: string(DataTypeInt32), - JSONPath: "limit", - Optional: true, + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", }, }, }, }, }, }, - Response: RPCMessage{ - Name: "QuerySearchResponse", + }, + }, + }, + }, + { + name: "Should create an execution plan for a query with an alias on a field with arguments", + query: `query { specificUser: user(id: "123") { userId: id userName: name } }`, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryUser", + Request: RPCMessage{ + Name: "QueryUserRequest", Fields: []RPCField{ { - Name: "search", + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + }, + }, + Response: RPCMessage{ + Name: "QueryUserResponse", + Fields: RPCFields{ + { + Name: "user", TypeName: string(DataTypeMessage), - JSONPath: "search", - Repeated: true, + JSONPath: "user", + Alias: "specificUser", + Optional: true, Message: &RPCMessage{ - Name: "SearchResult", - OneOfType: OneOfTypeUnion, - MemberTypes: []string{ - "Product", - "User", - "Category", - }, - Fields: RPCFields{}, - FieldSelectionSet: RPCFieldSelectionSet{ - "Product": { - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - { - Name: "price", - TypeName: string(DataTypeDouble), - JSONPath: "price", - }, - }, - "User": { - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, + Name: "User", + Fields: RPCFields{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + Alias: "userId", }, - "Category": { - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - { - Name: "kind", - TypeName: string(DataTypeEnum), - JSONPath: "kind", - EnumName: "CategoryKind", - }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + Alias: "userName", }, }, }, @@ -1824,1292 +1466,8 @@ func TestCompositeTypeExecutionPlan(t *testing.T) { }, }, { - name: "Should create an execution plan for a single SearchResult union query", - query: "query RandomSearchQuery { randomSearchResult { ... on Product { id name price } ... on User { id name } ... on Category { id name kind } } }", - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "QueryRandomSearchResult", - Request: RPCMessage{ - Name: "QueryRandomSearchResultRequest", - }, - Response: RPCMessage{ - Name: "QueryRandomSearchResultResponse", - Fields: []RPCField{ - { - Name: "random_search_result", - TypeName: string(DataTypeMessage), - JSONPath: "randomSearchResult", - Message: &RPCMessage{ - Name: "SearchResult", - OneOfType: OneOfTypeUnion, - MemberTypes: []string{ - "Product", - "User", - "Category", - }, - Fields: RPCFields{}, - FieldSelectionSet: RPCFieldSelectionSet{ - "Product": { - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - { - Name: "price", - TypeName: string(DataTypeDouble), - JSONPath: "price", - }, - }, - "User": { - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - }, - "Category": { - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - { - Name: "kind", - TypeName: string(DataTypeEnum), - JSONPath: "kind", - EnumName: "CategoryKind", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "Should create an execution plan for a SearchResult union with partial selection", - query: "query PartialSearchQuery($input: SearchInput!) { search(input: $input) { ... on Product { id name } ... on User { id name } } }", - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "QuerySearch", - Request: RPCMessage{ - Name: "QuerySearchRequest", - Fields: []RPCField{ - { - Name: "input", - TypeName: string(DataTypeMessage), - JSONPath: "input", - Message: &RPCMessage{ - Name: "SearchInput", - Fields: []RPCField{ - { - Name: "query", - TypeName: string(DataTypeString), - JSONPath: "query", - }, - { - Name: "limit", - TypeName: string(DataTypeInt32), - JSONPath: "limit", - Optional: true, - }, - }, - }, - }, - }, - }, - Response: RPCMessage{ - Name: "QuerySearchResponse", - Fields: []RPCField{ - { - Name: "search", - TypeName: string(DataTypeMessage), - JSONPath: "search", - Repeated: true, - Message: &RPCMessage{ - Name: "SearchResult", - OneOfType: OneOfTypeUnion, - MemberTypes: []string{ - "Product", - "User", - "Category", - }, - Fields: RPCFields{}, - FieldSelectionSet: RPCFieldSelectionSet{ - "Product": { - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - }, - "User": { - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - // Parse the GraphQL schema - schemaDoc := grpctest.MustGraphQLSchema(t) - - // Parse the GraphQL query - queryDoc, report := astparser.ParseGraphqlDocumentString(tt.query) - if report.HasErrors() { - t.Fatalf("failed to parse query: %s", report.Error()) - } - - walker := astvisitor.NewWalker(48) - - rpcPlanVisitor := newRPCPlanVisitor(&walker, rpcPlanVisitorConfig{ - subgraphName: "Products", - mapping: testMapping(), - }) - - walker.Walk(&queryDoc, &schemaDoc, &report) - - if report.HasErrors() { - require.NotEmpty(t, tt.expectedError) - require.Contains(t, report.Error(), tt.expectedError) - return - } - - require.Empty(t, tt.expectedError) - diff := cmp.Diff(tt.expectedPlan, rpcPlanVisitor.plan) - if diff != "" { - t.Fatalf("execution plan mismatch: %s", diff) - } - }) - } -} - -func TestMutationUnionExecutionPlan(t *testing.T) { - tests := []struct { - name string - query string - expectedPlan *RPCExecutionPlan - expectedError string - }{ - { - name: "Should create an execution plan for ActionResult union mutation", - query: "mutation PerformActionMutation($input: ActionInput!) { performAction(input: $input) { ... on ActionSuccess { message timestamp } ... on ActionError { message code } } }", - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "MutationPerformAction", - Request: RPCMessage{ - Name: "MutationPerformActionRequest", - Fields: []RPCField{ - { - Name: "input", - TypeName: string(DataTypeMessage), - JSONPath: "input", - Message: &RPCMessage{ - Name: "ActionInput", - Fields: []RPCField{ - { - Name: "type", - TypeName: string(DataTypeString), - JSONPath: "type", - }, - { - Name: "payload", - TypeName: string(DataTypeString), - JSONPath: "payload", - }, - }, - }, - }, - }, - }, - Response: RPCMessage{ - Name: "MutationPerformActionResponse", - Fields: []RPCField{ - { - Name: "perform_action", - TypeName: string(DataTypeMessage), - JSONPath: "performAction", - Message: &RPCMessage{ - Name: "ActionResult", - OneOfType: OneOfTypeUnion, - MemberTypes: []string{ - "ActionSuccess", - "ActionError", - }, - Fields: RPCFields{}, - FieldSelectionSet: RPCFieldSelectionSet{ - "ActionSuccess": { - { - Name: "message", - TypeName: string(DataTypeString), - JSONPath: "message", - }, - { - Name: "timestamp", - TypeName: string(DataTypeString), - JSONPath: "timestamp", - }, - }, - "ActionError": { - { - Name: "message", - TypeName: string(DataTypeString), - JSONPath: "message", - }, - { - Name: "code", - TypeName: string(DataTypeString), - JSONPath: "code", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "Should create an execution plan for ActionResult union with only success case", - query: "mutation PerformSuccessActionMutation($input: ActionInput!) { performAction(input: $input) { ... on ActionSuccess { message timestamp } } }", - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "MutationPerformAction", - Request: RPCMessage{ - Name: "MutationPerformActionRequest", - Fields: []RPCField{ - { - Name: "input", - TypeName: string(DataTypeMessage), - JSONPath: "input", - Message: &RPCMessage{ - Name: "ActionInput", - Fields: []RPCField{ - { - Name: "type", - TypeName: string(DataTypeString), - JSONPath: "type", - }, - { - Name: "payload", - TypeName: string(DataTypeString), - JSONPath: "payload", - }, - }, - }, - }, - }, - }, - Response: RPCMessage{ - Name: "MutationPerformActionResponse", - Fields: []RPCField{ - { - Name: "perform_action", - TypeName: string(DataTypeMessage), - JSONPath: "performAction", - Message: &RPCMessage{ - Name: "ActionResult", - OneOfType: OneOfTypeUnion, - MemberTypes: []string{ - "ActionSuccess", - "ActionError", - }, - Fields: RPCFields{}, - FieldSelectionSet: RPCFieldSelectionSet{ - "ActionSuccess": { - { - Name: "message", - TypeName: string(DataTypeString), - JSONPath: "message", - }, - { - Name: "timestamp", - TypeName: string(DataTypeString), - JSONPath: "timestamp", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "Should create an execution plan for ActionResult union with only error case", - query: "mutation PerformErrorActionMutation($input: ActionInput!) { performAction(input: $input) { ... on ActionError { message code } } }", - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "MutationPerformAction", - Request: RPCMessage{ - Name: "MutationPerformActionRequest", - Fields: []RPCField{ - { - Name: "input", - TypeName: string(DataTypeMessage), - JSONPath: "input", - Message: &RPCMessage{ - Name: "ActionInput", - Fields: []RPCField{ - { - Name: "type", - TypeName: string(DataTypeString), - JSONPath: "type", - }, - { - Name: "payload", - TypeName: string(DataTypeString), - JSONPath: "payload", - }, - }, - }, - }, - }, - }, - Response: RPCMessage{ - Name: "MutationPerformActionResponse", - Fields: []RPCField{ - { - Name: "perform_action", - TypeName: string(DataTypeMessage), - JSONPath: "performAction", - Message: &RPCMessage{ - Name: "ActionResult", - OneOfType: OneOfTypeUnion, - MemberTypes: []string{ - "ActionSuccess", - "ActionError", - }, - Fields: RPCFields{}, - FieldSelectionSet: RPCFieldSelectionSet{ - "ActionError": { - { - Name: "message", - TypeName: string(DataTypeString), - JSONPath: "message", - }, - { - Name: "code", - TypeName: string(DataTypeString), - JSONPath: "code", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - // Parse the GraphQL schema - schemaDoc := grpctest.MustGraphQLSchema(t) - - // Parse the GraphQL query - queryDoc, report := astparser.ParseGraphqlDocumentString(tt.query) - if report.HasErrors() { - t.Fatalf("failed to parse query: %s", report.Error()) - } - - walker := astvisitor.NewWalker(48) - - rpcPlanVisitor := newRPCPlanVisitor(&walker, rpcPlanVisitorConfig{ - subgraphName: "Products", - mapping: testMapping(), - }) - - walker.Walk(&queryDoc, &schemaDoc, &report) - - if report.HasErrors() { - require.NotEmpty(t, tt.expectedError) - require.Contains(t, report.Error(), tt.expectedError) - return - } - - require.Empty(t, tt.expectedError) - diff := cmp.Diff(tt.expectedPlan, rpcPlanVisitor.plan) - if diff != "" { - t.Fatalf("execution plan mismatch: %s", diff) - } - }) - } -} - -func TestProductExecutionPlan(t *testing.T) { - tests := []struct { - name string - query string - expectedPlan *RPCExecutionPlan - expectedError string - }{ - { - name: "Should create an execution plan for a query with categories by kind", - query: "query CategoriesQuery($kind: CategoryKind!) { categoriesByKind(kind: $kind) { id name kind } }", - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "QueryCategoriesByKind", - Request: RPCMessage{ - Name: "QueryCategoriesByKindRequest", - Fields: []RPCField{ - { - Name: "kind", - TypeName: string(DataTypeEnum), - JSONPath: "kind", - EnumName: "CategoryKind", - }, - }, - }, - Response: RPCMessage{ - Name: "QueryCategoriesByKindResponse", - Fields: []RPCField{ - { - Name: "categories_by_kind", - TypeName: string(DataTypeMessage), - JSONPath: "categoriesByKind", - Repeated: true, - Message: &RPCMessage{ - Name: "Category", - Fields: []RPCField{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - { - Name: "kind", - TypeName: string(DataTypeEnum), - JSONPath: "kind", - EnumName: "CategoryKind", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "Should create an execution plan for a query with categories by kinds", - query: "query CategoriesQuery($kinds: [CategoryKind!]!) { categoriesByKinds(kinds: $kinds) { id name kind } }", - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "QueryCategoriesByKinds", - Request: RPCMessage{ - Name: "QueryCategoriesByKindsRequest", - Fields: []RPCField{ - { - Name: "kinds", - TypeName: string(DataTypeEnum), - JSONPath: "kinds", - EnumName: "CategoryKind", - Repeated: true, - }, - }, - }, - Response: RPCMessage{ - Name: "QueryCategoriesByKindsResponse", - Fields: []RPCField{ - { - Name: "categories_by_kinds", - TypeName: string(DataTypeMessage), - JSONPath: "categoriesByKinds", - Repeated: true, - Message: &RPCMessage{ - Name: "Category", - Fields: []RPCField{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - { - Name: "kind", - TypeName: string(DataTypeEnum), - JSONPath: "kind", - EnumName: "CategoryKind", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "Should create an execution plan for a query with filtered categories", - query: "query FilterCategoriesQuery($filter: CategoryFilter!) { filterCategories(filter: $filter) { id name kind } }", - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "QueryFilterCategories", - Request: RPCMessage{ - Name: "QueryFilterCategoriesRequest", - Fields: []RPCField{ - { - Name: "filter", - TypeName: string(DataTypeMessage), - JSONPath: "filter", - Message: &RPCMessage{ - Name: "CategoryFilter", - Fields: []RPCField{ - { - Name: "category", - TypeName: string(DataTypeEnum), - JSONPath: "category", - EnumName: "CategoryKind", - }, - { - Name: "pagination", - TypeName: string(DataTypeMessage), - JSONPath: "pagination", - Message: &RPCMessage{ - Name: "Pagination", - Fields: []RPCField{ - { - Name: "page", - TypeName: string(DataTypeInt32), - JSONPath: "page", - }, - { - Name: "per_page", - TypeName: string(DataTypeInt32), - JSONPath: "perPage", - }, - }, - }, - }, - }, - }, - }, - }, - }, - Response: RPCMessage{ - Name: "QueryFilterCategoriesResponse", - Fields: []RPCField{ - { - Name: "filter_categories", - TypeName: string(DataTypeMessage), - JSONPath: "filterCategories", - Repeated: true, - Message: &RPCMessage{ - Name: "Category", - Fields: []RPCField{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - { - Name: "kind", - TypeName: string(DataTypeEnum), - JSONPath: "kind", - EnumName: "CategoryKind", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - report := &operationreport.Report{} - // Parse the GraphQL schema - schemaDoc := grpctest.MustGraphQLSchema(t) - - astvalidation.DefaultDefinitionValidator().Validate(&schemaDoc, report) - if report.HasErrors() { - t.Fatalf("failed to validate schema: %s", report.Error()) - } - - // Parse the GraphQL query - queryDoc, queryReport := astparser.ParseGraphqlDocumentString(tt.query) - if queryReport.HasErrors() { - t.Fatalf("failed to parse query: %s", queryReport.Error()) - } - - astvalidation.DefaultOperationValidator().Validate(&queryDoc, &schemaDoc, report) - if report.HasErrors() { - t.Fatalf("failed to validate query: %s", report.Error()) - } - - planner := NewPlanner("Products", testMapping()) - outPlan, err := planner.PlanOperation(&queryDoc, &schemaDoc) - - if tt.expectedError != "" { - if err == nil { - t.Fatalf("expected error, got nil") - } - if !strings.Contains(err.Error(), tt.expectedError) { - t.Fatalf("expected error to contain %q, got %q", tt.expectedError, err.Error()) - } - return - } - - if err != nil { - t.Fatalf("unexpected error: %s", err) - } - - diff := cmp.Diff(tt.expectedPlan, outPlan) - if diff != "" { - t.Fatalf("execution plan mismatch: %s", diff) - } - }) - } -} - -func TestProductExecutionPlanWithAliases(t *testing.T) { - tests := []struct { - name string - query string - expectedPlan *RPCExecutionPlan - expectedError string - }{ - { - name: "Should create an execution plan for a query with an alias on the users root field", - query: "query { foo: users { id name } }", - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "QueryUsers", - Request: RPCMessage{ - Name: "QueryUsersRequest", - }, - Response: RPCMessage{ - Name: "QueryUsersResponse", - Fields: RPCFields{ - { - Name: "users", - TypeName: string(DataTypeMessage), - JSONPath: "users", - Alias: "foo", - Repeated: true, - Message: &RPCMessage{ - Name: "User", - Fields: RPCFields{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "Should create an execution plan for a query with an alias on a field with arguments", - query: `query { specificUser: user(id: "123") { userId: id userName: name } }`, - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "QueryUser", - Request: RPCMessage{ - Name: "QueryUserRequest", - Fields: []RPCField{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - }, - }, - Response: RPCMessage{ - Name: "QueryUserResponse", - Fields: RPCFields{ - { - Name: "user", - TypeName: string(DataTypeMessage), - JSONPath: "user", - Alias: "specificUser", - Message: &RPCMessage{ - Name: "User", - Fields: RPCFields{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - Alias: "userId", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "userName", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "Should create an execution plan for a query with multiple aliases on the same level", - query: "query { allUsers: users { id name } allCategories: categories { id name categoryType: kind } }", - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "QueryUsers", - Request: RPCMessage{ - Name: "QueryUsersRequest", - }, - Response: RPCMessage{ - Name: "QueryUsersResponse", - Fields: RPCFields{ - { - Name: "users", - TypeName: string(DataTypeMessage), - JSONPath: "users", - Alias: "allUsers", - Repeated: true, - Message: &RPCMessage{ - Name: "User", - Fields: RPCFields{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - }, - }, - }, - }, - }, - }, - { - ServiceName: "Products", - MethodName: "QueryCategories", - CallID: 1, - Request: RPCMessage{ - Name: "QueryCategoriesRequest", - }, - Response: RPCMessage{ - Name: "QueryCategoriesResponse", - Fields: RPCFields{ - { - Name: "categories", - TypeName: string(DataTypeMessage), - JSONPath: "categories", - Alias: "allCategories", - Repeated: true, - Message: &RPCMessage{ - Name: "Category", - Fields: RPCFields{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - { - Name: "kind", - TypeName: string(DataTypeEnum), - JSONPath: "kind", - Alias: "categoryType", - EnumName: "CategoryKind", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "Should create an execution plan for a query with aliases on nested object fields", - query: "query { nestedData: nestedType { identifier: id title: name childB: b { identifier: id title: name grandChild: c { identifier: id title: name } } } }", - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "QueryNestedType", - Request: RPCMessage{ - Name: "QueryNestedTypeRequest", - }, - Response: RPCMessage{ - Name: "QueryNestedTypeResponse", - Fields: RPCFields{ - { - Name: "nested_type", - TypeName: string(DataTypeMessage), - JSONPath: "nestedType", - Alias: "nestedData", - Repeated: true, - Message: &RPCMessage{ - Name: "NestedTypeA", - Fields: RPCFields{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - Alias: "identifier", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "title", - }, - { - Name: "b", - TypeName: string(DataTypeMessage), - JSONPath: "b", - Alias: "childB", - Message: &RPCMessage{ - Name: "NestedTypeB", - Fields: RPCFields{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - Alias: "identifier", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "title", - }, - { - Name: "c", - TypeName: string(DataTypeMessage), - JSONPath: "c", - Alias: "grandChild", - Message: &RPCMessage{ - Name: "NestedTypeC", - Fields: RPCFields{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - Alias: "identifier", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "title", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "Should create an execution plan for a query with aliases on interface fields", - query: "query { pet: randomPet { identifier: id petName: name animalKind: kind ... on Cat { volumeLevel: meowVolume } ... on Dog { volumeLevel: barkVolume } } }", - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "QueryRandomPet", - Request: RPCMessage{ - Name: "QueryRandomPetRequest", - }, - Response: RPCMessage{ - Name: "QueryRandomPetResponse", - Fields: RPCFields{ - { - Name: "random_pet", - TypeName: string(DataTypeMessage), - JSONPath: "randomPet", - Alias: "pet", - Message: &RPCMessage{ - Name: "Animal", - OneOfType: OneOfTypeInterface, - MemberTypes: []string{ - "Cat", - "Dog", - }, - FieldSelectionSet: RPCFieldSelectionSet{ - "Cat": { - { - Name: "meow_volume", - TypeName: string(DataTypeInt32), - JSONPath: "meowVolume", - Alias: "volumeLevel", - }, - }, - "Dog": { - { - Name: "bark_volume", - TypeName: string(DataTypeInt32), - JSONPath: "barkVolume", - Alias: "volumeLevel", - }, - }, - }, - Fields: RPCFields{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - Alias: "identifier", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "petName", - }, - { - Name: "kind", - TypeName: string(DataTypeString), - JSONPath: "kind", - Alias: "animalKind", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "Should create an execution plan for a query with aliases on union type fields", - query: "query { searchResults: randomSearchResult { ... on Product { productId: id productName: name cost: price } ... on User { userId: id userName: name } ... on Category { categoryId: id categoryName: name categoryType: kind } } }", - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "QueryRandomSearchResult", - Request: RPCMessage{ - Name: "QueryRandomSearchResultRequest", - }, - Response: RPCMessage{ - Name: "QueryRandomSearchResultResponse", - Fields: RPCFields{ - { - Name: "random_search_result", - TypeName: string(DataTypeMessage), - JSONPath: "randomSearchResult", - Alias: "searchResults", - Message: &RPCMessage{ - Name: "SearchResult", - OneOfType: OneOfTypeUnion, - MemberTypes: []string{ - "Product", - "User", - "Category", - }, - Fields: RPCFields{}, - FieldSelectionSet: RPCFieldSelectionSet{ - "Product": { - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - Alias: "productId", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "productName", - }, - { - Name: "price", - TypeName: string(DataTypeDouble), - JSONPath: "price", - Alias: "cost", - }, - }, - "User": { - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - Alias: "userId", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "userName", - }, - }, - "Category": { - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - Alias: "categoryId", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "categoryName", - }, - { - Name: "kind", - TypeName: string(DataTypeEnum), - JSONPath: "kind", - Alias: "categoryType", - EnumName: "CategoryKind", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "Should create an execution plan for a mutation with aliases", - query: `mutation { newUser: createUser(input: { name: "John Doe" }) { userId: id fullName: name } }`, - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "MutationCreateUser", - Request: RPCMessage{ - Name: "MutationCreateUserRequest", - Fields: []RPCField{ - { - Name: "input", - TypeName: string(DataTypeMessage), - JSONPath: "input", - Message: &RPCMessage{ - Name: "UserInput", - Fields: []RPCField{ - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - }, - }, - }, - }, - }, - Response: RPCMessage{ - Name: "MutationCreateUserResponse", - Fields: RPCFields{ - { - Name: "create_user", - TypeName: string(DataTypeMessage), - JSONPath: "createUser", - Alias: "newUser", - Message: &RPCMessage{ - Name: "User", - Fields: RPCFields{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - Alias: "userId", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "fullName", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "Should create an execution plan for a query with aliases on field with complex input type", - query: `query { bookCategories: categoriesByKind(kind: BOOK) { identifier: id title: name type: kind } }`, - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "QueryCategoriesByKind", - Request: RPCMessage{ - Name: "QueryCategoriesByKindRequest", - Fields: []RPCField{ - { - Name: "kind", - TypeName: string(DataTypeEnum), - JSONPath: "kind", - EnumName: "CategoryKind", - }, - }, - }, - Response: RPCMessage{ - Name: "QueryCategoriesByKindResponse", - Fields: RPCFields{ - { - Name: "categories_by_kind", - TypeName: string(DataTypeMessage), - JSONPath: "categoriesByKind", - Alias: "bookCategories", - Repeated: true, - Message: &RPCMessage{ - Name: "Category", - Fields: RPCFields{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - Alias: "identifier", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "title", - }, - { - Name: "kind", - TypeName: string(DataTypeEnum), - JSONPath: "kind", - Alias: "type", - EnumName: "CategoryKind", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "Should create an execution plan for a query with multiple aliases for the same field", - query: `query { users { id name1: name name2: name name3: name } }`, + name: "Should create an execution plan for a query with multiple aliases on the same level", + query: "query { allUsers: users { id name } allCategories: categories { id name categoryType: kind } }", expectedPlan: &RPCExecutionPlan{ Calls: []RPCCall{ { @@ -3125,68 +1483,8 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { Name: "users", TypeName: string(DataTypeMessage), JSONPath: "users", + Alias: "allUsers", Repeated: true, - Message: &RPCMessage{ - Name: "User", - Fields: RPCFields{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "name1", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "name2", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "name3", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - { - name: "Should create an execution plan for a query with multiple aliases for the same field with arguments", - query: `query { user1: user(id: "123") { id name } user2: user(id: "456") { id name } sameUser: user(id: "123") { userId: id userName: name } }`, - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "QueryUser", - Request: RPCMessage{ - Name: "QueryUserRequest", - Fields: []RPCField{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - }, - }, - Response: RPCMessage{ - Name: "QueryUserResponse", - Fields: RPCFields{ - { - Name: "user", - TypeName: string(DataTypeMessage), - JSONPath: "user", - Alias: "user1", Message: &RPCMessage{ Name: "User", Fields: RPCFields{ @@ -3208,81 +1506,39 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { }, { ServiceName: "Products", - MethodName: "QueryUser", + MethodName: "QueryCategories", CallID: 1, Request: RPCMessage{ - Name: "QueryUserRequest", - Fields: []RPCField{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - }, - }, - Response: RPCMessage{ - Name: "QueryUserResponse", - Fields: RPCFields{ - { - Name: "user", - TypeName: string(DataTypeMessage), - JSONPath: "user", - Alias: "user2", - Message: &RPCMessage{ - Name: "User", - Fields: RPCFields{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - }, - }, - }, - }, - }, - }, - { - ServiceName: "Products", - MethodName: "QueryUser", - CallID: 2, - Request: RPCMessage{ - Name: "QueryUserRequest", - Fields: []RPCField{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - }, + Name: "QueryCategoriesRequest", }, Response: RPCMessage{ - Name: "QueryUserResponse", + Name: "QueryCategoriesResponse", Fields: RPCFields{ { - Name: "user", + Name: "categories", TypeName: string(DataTypeMessage), - JSONPath: "user", - Alias: "sameUser", + JSONPath: "categories", + Alias: "allCategories", + Repeated: true, Message: &RPCMessage{ - Name: "User", + Name: "Category", Fields: RPCFields{ { Name: "id", TypeName: string(DataTypeString), JSONPath: "id", - Alias: "userId", }, { Name: "name", TypeName: string(DataTypeString), JSONPath: "name", - Alias: "userName", + }, + { + Name: "kind", + TypeName: string(DataTypeEnum), + JSONPath: "kind", + Alias: "categoryType", + EnumName: "CategoryKind", }, }, }, @@ -3294,8 +1550,8 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { }, }, { - name: "Should create an execution plan for a query with multiple aliases for the same field in nested objects", - query: `query { nestedType { id name1: name name2: name b { id title1: name title2: name c { id label1: name label2: name } } } }`, + name: "Should create an execution plan for a query with aliases on nested object fields", + query: "query { nestedData: nestedType { identifier: id title: name childB: b { identifier: id title: name grandChild: c { identifier: id title: name } } } }", expectedPlan: &RPCExecutionPlan{ Calls: []RPCCall{ { @@ -3311,6 +1567,7 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { Name: "nested_type", TypeName: string(DataTypeMessage), JSONPath: "nestedType", + Alias: "nestedData", Repeated: true, Message: &RPCMessage{ Name: "NestedTypeA", @@ -3319,23 +1576,19 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { Name: "id", TypeName: string(DataTypeString), JSONPath: "id", + Alias: "identifier", }, { Name: "name", TypeName: string(DataTypeString), JSONPath: "name", - Alias: "name1", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "name2", + Alias: "title", }, { Name: "b", TypeName: string(DataTypeMessage), JSONPath: "b", + Alias: "childB", Message: &RPCMessage{ Name: "NestedTypeB", Fields: RPCFields{ @@ -3343,23 +1596,19 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { Name: "id", TypeName: string(DataTypeString), JSONPath: "id", + Alias: "identifier", }, { Name: "name", TypeName: string(DataTypeString), JSONPath: "name", - Alias: "title1", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "title2", + Alias: "title", }, { Name: "c", TypeName: string(DataTypeMessage), JSONPath: "c", + Alias: "grandChild", Message: &RPCMessage{ Name: "NestedTypeC", Fields: RPCFields{ @@ -3367,18 +1616,13 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { Name: "id", TypeName: string(DataTypeString), JSONPath: "id", + Alias: "identifier", }, { Name: "name", TypeName: string(DataTypeString), JSONPath: "name", - Alias: "label1", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "label2", + Alias: "title", }, }, }, @@ -3396,8 +1640,8 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { }, }, { - name: "Should create an execution plan for a query with multiple aliases for the same field in interface fragments", - query: `query { randomPet { id name1: name name2: name kind ... on Cat { volume1: meowVolume volume2: meowVolume } ... on Dog { volume1: barkVolume volume2: barkVolume } } }`, + name: "Should create an execution plan for a query with aliases on interface fields", + query: "query { pet: randomPet { identifier: id petName: name animalKind: kind ... on Cat { volumeLevel: meowVolume } ... on Dog { volumeLevel: barkVolume } } }", expectedPlan: &RPCExecutionPlan{ Calls: []RPCCall{ { @@ -3413,6 +1657,7 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { Name: "random_pet", TypeName: string(DataTypeMessage), JSONPath: "randomPet", + Alias: "pet", Message: &RPCMessage{ Name: "Animal", OneOfType: OneOfTypeInterface, @@ -3426,13 +1671,7 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { Name: "meow_volume", TypeName: string(DataTypeInt32), JSONPath: "meowVolume", - Alias: "volume1", - }, - { - Name: "meow_volume", - TypeName: string(DataTypeInt32), - JSONPath: "meowVolume", - Alias: "volume2", + Alias: "volumeLevel", }, }, "Dog": { @@ -3440,13 +1679,7 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { Name: "bark_volume", TypeName: string(DataTypeInt32), JSONPath: "barkVolume", - Alias: "volume1", - }, - { - Name: "bark_volume", - TypeName: string(DataTypeInt32), - JSONPath: "barkVolume", - Alias: "volume2", + Alias: "volumeLevel", }, }, }, @@ -3455,23 +1688,19 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { Name: "id", TypeName: string(DataTypeString), JSONPath: "id", + Alias: "identifier", }, { Name: "name", TypeName: string(DataTypeString), JSONPath: "name", - Alias: "name1", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "name2", + Alias: "petName", }, { Name: "kind", TypeName: string(DataTypeString), JSONPath: "kind", + Alias: "animalKind", }, }, }, @@ -3483,8 +1712,8 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { }, }, { - name: "Should create an execution plan for a query with multiple aliases for the same field in union fragments", - query: `query { randomSearchResult { ... on Product { id name1: name name2: name price1: price price2: price } ... on User { id name1: name name2: name } ... on Category { id name1: name name2: name kind1: kind kind2: kind } } }`, + name: "Should create an execution plan for a query with aliases on union type fields", + query: "query { searchResults: randomSearchResult { ... on Product { productId: id productName: name cost: price } ... on User { userId: id userName: name } ... on Category { categoryId: id categoryName: name categoryType: kind } } }", expectedPlan: &RPCExecutionPlan{ Calls: []RPCCall{ { @@ -3500,6 +1729,7 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { Name: "random_search_result", TypeName: string(DataTypeMessage), JSONPath: "randomSearchResult", + Alias: "searchResults", Message: &RPCMessage{ Name: "SearchResult", OneOfType: OneOfTypeUnion, @@ -3515,30 +1745,19 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { Name: "id", TypeName: string(DataTypeString), JSONPath: "id", + Alias: "productId", }, { Name: "name", TypeName: string(DataTypeString), JSONPath: "name", - Alias: "name1", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "name2", - }, - { - Name: "price", - TypeName: string(DataTypeDouble), - JSONPath: "price", - Alias: "price1", + Alias: "productName", }, { Name: "price", TypeName: string(DataTypeDouble), JSONPath: "price", - Alias: "price2", + Alias: "cost", }, }, "User": { @@ -3546,18 +1765,13 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { Name: "id", TypeName: string(DataTypeString), JSONPath: "id", + Alias: "userId", }, { Name: "name", TypeName: string(DataTypeString), JSONPath: "name", - Alias: "name1", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "name2", + Alias: "userName", }, }, "Category": { @@ -3565,31 +1779,19 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { Name: "id", TypeName: string(DataTypeString), JSONPath: "id", + Alias: "categoryId", }, { Name: "name", TypeName: string(DataTypeString), JSONPath: "name", - Alias: "name1", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - Alias: "name2", - }, - { - Name: "kind", - TypeName: string(DataTypeEnum), - JSONPath: "kind", - Alias: "kind1", - EnumName: "CategoryKind", + Alias: "categoryName", }, { Name: "kind", TypeName: string(DataTypeEnum), JSONPath: "kind", - Alias: "kind2", + Alias: "categoryType", EnumName: "CategoryKind", }, }, @@ -3602,173 +1804,28 @@ func TestProductExecutionPlanWithAliases(t *testing.T) { }, }, }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - report := &operationreport.Report{} - // Parse the GraphQL schema - schemaDoc := grpctest.MustGraphQLSchema(t) - - astvalidation.DefaultDefinitionValidator().Validate(&schemaDoc, report) - if report.HasErrors() { - t.Fatalf("failed to validate schema: %s", report.Error()) - } - - // Parse the GraphQL query - queryDoc, queryReport := astparser.ParseGraphqlDocumentString(tt.query) - if queryReport.HasErrors() { - t.Fatalf("failed to parse query: %s", queryReport.Error()) - } - - astvalidation.DefaultOperationValidator().Validate(&queryDoc, &schemaDoc, report) - if report.HasErrors() { - t.Fatalf("failed to validate query: %s", report.Error()) - } - - planner := NewPlanner("Products", testMapping()) - outPlan, err := planner.PlanOperation(&queryDoc, &schemaDoc) - - if tt.expectedError != "" { - if err == nil { - t.Fatalf("expected error, got nil") - } - if !strings.Contains(err.Error(), tt.expectedError) { - t.Fatalf("expected error to contain %q, got %q", tt.expectedError, err.Error()) - } - return - } - - if err != nil { - t.Fatalf("unexpected error: %s", err) - } - - diff := cmp.Diff(tt.expectedPlan, outPlan) - if diff != "" { - t.Fatalf("execution plan mismatch: %s", diff) - } - }) - } - -} - -func TestNullableFieldsExecutionPlan(t *testing.T) { - tests := []struct { - name string - query string - expectedPlan *RPCExecutionPlan - expectedError string - }{ - { - name: "Should create an execution plan for a query with nullable fields type", - query: "query NullableFieldsTypeQuery { nullableFieldsType { id name optionalString optionalInt optionalFloat optionalBoolean requiredString requiredInt } }", - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ - { - ServiceName: "Products", - MethodName: "QueryNullableFieldsType", - Request: RPCMessage{ - Name: "QueryNullableFieldsTypeRequest", - }, - Response: RPCMessage{ - Name: "QueryNullableFieldsTypeResponse", - Fields: []RPCField{ - { - Name: "nullable_fields_type", - TypeName: string(DataTypeMessage), - JSONPath: "nullableFieldsType", - Message: &RPCMessage{ - Name: "NullableFieldsType", - Fields: []RPCField{ - { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", - }, - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, - { - Name: "optional_string", - TypeName: string(DataTypeString), - JSONPath: "optionalString", - Optional: true, - }, - { - Name: "optional_int", - TypeName: string(DataTypeInt32), - JSONPath: "optionalInt", - Optional: true, - }, - { - Name: "optional_float", - TypeName: string(DataTypeDouble), - JSONPath: "optionalFloat", - Optional: true, - }, - { - Name: "optional_boolean", - TypeName: string(DataTypeBool), - JSONPath: "optionalBoolean", - Optional: true, - }, - { - Name: "required_string", - TypeName: string(DataTypeString), - JSONPath: "requiredString", - }, - { - Name: "required_int", - TypeName: string(DataTypeInt32), - JSONPath: "requiredInt", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, { - name: "Should create an execution plan for a query with nullable fields in the request", - query: `query NullableFieldsTypeWithFilterQuery($filter: NullableFieldsFilter!) { nullableFieldsTypeWithFilter(filter: $filter) { id name optionalString optionalInt optionalFloat optionalBoolean } }`, + name: "Should create an execution plan for a mutation with aliases", + query: `mutation { newUser: createUser(input: { name: "John Doe" }) { userId: id fullName: name } }`, expectedPlan: &RPCExecutionPlan{ Calls: []RPCCall{ { ServiceName: "Products", - MethodName: "QueryNullableFieldsTypeWithFilter", + MethodName: "MutationCreateUser", Request: RPCMessage{ - Name: "QueryNullableFieldsTypeWithFilterRequest", + Name: "MutationCreateUserRequest", Fields: []RPCField{ { - Name: "filter", + Name: "input", TypeName: string(DataTypeMessage), - JSONPath: "filter", + JSONPath: "input", Message: &RPCMessage{ - Name: "NullableFieldsFilter", + Name: "UserInput", Fields: []RPCField{ { Name: "name", TypeName: string(DataTypeString), JSONPath: "name", - Optional: true, - }, - { - Name: "optional_string", - TypeName: string(DataTypeString), - JSONPath: "optionalString", - Optional: true, - }, - { - Name: "include_nulls", - TypeName: string(DataTypeBool), - JSONPath: "includeNulls", - Optional: true, }, }, }, @@ -3776,49 +1833,27 @@ func TestNullableFieldsExecutionPlan(t *testing.T) { }, }, Response: RPCMessage{ - Name: "QueryNullableFieldsTypeWithFilterResponse", - Fields: []RPCField{ + Name: "MutationCreateUserResponse", + Fields: RPCFields{ { - Name: "nullable_fields_type_with_filter", + Name: "create_user", TypeName: string(DataTypeMessage), - JSONPath: "nullableFieldsTypeWithFilter", - Repeated: true, + JSONPath: "createUser", + Alias: "newUser", Message: &RPCMessage{ - Name: "NullableFieldsType", - Fields: []RPCField{ + Name: "User", + Fields: RPCFields{ { Name: "id", TypeName: string(DataTypeString), JSONPath: "id", + Alias: "userId", }, { Name: "name", TypeName: string(DataTypeString), JSONPath: "name", - }, - { - Name: "optional_string", - TypeName: string(DataTypeString), - JSONPath: "optionalString", - Optional: true, - }, - { - Name: "optional_int", - TypeName: string(DataTypeInt32), - JSONPath: "optionalInt", - Optional: true, - }, - { - Name: "optional_float", - TypeName: string(DataTypeDouble), - JSONPath: "optionalFloat", - Optional: true, - }, - { - Name: "optional_boolean", - TypeName: string(DataTypeBool), - JSONPath: "optionalBoolean", - Optional: true, + Alias: "fullName", }, }, }, @@ -3830,53 +1865,54 @@ func TestNullableFieldsExecutionPlan(t *testing.T) { }, }, { - name: "Should create an execution plan for nullable fields type by ID query", - query: `query NullableFieldsTypeByIdQuery($id: ID!) { nullableFieldsTypeById(id: $id) { id name optionalString requiredString } }`, + name: "Should create an execution plan for a query with aliases on field with complex input type", + query: `query { bookCategories: categoriesByKind(kind: BOOK) { identifier: id title: name type: kind } }`, expectedPlan: &RPCExecutionPlan{ Calls: []RPCCall{ { ServiceName: "Products", - MethodName: "QueryNullableFieldsTypeById", + MethodName: "QueryCategoriesByKind", Request: RPCMessage{ - Name: "QueryNullableFieldsTypeByIdRequest", + Name: "QueryCategoriesByKindRequest", Fields: []RPCField{ { - Name: "id", - TypeName: string(DataTypeString), - JSONPath: "id", + Name: "kind", + TypeName: string(DataTypeEnum), + JSONPath: "kind", + EnumName: "CategoryKind", }, }, }, Response: RPCMessage{ - Name: "QueryNullableFieldsTypeByIdResponse", - Fields: []RPCField{ + Name: "QueryCategoriesByKindResponse", + Fields: RPCFields{ { - Name: "nullable_fields_type_by_id", + Name: "categories_by_kind", TypeName: string(DataTypeMessage), - JSONPath: "nullableFieldsTypeById", + JSONPath: "categoriesByKind", + Alias: "bookCategories", + Repeated: true, Message: &RPCMessage{ - Name: "NullableFieldsType", - Fields: []RPCField{ + Name: "Category", + Fields: RPCFields{ { Name: "id", TypeName: string(DataTypeString), JSONPath: "id", + Alias: "identifier", }, { Name: "name", TypeName: string(DataTypeString), JSONPath: "name", + Alias: "title", }, { - Name: "optional_string", - TypeName: string(DataTypeString), - JSONPath: "optionalString", - Optional: true, - }, - { - Name: "required_string", - TypeName: string(DataTypeString), - JSONPath: "requiredString", + Name: "kind", + TypeName: string(DataTypeEnum), + JSONPath: "kind", + Alias: "type", + EnumName: "CategoryKind", }, }, }, @@ -3888,27 +1924,27 @@ func TestNullableFieldsExecutionPlan(t *testing.T) { }, }, { - name: "Should create an execution plan for all nullable fields types query", - query: "query AllNullableFieldsTypesQuery { allNullableFieldsTypes { id name optionalString optionalInt requiredString requiredInt } }", + name: "Should create an execution plan for a query with multiple aliases for the same field", + query: `query { users { id name1: name name2: name name3: name } }`, expectedPlan: &RPCExecutionPlan{ Calls: []RPCCall{ { ServiceName: "Products", - MethodName: "QueryAllNullableFieldsTypes", + MethodName: "QueryUsers", Request: RPCMessage{ - Name: "QueryAllNullableFieldsTypesRequest", + Name: "QueryUsersRequest", }, Response: RPCMessage{ - Name: "QueryAllNullableFieldsTypesResponse", - Fields: []RPCField{ + Name: "QueryUsersResponse", + Fields: RPCFields{ { - Name: "all_nullable_fields_types", + Name: "users", TypeName: string(DataTypeMessage), - JSONPath: "allNullableFieldsTypes", + JSONPath: "users", Repeated: true, Message: &RPCMessage{ - Name: "NullableFieldsType", - Fields: []RPCField{ + Name: "User", + Fields: RPCFields{ { Name: "id", TypeName: string(DataTypeString), @@ -3918,28 +1954,19 @@ func TestNullableFieldsExecutionPlan(t *testing.T) { Name: "name", TypeName: string(DataTypeString), JSONPath: "name", + Alias: "name1", }, { - Name: "optional_string", + Name: "name", TypeName: string(DataTypeString), - JSONPath: "optionalString", - Optional: true, - }, - { - Name: "optional_int", - TypeName: string(DataTypeInt32), - JSONPath: "optionalInt", - Optional: true, + JSONPath: "name", + Alias: "name2", }, { - Name: "required_string", + Name: "name", TypeName: string(DataTypeString), - JSONPath: "requiredString", - }, - { - Name: "required_int", - TypeName: string(DataTypeInt32), - JSONPath: "requiredInt", + JSONPath: "name", + Alias: "name3", }, }, }, @@ -3951,77 +1978,77 @@ func TestNullableFieldsExecutionPlan(t *testing.T) { }, }, { - name: "Should create an execution plan for create nullable fields type mutation", - query: `mutation CreateNullableFieldsType($input: NullableFieldsInput!) { createNullableFieldsType(input: $input) { id name optionalString optionalInt optionalFloat optionalBoolean requiredString requiredInt } }`, + name: "Should create an execution plan for a query with multiple aliases for the same field with arguments", + query: `query { user1: user(id: "123") { id name } user2: user(id: "456") { id name } sameUser: user(id: "123") { userId: id userName: name } }`, expectedPlan: &RPCExecutionPlan{ Calls: []RPCCall{ { ServiceName: "Products", - MethodName: "MutationCreateNullableFieldsType", + MethodName: "QueryUser", Request: RPCMessage{ - Name: "MutationCreateNullableFieldsTypeRequest", + Name: "QueryUserRequest", Fields: []RPCField{ { - Name: "input", + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + }, + }, + Response: RPCMessage{ + Name: "QueryUserResponse", + Fields: RPCFields{ + { + Name: "user", TypeName: string(DataTypeMessage), - JSONPath: "input", + JSONPath: "user", + Alias: "user1", + Optional: true, Message: &RPCMessage{ - Name: "NullableFieldsInput", - Fields: []RPCField{ - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, + Name: "User", + Fields: RPCFields{ { - Name: "optional_string", + Name: "id", TypeName: string(DataTypeString), - JSONPath: "optionalString", - Optional: true, - }, - { - Name: "optional_int", - TypeName: string(DataTypeInt32), - JSONPath: "optionalInt", - Optional: true, - }, - { - Name: "optional_float", - TypeName: string(DataTypeDouble), - JSONPath: "optionalFloat", - Optional: true, - }, - { - Name: "optional_boolean", - TypeName: string(DataTypeBool), - JSONPath: "optionalBoolean", - Optional: true, + JSONPath: "id", }, { - Name: "required_string", + Name: "name", TypeName: string(DataTypeString), - JSONPath: "requiredString", - }, - { - Name: "required_int", - TypeName: string(DataTypeInt32), - JSONPath: "requiredInt", + JSONPath: "name", }, }, }, }, }, }, - Response: RPCMessage{ - Name: "MutationCreateNullableFieldsTypeResponse", + }, + { + ServiceName: "Products", + MethodName: "QueryUser", + CallID: 1, + Request: RPCMessage{ + Name: "QueryUserRequest", Fields: []RPCField{ { - Name: "create_nullable_fields_type", + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + }, + }, + Response: RPCMessage{ + Name: "QueryUserResponse", + Fields: RPCFields{ + { + Name: "user", TypeName: string(DataTypeMessage), - JSONPath: "createNullableFieldsType", + JSONPath: "user", + Alias: "user2", + Optional: true, Message: &RPCMessage{ - Name: "NullableFieldsType", - Fields: []RPCField{ + Name: "User", + Fields: RPCFields{ { Name: "id", TypeName: string(DataTypeString), @@ -4032,126 +2059,81 @@ func TestNullableFieldsExecutionPlan(t *testing.T) { TypeName: string(DataTypeString), JSONPath: "name", }, - { - Name: "optional_string", - TypeName: string(DataTypeString), - JSONPath: "optionalString", - Optional: true, - }, - { - Name: "optional_int", - TypeName: string(DataTypeInt32), - JSONPath: "optionalInt", - Optional: true, - }, - { - Name: "optional_float", - TypeName: string(DataTypeDouble), - JSONPath: "optionalFloat", - Optional: true, - }, - { - Name: "optional_boolean", - TypeName: string(DataTypeBool), - JSONPath: "optionalBoolean", - Optional: true, - }, - { - Name: "required_string", - TypeName: string(DataTypeString), - JSONPath: "requiredString", - }, - { - Name: "required_int", - TypeName: string(DataTypeInt32), - JSONPath: "requiredInt", - }, }, }, }, }, }, }, - }, - }, - }, - { - name: "Should create an execution plan for update nullable fields type mutation", - query: `mutation UpdateNullableFieldsType($id: ID!, $input: NullableFieldsInput!) { updateNullableFieldsType(id: $id, input: $input) { id name optionalString requiredString } }`, - expectedPlan: &RPCExecutionPlan{ - Calls: []RPCCall{ { ServiceName: "Products", - MethodName: "MutationUpdateNullableFieldsType", + MethodName: "QueryUser", + CallID: 2, Request: RPCMessage{ - Name: "MutationUpdateNullableFieldsTypeRequest", + Name: "QueryUserRequest", Fields: []RPCField{ { Name: "id", TypeName: string(DataTypeString), JSONPath: "id", }, + }, + }, + Response: RPCMessage{ + Name: "QueryUserResponse", + Fields: RPCFields{ { - Name: "input", + Name: "user", TypeName: string(DataTypeMessage), - JSONPath: "input", + JSONPath: "user", + Alias: "sameUser", + Optional: true, Message: &RPCMessage{ - Name: "NullableFieldsInput", - Fields: []RPCField{ - { - Name: "name", - TypeName: string(DataTypeString), - JSONPath: "name", - }, + Name: "User", + Fields: RPCFields{ { - Name: "optional_string", + Name: "id", TypeName: string(DataTypeString), - JSONPath: "optionalString", - Optional: true, - }, - { - Name: "optional_int", - TypeName: string(DataTypeInt32), - JSONPath: "optionalInt", - Optional: true, - }, - { - Name: "optional_float", - TypeName: string(DataTypeDouble), - JSONPath: "optionalFloat", - Optional: true, - }, - { - Name: "optional_boolean", - TypeName: string(DataTypeBool), - JSONPath: "optionalBoolean", - Optional: true, + JSONPath: "id", + Alias: "userId", }, { - Name: "required_string", + Name: "name", TypeName: string(DataTypeString), - JSONPath: "requiredString", - }, - { - Name: "required_int", - TypeName: string(DataTypeInt32), - JSONPath: "requiredInt", + JSONPath: "name", + Alias: "userName", }, }, }, }, }, }, + }, + }, + }, + }, + { + name: "Should create an execution plan for a query with multiple aliases for the same field in nested objects", + query: `query { nestedType { id name1: name name2: name b { id title1: name title2: name c { id label1: name label2: name } } } }`, + expectedPlan: &RPCExecutionPlan{ + Calls: []RPCCall{ + { + ServiceName: "Products", + MethodName: "QueryNestedType", + Request: RPCMessage{ + Name: "QueryNestedTypeRequest", + }, Response: RPCMessage{ - Name: "MutationUpdateNullableFieldsTypeResponse", - Fields: []RPCField{ + Name: "QueryNestedTypeResponse", + Fields: RPCFields{ { - Name: "update_nullable_fields_type", + Name: "nested_type", TypeName: string(DataTypeMessage), - JSONPath: "updateNullableFieldsType", + JSONPath: "nestedType", + Repeated: true, Message: &RPCMessage{ - Name: "NullableFieldsType", - Fields: []RPCField{ + Name: "NestedTypeA", + Fields: RPCFields{ { Name: "id", TypeName: string(DataTypeString), @@ -4161,17 +2143,67 @@ func TestNullableFieldsExecutionPlan(t *testing.T) { Name: "name", TypeName: string(DataTypeString), JSONPath: "name", + Alias: "name1", }, { - Name: "optional_string", + Name: "name", TypeName: string(DataTypeString), - JSONPath: "optionalString", - Optional: true, + JSONPath: "name", + Alias: "name2", }, { - Name: "required_string", - TypeName: string(DataTypeString), - JSONPath: "requiredString", + Name: "b", + TypeName: string(DataTypeMessage), + JSONPath: "b", + Message: &RPCMessage{ + Name: "NestedTypeB", + Fields: RPCFields{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + Alias: "title1", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + Alias: "title2", + }, + { + Name: "c", + TypeName: string(DataTypeMessage), + JSONPath: "c", + Message: &RPCMessage{ + Name: "NestedTypeC", + Fields: RPCFields{ + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + Alias: "label1", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + Alias: "label2", + }, + }, + }, + }, + }, + }, }, }, }, @@ -4183,36 +2215,82 @@ func TestNullableFieldsExecutionPlan(t *testing.T) { }, }, { - name: "Should create an execution plan for nullable fields with partial field selection", - query: "query PartialNullableFieldsQuery { nullableFieldsType { id optionalString } }", + name: "Should create an execution plan for a query with multiple aliases for the same field in interface fragments", + query: `query { randomPet { id name1: name name2: name kind ... on Cat { volume1: meowVolume volume2: meowVolume } ... on Dog { volume1: barkVolume volume2: barkVolume } } }`, expectedPlan: &RPCExecutionPlan{ Calls: []RPCCall{ { ServiceName: "Products", - MethodName: "QueryNullableFieldsType", + MethodName: "QueryRandomPet", Request: RPCMessage{ - Name: "QueryNullableFieldsTypeRequest", + Name: "QueryRandomPetRequest", }, Response: RPCMessage{ - Name: "QueryNullableFieldsTypeResponse", - Fields: []RPCField{ + Name: "QueryRandomPetResponse", + Fields: RPCFields{ { - Name: "nullable_fields_type", + Name: "random_pet", TypeName: string(DataTypeMessage), - JSONPath: "nullableFieldsType", + JSONPath: "randomPet", Message: &RPCMessage{ - Name: "NullableFieldsType", - Fields: []RPCField{ + Name: "Animal", + OneOfType: OneOfTypeInterface, + MemberTypes: []string{ + "Cat", + "Dog", + }, + FieldSelectionSet: RPCFieldSelectionSet{ + "Cat": { + { + Name: "meow_volume", + TypeName: string(DataTypeInt32), + JSONPath: "meowVolume", + Alias: "volume1", + }, + { + Name: "meow_volume", + TypeName: string(DataTypeInt32), + JSONPath: "meowVolume", + Alias: "volume2", + }, + }, + "Dog": { + { + Name: "bark_volume", + TypeName: string(DataTypeInt32), + JSONPath: "barkVolume", + Alias: "volume1", + }, + { + Name: "bark_volume", + TypeName: string(DataTypeInt32), + JSONPath: "barkVolume", + Alias: "volume2", + }, + }, + }, + Fields: RPCFields{ { Name: "id", TypeName: string(DataTypeString), JSONPath: "id", }, { - Name: "optional_string", + Name: "name", TypeName: string(DataTypeString), - JSONPath: "optionalString", - Optional: true, + JSONPath: "name", + Alias: "name1", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + Alias: "name2", + }, + { + Name: "kind", + TypeName: string(DataTypeString), + JSONPath: "kind", }, }, }, @@ -4224,49 +2302,115 @@ func TestNullableFieldsExecutionPlan(t *testing.T) { }, }, { - name: "Should create an execution plan for nullable fields with only optional fields", - query: "query OptionalFieldsOnlyQuery { nullableFieldsType { optionalString optionalInt optionalFloat optionalBoolean } }", + name: "Should create an execution plan for a query with multiple aliases for the same field in union fragments", + query: `query { randomSearchResult { ... on Product { id name1: name name2: name price1: price price2: price } ... on User { id name1: name name2: name } ... on Category { id name1: name name2: name kind1: kind kind2: kind } } }`, expectedPlan: &RPCExecutionPlan{ Calls: []RPCCall{ { ServiceName: "Products", - MethodName: "QueryNullableFieldsType", + MethodName: "QueryRandomSearchResult", Request: RPCMessage{ - Name: "QueryNullableFieldsTypeRequest", + Name: "QueryRandomSearchResultRequest", }, Response: RPCMessage{ - Name: "QueryNullableFieldsTypeResponse", - Fields: []RPCField{ + Name: "QueryRandomSearchResultResponse", + Fields: RPCFields{ { - Name: "nullable_fields_type", + Name: "random_search_result", TypeName: string(DataTypeMessage), - JSONPath: "nullableFieldsType", + JSONPath: "randomSearchResult", Message: &RPCMessage{ - Name: "NullableFieldsType", - Fields: []RPCField{ - { - Name: "optional_string", - TypeName: string(DataTypeString), - JSONPath: "optionalString", - Optional: true, - }, - { - Name: "optional_int", - TypeName: string(DataTypeInt32), - JSONPath: "optionalInt", - Optional: true, + Name: "SearchResult", + OneOfType: OneOfTypeUnion, + MemberTypes: []string{ + "Product", + "User", + "Category", + }, + Fields: RPCFields{}, + FieldSelectionSet: RPCFieldSelectionSet{ + "Product": { + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + Alias: "name1", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + Alias: "name2", + }, + { + Name: "price", + TypeName: string(DataTypeDouble), + JSONPath: "price", + Alias: "price1", + }, + { + Name: "price", + TypeName: string(DataTypeDouble), + JSONPath: "price", + Alias: "price2", + }, }, - { - Name: "optional_float", - TypeName: string(DataTypeDouble), - JSONPath: "optionalFloat", - Optional: true, + "User": { + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + Alias: "name1", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + Alias: "name2", + }, }, - { - Name: "optional_boolean", - TypeName: string(DataTypeBool), - JSONPath: "optionalBoolean", - Optional: true, + "Category": { + { + Name: "id", + TypeName: string(DataTypeString), + JSONPath: "id", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + Alias: "name1", + }, + { + Name: "name", + TypeName: string(DataTypeString), + JSONPath: "name", + Alias: "name2", + }, + { + Name: "kind", + TypeName: string(DataTypeEnum), + JSONPath: "kind", + Alias: "kind1", + EnumName: "CategoryKind", + }, + { + Name: "kind", + TypeName: string(DataTypeEnum), + JSONPath: "kind", + Alias: "kind2", + EnumName: "CategoryKind", + }, }, }, }, @@ -4282,11 +2426,48 @@ func TestNullableFieldsExecutionPlan(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() - runTest(t, testCase{ - query: tt.query, - expectedPlan: tt.expectedPlan, - expectedError: tt.expectedError, - }) + report := &operationreport.Report{} + // Parse the GraphQL schema + schemaDoc := grpctest.MustGraphQLSchema(t) + + astvalidation.DefaultDefinitionValidator().Validate(&schemaDoc, report) + if report.HasErrors() { + t.Fatalf("failed to validate schema: %s", report.Error()) + } + + // Parse the GraphQL query + queryDoc, queryReport := astparser.ParseGraphqlDocumentString(tt.query) + if queryReport.HasErrors() { + t.Fatalf("failed to parse query: %s", queryReport.Error()) + } + + astvalidation.DefaultOperationValidator().Validate(&queryDoc, &schemaDoc, report) + if report.HasErrors() { + t.Fatalf("failed to validate query: %s", report.Error()) + } + + planner := NewPlanner("Products", testMapping()) + outPlan, err := planner.PlanOperation(&queryDoc, &schemaDoc) + + if tt.expectedError != "" { + if err == nil { + t.Fatalf("expected error, got nil") + } + if !strings.Contains(err.Error(), tt.expectedError) { + t.Fatalf("expected error to contain %q, got %q", tt.expectedError, err.Error()) + } + return + } + + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + + diff := cmp.Diff(tt.expectedPlan, outPlan) + if diff != "" { + t.Fatalf("execution plan mismatch: %s", diff) + } }) } + } diff --git a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor.go b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor.go index ac1dcc7c40..3ce12f733f 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor.go +++ b/v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor.go @@ -324,18 +324,47 @@ func (r *rpcPlanVisitor) EnterField(ref int) { return } + field := r.buildField(fd, fieldName, fieldAlias) + + if ref, ok := r.IsInlineFragmentField(); ok && !r.planInfo.isEntityLookup { + if r.planInfo.currentResponseMessage.FieldSelectionSet == nil { + r.planInfo.currentResponseMessage.FieldSelectionSet = make(RPCFieldSelectionSet) + } + + inlineFragmentName := r.operation.InlineFragmentTypeConditionNameString(ref) + r.planInfo.currentResponseMessage.FieldSelectionSet.Add(inlineFragmentName, field) + return + } + + r.planInfo.currentResponseMessage.Fields = append(r.planInfo.currentResponseMessage.Fields, field) +} + +// buildField builds a field from a field definition. +// It handles lists, enums, and other types. +func (r *rpcPlanVisitor) buildField(fd int, fieldName, fieldAlias string) RPCField { fdt := r.definition.FieldDefinitionType(fd) typeName := r.toDataType(&r.definition.Types[fdt]) - parentTypeName := r.walker.EnclosingTypeDefinition.NameString(r.definition) field := RPCField{ Name: r.resolveFieldMapping(parentTypeName, fieldName), - TypeName: typeName.String(), - JSONPath: fieldName, - Repeated: r.definition.TypeIsList(fdt), Alias: fieldAlias, - Optional: r.isNullableScalar(fdt), + Optional: !r.definition.TypeIsNonNull(fdt), + JSONPath: fieldName, + TypeName: typeName.String(), + } + + if r.definition.TypeIsList(fdt) { + switch { + // for nullable or nested lists we need to build a wrapper message + // Nullability is handled by the datasource during the execution. + case r.typeIsNullableOrNestedList(fdt): + field.ListMetadata = r.createListMetadata(fdt) + field.IsListType = true + default: + // For non-nullable single lists we can directly use the repeated syntax in protobuf. + field.Repeated = true + } } if typeName == DataTypeEnum { @@ -346,17 +375,7 @@ func (r *rpcPlanVisitor) EnterField(ref int) { field.StaticValue = parentTypeName } - if ref, ok := r.IsInlineFragmentField(); ok && !r.planInfo.isEntityLookup { - if r.planInfo.currentResponseMessage.FieldSelectionSet == nil { - r.planInfo.currentResponseMessage.FieldSelectionSet = make(RPCFieldSelectionSet) - } - - inlineFragmentName := r.operation.InlineFragmentTypeConditionNameString(ref) - r.planInfo.currentResponseMessage.FieldSelectionSet.Add(inlineFragmentName, field) - return - } - - r.planInfo.currentResponseMessage.Fields = append(r.planInfo.currentResponseMessage.Fields, field) + return field } // LeaveField implements astvisitor.FieldVisitor. @@ -435,7 +454,7 @@ func (r *rpcPlanVisitor) enrichRequestMessageFromInputArgument(argRef, typeRef i TypeName: DataTypeMessage.String(), JSONPath: jsonPath, Message: msg, - Repeated: r.definition.TypeIsList(typeRef), + Repeated: r.definition.TypeIsNonNullList(typeRef), }) // Add the current request message to the ancestors and set the current request message to the new message. @@ -456,8 +475,15 @@ func (r *rpcPlanVisitor) enrichRequestMessageFromInputArgument(argRef, typeRef i Name: r.resolveInputArgument(baseType, r.walker.Ancestor().Ref, fieldName), TypeName: dt.String(), JSONPath: jsonPath, - Repeated: r.definition.TypeIsList(typeRef), - Optional: r.isNullableScalar(typeRef), + Repeated: r.definition.TypeIsNonNullList(typeRef), + Optional: !r.definition.TypeIsNonNull(typeRef), + } + + // For nullable or nested lists we need to build a wrapper message + if r.typeIsNullableOrNestedList(typeRef) { + field.ListMetadata = r.createListMetadata(typeRef) + field.Repeated = false + field.IsListType = true } if dt == DataTypeEnum { @@ -498,19 +524,13 @@ func (r *rpcPlanVisitor) buildMessageField(fieldName string, typeRef, parentType } parentTypeName := r.definition.InputObjectTypeDefinitionNameString(parentTypeRef) + mappedName := r.resolveFieldMapping(parentTypeName, fieldName) // If the type is not an object, directly add the field to the request message // TODO: check interfaces, unions, etc. if underlyingTypeNode.Kind != ast.NodeKindInputObjectTypeDefinition { dt := r.toDataType(&inputValueDefinitionType) - - field := RPCField{ - Name: r.resolveFieldMapping(parentTypeName, fieldName), - TypeName: dt.String(), - JSONPath: fieldName, - Repeated: r.definition.TypeIsList(typeRef), - Optional: r.isNullableScalar(typeRef), - } + field := r.buildInputMessageField(typeRef, mappedName, fieldName, dt) if dt == DataTypeEnum { field.EnumName = underlyingTypeName @@ -525,13 +545,10 @@ func (r *rpcPlanVisitor) buildMessageField(fieldName string, typeRef, parentType Name: underlyingTypeName, } - r.planInfo.currentRequestMessage.Fields = append(r.planInfo.currentRequestMessage.Fields, RPCField{ - Name: r.resolveFieldMapping(parentTypeName, fieldName), - TypeName: DataTypeMessage.String(), - JSONPath: fieldName, - Message: msg, - Repeated: r.definition.TypeIsList(typeRef), - }) + field := r.buildInputMessageField(typeRef, mappedName, fieldName, DataTypeMessage) + field.Message = msg + + r.planInfo.currentRequestMessage.Fields = append(r.planInfo.currentRequestMessage.Fields, field) r.planInfo.requestMessageAncestors = append(r.planInfo.requestMessageAncestors, r.planInfo.currentRequestMessage) r.planInfo.currentRequestMessage = msg @@ -542,6 +559,53 @@ func (r *rpcPlanVisitor) buildMessageField(fieldName string, typeRef, parentType r.planInfo.requestMessageAncestors = r.planInfo.requestMessageAncestors[:len(r.planInfo.requestMessageAncestors)-1] } +func (r *rpcPlanVisitor) buildInputMessageField(typeRef int, fieldName, jsonPath string, dt DataType) RPCField { + field := RPCField{ + Name: fieldName, + Optional: !r.definition.TypeIsNonNull(typeRef), + TypeName: dt.String(), + JSONPath: jsonPath, + } + + if r.definition.TypeIsList(typeRef) { + switch { + // for nullable or nested lists we need to build a wrapper message + // Nullability is handled by the datasource during the execution. + case r.typeIsNullableOrNestedList(typeRef): + field.ListMetadata = r.createListMetadata(typeRef) + field.IsListType = true + default: + // For non-nullable single lists we can directly use the repeated syntax in protobuf. + field.Repeated = true + } + } + + return field +} + +func (r *rpcPlanVisitor) createListMetadata(typeRef int) *ListMetadata { + nestingLevel := r.definition.TypeNumberOfListWraps(typeRef) + + md := &ListMetadata{ + NestingLevel: nestingLevel, + LevelInfo: make([]LevelInfo, nestingLevel), + } + + for i := 0; i < nestingLevel; i++ { + md.LevelInfo[i] = LevelInfo{ + Optional: !r.definition.TypeIsNonNull(typeRef), + } + + typeRef = r.definition.ResolveNestedListOrListType(typeRef) + if typeRef == ast.InvalidRef { + r.walker.StopWithInternalErr(fmt.Errorf("unable to resolve underlying list type for ref: %d", typeRef)) + return nil + } + } + + return md +} + func (r *rpcPlanVisitor) resolveEntityInformation(inlineFragmentRef int) { // TODO support multiple entities in a single query if !r.planInfo.isEntityLookup || r.planInfo.entityInfo.name != "" { @@ -819,8 +883,16 @@ func (r *rpcPlanVisitor) parseGraphQLType(t *ast.Type) DataType { } } -func (r *rpcPlanVisitor) isNullableScalar(fdt int) bool { - return r.definition.TypeIsScalar(fdt, r.definition) && !r.definition.TypeIsNonNull(fdt) +func (r *rpcPlanVisitor) typeIsNullableOrNestedList(typeRef int) bool { + if !r.definition.TypeIsNonNull(typeRef) && r.definition.TypeIsList(typeRef) { + return true + } + + if r.definition.TypeNumberOfListWraps(typeRef) > 1 { + return true + } + + return false } // titleSlice capitalizes the first letter of each string in a slice. diff --git a/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource.go b/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource.go index 358ff18248..626b4a69f2 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource.go +++ b/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource.go @@ -9,6 +9,7 @@ package grpcdatasource import ( "bytes" "context" + "errors" "fmt" "strconv" @@ -184,9 +185,6 @@ func (d *DataSource) marshalResponseJSON(arena *astjson.Arena, message *RPCMessa if fd.IsList() { list := data.Get(fd).List() - // We currently do not yet support to distingish between nullable and non-nullable lists. - // Therefore we always return an empty array for now. - // TODO: Add support for nullable lists. arr := arena.NewArray() root.Set(field.AliasOrPath(), arr) @@ -221,7 +219,17 @@ func (d *DataSource) marshalResponseJSON(arena *astjson.Arena, message *RPCMessa continue } - if field.Optional { + if field.IsListType { + arr, err := d.flattenListStructure(arena, field.ListMetadata, msg, field.Message) + if err != nil { + return nil, err + } + + root.Set(field.AliasOrPath(), arr) + continue + } + + if field.IsOptionalScalar() { err := d.resolveOptionalField(arena, root, field.JSONPath, msg) if err != nil { return nil, err @@ -253,10 +261,100 @@ func (d *DataSource) marshalResponseJSON(arena *astjson.Arena, message *RPCMessa return root, nil } +func (d *DataSource) flattenListStructure(arena *astjson.Arena, md *ListMetadata, data protoref.Message, message *RPCMessage) (*astjson.Value, error) { + if md == nil { + return arena.NewNull(), errors.New("unable to flatten list structure: list metadata not found") + } + + if len(md.LevelInfo) < md.NestingLevel { + return arena.NewNull(), errors.New("unable to flatten list structure: nesting level data does not match the number of levels in the list metadata") + } + + if !data.IsValid() { + if md.LevelInfo[0].Optional { + return arena.NewNull(), nil + } + + return arena.NewNull(), errors.New("cannot add null item to response for non nullable list") + } + + root := arena.NewArray() + return d.traverseList(0, arena, root, md, data, message) +} + +func (d *DataSource) traverseList(level int, arena *astjson.Arena, current *astjson.Value, md *ListMetadata, data protoref.Message, message *RPCMessage) (*astjson.Value, error) { + if level > md.NestingLevel { + return current, nil + } + + // List wrappers always use field number 1 + fd := data.Descriptor().Fields().ByNumber(1) + if fd == nil { + return arena.NewNull(), fmt.Errorf("unable to flatten list structure: field with number %d not found in message %q", 1, data.Descriptor().Name()) + } + + if fd.Kind() != protoref.MessageKind { + return arena.NewNull(), fmt.Errorf("unable to flatten list structure: field %q is not a message", fd.Name()) + } + + msg := data.Get(fd).Message() + if !msg.IsValid() { + if md.LevelInfo[level].Optional { + return arena.NewNull(), nil + } + + return arena.NewArray(), nil + } + + fd = msg.Descriptor().Fields().ByNumber(1) + if !fd.IsList() { + return arena.NewNull(), fmt.Errorf("unable to flatten list structure: field %q is not a list", fd.Name()) + } + + if level < md.NestingLevel-1 { + list := msg.Get(fd).List() + for i := 0; i < list.Len(); i++ { + next := arena.NewArray() + val, err := d.traverseList(level+1, arena, next, md, list.Get(i).Message(), message) + if err != nil { + return nil, err + } + + current.SetArrayItem(i, val) + } + + return current, nil + } + + list := msg.Get(fd).List() + if !list.IsValid() { + if md.LevelInfo[level].Optional { + return arena.NewNull(), nil + } + + return arena.NewNull(), fmt.Errorf("cannot add null item to response for non nullable list") + } + + for i := 0; i < list.Len(); i++ { + if message != nil { + val, err := d.marshalResponseJSON(arena, message, list.Get(i).Message()) + if err != nil { + return nil, err + } + + current.SetArrayItem(i, val) + } else { + d.setArrayItem(i, arena, current, list.Get(i), fd) + } + } + + return current, nil +} + func (d *DataSource) resolveOptionalField(arena *astjson.Arena, root *astjson.Value, name string, data protoref.Message) error { fd := data.Descriptor().Fields().ByName(protoref.Name("value")) if fd == nil { - return fmt.Errorf("unable to resolve optional field: field value not found in message %s", data.Descriptor().Name()) + return fmt.Errorf("unable to resolve optional field: field %q not found in message %s", "value", data.Descriptor().Name()) } d.setJSONValue(arena, root, name, data, fd) diff --git a/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go b/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go index a99654c1a9..88dd342dff 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go +++ b/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go @@ -5,6 +5,7 @@ import ( "context" "encoding/json" "fmt" + "math" "net" "strings" "testing" @@ -425,13 +426,17 @@ func TestMarshalResponseJSON(t *testing.T) { t.Fatalf("failed to compile proto: %v", err) } - productMessageDesc := compiler.doc.MessageByName("Product").Desc + productMsg, ok := compiler.doc.MessageByName("Product") + require.True(t, ok) + productMessageDesc := productMsg.Desc productMessage := dynamicpb.NewMessage(productMessageDesc) productMessage.Set(productMessageDesc.Fields().ByName("id"), protoref.ValueOfString("123")) productMessage.Set(productMessageDesc.Fields().ByName("name"), protoref.ValueOfString("test")) productMessage.Set(productMessageDesc.Fields().ByName("price"), protoref.ValueOfFloat64(123.45)) - responseMessageDesc := compiler.doc.MessageByName("LookupProductByIdResponse").Desc + responseMsg, ok := compiler.doc.MessageByName("LookupProductByIdResponse") + require.True(t, ok) + responseMessageDesc := responseMsg.Desc responseMessage := dynamicpb.NewMessage(responseMessageDesc) responseMessage.Mutable(responseMessageDesc.Fields().ByName("result")).List().Append(protoref.ValueOfMessage(productMessage)) @@ -1875,7 +1880,7 @@ func Test_DataSource_Load_WithNullableFieldsType(t *testing.T) { require.Equal(t, "Full Data Entry", firstEntry["name"]) require.Equal(t, "Optional String Value", firstEntry["optionalString"]) require.Equal(t, float64(42), firstEntry["optionalInt"]) - require.InDelta(t, float64(3.14), firstEntry["optionalFloat"], 0.01) + require.InDelta(t, math.MaxFloat64, firstEntry["optionalFloat"], 0.01) require.Equal(t, true, firstEntry["optionalBoolean"]) require.Equal(t, "Required String 1", firstEntry["requiredString"]) require.Equal(t, float64(100), firstEntry["requiredInt"]) @@ -2084,3 +2089,854 @@ func Test_DataSource_Load_WithNullableFieldsType(t *testing.T) { }) } } + +func Test_DataSource_Load_WithNestedLists(t *testing.T) { + conn, cleanup := setupTestGRPCServer(t) + defer cleanup() + + testCases := []struct { + name string + query string + vars string + validate func(t *testing.T, data map[string]interface{}) + }{ + { + name: "Should handle BlogPost with single lists of different nullability", + query: `query { + blogPost { + id + title + content + tags + optionalTags + categories + keywords + } + }`, + vars: "{}", + validate: func(t *testing.T, data map[string]interface{}) { + blogPost, ok := data["blogPost"].(map[string]interface{}) + require.True(t, ok, "blogPost should be an object") + + // Check required fields + require.NotEmpty(t, blogPost["id"]) + require.NotEmpty(t, blogPost["title"]) + require.NotEmpty(t, blogPost["content"]) + + // Check required list with required items + tags, ok := blogPost["tags"].([]interface{}) + require.True(t, ok, "tags should be an array") + require.NotEmpty(t, tags, "tags should not be empty") + + // Check optional list with required items (can be null or array) + if optionalTags := blogPost["optionalTags"]; optionalTags != nil { + optionalTagsArr, ok := optionalTags.([]interface{}) + require.True(t, ok, "optionalTags should be an array if present") + require.NotEmpty(t, optionalTagsArr, "optionalTags should not be empty if present") + } + + // Check required list with optional items + _, ok = blogPost["categories"].([]interface{}) + require.True(t, ok, "categories should be an array") + // categories can contain null items + + // Check optional list with optional items (can be null or array) + if keywords := blogPost["keywords"]; keywords != nil { + _, ok := keywords.([]interface{}) + require.True(t, ok, "keywords should be an array if present") + // keywords array can contain null items + } + }, + }, + { + name: "Should handle BlogPost with scalar type lists", + query: `query { + blogPost { + id + title + viewCounts + ratings + isPublished + } + }`, + vars: "{}", + validate: func(t *testing.T, data map[string]interface{}) { + blogPost, ok := data["blogPost"].(map[string]interface{}) + require.True(t, ok, "blogPost should be an object") + + // Check required list of required ints + viewCounts, ok := blogPost["viewCounts"].([]interface{}) + require.True(t, ok, "viewCounts should be an array") + require.NotEmpty(t, viewCounts, "viewCounts should not be empty") + for _, count := range viewCounts { + require.IsType(t, float64(0), count, "viewCounts items should be numbers") + } + + // Check optional list of optional floats + if ratings := blogPost["ratings"]; ratings != nil { + _, ok := ratings.([]interface{}) + require.True(t, ok, "ratings should be an array if present") + // ratings can contain null values + } + + // Check optional list of required booleans + if isPublished := blogPost["isPublished"]; isPublished != nil { + isPublishedArr, ok := isPublished.([]interface{}) + require.True(t, ok, "isPublished should be an array if present") + for _, published := range isPublishedArr { + require.IsType(t, true, published, "isPublished items should be booleans") + } + } + }, + }, + { + name: "Should handle BlogPost with nested lists", + query: `query { + blogPost { + id + title + tagGroups + relatedTopics + commentThreads + suggestions + } + }`, + vars: "{}", + validate: func(t *testing.T, data map[string]interface{}) { + blogPost, ok := data["blogPost"].(map[string]interface{}) + require.True(t, ok, "blogPost should be an object") + + // Check required list of required lists with required items + tagGroups, ok := blogPost["tagGroups"].([]interface{}) + require.True(t, ok, "tagGroups should be an array") + require.NotEmpty(t, tagGroups, "tagGroups should not be empty") + for _, group := range tagGroups { + groupArr, ok := group.([]interface{}) + require.True(t, ok, "tagGroups items should be arrays") + require.NotEmpty(t, groupArr, "tagGroups inner arrays should not be empty") + for _, tag := range groupArr { + require.IsType(t, "", tag, "tags should be strings") + } + } + + // Check required list of optional lists with required items + _, ok = blogPost["relatedTopics"].([]interface{}) + require.True(t, ok, "relatedTopics should be an array") + // relatedTopics can contain null inner arrays + + // Check required list of required lists with optional items + commentThreads, ok := blogPost["commentThreads"].([]interface{}) + require.True(t, ok, "commentThreads should be an array") + require.NotEmpty(t, commentThreads, "commentThreads should not be empty") + for _, thread := range commentThreads { + _, ok := thread.([]interface{}) + require.True(t, ok, "commentThreads items should be arrays") + for _, item := range thread.([]interface{}) { + require.IsType(t, "", item, "commentThreads items should be strings") + } + } + + // Check optional list of optional lists with optional items + if suggestions := blogPost["suggestions"]; suggestions != nil { + _, ok := suggestions.([]interface{}) + require.True(t, ok, "suggestions should be an array if present") + for _, suggestion := range suggestions.([]interface{}) { + _, ok := suggestion.([]interface{}) + require.True(t, ok, "suggestions items should be arrays") + } + } + }, + }, + { + name: "Should handle Author with single lists", + query: `query { + author { + id + name + email + skills + languages + socialLinks + } + }`, + vars: "{}", + validate: func(t *testing.T, data map[string]interface{}) { + author, ok := data["author"].(map[string]interface{}) + require.True(t, ok, "author should be an object") + + // Check required fields + require.NotEmpty(t, author["id"]) + require.NotEmpty(t, author["name"]) + + // Check required list with required items + skills, ok := author["skills"].([]interface{}) + require.True(t, ok, "skills should be an array") + require.NotEmpty(t, skills, "skills should not be empty") + + // Check required list with optional items + _, ok = author["languages"].([]interface{}) + require.True(t, ok, "languages should be an array") + // languages can contain null items + + // Check optional list with optional items + if socialLinks := author["socialLinks"]; socialLinks != nil { + _, ok := socialLinks.([]interface{}) + require.True(t, ok, "socialLinks should be an array if present") + // socialLinks can contain null items + } + }, + }, + { + name: "Should handle Author with nested lists", + query: `query { + author { + id + name + teamsByProject + collaborations + } + }`, + vars: "{}", + validate: func(t *testing.T, data map[string]interface{}) { + author, ok := data["author"].(map[string]interface{}) + require.True(t, ok, "author should be an object") + + // Check required list of required lists with required items + teamsByProject, ok := author["teamsByProject"].([]interface{}) + require.True(t, ok, "teamsByProject should be an array") + require.NotEmpty(t, teamsByProject, "teamsByProject should not be empty") + for _, project := range teamsByProject { + projectArr, ok := project.([]interface{}) + require.True(t, ok, "teamsByProject items should be arrays") + require.NotEmpty(t, projectArr, "teamsByProject inner arrays should not be empty") + for _, member := range projectArr { + require.IsType(t, "", member, "team members should be strings") + } + } + + // Check optional list of optional lists with optional items + if collaborations := author["collaborations"]; collaborations != nil { + _, ok := collaborations.([]interface{}) + require.True(t, ok, "collaborations should be an array if present") + // collaborations can contain null inner arrays and null items + } + }, + }, + { + name: "Should handle BlogPost query by ID", + query: `query($id: ID!) { + blogPostById(id: $id) { + id + title + content + tags + tagGroups + } + }`, + vars: `{"variables":{"id":"test-blog-1"}}`, + validate: func(t *testing.T, data map[string]interface{}) { + blogPost, ok := data["blogPostById"].(map[string]interface{}) + require.True(t, ok, "blogPostById should be an object") + require.Equal(t, "test-blog-1", blogPost["id"]) + require.NotEmpty(t, blogPost["title"]) + require.NotEmpty(t, blogPost["tags"]) + require.NotEmpty(t, blogPost["tagGroups"]) + }, + }, + { + name: "Should handle Author query by ID", + query: `query($id: ID!) { + authorById(id: $id) { + id + name + skills + teamsByProject + } + }`, + vars: `{"variables":{"id":"test-author-1"}}`, + validate: func(t *testing.T, data map[string]interface{}) { + author, ok := data["authorById"].(map[string]interface{}) + require.True(t, ok, "authorById should be an object") + require.Equal(t, "test-author-1", author["id"]) + require.NotEmpty(t, author["name"]) + require.NotEmpty(t, author["skills"]) + require.NotEmpty(t, author["teamsByProject"]) + }, + }, + { + name: "Should handle BlogPost filtered query", + query: `query($filter: BlogPostFilter!) { + blogPostsWithFilter(filter: $filter) { + id + title + tags + categories + tagGroups + } + }`, + vars: `{"variables":{"filter":{"title":"Test","hasCategories":true,"minTags":2}}}`, + validate: func(t *testing.T, data map[string]interface{}) { + blogPosts, ok := data["blogPostsWithFilter"].([]interface{}) + require.True(t, ok, "blogPostsWithFilter should be an array") + require.NotEmpty(t, blogPosts, "blogPostsWithFilter should not be empty") + + for _, post := range blogPosts { + blogPost, ok := post.(map[string]interface{}) + require.True(t, ok, "each post should be an object") + require.NotEmpty(t, blogPost["id"]) + require.NotEmpty(t, blogPost["title"]) + require.NotEmpty(t, blogPost["tags"]) + require.NotEmpty(t, blogPost["categories"]) + require.NotEmpty(t, blogPost["tagGroups"]) + } + }, + }, + { + name: "Should handle Author filtered query", + query: `query($filter: AuthorFilter!) { + authorsWithFilter(filter: $filter) { + id + name + skills + teamsByProject + } + }`, + vars: `{"variables":{"filter":{"name":"Test","hasTeams":true,"skillCount":3}}}`, + validate: func(t *testing.T, data map[string]interface{}) { + authors, ok := data["authorsWithFilter"].([]interface{}) + require.True(t, ok, "authorsWithFilter should be an array") + require.NotEmpty(t, authors, "authorsWithFilter should not be empty") + + for _, auth := range authors { + author, ok := auth.(map[string]interface{}) + require.True(t, ok, "each author should be an object") + require.NotEmpty(t, author["id"]) + require.NotEmpty(t, author["name"]) + require.NotEmpty(t, author["skills"]) + require.NotEmpty(t, author["teamsByProject"]) + } + }, + }, + { + name: "Should handle BlogPost creation mutation", + query: `mutation($input: BlogPostInput!) { + createBlogPost(input: $input) { + id + title + content + tags + optionalTags + tagGroups + relatedTopics + } + }`, + vars: `{"variables":{"input":{"title":"New Blog Post","content":"Content here","tags":["tech","programming"],"optionalTags":["optional1","optional2"],"categories":["Technology","Programming"],"keywords":["keyword1","keyword2"],"viewCounts":[100,200,300],"ratings":[4.5,5.0,3.8],"isPublished":[true,false,true],"tagGroups":[["tech","go"],["programming","backend"]],"relatedTopics":[["topic1","topic2"],["topic3"]],"commentThreads":[["comment1","comment2"],["comment3","comment4"]],"suggestions":[["suggestion1"],["suggestion2","suggestion3"]]}}}`, + validate: func(t *testing.T, data map[string]interface{}) { + createBlogPost, ok := data["createBlogPost"].(map[string]interface{}) + require.True(t, ok, "createBlogPost should be an object") + require.NotEmpty(t, createBlogPost["id"]) + require.Equal(t, "New Blog Post", createBlogPost["title"]) + require.Equal(t, "Content here", createBlogPost["content"]) + + // Verify lists + tags, ok := createBlogPost["tags"].([]interface{}) + require.True(t, ok, "tags should be an array") + require.Contains(t, tags, "tech") + require.Contains(t, tags, "programming") + + optionalTags, ok := createBlogPost["optionalTags"].([]interface{}) + require.True(t, ok, "optionalTags should be an array") + require.Contains(t, optionalTags, "optional1") + require.Contains(t, optionalTags, "optional2") + + // Verify nested lists + tagGroups, ok := createBlogPost["tagGroups"].([]interface{}) + require.True(t, ok, "tagGroups should be an array") + require.Len(t, tagGroups, 2) + + relatedTopics, ok := createBlogPost["relatedTopics"].([]interface{}) + require.True(t, ok, "relatedTopics should be an array") + require.Len(t, relatedTopics, 2) + }, + }, + { + name: "Should handle Author creation mutation", + query: `mutation($input: AuthorInput!) { + createAuthor(input: $input) { + id + name + email + skills + languages + socialLinks + teamsByProject + collaborations + } + }`, + vars: `{"variables":{"input":{"name":"New Author","email":"author@example.com","skills":["Go","GraphQL","gRPC"],"languages":["English","Spanish"],"socialLinks":["twitter.com/author","github.com/author"],"teamsByProject":[["Alice","Bob"],["Charlie","David","Eve"]],"collaborations":[["Project1","Project2"],["Project3"]]}}}`, + validate: func(t *testing.T, data map[string]interface{}) { + createAuthor, ok := data["createAuthor"].(map[string]interface{}) + require.True(t, ok, "createAuthor should be an object") + require.NotEmpty(t, createAuthor["id"]) + require.Equal(t, "New Author", createAuthor["name"]) + require.Equal(t, "author@example.com", createAuthor["email"]) + + // Verify single lists + skills, ok := createAuthor["skills"].([]interface{}) + require.True(t, ok, "skills should be an array") + require.Contains(t, skills, "Go") + require.Contains(t, skills, "GraphQL") + require.Contains(t, skills, "gRPC") + + languages, ok := createAuthor["languages"].([]interface{}) + require.True(t, ok, "languages should be an array") + require.Contains(t, languages, "English") + require.Contains(t, languages, "Spanish") + + socialLinks, ok := createAuthor["socialLinks"].([]interface{}) + require.True(t, ok, "socialLinks should be an array") + require.Contains(t, socialLinks, "twitter.com/author") + require.Contains(t, socialLinks, "github.com/author") + + // Verify nested lists + teamsByProject, ok := createAuthor["teamsByProject"].([]interface{}) + require.True(t, ok, "teamsByProject should be an array") + require.Len(t, teamsByProject, 2) + + collaborations, ok := createAuthor["collaborations"].([]interface{}) + require.True(t, ok, "collaborations should be an array") + require.Len(t, collaborations, 2) + }, + }, + { + name: "Should handle all BlogPosts query", + query: `query { + allBlogPosts { + id + title + tags + tagGroups + viewCounts + ratings + } + }`, + vars: "{}", + validate: func(t *testing.T, data map[string]interface{}) { + allBlogPosts, ok := data["allBlogPosts"].([]interface{}) + require.True(t, ok, "allBlogPosts should be an array") + require.NotEmpty(t, allBlogPosts, "allBlogPosts should not be empty") + + for _, post := range allBlogPosts { + blogPost, ok := post.(map[string]interface{}) + require.True(t, ok, "each post should be an object") + require.NotEmpty(t, blogPost["id"]) + require.NotEmpty(t, blogPost["title"]) + require.NotEmpty(t, blogPost["tags"]) + } + }, + }, + { + name: "Should handle all Authors query", + query: `query { + allAuthors { + id + name + skills + teamsByProject + } + }`, + vars: "{}", + validate: func(t *testing.T, data map[string]interface{}) { + allAuthors, ok := data["allAuthors"].([]interface{}) + require.True(t, ok, "allAuthors should be an array") + require.NotEmpty(t, allAuthors, "allAuthors should not be empty") + + for _, auth := range allAuthors { + author, ok := auth.(map[string]interface{}) + require.True(t, ok, "each author should be an object") + require.NotEmpty(t, author["id"]) + require.NotEmpty(t, author["name"]) + require.NotEmpty(t, author["skills"]) + } + }, + }, + { + name: "Should handle BlogPost creation with complex input lists and nested complex input lists", + query: `mutation($input: BlogPostInput!) { + createBlogPost(input: $input) { + id + title + content + tags + optionalTags + categories + keywords + viewCounts + ratings + isPublished + tagGroups + relatedTopics + commentThreads + suggestions + relatedCategories { + id + name + kind + } + contributors { + id + name + } + categoryGroups { + id + name + kind + } + } + }`, + vars: `{"variables":{"input":{"title":"Complex Lists Blog Post","content":"Testing complex input lists","tags":["graphql","grpc","lists"],"optionalTags":["optional1","optional2"],"categories":["Technology","Programming"],"keywords":["nested","complex","types"],"viewCounts":[150,250,350],"ratings":[4.2,4.8,3.9],"isPublished":[true,false,true],"tagGroups":[["graphql","schema"],["grpc","protobuf"],["lists","arrays"]],"relatedTopics":[["backend","api"],["frontend","ui"]],"commentThreads":[["Great post!","Thanks for sharing"],["Very helpful","Keep it up"]],"suggestions":[["Add examples"],["More details","Better formatting"]],"relatedCategories":[{"name":"Web Development","kind":"ELECTRONICS"},{"name":"API Design","kind":"OTHER"}],"contributors":[{"name":"Alice Developer"},{"name":"Bob Engineer"}],"categoryGroups":[[{"name":"Backend","kind":"ELECTRONICS"},{"name":"Database","kind":"OTHER"}],[{"name":"Frontend","kind":"ELECTRONICS"}]]}}}`, + validate: func(t *testing.T, data map[string]interface{}) { + createBlogPost, ok := data["createBlogPost"].(map[string]interface{}) + require.True(t, ok, "createBlogPost should be an object") + + // Check basic fields from input + require.NotEmpty(t, createBlogPost["id"]) + require.Equal(t, "Complex Lists Blog Post", createBlogPost["title"]) + require.Equal(t, "Testing complex input lists", createBlogPost["content"]) + + // Check scalar lists from input + tags, ok := createBlogPost["tags"].([]interface{}) + require.True(t, ok, "tags should be an array") + require.Contains(t, tags, "graphql") + require.Contains(t, tags, "grpc") + require.Contains(t, tags, "lists") + + optionalTags, ok := createBlogPost["optionalTags"].([]interface{}) + require.True(t, ok, "optionalTags should be an array") + require.Contains(t, optionalTags, "optional1") + require.Contains(t, optionalTags, "optional2") + + categories, ok := createBlogPost["categories"].([]interface{}) + require.True(t, ok, "categories should be an array") + require.Contains(t, categories, "Technology") + require.Contains(t, categories, "Programming") + + keywords, ok := createBlogPost["keywords"].([]interface{}) + require.True(t, ok, "keywords should be an array") + require.Contains(t, keywords, "nested") + require.Contains(t, keywords, "complex") + require.Contains(t, keywords, "types") + + // Check nested scalar lists from input + tagGroups, ok := createBlogPost["tagGroups"].([]interface{}) + require.True(t, ok, "tagGroups should be an array") + require.Len(t, tagGroups, 3) + + firstTagGroup, ok := tagGroups[0].([]interface{}) + require.True(t, ok, "first tag group should be an array") + require.Contains(t, firstTagGroup, "graphql") + require.Contains(t, firstTagGroup, "schema") + + relatedTopics, ok := createBlogPost["relatedTopics"].([]interface{}) + require.True(t, ok, "relatedTopics should be an array") + require.Len(t, relatedTopics, 2) + + commentThreads, ok := createBlogPost["commentThreads"].([]interface{}) + require.True(t, ok, "commentThreads should be an array") + require.Len(t, commentThreads, 2) + + suggestions, ok := createBlogPost["suggestions"].([]interface{}) + require.True(t, ok, "suggestions should be an array") + require.Len(t, suggestions, 2) + + // Check single complex lists from input - converted from input types to output types + // relatedCategories: [CategoryInput] -> [Category] + relatedCategories, ok := createBlogPost["relatedCategories"].([]interface{}) + require.True(t, ok, "relatedCategories should be an array") + require.Len(t, relatedCategories, 2) + for i, cat := range relatedCategories { + category, ok := cat.(map[string]interface{}) + require.True(t, ok, "each category should be an object") + require.NotEmpty(t, category["id"]) + require.NotEmpty(t, category["name"]) + require.NotEmpty(t, category["kind"]) + switch i { + case 0: + require.Equal(t, "Web Development", category["name"]) + require.Equal(t, "ELECTRONICS", category["kind"]) + case 1: + require.Equal(t, "API Design", category["name"]) + require.Equal(t, "OTHER", category["kind"]) + } + } + + // contributors: [UserInput] -> [User] + contributors, ok := createBlogPost["contributors"].([]interface{}) + require.True(t, ok, "contributors should be an array") + require.Len(t, contributors, 2) + for i, cont := range contributors { + contributor, ok := cont.(map[string]interface{}) + require.True(t, ok, "each contributor should be an object") + require.NotEmpty(t, contributor["id"]) + require.NotEmpty(t, contributor["name"]) + switch i { + case 0: + require.Equal(t, "Alice Developer", contributor["name"]) + case 1: + require.Equal(t, "Bob Engineer", contributor["name"]) + } + } + + // Check nested complex lists from input - converted from input types to output types + // categoryGroups: [[CategoryInput!]] -> [[Category!]] + categoryGroups, ok := createBlogPost["categoryGroups"].([]interface{}) + require.True(t, ok, "categoryGroups should be an array") + require.Len(t, categoryGroups, 2) + + // First group should have 2 categories + firstCategoryGroup, ok := categoryGroups[0].([]interface{}) + require.True(t, ok, "first category group should be an array") + require.Len(t, firstCategoryGroup, 2) + for i, cat := range firstCategoryGroup { + category, ok := cat.(map[string]interface{}) + require.True(t, ok, "each category should be an object") + require.NotEmpty(t, category["id"]) + require.NotEmpty(t, category["name"]) + require.NotEmpty(t, category["kind"]) + switch i { + case 0: + require.Equal(t, "Backend", category["name"]) + require.Equal(t, "ELECTRONICS", category["kind"]) + case 1: + require.Equal(t, "Database", category["name"]) + require.Equal(t, "OTHER", category["kind"]) + } + } + + // Second group should have 1 category + secondCategoryGroup, ok := categoryGroups[1].([]interface{}) + require.True(t, ok, "second category group should be an array") + require.Len(t, secondCategoryGroup, 1) + category, ok := secondCategoryGroup[0].(map[string]interface{}) + require.True(t, ok, "category should be an object") + require.NotEmpty(t, category["id"]) + require.Equal(t, "Frontend", category["name"]) + require.Equal(t, "ELECTRONICS", category["kind"]) + }, + }, + { + name: "Should handle Author with complex lists and nested complex lists", + query: `query { + author { + id + name + email + writtenPosts { + id + title + content + } + favoriteCategories { + id + name + kind + } + relatedAuthors { + id + name + } + productReviews { + id + name + price + } + authorGroups { + id + name + } + categoryPreferences { + id + name + kind + } + projectTeams { + id + name + } + } + }`, + vars: "{}", + validate: func(t *testing.T, data map[string]interface{}) { + author, ok := data["author"].(map[string]interface{}) + require.True(t, ok, "author should be an object") + + // Check basic fields + require.NotEmpty(t, author["id"]) + require.NotEmpty(t, author["name"]) + + // Check single complex lists + // writtenPosts: [BlogPost] - Optional list of blog posts + if writtenPosts := author["writtenPosts"]; writtenPosts != nil { + writtenPostsArr, ok := writtenPosts.([]interface{}) + require.True(t, ok, "writtenPosts should be an array if present") + for _, post := range writtenPostsArr { + if post != nil { // posts can be null + blogPost, ok := post.(map[string]interface{}) + require.True(t, ok, "each blog post should be an object") + require.NotEmpty(t, blogPost["id"]) + require.NotEmpty(t, blogPost["title"]) + require.NotEmpty(t, blogPost["content"]) + } + } + } + + // favoriteCategories: [Category!]! - Required list of required categories + favoriteCategories, ok := author["favoriteCategories"].([]interface{}) + require.True(t, ok, "favoriteCategories should be an array") + require.NotEmpty(t, favoriteCategories, "favoriteCategories should not be empty") + for _, cat := range favoriteCategories { + category, ok := cat.(map[string]interface{}) + require.True(t, ok, "each category should be an object") + require.NotEmpty(t, category["id"]) + require.NotEmpty(t, category["name"]) + require.NotEmpty(t, category["kind"]) + } + + // relatedAuthors: [User] - Optional list of related authors/collaborators + if relatedAuthors := author["relatedAuthors"]; relatedAuthors != nil { + relatedAuthorsArr, ok := relatedAuthors.([]interface{}) + require.True(t, ok, "relatedAuthors should be an array if present") + for _, auth := range relatedAuthorsArr { + if auth != nil { // authors can be null + authorObj, ok := auth.(map[string]interface{}) + require.True(t, ok, "each author should be an object") + require.NotEmpty(t, authorObj["id"]) + require.NotEmpty(t, authorObj["name"]) + } + } + } + + // productReviews: [Product] - Optional list of products they've reviewed + if productReviews := author["productReviews"]; productReviews != nil { + productReviewsArr, ok := productReviews.([]interface{}) + require.True(t, ok, "productReviews should be an array if present") + for _, prod := range productReviewsArr { + if prod != nil { // products can be null + product, ok := prod.(map[string]interface{}) + require.True(t, ok, "each product should be an object") + require.NotEmpty(t, product["id"]) + require.NotEmpty(t, product["name"]) + require.NotEmpty(t, product["price"]) + } + } + } + + // Nested complex lists + // authorGroups: [[User!]] - Optional groups of required authors + if authorGroups := author["authorGroups"]; authorGroups != nil { + authorGroupsArr, ok := authorGroups.([]interface{}) + require.True(t, ok, "authorGroups should be an array if present") + for _, group := range authorGroupsArr { + if group != nil { // groups can be null + groupArr, ok := group.([]interface{}) + require.True(t, ok, "authorGroups items should be arrays") + for _, auth := range groupArr { + authorObj, ok := auth.(map[string]interface{}) + require.True(t, ok, "each author should be an object") + require.NotEmpty(t, authorObj["id"]) + require.NotEmpty(t, authorObj["name"]) + } + } + } + } + + // categoryPreferences: [[Category!]!]! - Required groups of required category preferences + categoryPreferences, ok := author["categoryPreferences"].([]interface{}) + require.True(t, ok, "categoryPreferences should be an array") + require.NotEmpty(t, categoryPreferences, "categoryPreferences should not be empty") + for _, group := range categoryPreferences { + groupArr, ok := group.([]interface{}) + require.True(t, ok, "categoryPreferences items should be arrays") + require.NotEmpty(t, groupArr, "categoryPreferences inner arrays should not be empty") + for _, cat := range groupArr { + category, ok := cat.(map[string]interface{}) + require.True(t, ok, "each category should be an object") + require.NotEmpty(t, category["id"]) + require.NotEmpty(t, category["name"]) + require.NotEmpty(t, category["kind"]) + } + } + + // projectTeams: [[User]] - Optional groups of optional users for projects + if projectTeams := author["projectTeams"]; projectTeams != nil { + projectTeamsArr, ok := projectTeams.([]interface{}) + require.True(t, ok, "projectTeams should be an array if present") + for _, team := range projectTeamsArr { + if team != nil { // teams can be null + teamArr, ok := team.([]interface{}) + require.True(t, ok, "projectTeams items should be arrays") + for _, user := range teamArr { + if user != nil { // users can be null + userObj, ok := user.(map[string]interface{}) + require.True(t, ok, "each user should be an object") + require.NotEmpty(t, userObj["id"]) + require.NotEmpty(t, userObj["name"]) + } + } + } + } + } + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Parse the GraphQL schema + schemaDoc := grpctest.MustGraphQLSchema(t) + + // Parse the GraphQL query + queryDoc, report := astparser.ParseGraphqlDocumentString(tc.query) + if report.HasErrors() { + t.Fatalf("failed to parse query: %s", report.Error()) + } + + compiler, err := NewProtoCompiler(grpctest.MustProtoSchema(t), testMapping()) + if err != nil { + t.Fatalf("failed to compile proto: %v", err) + } + + // Create the datasource + ds, err := NewDataSource(conn, DataSourceConfig{ + Operation: &queryDoc, + Definition: &schemaDoc, + SubgraphName: "Products", + Mapping: testMapping(), + Compiler: compiler, + }) + require.NoError(t, err) + + // Execute the query through our datasource + output := new(bytes.Buffer) + input := fmt.Sprintf(`{"query":%q,"body":%s}`, tc.query, tc.vars) + err = ds.Load(context.Background(), []byte(input), output) + require.NoError(t, err) + + // Parse the response + var resp struct { + Data map[string]interface{} `json:"data"` + Errors []struct { + Message string `json:"message"` + } `json:"errors,omitempty"` + } + + err = json.Unmarshal(output.Bytes(), &resp) + require.NoError(t, err, "Failed to unmarshal response") + require.Empty(t, resp.Errors, "Response should not contain errors") + require.NotEmpty(t, resp.Data, "Response should contain data") + + // Run the validation function + tc.validate(t, resp.Data) + }) + } +} diff --git a/v2/pkg/engine/datasource/grpc_datasource/mapping_test_helper.go b/v2/pkg/engine/datasource/grpc_datasource/mapping_test_helper.go index 8149103b12..8f65a97a11 100644 --- a/v2/pkg/engine/datasource/grpc_datasource/mapping_test_helper.go +++ b/v2/pkg/engine/datasource/grpc_datasource/mapping_test_helper.go @@ -104,6 +104,46 @@ func testMapping() *GRPCMapping { Request: "QueryAllNullableFieldsTypesRequest", Response: "QueryAllNullableFieldsTypesResponse", }, + "blogPost": { + RPC: "QueryBlogPost", + Request: "QueryBlogPostRequest", + Response: "QueryBlogPostResponse", + }, + "blogPostById": { + RPC: "QueryBlogPostById", + Request: "QueryBlogPostByIdRequest", + Response: "QueryBlogPostByIdResponse", + }, + "blogPostsWithFilter": { + RPC: "QueryBlogPostsWithFilter", + Request: "QueryBlogPostsWithFilterRequest", + Response: "QueryBlogPostsWithFilterResponse", + }, + "allBlogPosts": { + RPC: "QueryAllBlogPosts", + Request: "QueryAllBlogPostsRequest", + Response: "QueryAllBlogPostsResponse", + }, + "author": { + RPC: "QueryAuthor", + Request: "QueryAuthorRequest", + Response: "QueryAuthorResponse", + }, + "authorById": { + RPC: "QueryAuthorById", + Request: "QueryAuthorByIdRequest", + Response: "QueryAuthorByIdResponse", + }, + "authorsWithFilter": { + RPC: "QueryAuthorsWithFilter", + Request: "QueryAuthorsWithFilterRequest", + Response: "QueryAuthorsWithFilterResponse", + }, + "allAuthors": { + RPC: "QueryAllAuthors", + Request: "QueryAllAuthorsRequest", + Response: "QueryAllAuthorsResponse", + }, }, MutationRPCs: RPCConfigMap{ "createUser": { @@ -126,6 +166,26 @@ func testMapping() *GRPCMapping { Request: "MutationUpdateNullableFieldsTypeRequest", Response: "MutationUpdateNullableFieldsTypeResponse", }, + "createBlogPost": { + RPC: "MutationCreateBlogPost", + Request: "MutationCreateBlogPostRequest", + Response: "MutationCreateBlogPostResponse", + }, + "updateBlogPost": { + RPC: "MutationUpdateBlogPost", + Request: "MutationUpdateBlogPostRequest", + Response: "MutationUpdateBlogPostResponse", + }, + "createAuthor": { + RPC: "MutationCreateAuthor", + Request: "MutationCreateAuthorRequest", + Response: "MutationCreateAuthorResponse", + }, + "updateAuthor": { + RPC: "MutationUpdateAuthor", + Request: "MutationUpdateAuthorRequest", + Response: "MutationUpdateAuthorResponse", + }, }, SubscriptionRPCs: RPCConfigMap{}, EntityRPCs: map[string]EntityRPCConfig{ @@ -247,6 +307,42 @@ func testMapping() *GRPCMapping { "allNullableFieldsTypes": { TargetName: "all_nullable_fields_types", }, + "blogPost": { + TargetName: "blog_post", + }, + "blogPostById": { + TargetName: "blog_post_by_id", + ArgumentMappings: map[string]string{ + "id": "id", + }, + }, + "blogPostsWithFilter": { + TargetName: "blog_posts_with_filter", + ArgumentMappings: map[string]string{ + "filter": "filter", + }, + }, + "allBlogPosts": { + TargetName: "all_blog_posts", + }, + "author": { + TargetName: "author", + }, + "authorById": { + TargetName: "author_by_id", + ArgumentMappings: map[string]string{ + "id": "id", + }, + }, + "authorsWithFilter": { + TargetName: "authors_with_filter", + ArgumentMappings: map[string]string{ + "filter": "filter", + }, + }, + "allAuthors": { + TargetName: "all_authors", + }, }, "Mutation": { "createUser": { @@ -274,6 +370,32 @@ func testMapping() *GRPCMapping { "input": "input", }, }, + "createBlogPost": { + TargetName: "create_blog_post", + ArgumentMappings: map[string]string{ + "input": "input", + }, + }, + "updateBlogPost": { + TargetName: "update_blog_post", + ArgumentMappings: map[string]string{ + "id": "id", + "input": "input", + }, + }, + "createAuthor": { + TargetName: "create_author", + ArgumentMappings: map[string]string{ + "input": "input", + }, + }, + "updateAuthor": { + TargetName: "update_author", + ArgumentMappings: map[string]string{ + "id": "id", + "input": "input", + }, + }, }, "UserInput": { "name": { @@ -534,6 +656,19 @@ func testMapping() *GRPCMapping { TargetName: "payload", }, }, + "SearchResult": { + "product": { + TargetName: "product", + }, + }, + "ActionResult": { + "actionSuccess": { + TargetName: "action_success", + }, + "actionError": { + TargetName: "action_error", + }, + }, "NullableFieldsType": { "id": { TargetName: "id", @@ -594,6 +729,219 @@ func testMapping() *GRPCMapping { TargetName: "include_nulls", }, }, + "BlogPost": { + "id": { + TargetName: "id", + }, + "title": { + TargetName: "title", + }, + "content": { + TargetName: "content", + }, + "tags": { + TargetName: "tags", + }, + "optionalTags": { + TargetName: "optional_tags", + }, + "categories": { + TargetName: "categories", + }, + "keywords": { + TargetName: "keywords", + }, + "viewCounts": { + TargetName: "view_counts", + }, + "ratings": { + TargetName: "ratings", + }, + "isPublished": { + TargetName: "is_published", + }, + "tagGroups": { + TargetName: "tag_groups", + }, + "relatedTopics": { + TargetName: "related_topics", + }, + "commentThreads": { + TargetName: "comment_threads", + }, + "suggestions": { + TargetName: "suggestions", + }, + "relatedCategories": { + TargetName: "related_categories", + }, + "contributors": { + TargetName: "contributors", + }, + "mentionedProducts": { + TargetName: "mentioned_products", + }, + "mentionedUsers": { + TargetName: "mentioned_users", + }, + "categoryGroups": { + TargetName: "category_groups", + }, + "contributorTeams": { + TargetName: "contributor_teams", + }, + }, + "Author": { + "id": { + TargetName: "id", + }, + "name": { + TargetName: "name", + }, + "email": { + TargetName: "email", + }, + "skills": { + TargetName: "skills", + }, + "languages": { + TargetName: "languages", + }, + "socialLinks": { + TargetName: "social_links", + }, + "teamsByProject": { + TargetName: "teams_by_project", + }, + "collaborations": { + TargetName: "collaborations", + }, + "writtenPosts": { + TargetName: "written_posts", + }, + "favoriteCategories": { + TargetName: "favorite_categories", + }, + "relatedAuthors": { + TargetName: "related_authors", + }, + "productReviews": { + TargetName: "product_reviews", + }, + "authorGroups": { + TargetName: "author_groups", + }, + "categoryPreferences": { + TargetName: "category_preferences", + }, + "projectTeams": { + TargetName: "project_teams", + }, + }, + "BlogPostInput": { + "title": { + TargetName: "title", + }, + "content": { + TargetName: "content", + }, + "tags": { + TargetName: "tags", + }, + "optionalTags": { + TargetName: "optional_tags", + }, + "categories": { + TargetName: "categories", + }, + "keywords": { + TargetName: "keywords", + }, + "viewCounts": { + TargetName: "view_counts", + }, + "ratings": { + TargetName: "ratings", + }, + "isPublished": { + TargetName: "is_published", + }, + "tagGroups": { + TargetName: "tag_groups", + }, + "relatedTopics": { + TargetName: "related_topics", + }, + "commentThreads": { + TargetName: "comment_threads", + }, + "suggestions": { + TargetName: "suggestions", + }, + "relatedCategories": { + TargetName: "related_categories", + }, + "contributors": { + TargetName: "contributors", + }, + "categoryGroups": { + TargetName: "category_groups", + }, + }, + "AuthorInput": { + "name": { + TargetName: "name", + }, + "email": { + TargetName: "email", + }, + "skills": { + TargetName: "skills", + }, + "languages": { + TargetName: "languages", + }, + "socialLinks": { + TargetName: "social_links", + }, + "teamsByProject": { + TargetName: "teams_by_project", + }, + "collaborations": { + TargetName: "collaborations", + }, + "favoriteCategories": { + TargetName: "favorite_categories", + }, + "authorGroups": { + TargetName: "author_groups", + }, + "projectTeams": { + TargetName: "project_teams", + }, + }, + "BlogPostFilter": { + "title": { + TargetName: "title", + }, + "hasCategories": { + TargetName: "has_categories", + }, + "minTags": { + TargetName: "min_tags", + }, + }, + "AuthorFilter": { + "name": { + TargetName: "name", + }, + "hasTeams": { + TargetName: "has_teams", + }, + "skillCount": { + TargetName: "skill_count", + }, + }, }, } } diff --git a/v2/pkg/grpctest/Makefile b/v2/pkg/grpctest/Makefile index 6a73e4a8d1..847d67b725 100644 --- a/v2/pkg/grpctest/Makefile +++ b/v2/pkg/grpctest/Makefile @@ -3,12 +3,16 @@ install-protoc: go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest -PHONY: generate-proto +.PHONY: generate-proto generate-proto: install-protoc protoc --go_out=productv1 --go_opt=paths=source_relative \ --go-grpc_out=productv1 --go-grpc_opt=paths=source_relative \ product.proto +.PHONY: build-plugin build-plugin: go build -o plugin/plugin_service plugin/plugin_service.go +.PHONY: regenerate-proto +regenerate-proto: + pnpx wgc@latest grpc-service generate -i testdata/products.graphqls -o testdata/ -p productv1 -g "cosmo/pkg/proto/productv1;productv1" Product diff --git a/v2/pkg/grpctest/mapping/mapping.go b/v2/pkg/grpctest/mapping/mapping.go index fe22e10538..d9f563780d 100644 --- a/v2/pkg/grpctest/mapping/mapping.go +++ b/v2/pkg/grpctest/mapping/mapping.go @@ -9,7 +9,7 @@ import ( // DefaultGRPCMapping returns a hardcoded default mapping between GraphQL and Protobuf func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { return &grpcdatasource.GRPCMapping{ - Service: "ProductService", + Service: "Products", QueryRPCs: map[string]grpcdatasource.RPCConfig{ "users": { RPC: "QueryUsers", @@ -111,6 +111,46 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { Request: "QueryAllNullableFieldsTypesRequest", Response: "QueryAllNullableFieldsTypesResponse", }, + "blogPost": { + RPC: "QueryBlogPost", + Request: "QueryBlogPostRequest", + Response: "QueryBlogPostResponse", + }, + "blogPostById": { + RPC: "QueryBlogPostById", + Request: "QueryBlogPostByIdRequest", + Response: "QueryBlogPostByIdResponse", + }, + "blogPostsWithFilter": { + RPC: "QueryBlogPostsWithFilter", + Request: "QueryBlogPostsWithFilterRequest", + Response: "QueryBlogPostsWithFilterResponse", + }, + "allBlogPosts": { + RPC: "QueryAllBlogPosts", + Request: "QueryAllBlogPostsRequest", + Response: "QueryAllBlogPostsResponse", + }, + "author": { + RPC: "QueryAuthor", + Request: "QueryAuthorRequest", + Response: "QueryAuthorResponse", + }, + "authorById": { + RPC: "QueryAuthorById", + Request: "QueryAuthorByIdRequest", + Response: "QueryAuthorByIdResponse", + }, + "authorsWithFilter": { + RPC: "QueryAuthorsWithFilter", + Request: "QueryAuthorsWithFilterRequest", + Response: "QueryAuthorsWithFilterResponse", + }, + "allAuthors": { + RPC: "QueryAllAuthors", + Request: "QueryAllAuthorsRequest", + Response: "QueryAllAuthorsResponse", + }, }, MutationRPCs: grpcdatasource.RPCConfigMap{ "createUser": { @@ -133,6 +173,26 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { Request: "MutationUpdateNullableFieldsTypeRequest", Response: "MutationUpdateNullableFieldsTypeResponse", }, + "createBlogPost": { + RPC: "MutationCreateBlogPost", + Request: "MutationCreateBlogPostRequest", + Response: "MutationCreateBlogPostResponse", + }, + "updateBlogPost": { + RPC: "MutationUpdateBlogPost", + Request: "MutationUpdateBlogPostRequest", + Response: "MutationUpdateBlogPostResponse", + }, + "createAuthor": { + RPC: "MutationCreateAuthor", + Request: "MutationCreateAuthorRequest", + Response: "MutationCreateAuthorResponse", + }, + "updateAuthor": { + RPC: "MutationUpdateAuthor", + Request: "MutationUpdateAuthorRequest", + Response: "MutationUpdateAuthorResponse", + }, }, SubscriptionRPCs: grpcdatasource.RPCConfigMap{}, EntityRPCs: map[string]grpcdatasource.EntityRPCConfig{ @@ -254,6 +314,42 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { "allNullableFieldsTypes": { TargetName: "all_nullable_fields_types", }, + "blogPost": { + TargetName: "blog_post", + }, + "blogPostById": { + TargetName: "blog_post_by_id", + ArgumentMappings: map[string]string{ + "id": "id", + }, + }, + "blogPostsWithFilter": { + TargetName: "blog_posts_with_filter", + ArgumentMappings: map[string]string{ + "filter": "filter", + }, + }, + "allBlogPosts": { + TargetName: "all_blog_posts", + }, + "author": { + TargetName: "author", + }, + "authorById": { + TargetName: "author_by_id", + ArgumentMappings: map[string]string{ + "id": "id", + }, + }, + "authorsWithFilter": { + TargetName: "authors_with_filter", + ArgumentMappings: map[string]string{ + "filter": "filter", + }, + }, + "allAuthors": { + TargetName: "all_authors", + }, }, "Mutation": { "createUser": { @@ -281,6 +377,32 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { "input": "input", }, }, + "createBlogPost": { + TargetName: "create_blog_post", + ArgumentMappings: map[string]string{ + "input": "input", + }, + }, + "updateBlogPost": { + TargetName: "update_blog_post", + ArgumentMappings: map[string]string{ + "id": "id", + "input": "input", + }, + }, + "createAuthor": { + TargetName: "create_author", + ArgumentMappings: map[string]string{ + "input": "input", + }, + }, + "updateAuthor": { + TargetName: "update_author", + ArgumentMappings: map[string]string{ + "id": "id", + "input": "input", + }, + }, }, "UserInput": { "name": { @@ -614,6 +736,219 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping { TargetName: "include_nulls", }, }, + "BlogPost": { + "id": { + TargetName: "id", + }, + "title": { + TargetName: "title", + }, + "content": { + TargetName: "content", + }, + "tags": { + TargetName: "tags", + }, + "optionalTags": { + TargetName: "optional_tags", + }, + "categories": { + TargetName: "categories", + }, + "keywords": { + TargetName: "keywords", + }, + "viewCounts": { + TargetName: "view_counts", + }, + "ratings": { + TargetName: "ratings", + }, + "isPublished": { + TargetName: "is_published", + }, + "tagGroups": { + TargetName: "tag_groups", + }, + "relatedTopics": { + TargetName: "related_topics", + }, + "commentThreads": { + TargetName: "comment_threads", + }, + "suggestions": { + TargetName: "suggestions", + }, + "relatedCategories": { + TargetName: "related_categories", + }, + "contributors": { + TargetName: "contributors", + }, + "mentionedProducts": { + TargetName: "mentioned_products", + }, + "mentionedUsers": { + TargetName: "mentioned_users", + }, + "categoryGroups": { + TargetName: "category_groups", + }, + "contributorTeams": { + TargetName: "contributor_teams", + }, + }, + "Author": { + "id": { + TargetName: "id", + }, + "name": { + TargetName: "name", + }, + "email": { + TargetName: "email", + }, + "skills": { + TargetName: "skills", + }, + "languages": { + TargetName: "languages", + }, + "socialLinks": { + TargetName: "social_links", + }, + "teamsByProject": { + TargetName: "teams_by_project", + }, + "collaborations": { + TargetName: "collaborations", + }, + "writtenPosts": { + TargetName: "written_posts", + }, + "favoriteCategories": { + TargetName: "favorite_categories", + }, + "relatedAuthors": { + TargetName: "related_authors", + }, + "productReviews": { + TargetName: "product_reviews", + }, + "authorGroups": { + TargetName: "author_groups", + }, + "categoryPreferences": { + TargetName: "category_preferences", + }, + "projectTeams": { + TargetName: "project_teams", + }, + }, + "BlogPostInput": { + "title": { + TargetName: "title", + }, + "content": { + TargetName: "content", + }, + "tags": { + TargetName: "tags", + }, + "optionalTags": { + TargetName: "optional_tags", + }, + "categories": { + TargetName: "categories", + }, + "keywords": { + TargetName: "keywords", + }, + "viewCounts": { + TargetName: "view_counts", + }, + "ratings": { + TargetName: "ratings", + }, + "isPublished": { + TargetName: "is_published", + }, + "tagGroups": { + TargetName: "tag_groups", + }, + "relatedTopics": { + TargetName: "related_topics", + }, + "commentThreads": { + TargetName: "comment_threads", + }, + "suggestions": { + TargetName: "suggestions", + }, + "relatedCategories": { + TargetName: "related_categories", + }, + "contributors": { + TargetName: "contributors", + }, + "categoryGroups": { + TargetName: "category_groups", + }, + }, + "AuthorInput": { + "name": { + TargetName: "name", + }, + "email": { + TargetName: "email", + }, + "skills": { + TargetName: "skills", + }, + "languages": { + TargetName: "languages", + }, + "socialLinks": { + TargetName: "social_links", + }, + "teamsByProject": { + TargetName: "teams_by_project", + }, + "collaborations": { + TargetName: "collaborations", + }, + "favoriteCategories": { + TargetName: "favorite_categories", + }, + "authorGroups": { + TargetName: "author_groups", + }, + "projectTeams": { + TargetName: "project_teams", + }, + }, + "BlogPostFilter": { + "title": { + TargetName: "title", + }, + "hasCategories": { + TargetName: "has_categories", + }, + "minTags": { + TargetName: "min_tags", + }, + }, + "AuthorFilter": { + "name": { + TargetName: "name", + }, + "hasTeams": { + TargetName: "has_teams", + }, + "skillCount": { + TargetName: "skill_count", + }, + }, }, } } diff --git a/v2/pkg/grpctest/mockservice.go b/v2/pkg/grpctest/mockservice.go index dd5fc40caa..54f4283f4a 100644 --- a/v2/pkg/grpctest/mockservice.go +++ b/v2/pkg/grpctest/mockservice.go @@ -3,6 +3,7 @@ package grpctest import ( context "context" "fmt" + "math" "math/rand" "strconv" @@ -18,6 +19,116 @@ type MockService struct { productv1.UnimplementedProductServiceServer } +// Helper functions to convert input types to output types +func convertCategoryInputsToCategories(inputs []*productv1.CategoryInput) []*productv1.Category { + if inputs == nil { + return nil + } + results := make([]*productv1.Category, len(inputs)) + for i, input := range inputs { + results[i] = &productv1.Category{ + Id: fmt.Sprintf("cat-input-%d", i), + Name: input.GetName(), + Kind: input.GetKind(), + } + } + return results +} + +func convertCategoryInputListToCategories(inputs *productv1.ListOfCategoryInput) []*productv1.Category { + if inputs == nil || inputs.List == nil || inputs.List.Items == nil { + return nil + } + results := make([]*productv1.Category, len(inputs.List.Items)) + for i, input := range inputs.List.Items { + results[i] = &productv1.Category{ + Id: fmt.Sprintf("cat-list-input-%d", i), + Name: input.GetName(), + Kind: input.GetKind(), + } + } + return results +} + +func convertUserInputsToUsers(inputs *productv1.ListOfUserInput) []*productv1.User { + if inputs == nil || inputs.List == nil || inputs.List.Items == nil { + return nil + } + results := make([]*productv1.User, len(inputs.List.Items)) + for i, input := range inputs.List.Items { + results[i] = &productv1.User{ + Id: fmt.Sprintf("user-input-%d", i), + Name: input.GetName(), + } + } + return results +} + +func convertNestedUserInputsToUsers(nestedInputs *productv1.ListOfListOfUserInput) *productv1.ListOfListOfUser { + if nestedInputs == nil || nestedInputs.List == nil { + return &productv1.ListOfListOfUser{ + List: &productv1.ListOfListOfUser_List{ + Items: []*productv1.ListOfUser{}, + }, + } + } + + results := make([]*productv1.ListOfUser, len(nestedInputs.List.Items)) + for i, userList := range nestedInputs.List.Items { + users := make([]*productv1.User, len(userList.List.Items)) + for j, userInput := range userList.List.Items { + users[j] = &productv1.User{ + Id: fmt.Sprintf("nested-user-%d-%d", i, j), + Name: userInput.GetName(), + } + } + results[i] = &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: users, + }, + } + } + + return &productv1.ListOfListOfUser{ + List: &productv1.ListOfListOfUser_List{ + Items: results, + }, + } +} + +func convertNestedCategoryInputsToCategories(nestedInputs *productv1.ListOfListOfCategoryInput) *productv1.ListOfListOfCategory { + if nestedInputs == nil || nestedInputs.List == nil { + return &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{}, + }, + } + } + + results := make([]*productv1.ListOfCategory, len(nestedInputs.List.Items)) + for i, categoryList := range nestedInputs.List.Items { + categories := make([]*productv1.Category, len(categoryList.List.Items)) + for j, categoryInput := range categoryList.List.Items { + categories[j] = &productv1.Category{ + Id: fmt.Sprintf("nested-cat-%d-%d", i, j), + Name: categoryInput.GetName(), + Kind: categoryInput.GetKind(), + } + } + results[i] = &productv1.ListOfCategory{ + List: &productv1.ListOfCategory_List{ + Items: categories, + }, + } + } + + return &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: results, + }, + } +} + // MutationCreateNullableFieldsType implements productv1.ProductServiceServer. func (s *MockService) MutationCreateNullableFieldsType(ctx context.Context, in *productv1.MutationCreateNullableFieldsTypeRequest) (*productv1.MutationCreateNullableFieldsTypeResponse, error) { input := in.GetInput() @@ -38,7 +149,7 @@ func (s *MockService) MutationCreateNullableFieldsType(ctx context.Context, in * result.OptionalInt = &wrapperspb.Int32Value{Value: input.OptionalInt.GetValue()} } if input.OptionalFloat != nil { - result.OptionalFloat = &wrapperspb.FloatValue{Value: input.OptionalFloat.GetValue()} + result.OptionalFloat = &wrapperspb.DoubleValue{Value: input.OptionalFloat.GetValue()} } if input.OptionalBoolean != nil { result.OptionalBoolean = &wrapperspb.BoolValue{Value: input.OptionalBoolean.GetValue()} @@ -77,7 +188,7 @@ func (s *MockService) MutationUpdateNullableFieldsType(ctx context.Context, in * result.OptionalInt = &wrapperspb.Int32Value{Value: input.OptionalInt.GetValue()} } if input.OptionalFloat != nil { - result.OptionalFloat = &wrapperspb.FloatValue{Value: input.OptionalFloat.GetValue()} + result.OptionalFloat = &wrapperspb.DoubleValue{Value: input.OptionalFloat.GetValue()} } if input.OptionalBoolean != nil { result.OptionalBoolean = &wrapperspb.BoolValue{Value: input.OptionalBoolean.GetValue()} @@ -100,7 +211,7 @@ func (s *MockService) QueryAllNullableFieldsTypes(ctx context.Context, in *produ Name: "Full Data Entry", OptionalString: &wrapperspb.StringValue{Value: "Optional String Value"}, OptionalInt: &wrapperspb.Int32Value{Value: 42}, - OptionalFloat: &wrapperspb.FloatValue{Value: 3.14}, + OptionalFloat: &wrapperspb.DoubleValue{Value: math.MaxFloat64}, OptionalBoolean: &wrapperspb.BoolValue{Value: true}, RequiredString: "Required String 1", RequiredInt: 100, @@ -175,7 +286,7 @@ func (s *MockService) QueryNullableFieldsTypeById(ctx context.Context, in *produ Name: "Full Data by ID", OptionalString: &wrapperspb.StringValue{Value: "All fields populated"}, OptionalInt: &wrapperspb.Int32Value{Value: 123}, - OptionalFloat: &wrapperspb.FloatValue{Value: 12.34}, + OptionalFloat: &wrapperspb.DoubleValue{Value: 12.34}, OptionalBoolean: &wrapperspb.BoolValue{Value: false}, RequiredString: "Required by ID", RequiredInt: 456, @@ -209,7 +320,7 @@ func (s *MockService) QueryNullableFieldsTypeById(ctx context.Context, in *produ Name: fmt.Sprintf("Nullable Type %s", id), OptionalString: &wrapperspb.StringValue{Value: fmt.Sprintf("Optional for %s", id)}, OptionalInt: &wrapperspb.Int32Value{Value: int32(len(id) * 10)}, - OptionalFloat: &wrapperspb.FloatValue{Value: float32(len(id)) * 1.5}, + OptionalFloat: &wrapperspb.DoubleValue{Value: float64(len(id)) * 1.5}, OptionalBoolean: &wrapperspb.BoolValue{Value: len(id)%2 == 0}, RequiredString: fmt.Sprintf("Required for %s", id), RequiredInt: int32(len(id) * 100), @@ -253,7 +364,7 @@ func (s *MockService) QueryNullableFieldsTypeWithFilter(ctx context.Context, in for i := 1; i <= 3; i++ { var optionalString *wrapperspb.StringValue var optionalInt *wrapperspb.Int32Value - var optionalFloat *wrapperspb.FloatValue + var optionalFloat *wrapperspb.DoubleValue var optionalBoolean *wrapperspb.BoolValue // Vary the nullable fields based on includeNulls and index @@ -270,7 +381,7 @@ func (s *MockService) QueryNullableFieldsTypeWithFilter(ctx context.Context, in } if includeNulls || i%2 == 0 { - optionalFloat = &wrapperspb.FloatValue{Value: float32(i) * 10.5} + optionalFloat = &wrapperspb.DoubleValue{Value: float64(i) * 10.5} } if includeNulls || i%4 != 0 { @@ -397,14 +508,14 @@ func (s *MockService) QuerySearch(ctx context.Context, in *productv1.QuerySearch limit := input.GetLimit() // Default limit if not specified - if limit <= 0 { - limit = 10 + if limit.GetValue() <= 0 { + limit = &wrapperspb.Int32Value{Value: 10} } var results []*productv1.SearchResult // Generate a mix of different union types based on the query - for i := int32(0); i < limit && i < 6; i++ { // Cap at 6 results for testing + for i := int32(0); i < limit.GetValue() && i < 6; i++ { // Cap at 6 results for testing switch i % 3 { case 0: // Add a Product @@ -850,7 +961,11 @@ func (s *MockService) QueryCalculateTotals(ctx context.Context, in *productv1.Qu OrderId: orderInput.GetOrderId(), CustomerName: orderInput.GetCustomerName(), TotalItems: totalItems, - OrderLines: orderLines, + OrderLines: &productv1.ListOfOrderLine{ + List: &productv1.ListOfOrderLine_List{ + Items: orderLines, + }, + }, }) } @@ -858,3 +973,1228 @@ func (s *MockService) QueryCalculateTotals(ctx context.Context, in *productv1.Qu CalculateTotals: calculatedOrders, }, nil } + +// BlogPost query implementations +func (s *MockService) QueryBlogPost(ctx context.Context, in *productv1.QueryBlogPostRequest) (*productv1.QueryBlogPostResponse, error) { + // Return a default blog post with comprehensive list examples + result := &productv1.BlogPost{ + Id: "blog-default", + Title: "Default Blog Post", + Content: "This is a sample blog post content for testing nested lists.", + Tags: []string{"tech", "programming", "go"}, + OptionalTags: &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{"optional1", "optional2"}, + }, + }, + Categories: []string{"Technology", "", "Programming"}, // includes null/empty + Keywords: &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{"keyword1", "keyword2"}, + }, + }, + ViewCounts: []int32{100, 150, 200, 250}, + Ratings: &productv1.ListOfFloat{ + List: &productv1.ListOfFloat_List{ + Items: []float64{4.5, 3.8, 5.0}, + }, + }, + IsPublished: &productv1.ListOfBoolean{ + List: &productv1.ListOfBoolean_List{ + Items: []bool{false, true, true}, + }, + }, + TagGroups: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{"tech", "programming"}, + }}, + {List: &productv1.ListOfString_List{ + Items: []string{"golang", "backend"}, + }}, + }, + }, + }, + RelatedTopics: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"microservices", "api"}}}, + {List: &productv1.ListOfString_List{Items: []string{"databases", "performance"}}}, + }, + }, + }, + CommentThreads: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"Great post!", "Very helpful"}}}, + {List: &productv1.ListOfString_List{Items: []string{"Could use more examples", "Thanks for sharing"}}}, + }, + }, + }, + Suggestions: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"Add code examples", "Include diagrams"}}}, + }, + }, + }, + RelatedCategories: []*productv1.Category{ + {Id: "cat-1", Name: "Technology", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + {Id: "cat-2", Name: "Programming", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, + }, + Contributors: []*productv1.User{ + {Id: "user-1", Name: "John Doe"}, + {Id: "user-2", Name: "Jane Smith"}, + }, + MentionedProducts: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: "prod-1", Name: "Sample Product", Price: 99.99}, + }, + }, + }, + MentionedUsers: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "user-3", Name: "Bob Johnson"}, + }, + }, + }, + CategoryGroups: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "cat-3", Name: "Web Development", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + {Id: "cat-4", Name: "Backend", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + }, + }}, + }, + }, + }, + ContributorTeams: &productv1.ListOfListOfUser{ + List: &productv1.ListOfListOfUser_List{ + Items: []*productv1.ListOfUser{ + {List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "user-4", Name: "Alice Brown"}, + {Id: "user-5", Name: "Charlie Wilson"}, + }, + }}, + }, + }, + }, + } + + return &productv1.QueryBlogPostResponse{ + BlogPost: result, + }, nil +} + +func (s *MockService) QueryBlogPostById(ctx context.Context, in *productv1.QueryBlogPostByIdRequest) (*productv1.QueryBlogPostByIdResponse, error) { + id := in.GetId() + + // Return null for specific test IDs + if id == "not-found" { + return &productv1.QueryBlogPostByIdResponse{ + BlogPostById: nil, + }, nil + } + + // Create different test data based on ID + var result *productv1.BlogPost + + switch id { + case "simple": + result = &productv1.BlogPost{ + Id: id, + Title: "Simple Post", + Content: "Simple content", + Tags: []string{"simple"}, + Categories: []string{"Basic"}, + ViewCounts: []int32{10}, + // Required nested lists must have data + TagGroups: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"simple"}}}, + }, + }, + }, + RelatedTopics: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"basic"}}}, + }, + }, + }, + CommentThreads: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"Nice post"}}}, + }, + }, + }, + // Required complex lists must have data + RelatedCategories: []*productv1.Category{ + {Id: "cat-simple", Name: "Basic", Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + Contributors: []*productv1.User{ + {Id: "user-simple", Name: "Simple Author"}, + }, + CategoryGroups: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "cat-group-simple", Name: "Simple Category", Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + }}, + }, + }, + }, + } + case "complex": + result = &productv1.BlogPost{ + Id: id, + Title: "Complex Blog Post", + Content: "Complex content with comprehensive lists", + Tags: []string{"complex", "advanced", "detailed"}, + OptionalTags: &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{"deep-dive", "tutorial"}, + }, + }, + Categories: []string{"Advanced", "Tutorial", "Guide"}, + Keywords: &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{"advanced", "complex", "comprehensive"}, + }, + }, + ViewCounts: []int32{500, 600, 750, 800, 950}, + Ratings: &productv1.ListOfFloat{ + List: &productv1.ListOfFloat_List{ + Items: []float64{4.8, 4.9, 4.7, 5.0}, + }, + }, + IsPublished: &productv1.ListOfBoolean{ + List: &productv1.ListOfBoolean_List{ + Items: []bool{false, false, true, true}, + }, + }, + TagGroups: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"advanced", "expert"}}}, + {List: &productv1.ListOfString_List{Items: []string{"tutorial", "guide", "comprehensive"}}}, + {List: &productv1.ListOfString_List{Items: []string{"deep-dive", "detailed"}}}, + }, + }, + }, + RelatedTopics: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"architecture", "patterns", "design"}}}, + {List: &productv1.ListOfString_List{Items: []string{"optimization", "performance", "scaling"}}}, + }, + }, + }, + CommentThreads: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"Excellent deep dive!", "Very thorough"}}}, + {List: &productv1.ListOfString_List{Items: []string{"Could be longer", "More examples please"}}}, + {List: &productv1.ListOfString_List{Items: []string{"Best tutorial I've read", "Thank you!"}}}, + }, + }, + }, + Suggestions: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{Items: []string{"Add video content", "Include interactive examples"}}}, + {List: &productv1.ListOfString_List{Items: []string{"Create follow-up posts", "Add Q&A section"}}}, + }, + }, + }, + // Complex example includes all new complex list fields + RelatedCategories: []*productv1.Category{ + {Id: "cat-complex-1", Name: "Advanced Programming", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + {Id: "cat-complex-2", Name: "Software Architecture", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, + }, + Contributors: []*productv1.User{ + {Id: "user-complex-1", Name: "Expert Author"}, + {Id: "user-complex-2", Name: "Technical Reviewer"}, + }, + MentionedProducts: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: "prod-complex-1", Name: "Advanced IDE", Price: 299.99}, + {Id: "prod-complex-2", Name: "Profiling Tool", Price: 149.99}, + }, + }, + }, + MentionedUsers: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "user-complex-3", Name: "Referenced Expert"}, + }, + }, + }, + CategoryGroups: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "cat-group-1", Name: "System Design", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + {Id: "cat-group-2", Name: "Architecture Patterns", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, + }, + }}, + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "cat-group-3", Name: "Performance", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + }, + }}, + }, + }, + }, + ContributorTeams: &productv1.ListOfListOfUser{ + List: &productv1.ListOfListOfUser_List{ + Items: []*productv1.ListOfUser{ + {List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "team-complex-1", Name: "Senior Engineer A"}, + {Id: "team-complex-2", Name: "Senior Engineer B"}, + }, + }}, + {List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "team-complex-3", Name: "QA Lead"}, + }, + }}, + }, + }, + }, + } + default: + // Generic response for any other ID + result = &productv1.BlogPost{ + Id: id, + Title: fmt.Sprintf("Blog Post %s", id), + Content: fmt.Sprintf("Content for blog post %s", id), + Tags: []string{fmt.Sprintf("tag-%s", id), "general"}, + Categories: []string{"General", fmt.Sprintf("Category-%s", id)}, + ViewCounts: []int32{int32(len(id) * 10), int32(len(id) * 20)}, + // Required nested lists must have data + TagGroups: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("tag-%s", id), "group"}, + }}, + }, + }, + }, + RelatedTopics: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("topic-%s", id)}, + }}, + }, + }, + }, + CommentThreads: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("Comment on %s", id)}, + }}, + }, + }, + }, + // Required complex lists must have data + RelatedCategories: []*productv1.Category{ + {Id: fmt.Sprintf("cat-%s", id), Name: fmt.Sprintf("Category %s", id), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + Contributors: []*productv1.User{ + {Id: fmt.Sprintf("user-%s", id), Name: fmt.Sprintf("Author %s", id)}, + }, + CategoryGroups: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: fmt.Sprintf("cat-group-%s", id), Name: fmt.Sprintf("Group Category %s", id), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + }}, + }, + }, + }, + } + } + + return &productv1.QueryBlogPostByIdResponse{ + BlogPostById: result, + }, nil +} + +func (s *MockService) QueryBlogPostsWithFilter(ctx context.Context, in *productv1.QueryBlogPostsWithFilterRequest) (*productv1.QueryBlogPostsWithFilterResponse, error) { + filter := in.GetFilter() + var results []*productv1.BlogPost + + // If no filter provided, return empty results + if filter == nil { + return &productv1.QueryBlogPostsWithFilterResponse{ + BlogPostsWithFilter: results, + }, nil + } + + titleFilter := "" + if filter.Title != nil { + titleFilter = filter.Title.GetValue() + } + + hasCategories := false + if filter.HasCategories != nil { + hasCategories = filter.HasCategories.GetValue() + } + + minTags := int32(0) + if filter.MinTags != nil { + minTags = filter.MinTags.GetValue() + } + + // Generate filtered results + for i := 1; i <= 3; i++ { + title := fmt.Sprintf("Filtered Post %d", i) + if titleFilter != "" { + title = fmt.Sprintf("%s - Post %d", titleFilter, i) + } + + var tags []string + tagsCount := minTags + int32(i) + for j := int32(0); j < tagsCount; j++ { + tags = append(tags, fmt.Sprintf("tag%d", j+1)) + } + + var categories []string + if hasCategories { + categories = []string{fmt.Sprintf("Category%d", i), "Filtered"} + } + + results = append(results, &productv1.BlogPost{ + Id: fmt.Sprintf("filtered-blog-%d", i), + Title: title, + Content: fmt.Sprintf("Filtered content %d", i), + Tags: tags, + Categories: categories, + ViewCounts: []int32{int32(i * 100)}, + // Required nested lists must have data + TagGroups: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("filtered-tag-%d", i)}, + }}, + }, + }, + }, + RelatedTopics: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("filtered-topic-%d", i)}, + }}, + }, + }, + }, + CommentThreads: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("Filtered comment %d", i)}, + }}, + }, + }, + }, + // Required complex lists must have data + RelatedCategories: []*productv1.Category{ + {Id: fmt.Sprintf("cat-filtered-%d", i), Name: fmt.Sprintf("Filtered Category %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + Contributors: []*productv1.User{ + {Id: fmt.Sprintf("user-filtered-%d", i), Name: fmt.Sprintf("Filtered Author %d", i)}, + }, + CategoryGroups: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: fmt.Sprintf("cat-group-filtered-%d", i), Name: fmt.Sprintf("Filtered Group %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + }}, + }, + }, + }, + }) + } + + return &productv1.QueryBlogPostsWithFilterResponse{ + BlogPostsWithFilter: results, + }, nil +} + +func (s *MockService) QueryAllBlogPosts(ctx context.Context, in *productv1.QueryAllBlogPostsRequest) (*productv1.QueryAllBlogPostsResponse, error) { + var results []*productv1.BlogPost + + // Create a variety of blog posts + for i := 1; i <= 4; i++ { + var optionalTags *productv1.ListOfString + var keywords *productv1.ListOfString + var ratings *productv1.ListOfFloat + + // Vary the optional fields + if i%2 == 1 { + optionalTags = &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("optional%d", i), "common"}, + }, + } + } + + if i%3 == 0 { + keywords = &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("keyword%d", i)}, + }, + } + } + + if i%2 == 0 { + ratings = &productv1.ListOfFloat{ + List: &productv1.ListOfFloat_List{ + Items: []float64{float64(i) + 0.5, float64(i) + 1.0}, + }, + } + } + + results = append(results, &productv1.BlogPost{ + Id: fmt.Sprintf("blog-%d", i), + Title: fmt.Sprintf("Blog Post %d", i), + Content: fmt.Sprintf("Content for blog post %d", i), + Tags: []string{fmt.Sprintf("tag%d", i), "common"}, + OptionalTags: optionalTags, + Categories: []string{fmt.Sprintf("Category%d", i)}, + Keywords: keywords, + ViewCounts: []int32{int32(i * 100), int32(i * 150)}, + Ratings: ratings, + IsPublished: &productv1.ListOfBoolean{ + List: &productv1.ListOfBoolean_List{ + Items: []bool{i%2 == 0, true}, + }, + }, + TagGroups: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("group%d", i), "shared"}, + }}, + }, + }, + }, + RelatedTopics: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("topic%d", i)}, + }}, + }, + }, + }, + CommentThreads: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("Comment for post %d", i)}, + }}, + }, + }, + }, + // Required complex lists must have data + RelatedCategories: []*productv1.Category{ + {Id: fmt.Sprintf("cat-all-%d", i), Name: fmt.Sprintf("Category %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + Contributors: []*productv1.User{ + {Id: fmt.Sprintf("user-all-%d", i), Name: fmt.Sprintf("Author %d", i)}, + }, + CategoryGroups: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: fmt.Sprintf("cat-group-all-%d", i), Name: fmt.Sprintf("Group Category %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + }}, + }, + }, + }, + // Optional list - can be empty + Suggestions: &productv1.ListOfListOfString{}, + }) + } + + return &productv1.QueryAllBlogPostsResponse{ + AllBlogPosts: results, + }, nil +} + +// Author query implementations +func (s *MockService) QueryAuthor(ctx context.Context, in *productv1.QueryAuthorRequest) (*productv1.QueryAuthorResponse, error) { + result := &productv1.Author{ + Id: "author-default", + Name: "Default Author", + Email: &wrapperspb.StringValue{ + Value: "author@example.com", + }, + Skills: []string{"Go", "GraphQL", "Protocol Buffers"}, + Languages: []string{"English", "Spanish", ""}, + SocialLinks: &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{"https://twitter.com/author", "https://linkedin.com/in/author"}, + }, + }, + TeamsByProject: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{"Alice", "Bob", "Charlie"}, + }}, + {List: &productv1.ListOfString_List{ + Items: []string{"David", "Eve"}, + }}, + }, + }, + }, + Collaborations: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{"Open Source Project A", "Research Paper B"}, + }}, + {List: &productv1.ListOfString_List{ + Items: []string{"Conference Talk C"}, + }}, + }, + }, + }, + WrittenPosts: &productv1.ListOfBlogPost{ + List: &productv1.ListOfBlogPost_List{ + Items: []*productv1.BlogPost{ + {Id: "blog-1", Title: "GraphQL Best Practices", Content: "Content here..."}, + {Id: "blog-2", Title: "gRPC vs REST", Content: "Comparison content..."}, + }, + }, + }, + FavoriteCategories: []*productv1.Category{ + {Id: "cat-fav-1", Name: "Software Engineering", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + {Id: "cat-fav-2", Name: "Technical Writing", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, + }, + RelatedAuthors: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "author-rel-1", Name: "Related Author One"}, + {Id: "author-rel-2", Name: "Related Author Two"}, + }, + }, + }, + ProductReviews: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: "prod-rev-1", Name: "Code Editor Pro", Price: 199.99}, + }, + }, + }, + AuthorGroups: &productv1.ListOfListOfUser{ + List: &productv1.ListOfListOfUser_List{ + Items: []*productv1.ListOfUser{ + {List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "group-auth-1", Name: "Team Lead Alpha"}, + {Id: "group-auth-2", Name: "Senior Dev Beta"}, + }, + }}, + {List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "group-auth-3", Name: "Junior Dev Gamma"}, + }, + }}, + }, + }, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "pref-cat-1", Name: "Microservices", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + {Id: "pref-cat-2", Name: "Cloud Computing", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + }, + }}, + }, + }, + }, + } + + return &productv1.QueryAuthorResponse{ + Author: result, + }, nil +} + +func (s *MockService) QueryAuthorById(ctx context.Context, in *productv1.QueryAuthorByIdRequest) (*productv1.QueryAuthorByIdResponse, error) { + id := in.GetId() + + // Return null for specific test IDs + if id == "not-found" { + return &productv1.QueryAuthorByIdResponse{ + AuthorById: nil, + }, nil + } + + var result *productv1.Author + + switch id { + case "minimal": + result = &productv1.Author{ + Id: id, + Name: "Minimal Author", + Skills: []string{"Basic"}, + Languages: []string{"English"}, + TeamsByProject: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{"Solo"}, + }}, + }, + }, + }, + // Required complex lists must have data + FavoriteCategories: []*productv1.Category{ + {Id: "cat-minimal", Name: "Basic Category", Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "cat-pref-minimal", Name: "Minimal Preference", Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + }}, + }, + }, + }, + // Optional list - can be empty + Collaborations: &productv1.ListOfListOfString{}, + } + case "experienced": + result = &productv1.Author{ + Id: id, + Name: "Experienced Author", + Email: &wrapperspb.StringValue{ + Value: "experienced@example.com", + }, + Skills: []string{"Go", "GraphQL", "gRPC", "Microservices", "Kubernetes"}, + Languages: []string{"English", "French", "German"}, + SocialLinks: &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{ + "https://github.com/experienced", + "https://twitter.com/experienced", + "https://medium.com/@experienced", + }, + }, + }, + TeamsByProject: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{"Senior Dev 1", "Senior Dev 2", "Tech Lead"}, + }}, + {List: &productv1.ListOfString_List{ + Items: []string{"Architect", "Principal Engineer"}, + }}, + {List: &productv1.ListOfString_List{ + Items: []string{"PM", "Designer", "QA Lead"}, + }}, + }, + }, + }, + Collaborations: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{"Major OSS Project", "Industry Standard", "Research Initiative"}, + }}, + {List: &productv1.ListOfString_List{ + Items: []string{"Conference Keynote", "Workshop Series"}, + }}, + }, + }, + }, + // Required complex lists must have data + FavoriteCategories: []*productv1.Category{ + {Id: "cat-experienced-1", Name: "Advanced Programming", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + {Id: "cat-experienced-2", Name: "Technical Leadership", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "cat-pref-experienced-1", Name: "System Architecture", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + {Id: "cat-pref-experienced-2", Name: "Team Management", Kind: productv1.CategoryKind_CATEGORY_KIND_BOOK}, + }, + }}, + }, + }, + }, + } + default: + result = &productv1.Author{ + Id: id, + Name: fmt.Sprintf("Author %s", id), + Email: &wrapperspb.StringValue{ + Value: fmt.Sprintf("%s@example.com", id), + }, + Skills: []string{fmt.Sprintf("Skill-%s", id), "General"}, + Languages: []string{"English", fmt.Sprintf("Language-%s", id)}, + TeamsByProject: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("Team-%s", id)}, + }}, + }, + }, + }, + // Required complex lists must have data + FavoriteCategories: []*productv1.Category{ + {Id: fmt.Sprintf("cat-%s", id), Name: fmt.Sprintf("Favorite Category %s", id), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: fmt.Sprintf("cat-pref-%s", id), Name: fmt.Sprintf("Preference %s", id), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + }}, + }, + }, + }, + // Optional list - can be empty + Collaborations: &productv1.ListOfListOfString{}, + } + } + + return &productv1.QueryAuthorByIdResponse{ + AuthorById: result, + }, nil +} + +func (s *MockService) QueryAuthorsWithFilter(ctx context.Context, in *productv1.QueryAuthorsWithFilterRequest) (*productv1.QueryAuthorsWithFilterResponse, error) { + filter := in.GetFilter() + var results []*productv1.Author + + if filter == nil { + return &productv1.QueryAuthorsWithFilterResponse{ + AuthorsWithFilter: results, + }, nil + } + + nameFilter := "" + if filter.Name != nil { + nameFilter = filter.Name.GetValue() + } + + hasTeams := false + if filter.HasTeams != nil { + hasTeams = filter.HasTeams.GetValue() + } + + skillCount := int32(0) + if filter.SkillCount != nil { + skillCount = filter.SkillCount.GetValue() + } + + // Generate filtered results + for i := 1; i <= 3; i++ { + name := fmt.Sprintf("Filtered Author %d", i) + if nameFilter != "" { + name = fmt.Sprintf("%s - Author %d", nameFilter, i) + } + + var skills []string + skillsNeeded := skillCount + int32(i) + for j := int32(0); j < skillsNeeded; j++ { + skills = append(skills, fmt.Sprintf("Skill%d", j+1)) + } + + var teamsByProject *productv1.ListOfListOfString + if hasTeams { + teamsByProject = &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("Team%d", i), "SharedTeam"}, + }}, + }, + }, + } + } else { + teamsByProject = &productv1.ListOfListOfString{} + } + + results = append(results, &productv1.Author{ + Id: fmt.Sprintf("filtered-author-%d", i), + Name: name, + Skills: skills, + Languages: []string{"English", fmt.Sprintf("Lang%d", i)}, + TeamsByProject: teamsByProject, + // Required complex lists must have data + FavoriteCategories: []*productv1.Category{ + {Id: fmt.Sprintf("cat-filtered-%d", i), Name: fmt.Sprintf("Filtered Category %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: fmt.Sprintf("cat-pref-filtered-%d", i), Name: fmt.Sprintf("Filtered Preference %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + }}, + }, + }, + }, + // Optional list - can be empty + Collaborations: &productv1.ListOfListOfString{}, + }) + } + + return &productv1.QueryAuthorsWithFilterResponse{ + AuthorsWithFilter: results, + }, nil +} + +func (s *MockService) QueryAllAuthors(ctx context.Context, in *productv1.QueryAllAuthorsRequest) (*productv1.QueryAllAuthorsResponse, error) { + var results []*productv1.Author + + for i := 1; i <= 3; i++ { + var email *wrapperspb.StringValue + var socialLinks *productv1.ListOfString + var collaborations *productv1.ListOfListOfString + + if i%2 == 1 { + email = &wrapperspb.StringValue{ + Value: fmt.Sprintf("author%d@example.com", i), + } + } + + if i%3 == 0 { + socialLinks = &productv1.ListOfString{ + List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("https://github.com/author%d", i)}, + }, + } + } + + if i == 2 { + collaborations = &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{"Collaboration A", "Collaboration B"}, + }}, + }, + }, + } + } else { + collaborations = &productv1.ListOfListOfString{} + } + + results = append(results, &productv1.Author{ + Id: fmt.Sprintf("author-%d", i), + Name: fmt.Sprintf("Author %d", i), + Email: email, + Skills: []string{fmt.Sprintf("Skill%d", i), "Common"}, + Languages: []string{"English", fmt.Sprintf("Language%d", i)}, + SocialLinks: socialLinks, + TeamsByProject: &productv1.ListOfListOfString{ + List: &productv1.ListOfListOfString_List{ + Items: []*productv1.ListOfString{ + {List: &productv1.ListOfString_List{ + Items: []string{fmt.Sprintf("Team%d", i)}, + }}, + }, + }, + }, + // Required complex lists must have data + FavoriteCategories: []*productv1.Category{ + {Id: fmt.Sprintf("cat-all-%d", i), Name: fmt.Sprintf("All Category %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: fmt.Sprintf("cat-pref-all-%d", i), Name: fmt.Sprintf("All Preference %d", i), Kind: productv1.CategoryKind_CATEGORY_KIND_OTHER}, + }, + }}, + }, + }, + }, + // Optional list - can be empty/variable + Collaborations: collaborations, + }) + } + + return &productv1.QueryAllAuthorsResponse{ + AllAuthors: results, + }, nil +} + +// BlogPost mutation implementations +func (s *MockService) MutationCreateBlogPost(ctx context.Context, in *productv1.MutationCreateBlogPostRequest) (*productv1.MutationCreateBlogPostResponse, error) { + input := in.GetInput() + + result := &productv1.BlogPost{ + Id: fmt.Sprintf("blog-%d", rand.Intn(1000)), + Title: input.GetTitle(), + Content: input.GetContent(), + Tags: input.GetTags(), + OptionalTags: input.GetOptionalTags(), + Categories: input.GetCategories(), + Keywords: input.GetKeywords(), + ViewCounts: input.GetViewCounts(), + Ratings: input.GetRatings(), + IsPublished: input.GetIsPublished(), + TagGroups: input.GetTagGroups(), + RelatedTopics: input.GetRelatedTopics(), + CommentThreads: input.GetCommentThreads(), + Suggestions: input.GetSuggestions(), + // Convert input types to output types + RelatedCategories: convertCategoryInputListToCategories(input.GetRelatedCategories()), + Contributors: convertUserInputsToUsers(input.GetContributors()), + CategoryGroups: convertNestedCategoryInputsToCategories(input.GetCategoryGroups()), + MentionedProducts: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: "prod-1", Name: "Sample Product", Price: 99.99}, + }, + }, + }, + MentionedUsers: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "user-3", Name: "Bob Johnson"}, + }, + }, + }, + ContributorTeams: &productv1.ListOfListOfUser{ + List: &productv1.ListOfListOfUser_List{ + Items: []*productv1.ListOfUser{ + {List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "user-4", Name: "Alice Brown"}, + }, + }}, + }, + }, + }, + } + + return &productv1.MutationCreateBlogPostResponse{ + CreateBlogPost: result, + }, nil +} + +func (s *MockService) MutationUpdateBlogPost(ctx context.Context, in *productv1.MutationUpdateBlogPostRequest) (*productv1.MutationUpdateBlogPostResponse, error) { + id := in.GetId() + input := in.GetInput() + + if id == "non-existent" { + return &productv1.MutationUpdateBlogPostResponse{ + UpdateBlogPost: nil, + }, nil + } + + result := &productv1.BlogPost{ + Id: id, + Title: input.GetTitle(), + Content: input.GetContent(), + Tags: input.GetTags(), + OptionalTags: input.GetOptionalTags(), + Categories: input.GetCategories(), + Keywords: input.GetKeywords(), + ViewCounts: input.GetViewCounts(), + Ratings: input.GetRatings(), + IsPublished: input.GetIsPublished(), + TagGroups: input.GetTagGroups(), + RelatedTopics: input.GetRelatedTopics(), + CommentThreads: input.GetCommentThreads(), + Suggestions: input.GetSuggestions(), + // Convert input types to output types + RelatedCategories: convertCategoryInputListToCategories(input.GetRelatedCategories()), + Contributors: convertUserInputsToUsers(input.GetContributors()), + CategoryGroups: convertNestedCategoryInputsToCategories(input.GetCategoryGroups()), + MentionedProducts: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: "prod-updated", Name: "Updated Product", Price: 149.99}, + }, + }, + }, + MentionedUsers: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "user-updated", Name: "Updated User"}, + }, + }, + }, + ContributorTeams: &productv1.ListOfListOfUser{ + List: &productv1.ListOfListOfUser_List{ + Items: []*productv1.ListOfUser{ + {List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "user-team-updated", Name: "Updated Team Member"}, + }, + }}, + }, + }, + }, + } + + return &productv1.MutationUpdateBlogPostResponse{ + UpdateBlogPost: result, + }, nil +} + +// Author mutation implementations +func (s *MockService) MutationCreateAuthor(ctx context.Context, in *productv1.MutationCreateAuthorRequest) (*productv1.MutationCreateAuthorResponse, error) { + input := in.GetInput() + + result := &productv1.Author{ + Id: fmt.Sprintf("author-%d", rand.Intn(1000)), + Name: input.GetName(), + Email: input.GetEmail(), + Skills: input.GetSkills(), + Languages: input.GetLanguages(), + SocialLinks: input.GetSocialLinks(), + TeamsByProject: input.GetTeamsByProject(), + Collaborations: input.GetCollaborations(), + // Convert input types to output types for complex fields + FavoriteCategories: convertCategoryInputsToCategories(input.GetFavoriteCategories()), + AuthorGroups: convertNestedUserInputsToUsers(input.GetAuthorGroups()), + ProjectTeams: convertNestedUserInputsToUsers(input.GetProjectTeams()), + // Keep other complex fields with mock data since they're not in the simplified input + WrittenPosts: &productv1.ListOfBlogPost{ + List: &productv1.ListOfBlogPost_List{ + Items: []*productv1.BlogPost{ + {Id: "blog-created", Title: "Created Post", Content: "Content..."}, + }, + }, + }, + RelatedAuthors: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "related-author", Name: "Related Author"}, + }, + }, + }, + ProductReviews: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: "reviewed-product", Name: "Code Editor", Price: 199.99}, + }, + }, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "pref-cat", Name: "Backend Development", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + }, + }}, + }, + }, + }, + } + + return &productv1.MutationCreateAuthorResponse{ + CreateAuthor: result, + }, nil +} + +func (s *MockService) MutationUpdateAuthor(ctx context.Context, in *productv1.MutationUpdateAuthorRequest) (*productv1.MutationUpdateAuthorResponse, error) { + id := in.GetId() + input := in.GetInput() + + if id == "non-existent" { + return &productv1.MutationUpdateAuthorResponse{ + UpdateAuthor: nil, + }, nil + } + + result := &productv1.Author{ + Id: id, + Name: input.GetName(), + Email: input.GetEmail(), + Skills: input.GetSkills(), + Languages: input.GetLanguages(), + SocialLinks: input.GetSocialLinks(), + TeamsByProject: input.GetTeamsByProject(), + Collaborations: input.GetCollaborations(), + // Convert input types to output types for complex fields + FavoriteCategories: convertCategoryInputsToCategories(input.GetFavoriteCategories()), + AuthorGroups: convertNestedUserInputsToUsers(input.GetAuthorGroups()), + ProjectTeams: convertNestedUserInputsToUsers(input.GetProjectTeams()), + // Keep other complex fields with mock data since they're not in the simplified input + WrittenPosts: &productv1.ListOfBlogPost{ + List: &productv1.ListOfBlogPost_List{ + Items: []*productv1.BlogPost{ + {Id: "blog-updated", Title: "Updated Post", Content: "Updated content..."}, + }, + }, + }, + RelatedAuthors: &productv1.ListOfUser{ + List: &productv1.ListOfUser_List{ + Items: []*productv1.User{ + {Id: "related-author-updated", Name: "Updated Related Author"}, + }, + }, + }, + ProductReviews: &productv1.ListOfProduct{ + List: &productv1.ListOfProduct_List{ + Items: []*productv1.Product{ + {Id: "reviewed-product-updated", Name: "Updated Code Editor", Price: 249.99}, + }, + }, + }, + CategoryPreferences: &productv1.ListOfListOfCategory{ + List: &productv1.ListOfListOfCategory_List{ + Items: []*productv1.ListOfCategory{ + {List: &productv1.ListOfCategory_List{ + Items: []*productv1.Category{ + {Id: "pref-cat-updated", Name: "Updated Backend Development", Kind: productv1.CategoryKind_CATEGORY_KIND_ELECTRONICS}, + }, + }}, + }, + }, + }, + } + + return &productv1.MutationUpdateAuthorResponse{ + UpdateAuthor: result, + }, nil +} diff --git a/v2/pkg/grpctest/product.proto b/v2/pkg/grpctest/product.proto index 65876625ce..1106e9be0b 100644 --- a/v2/pkg/grpctest/product.proto +++ b/v2/pkg/grpctest/product.proto @@ -1,19 +1,34 @@ syntax = "proto3"; package productv1; -import "google/protobuf/wrappers.proto"; - option go_package = "cosmo/pkg/proto/productv1;productv1"; +import "google/protobuf/wrappers.proto"; + // Service definition for ProductService service ProductService { // Lookup Product entity by id rpc LookupProductById(LookupProductByIdRequest) returns (LookupProductByIdResponse) {} // Lookup Storage entity by id rpc LookupStorageById(LookupStorageByIdRequest) returns (LookupStorageByIdResponse) {} + rpc MutationCreateAuthor(MutationCreateAuthorRequest) returns (MutationCreateAuthorResponse) {} + rpc MutationCreateBlogPost(MutationCreateBlogPostRequest) returns (MutationCreateBlogPostResponse) {} + rpc MutationCreateNullableFieldsType(MutationCreateNullableFieldsTypeRequest) returns (MutationCreateNullableFieldsTypeResponse) {} rpc MutationCreateUser(MutationCreateUserRequest) returns (MutationCreateUserResponse) {} rpc MutationPerformAction(MutationPerformActionRequest) returns (MutationPerformActionResponse) {} + rpc MutationUpdateAuthor(MutationUpdateAuthorRequest) returns (MutationUpdateAuthorResponse) {} + rpc MutationUpdateBlogPost(MutationUpdateBlogPostRequest) returns (MutationUpdateBlogPostResponse) {} + rpc MutationUpdateNullableFieldsType(MutationUpdateNullableFieldsTypeRequest) returns (MutationUpdateNullableFieldsTypeResponse) {} + rpc QueryAllAuthors(QueryAllAuthorsRequest) returns (QueryAllAuthorsResponse) {} + rpc QueryAllBlogPosts(QueryAllBlogPostsRequest) returns (QueryAllBlogPostsResponse) {} + rpc QueryAllNullableFieldsTypes(QueryAllNullableFieldsTypesRequest) returns (QueryAllNullableFieldsTypesResponse) {} rpc QueryAllPets(QueryAllPetsRequest) returns (QueryAllPetsResponse) {} + rpc QueryAuthor(QueryAuthorRequest) returns (QueryAuthorResponse) {} + rpc QueryAuthorById(QueryAuthorByIdRequest) returns (QueryAuthorByIdResponse) {} + rpc QueryAuthorsWithFilter(QueryAuthorsWithFilterRequest) returns (QueryAuthorsWithFilterResponse) {} + rpc QueryBlogPost(QueryBlogPostRequest) returns (QueryBlogPostResponse) {} + rpc QueryBlogPostById(QueryBlogPostByIdRequest) returns (QueryBlogPostByIdResponse) {} + rpc QueryBlogPostsWithFilter(QueryBlogPostsWithFilterRequest) returns (QueryBlogPostsWithFilterResponse) {} rpc QueryCalculateTotals(QueryCalculateTotalsRequest) returns (QueryCalculateTotalsResponse) {} rpc QueryCategories(QueryCategoriesRequest) returns (QueryCategoriesResponse) {} rpc QueryCategoriesByKind(QueryCategoriesByKindRequest) returns (QueryCategoriesByKindResponse) {} @@ -21,6 +36,9 @@ service ProductService { rpc QueryComplexFilterType(QueryComplexFilterTypeRequest) returns (QueryComplexFilterTypeResponse) {} rpc QueryFilterCategories(QueryFilterCategoriesRequest) returns (QueryFilterCategoriesResponse) {} rpc QueryNestedType(QueryNestedTypeRequest) returns (QueryNestedTypeResponse) {} + rpc QueryNullableFieldsType(QueryNullableFieldsTypeRequest) returns (QueryNullableFieldsTypeResponse) {} + rpc QueryNullableFieldsTypeById(QueryNullableFieldsTypeByIdRequest) returns (QueryNullableFieldsTypeByIdResponse) {} + rpc QueryNullableFieldsTypeWithFilter(QueryNullableFieldsTypeWithFilterRequest) returns (QueryNullableFieldsTypeWithFilterResponse) {} rpc QueryRandomPet(QueryRandomPetRequest) returns (QueryRandomPetResponse) {} rpc QueryRandomSearchResult(QueryRandomSearchResultRequest) returns (QueryRandomSearchResultResponse) {} rpc QueryRecursiveType(QueryRecursiveTypeRequest) returns (QueryRecursiveTypeResponse) {} @@ -29,15 +47,113 @@ service ProductService { rpc QueryTypeWithMultipleFilterFields(QueryTypeWithMultipleFilterFieldsRequest) returns (QueryTypeWithMultipleFilterFieldsResponse) {} rpc QueryUser(QueryUserRequest) returns (QueryUserResponse) {} rpc QueryUsers(QueryUsersRequest) returns (QueryUsersResponse) {} - // Nullable fields RPCs - rpc QueryNullableFieldsType(QueryNullableFieldsTypeRequest) returns (QueryNullableFieldsTypeResponse) {} - rpc QueryNullableFieldsTypeById(QueryNullableFieldsTypeByIdRequest) returns (QueryNullableFieldsTypeByIdResponse) {} - rpc QueryNullableFieldsTypeWithFilter(QueryNullableFieldsTypeWithFilterRequest) returns (QueryNullableFieldsTypeWithFilterResponse) {} - rpc QueryAllNullableFieldsTypes(QueryAllNullableFieldsTypesRequest) returns (QueryAllNullableFieldsTypesResponse) {} - rpc MutationCreateNullableFieldsType(MutationCreateNullableFieldsTypeRequest) returns (MutationCreateNullableFieldsTypeResponse) {} - rpc MutationUpdateNullableFieldsType(MutationUpdateNullableFieldsTypeRequest) returns (MutationUpdateNullableFieldsTypeResponse) {} } +// Wrapper message for a list of BlogPost. +message ListOfBlogPost { + message List { + repeated BlogPost items = 1; + } + List list = 1; +} +// Wrapper message for a list of Boolean. +message ListOfBoolean { + message List { + repeated bool items = 1; + } + List list = 1; +} +// Wrapper message for a list of Category. +message ListOfCategory { + message List { + repeated Category items = 1; + } + List list = 1; +} +// Wrapper message for a list of CategoryInput. +message ListOfCategoryInput { + message List { + repeated CategoryInput items = 1; + } + List list = 1; +} +// Wrapper message for a list of Float. +message ListOfFloat { + message List { + repeated double items = 1; + } + List list = 1; +} +// Wrapper message for a list of Category. +message ListOfListOfCategory { + message List { + repeated ListOfCategory items = 1; + } + List list = 1; +} +// Wrapper message for a list of CategoryInput. +message ListOfListOfCategoryInput { + message List { + repeated ListOfCategoryInput items = 1; + } + List list = 1; +} +// Wrapper message for a list of String. +message ListOfListOfString { + message List { + repeated ListOfString items = 1; + } + List list = 1; +} +// Wrapper message for a list of User. +message ListOfListOfUser { + message List { + repeated ListOfUser items = 1; + } + List list = 1; +} +// Wrapper message for a list of UserInput. +message ListOfListOfUserInput { + message List { + repeated ListOfUserInput items = 1; + } + List list = 1; +} +// Wrapper message for a list of OrderLine. +message ListOfOrderLine { + message List { + repeated OrderLine items = 1; + } + List list = 1; +} +// Wrapper message for a list of Product. +message ListOfProduct { + message List { + repeated Product items = 1; + } + List list = 1; +} +// Wrapper message for a list of String. +message ListOfString { + message List { + repeated string items = 1; + } + List list = 1; +} +// Wrapper message for a list of User. +message ListOfUser { + message List { + repeated User items = 1; + } + List list = 1; +} +// Wrapper message for a list of UserInput. +message ListOfUserInput { + message List { + repeated UserInput items = 1; + } + List list = 1; +} // Key message for Product entity lookup message LookupProductByIdRequestKey { // Key field for Product entity lookup. @@ -228,23 +344,6 @@ message QueryRandomSearchResultRequest { message QueryRandomSearchResultResponse { SearchResult random_search_result = 1; } -// Request message for createUser operation. -message MutationCreateUserRequest { - UserInput input = 1; -} -// Response message for createUser operation. -message MutationCreateUserResponse { - User create_user = 1; -} -// Request message for performAction operation. -message MutationPerformActionRequest { - ActionInput input = 1; -} -// Response message for performAction operation. -message MutationPerformActionResponse { - ActionResult perform_action = 1; -} - // Request message for nullableFieldsType operation. message QueryNullableFieldsTypeRequest { } @@ -275,6 +374,82 @@ message QueryAllNullableFieldsTypesRequest { message QueryAllNullableFieldsTypesResponse { repeated NullableFieldsType all_nullable_fields_types = 1; } +// Request message for blogPost operation. +message QueryBlogPostRequest { +} +// Response message for blogPost operation. +message QueryBlogPostResponse { + BlogPost blog_post = 1; +} +// Request message for blogPostById operation. +message QueryBlogPostByIdRequest { + string id = 1; +} +// Response message for blogPostById operation. +message QueryBlogPostByIdResponse { + BlogPost blog_post_by_id = 1; +} +// Request message for blogPostsWithFilter operation. +message QueryBlogPostsWithFilterRequest { + BlogPostFilter filter = 1; +} +// Response message for blogPostsWithFilter operation. +message QueryBlogPostsWithFilterResponse { + repeated BlogPost blog_posts_with_filter = 1; +} +// Request message for allBlogPosts operation. +message QueryAllBlogPostsRequest { +} +// Response message for allBlogPosts operation. +message QueryAllBlogPostsResponse { + repeated BlogPost all_blog_posts = 1; +} +// Request message for author operation. +message QueryAuthorRequest { +} +// Response message for author operation. +message QueryAuthorResponse { + Author author = 1; +} +// Request message for authorById operation. +message QueryAuthorByIdRequest { + string id = 1; +} +// Response message for authorById operation. +message QueryAuthorByIdResponse { + Author author_by_id = 1; +} +// Request message for authorsWithFilter operation. +message QueryAuthorsWithFilterRequest { + AuthorFilter filter = 1; +} +// Response message for authorsWithFilter operation. +message QueryAuthorsWithFilterResponse { + repeated Author authors_with_filter = 1; +} +// Request message for allAuthors operation. +message QueryAllAuthorsRequest { +} +// Response message for allAuthors operation. +message QueryAllAuthorsResponse { + repeated Author all_authors = 1; +} +// Request message for createUser operation. +message MutationCreateUserRequest { + UserInput input = 1; +} +// Response message for createUser operation. +message MutationCreateUserResponse { + User create_user = 1; +} +// Request message for performAction operation. +message MutationPerformActionRequest { + ActionInput input = 1; +} +// Response message for performAction operation. +message MutationPerformActionResponse { + ActionResult perform_action = 1; +} // Request message for createNullableFieldsType operation. message MutationCreateNullableFieldsTypeRequest { NullableFieldsInput input = 1; @@ -292,6 +467,40 @@ message MutationUpdateNullableFieldsTypeRequest { message MutationUpdateNullableFieldsTypeResponse { NullableFieldsType update_nullable_fields_type = 1; } +// Request message for createBlogPost operation. +message MutationCreateBlogPostRequest { + BlogPostInput input = 1; +} +// Response message for createBlogPost operation. +message MutationCreateBlogPostResponse { + BlogPost create_blog_post = 1; +} +// Request message for updateBlogPost operation. +message MutationUpdateBlogPostRequest { + string id = 1; + BlogPostInput input = 2; +} +// Response message for updateBlogPost operation. +message MutationUpdateBlogPostResponse { + BlogPost update_blog_post = 1; +} +// Request message for createAuthor operation. +message MutationCreateAuthorRequest { + AuthorInput input = 1; +} +// Response message for createAuthor operation. +message MutationCreateAuthorResponse { + Author create_author = 1; +} +// Request message for updateAuthor operation. +message MutationUpdateAuthorRequest { + string id = 1; + AuthorInput input = 2; +} +// Response message for updateAuthor operation. +message MutationUpdateAuthorResponse { + Author update_author = 1; +} message Product { string id = 1; @@ -353,7 +562,7 @@ message Order { string order_id = 1; string customer_name = 2; int32 total_items = 3; - repeated OrderLine order_lines = 4; + ListOfOrderLine order_lines = 4; } message Category { @@ -376,7 +585,7 @@ message Animal { message SearchInput { string query = 1; - int32 limit = 2; + google.protobuf.Int32Value limit = 2; } message SearchResult { @@ -387,6 +596,76 @@ message SearchResult { } } +message NullableFieldsType { + string id = 1; + string name = 2; + google.protobuf.StringValue optional_string = 3; + google.protobuf.Int32Value optional_int = 4; + google.protobuf.DoubleValue optional_float = 5; + google.protobuf.BoolValue optional_boolean = 6; + string required_string = 7; + int32 required_int = 8; +} + +message NullableFieldsFilter { + google.protobuf.StringValue name = 1; + google.protobuf.StringValue optional_string = 2; + google.protobuf.BoolValue include_nulls = 3; +} + +message BlogPost { + string id = 1; + string title = 2; + string content = 3; + repeated string tags = 4; + ListOfString optional_tags = 5; + repeated string categories = 6; + ListOfString keywords = 7; + repeated int32 view_counts = 8; + ListOfFloat ratings = 9; + ListOfBoolean is_published = 10; + ListOfListOfString tag_groups = 11; + ListOfListOfString related_topics = 12; + ListOfListOfString comment_threads = 13; + ListOfListOfString suggestions = 14; + repeated Category related_categories = 15; + repeated User contributors = 16; + ListOfProduct mentioned_products = 17; + ListOfUser mentioned_users = 18; + ListOfListOfCategory category_groups = 19; + ListOfListOfUser contributor_teams = 20; +} + +message BlogPostFilter { + google.protobuf.StringValue title = 1; + google.protobuf.BoolValue has_categories = 2; + google.protobuf.Int32Value min_tags = 3; +} + +message Author { + string id = 1; + string name = 2; + google.protobuf.StringValue email = 3; + repeated string skills = 4; + repeated string languages = 5; + ListOfString social_links = 6; + ListOfListOfString teams_by_project = 7; + ListOfListOfString collaborations = 8; + ListOfBlogPost written_posts = 9; + repeated Category favorite_categories = 10; + ListOfUser related_authors = 11; + ListOfProduct product_reviews = 12; + ListOfListOfUser author_groups = 13; + ListOfListOfCategory category_preferences = 14; + ListOfListOfUser project_teams = 15; +} + +message AuthorFilter { + google.protobuf.StringValue name = 1; + google.protobuf.BoolValue has_teams = 2; + google.protobuf.Int32Value skill_count = 3; +} + message UserInput { string name = 1; } @@ -403,6 +682,48 @@ message ActionResult { } } +message NullableFieldsInput { + string name = 1; + google.protobuf.StringValue optional_string = 2; + google.protobuf.Int32Value optional_int = 3; + google.protobuf.DoubleValue optional_float = 4; + google.protobuf.BoolValue optional_boolean = 5; + string required_string = 6; + int32 required_int = 7; +} + +message BlogPostInput { + string title = 1; + string content = 2; + repeated string tags = 3; + ListOfString optional_tags = 4; + repeated string categories = 5; + ListOfString keywords = 6; + repeated int32 view_counts = 7; + ListOfFloat ratings = 8; + ListOfBoolean is_published = 9; + ListOfListOfString tag_groups = 10; + ListOfListOfString related_topics = 11; + ListOfListOfString comment_threads = 12; + ListOfListOfString suggestions = 13; + ListOfCategoryInput related_categories = 14; + ListOfUserInput contributors = 15; + ListOfListOfCategoryInput category_groups = 16; +} + +message AuthorInput { + string name = 1; + google.protobuf.StringValue email = 2; + repeated string skills = 3; + repeated string languages = 4; + ListOfString social_links = 5; + ListOfListOfString teams_by_project = 6; + ListOfListOfString collaborations = 7; + repeated CategoryInput favorite_categories = 8; + ListOfListOfUserInput author_groups = 9; + ListOfListOfUserInput project_teams = 10; +} + message NestedTypeB { string id = 1; string name = 2; @@ -429,13 +750,13 @@ message Pagination { message OrderLineInput { string product_id = 1; int32 quantity = 2; - repeated string modifiers = 3; + ListOfString modifiers = 3; } message OrderLine { string product_id = 1; int32 quantity = 2; - repeated string modifiers = 3; + ListOfString modifiers = 3; } enum CategoryKind { @@ -470,30 +791,7 @@ message ActionError { string code = 2; } -// New messages for testing nullable fields -message NullableFieldsType { - string id = 1; - string name = 2; - google.protobuf.StringValue optional_string = 3; - google.protobuf.Int32Value optional_int = 4; - google.protobuf.FloatValue optional_float = 5; - google.protobuf.BoolValue optional_boolean = 6; - string required_string = 7; - int32 required_int = 8; -} - -message NullableFieldsInput { +message CategoryInput { string name = 1; - google.protobuf.StringValue optional_string = 2; - google.protobuf.Int32Value optional_int = 3; - google.protobuf.FloatValue optional_float = 4; - google.protobuf.BoolValue optional_boolean = 5; - string required_string = 6; - int32 required_int = 7; -} - -message NullableFieldsFilter { - google.protobuf.StringValue name = 1; - google.protobuf.StringValue optional_string = 2; - google.protobuf.BoolValue include_nulls = 3; + CategoryKind kind = 2; } \ No newline at end of file diff --git a/v2/pkg/grpctest/productv1/product.pb.go b/v2/pkg/grpctest/productv1/product.pb.go index dcfee5f0ca..ce1d1f6cb2 100644 --- a/v2/pkg/grpctest/productv1/product.pb.go +++ b/v2/pkg/grpctest/productv1/product.pb.go @@ -77,29 +77,28 @@ func (CategoryKind) EnumDescriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{0} } -// Key message for Product entity lookup -type LookupProductByIdRequestKey struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Key field for Product entity lookup. - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +// Wrapper message for a list of BlogPost. +type ListOfBlogPost struct { + state protoimpl.MessageState `protogen:"open.v1"` + List *ListOfBlogPost_List `protobuf:"bytes,1,opt,name=list,proto3" json:"list,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *LookupProductByIdRequestKey) Reset() { - *x = LookupProductByIdRequestKey{} +func (x *ListOfBlogPost) Reset() { + *x = ListOfBlogPost{} mi := &file_product_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *LookupProductByIdRequestKey) String() string { +func (x *ListOfBlogPost) String() string { return protoimpl.X.MessageStringOf(x) } -func (*LookupProductByIdRequestKey) ProtoMessage() {} +func (*ListOfBlogPost) ProtoMessage() {} -func (x *LookupProductByIdRequestKey) ProtoReflect() protoreflect.Message { +func (x *ListOfBlogPost) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -111,42 +110,40 @@ func (x *LookupProductByIdRequestKey) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use LookupProductByIdRequestKey.ProtoReflect.Descriptor instead. -func (*LookupProductByIdRequestKey) Descriptor() ([]byte, []int) { +// Deprecated: Use ListOfBlogPost.ProtoReflect.Descriptor instead. +func (*ListOfBlogPost) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{0} } -func (x *LookupProductByIdRequestKey) GetId() string { +func (x *ListOfBlogPost) GetList() *ListOfBlogPost_List { if x != nil { - return x.Id + return x.List } - return "" + return nil } -// Request message for Product entity lookup. -type LookupProductByIdRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - // List of keys to look up Product entities. - // Order matters - each key maps to one entity in LookupProductByIdResponse. - Keys []*LookupProductByIdRequestKey `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` +// Wrapper message for a list of Boolean. +type ListOfBoolean struct { + state protoimpl.MessageState `protogen:"open.v1"` + List *ListOfBoolean_List `protobuf:"bytes,1,opt,name=list,proto3" json:"list,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *LookupProductByIdRequest) Reset() { - *x = LookupProductByIdRequest{} +func (x *ListOfBoolean) Reset() { + *x = ListOfBoolean{} mi := &file_product_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *LookupProductByIdRequest) String() string { +func (x *ListOfBoolean) String() string { return protoimpl.X.MessageStringOf(x) } -func (*LookupProductByIdRequest) ProtoMessage() {} +func (*ListOfBoolean) ProtoMessage() {} -func (x *LookupProductByIdRequest) ProtoReflect() protoreflect.Message { +func (x *ListOfBoolean) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -158,53 +155,40 @@ func (x *LookupProductByIdRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use LookupProductByIdRequest.ProtoReflect.Descriptor instead. -func (*LookupProductByIdRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use ListOfBoolean.ProtoReflect.Descriptor instead. +func (*ListOfBoolean) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{1} } -func (x *LookupProductByIdRequest) GetKeys() []*LookupProductByIdRequestKey { +func (x *ListOfBoolean) GetList() *ListOfBoolean_List { if x != nil { - return x.Keys + return x.List } return nil } -// Response message for Product entity lookup. -type LookupProductByIdResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - // List of Product entities in the same order as the keys in LookupProductByIdRequest. - // Always return the same number of entities as keys. Use null for entities that cannot be found. - // - // Example: - // - // LookupUserByIdRequest: - // keys: - // - id: 1 - // - id: 2 - // LookupUserByIdResponse: - // result: - // - id: 1 # User with id 1 found - // - null # User with id 2 not found - Result []*Product `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` +// Wrapper message for a list of Category. +type ListOfCategory struct { + state protoimpl.MessageState `protogen:"open.v1"` + List *ListOfCategory_List `protobuf:"bytes,1,opt,name=list,proto3" json:"list,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *LookupProductByIdResponse) Reset() { - *x = LookupProductByIdResponse{} +func (x *ListOfCategory) Reset() { + *x = ListOfCategory{} mi := &file_product_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *LookupProductByIdResponse) String() string { +func (x *ListOfCategory) String() string { return protoimpl.X.MessageStringOf(x) } -func (*LookupProductByIdResponse) ProtoMessage() {} +func (*ListOfCategory) ProtoMessage() {} -func (x *LookupProductByIdResponse) ProtoReflect() protoreflect.Message { +func (x *ListOfCategory) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -216,41 +200,40 @@ func (x *LookupProductByIdResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use LookupProductByIdResponse.ProtoReflect.Descriptor instead. -func (*LookupProductByIdResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use ListOfCategory.ProtoReflect.Descriptor instead. +func (*ListOfCategory) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{2} } -func (x *LookupProductByIdResponse) GetResult() []*Product { +func (x *ListOfCategory) GetList() *ListOfCategory_List { if x != nil { - return x.Result + return x.List } return nil } -// Key message for Storage entity lookup -type LookupStorageByIdRequestKey struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Key field for Storage entity lookup. - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +// Wrapper message for a list of CategoryInput. +type ListOfCategoryInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + List *ListOfCategoryInput_List `protobuf:"bytes,1,opt,name=list,proto3" json:"list,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *LookupStorageByIdRequestKey) Reset() { - *x = LookupStorageByIdRequestKey{} +func (x *ListOfCategoryInput) Reset() { + *x = ListOfCategoryInput{} mi := &file_product_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *LookupStorageByIdRequestKey) String() string { +func (x *ListOfCategoryInput) String() string { return protoimpl.X.MessageStringOf(x) } -func (*LookupStorageByIdRequestKey) ProtoMessage() {} +func (*ListOfCategoryInput) ProtoMessage() {} -func (x *LookupStorageByIdRequestKey) ProtoReflect() protoreflect.Message { +func (x *ListOfCategoryInput) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -262,42 +245,40 @@ func (x *LookupStorageByIdRequestKey) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use LookupStorageByIdRequestKey.ProtoReflect.Descriptor instead. -func (*LookupStorageByIdRequestKey) Descriptor() ([]byte, []int) { +// Deprecated: Use ListOfCategoryInput.ProtoReflect.Descriptor instead. +func (*ListOfCategoryInput) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{3} } -func (x *LookupStorageByIdRequestKey) GetId() string { +func (x *ListOfCategoryInput) GetList() *ListOfCategoryInput_List { if x != nil { - return x.Id + return x.List } - return "" + return nil } -// Request message for Storage entity lookup. -type LookupStorageByIdRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - // List of keys to look up Storage entities. - // Order matters - each key maps to one entity in LookupStorageByIdResponse. - Keys []*LookupStorageByIdRequestKey `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` +// Wrapper message for a list of Float. +type ListOfFloat struct { + state protoimpl.MessageState `protogen:"open.v1"` + List *ListOfFloat_List `protobuf:"bytes,1,opt,name=list,proto3" json:"list,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *LookupStorageByIdRequest) Reset() { - *x = LookupStorageByIdRequest{} +func (x *ListOfFloat) Reset() { + *x = ListOfFloat{} mi := &file_product_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *LookupStorageByIdRequest) String() string { +func (x *ListOfFloat) String() string { return protoimpl.X.MessageStringOf(x) } -func (*LookupStorageByIdRequest) ProtoMessage() {} +func (*ListOfFloat) ProtoMessage() {} -func (x *LookupStorageByIdRequest) ProtoReflect() protoreflect.Message { +func (x *ListOfFloat) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -309,53 +290,40 @@ func (x *LookupStorageByIdRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use LookupStorageByIdRequest.ProtoReflect.Descriptor instead. -func (*LookupStorageByIdRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use ListOfFloat.ProtoReflect.Descriptor instead. +func (*ListOfFloat) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{4} } -func (x *LookupStorageByIdRequest) GetKeys() []*LookupStorageByIdRequestKey { +func (x *ListOfFloat) GetList() *ListOfFloat_List { if x != nil { - return x.Keys + return x.List } return nil } -// Response message for Storage entity lookup. -type LookupStorageByIdResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - // List of Storage entities in the same order as the keys in LookupStorageByIdRequest. - // Always return the same number of entities as keys. Use null for entities that cannot be found. - // - // Example: - // - // LookupUserByIdRequest: - // keys: - // - id: 1 - // - id: 2 - // LookupUserByIdResponse: - // result: - // - id: 1 # User with id 1 found - // - null # User with id 2 not found - Result []*Storage `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` +// Wrapper message for a list of Category. +type ListOfListOfCategory struct { + state protoimpl.MessageState `protogen:"open.v1"` + List *ListOfListOfCategory_List `protobuf:"bytes,1,opt,name=list,proto3" json:"list,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *LookupStorageByIdResponse) Reset() { - *x = LookupStorageByIdResponse{} +func (x *ListOfListOfCategory) Reset() { + *x = ListOfListOfCategory{} mi := &file_product_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *LookupStorageByIdResponse) String() string { +func (x *ListOfListOfCategory) String() string { return protoimpl.X.MessageStringOf(x) } -func (*LookupStorageByIdResponse) ProtoMessage() {} +func (*ListOfListOfCategory) ProtoMessage() {} -func (x *LookupStorageByIdResponse) ProtoReflect() protoreflect.Message { +func (x *ListOfListOfCategory) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -367,39 +335,40 @@ func (x *LookupStorageByIdResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use LookupStorageByIdResponse.ProtoReflect.Descriptor instead. -func (*LookupStorageByIdResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use ListOfListOfCategory.ProtoReflect.Descriptor instead. +func (*ListOfListOfCategory) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{5} } -func (x *LookupStorageByIdResponse) GetResult() []*Storage { +func (x *ListOfListOfCategory) GetList() *ListOfListOfCategory_List { if x != nil { - return x.Result + return x.List } return nil } -// Request message for users operation. -type QueryUsersRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` +// Wrapper message for a list of CategoryInput. +type ListOfListOfCategoryInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + List *ListOfListOfCategoryInput_List `protobuf:"bytes,1,opt,name=list,proto3" json:"list,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryUsersRequest) Reset() { - *x = QueryUsersRequest{} +func (x *ListOfListOfCategoryInput) Reset() { + *x = ListOfListOfCategoryInput{} mi := &file_product_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryUsersRequest) String() string { +func (x *ListOfListOfCategoryInput) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryUsersRequest) ProtoMessage() {} +func (*ListOfListOfCategoryInput) ProtoMessage() {} -func (x *QueryUsersRequest) ProtoReflect() protoreflect.Message { +func (x *ListOfListOfCategoryInput) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -411,33 +380,40 @@ func (x *QueryUsersRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryUsersRequest.ProtoReflect.Descriptor instead. -func (*QueryUsersRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use ListOfListOfCategoryInput.ProtoReflect.Descriptor instead. +func (*ListOfListOfCategoryInput) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{6} } -// Response message for users operation. -type QueryUsersResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Users []*User `protobuf:"bytes,1,rep,name=users,proto3" json:"users,omitempty"` +func (x *ListOfListOfCategoryInput) GetList() *ListOfListOfCategoryInput_List { + if x != nil { + return x.List + } + return nil +} + +// Wrapper message for a list of String. +type ListOfListOfString struct { + state protoimpl.MessageState `protogen:"open.v1"` + List *ListOfListOfString_List `protobuf:"bytes,1,opt,name=list,proto3" json:"list,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryUsersResponse) Reset() { - *x = QueryUsersResponse{} +func (x *ListOfListOfString) Reset() { + *x = ListOfListOfString{} mi := &file_product_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryUsersResponse) String() string { +func (x *ListOfListOfString) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryUsersResponse) ProtoMessage() {} +func (*ListOfListOfString) ProtoMessage() {} -func (x *QueryUsersResponse) ProtoReflect() protoreflect.Message { +func (x *ListOfListOfString) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -449,40 +425,40 @@ func (x *QueryUsersResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryUsersResponse.ProtoReflect.Descriptor instead. -func (*QueryUsersResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use ListOfListOfString.ProtoReflect.Descriptor instead. +func (*ListOfListOfString) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{7} } -func (x *QueryUsersResponse) GetUsers() []*User { +func (x *ListOfListOfString) GetList() *ListOfListOfString_List { if x != nil { - return x.Users + return x.List } return nil } -// Request message for user operation. -type QueryUserRequest struct { +// Wrapper message for a list of User. +type ListOfListOfUser struct { state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + List *ListOfListOfUser_List `protobuf:"bytes,1,opt,name=list,proto3" json:"list,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryUserRequest) Reset() { - *x = QueryUserRequest{} +func (x *ListOfListOfUser) Reset() { + *x = ListOfListOfUser{} mi := &file_product_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryUserRequest) String() string { +func (x *ListOfListOfUser) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryUserRequest) ProtoMessage() {} +func (*ListOfListOfUser) ProtoMessage() {} -func (x *QueryUserRequest) ProtoReflect() protoreflect.Message { +func (x *ListOfListOfUser) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -494,40 +470,40 @@ func (x *QueryUserRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryUserRequest.ProtoReflect.Descriptor instead. -func (*QueryUserRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use ListOfListOfUser.ProtoReflect.Descriptor instead. +func (*ListOfListOfUser) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{8} } -func (x *QueryUserRequest) GetId() string { +func (x *ListOfListOfUser) GetList() *ListOfListOfUser_List { if x != nil { - return x.Id + return x.List } - return "" + return nil } -// Response message for user operation. -type QueryUserResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` +// Wrapper message for a list of UserInput. +type ListOfListOfUserInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + List *ListOfListOfUserInput_List `protobuf:"bytes,1,opt,name=list,proto3" json:"list,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryUserResponse) Reset() { - *x = QueryUserResponse{} +func (x *ListOfListOfUserInput) Reset() { + *x = ListOfListOfUserInput{} mi := &file_product_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryUserResponse) String() string { +func (x *ListOfListOfUserInput) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryUserResponse) ProtoMessage() {} +func (*ListOfListOfUserInput) ProtoMessage() {} -func (x *QueryUserResponse) ProtoReflect() protoreflect.Message { +func (x *ListOfListOfUserInput) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -539,39 +515,40 @@ func (x *QueryUserResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryUserResponse.ProtoReflect.Descriptor instead. -func (*QueryUserResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use ListOfListOfUserInput.ProtoReflect.Descriptor instead. +func (*ListOfListOfUserInput) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{9} } -func (x *QueryUserResponse) GetUser() *User { +func (x *ListOfListOfUserInput) GetList() *ListOfListOfUserInput_List { if x != nil { - return x.User + return x.List } return nil } -// Request message for nestedType operation. -type QueryNestedTypeRequest struct { +// Wrapper message for a list of OrderLine. +type ListOfOrderLine struct { state protoimpl.MessageState `protogen:"open.v1"` + List *ListOfOrderLine_List `protobuf:"bytes,1,opt,name=list,proto3" json:"list,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryNestedTypeRequest) Reset() { - *x = QueryNestedTypeRequest{} +func (x *ListOfOrderLine) Reset() { + *x = ListOfOrderLine{} mi := &file_product_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryNestedTypeRequest) String() string { +func (x *ListOfOrderLine) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryNestedTypeRequest) ProtoMessage() {} +func (*ListOfOrderLine) ProtoMessage() {} -func (x *QueryNestedTypeRequest) ProtoReflect() protoreflect.Message { +func (x *ListOfOrderLine) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -583,33 +560,40 @@ func (x *QueryNestedTypeRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryNestedTypeRequest.ProtoReflect.Descriptor instead. -func (*QueryNestedTypeRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use ListOfOrderLine.ProtoReflect.Descriptor instead. +func (*ListOfOrderLine) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{10} } -// Response message for nestedType operation. -type QueryNestedTypeResponse struct { +func (x *ListOfOrderLine) GetList() *ListOfOrderLine_List { + if x != nil { + return x.List + } + return nil +} + +// Wrapper message for a list of Product. +type ListOfProduct struct { state protoimpl.MessageState `protogen:"open.v1"` - NestedType []*NestedTypeA `protobuf:"bytes,1,rep,name=nested_type,json=nestedType,proto3" json:"nested_type,omitempty"` + List *ListOfProduct_List `protobuf:"bytes,1,opt,name=list,proto3" json:"list,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryNestedTypeResponse) Reset() { - *x = QueryNestedTypeResponse{} +func (x *ListOfProduct) Reset() { + *x = ListOfProduct{} mi := &file_product_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryNestedTypeResponse) String() string { +func (x *ListOfProduct) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryNestedTypeResponse) ProtoMessage() {} +func (*ListOfProduct) ProtoMessage() {} -func (x *QueryNestedTypeResponse) ProtoReflect() protoreflect.Message { +func (x *ListOfProduct) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -621,39 +605,40 @@ func (x *QueryNestedTypeResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryNestedTypeResponse.ProtoReflect.Descriptor instead. -func (*QueryNestedTypeResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use ListOfProduct.ProtoReflect.Descriptor instead. +func (*ListOfProduct) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{11} } -func (x *QueryNestedTypeResponse) GetNestedType() []*NestedTypeA { +func (x *ListOfProduct) GetList() *ListOfProduct_List { if x != nil { - return x.NestedType + return x.List } return nil } -// Request message for recursiveType operation. -type QueryRecursiveTypeRequest struct { +// Wrapper message for a list of String. +type ListOfString struct { state protoimpl.MessageState `protogen:"open.v1"` + List *ListOfString_List `protobuf:"bytes,1,opt,name=list,proto3" json:"list,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryRecursiveTypeRequest) Reset() { - *x = QueryRecursiveTypeRequest{} +func (x *ListOfString) Reset() { + *x = ListOfString{} mi := &file_product_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryRecursiveTypeRequest) String() string { +func (x *ListOfString) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryRecursiveTypeRequest) ProtoMessage() {} +func (*ListOfString) ProtoMessage() {} -func (x *QueryRecursiveTypeRequest) ProtoReflect() protoreflect.Message { +func (x *ListOfString) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -665,33 +650,40 @@ func (x *QueryRecursiveTypeRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryRecursiveTypeRequest.ProtoReflect.Descriptor instead. -func (*QueryRecursiveTypeRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use ListOfString.ProtoReflect.Descriptor instead. +func (*ListOfString) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{12} } -// Response message for recursiveType operation. -type QueryRecursiveTypeResponse struct { +func (x *ListOfString) GetList() *ListOfString_List { + if x != nil { + return x.List + } + return nil +} + +// Wrapper message for a list of User. +type ListOfUser struct { state protoimpl.MessageState `protogen:"open.v1"` - RecursiveType *RecursiveType `protobuf:"bytes,1,opt,name=recursive_type,json=recursiveType,proto3" json:"recursive_type,omitempty"` + List *ListOfUser_List `protobuf:"bytes,1,opt,name=list,proto3" json:"list,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryRecursiveTypeResponse) Reset() { - *x = QueryRecursiveTypeResponse{} +func (x *ListOfUser) Reset() { + *x = ListOfUser{} mi := &file_product_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryRecursiveTypeResponse) String() string { +func (x *ListOfUser) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryRecursiveTypeResponse) ProtoMessage() {} +func (*ListOfUser) ProtoMessage() {} -func (x *QueryRecursiveTypeResponse) ProtoReflect() protoreflect.Message { +func (x *ListOfUser) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -703,41 +695,40 @@ func (x *QueryRecursiveTypeResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryRecursiveTypeResponse.ProtoReflect.Descriptor instead. -func (*QueryRecursiveTypeResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use ListOfUser.ProtoReflect.Descriptor instead. +func (*ListOfUser) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{13} } -func (x *QueryRecursiveTypeResponse) GetRecursiveType() *RecursiveType { +func (x *ListOfUser) GetList() *ListOfUser_List { if x != nil { - return x.RecursiveType + return x.List } return nil } -// Request message for typeFilterWithArguments operation. -type QueryTypeFilterWithArgumentsRequest struct { +// Wrapper message for a list of UserInput. +type ListOfUserInput struct { state protoimpl.MessageState `protogen:"open.v1"` - FilterField_1 string `protobuf:"bytes,1,opt,name=filter_field_1,json=filterField1,proto3" json:"filter_field_1,omitempty"` - FilterField_2 string `protobuf:"bytes,2,opt,name=filter_field_2,json=filterField2,proto3" json:"filter_field_2,omitempty"` + List *ListOfUserInput_List `protobuf:"bytes,1,opt,name=list,proto3" json:"list,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryTypeFilterWithArgumentsRequest) Reset() { - *x = QueryTypeFilterWithArgumentsRequest{} +func (x *ListOfUserInput) Reset() { + *x = ListOfUserInput{} mi := &file_product_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryTypeFilterWithArgumentsRequest) String() string { +func (x *ListOfUserInput) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryTypeFilterWithArgumentsRequest) ProtoMessage() {} +func (*ListOfUserInput) ProtoMessage() {} -func (x *QueryTypeFilterWithArgumentsRequest) ProtoReflect() protoreflect.Message { +func (x *ListOfUserInput) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -749,47 +740,41 @@ func (x *QueryTypeFilterWithArgumentsRequest) ProtoReflect() protoreflect.Messag return mi.MessageOf(x) } -// Deprecated: Use QueryTypeFilterWithArgumentsRequest.ProtoReflect.Descriptor instead. -func (*QueryTypeFilterWithArgumentsRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use ListOfUserInput.ProtoReflect.Descriptor instead. +func (*ListOfUserInput) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{14} } -func (x *QueryTypeFilterWithArgumentsRequest) GetFilterField_1() string { +func (x *ListOfUserInput) GetList() *ListOfUserInput_List { if x != nil { - return x.FilterField_1 + return x.List } - return "" + return nil } -func (x *QueryTypeFilterWithArgumentsRequest) GetFilterField_2() string { - if x != nil { - return x.FilterField_2 - } - return "" +// Key message for Product entity lookup +type LookupProductByIdRequestKey struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Key field for Product entity lookup. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -// Response message for typeFilterWithArguments operation. -type QueryTypeFilterWithArgumentsResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - TypeFilterWithArguments []*TypeWithMultipleFilterFields `protobuf:"bytes,1,rep,name=type_filter_with_arguments,json=typeFilterWithArguments,proto3" json:"type_filter_with_arguments,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *QueryTypeFilterWithArgumentsResponse) Reset() { - *x = QueryTypeFilterWithArgumentsResponse{} +func (x *LookupProductByIdRequestKey) Reset() { + *x = LookupProductByIdRequestKey{} mi := &file_product_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryTypeFilterWithArgumentsResponse) String() string { +func (x *LookupProductByIdRequestKey) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryTypeFilterWithArgumentsResponse) ProtoMessage() {} +func (*LookupProductByIdRequestKey) ProtoMessage() {} -func (x *QueryTypeFilterWithArgumentsResponse) ProtoReflect() protoreflect.Message { +func (x *LookupProductByIdRequestKey) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -801,40 +786,42 @@ func (x *QueryTypeFilterWithArgumentsResponse) ProtoReflect() protoreflect.Messa return mi.MessageOf(x) } -// Deprecated: Use QueryTypeFilterWithArgumentsResponse.ProtoReflect.Descriptor instead. -func (*QueryTypeFilterWithArgumentsResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use LookupProductByIdRequestKey.ProtoReflect.Descriptor instead. +func (*LookupProductByIdRequestKey) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{15} } -func (x *QueryTypeFilterWithArgumentsResponse) GetTypeFilterWithArguments() []*TypeWithMultipleFilterFields { +func (x *LookupProductByIdRequestKey) GetId() string { if x != nil { - return x.TypeFilterWithArguments + return x.Id } - return nil + return "" } -// Request message for typeWithMultipleFilterFields operation. -type QueryTypeWithMultipleFilterFieldsRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Filter *FilterTypeInput `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` +// Request message for Product entity lookup. +type LookupProductByIdRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // List of keys to look up Product entities. + // Order matters - each key maps to one entity in LookupProductByIdResponse. + Keys []*LookupProductByIdRequestKey `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryTypeWithMultipleFilterFieldsRequest) Reset() { - *x = QueryTypeWithMultipleFilterFieldsRequest{} +func (x *LookupProductByIdRequest) Reset() { + *x = LookupProductByIdRequest{} mi := &file_product_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryTypeWithMultipleFilterFieldsRequest) String() string { +func (x *LookupProductByIdRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryTypeWithMultipleFilterFieldsRequest) ProtoMessage() {} +func (*LookupProductByIdRequest) ProtoMessage() {} -func (x *QueryTypeWithMultipleFilterFieldsRequest) ProtoReflect() protoreflect.Message { +func (x *LookupProductByIdRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -846,40 +833,53 @@ func (x *QueryTypeWithMultipleFilterFieldsRequest) ProtoReflect() protoreflect.M return mi.MessageOf(x) } -// Deprecated: Use QueryTypeWithMultipleFilterFieldsRequest.ProtoReflect.Descriptor instead. -func (*QueryTypeWithMultipleFilterFieldsRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use LookupProductByIdRequest.ProtoReflect.Descriptor instead. +func (*LookupProductByIdRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{16} } -func (x *QueryTypeWithMultipleFilterFieldsRequest) GetFilter() *FilterTypeInput { +func (x *LookupProductByIdRequest) GetKeys() []*LookupProductByIdRequestKey { if x != nil { - return x.Filter + return x.Keys } return nil } -// Response message for typeWithMultipleFilterFields operation. -type QueryTypeWithMultipleFilterFieldsResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - TypeWithMultipleFilterFields []*TypeWithMultipleFilterFields `protobuf:"bytes,1,rep,name=type_with_multiple_filter_fields,json=typeWithMultipleFilterFields,proto3" json:"type_with_multiple_filter_fields,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Response message for Product entity lookup. +type LookupProductByIdResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // List of Product entities in the same order as the keys in LookupProductByIdRequest. + // Always return the same number of entities as keys. Use null for entities that cannot be found. + // + // Example: + // + // LookupUserByIdRequest: + // keys: + // - id: 1 + // - id: 2 + // LookupUserByIdResponse: + // result: + // - id: 1 # User with id 1 found + // - null # User with id 2 not found + Result []*Product `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *QueryTypeWithMultipleFilterFieldsResponse) Reset() { - *x = QueryTypeWithMultipleFilterFieldsResponse{} +func (x *LookupProductByIdResponse) Reset() { + *x = LookupProductByIdResponse{} mi := &file_product_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryTypeWithMultipleFilterFieldsResponse) String() string { +func (x *LookupProductByIdResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryTypeWithMultipleFilterFieldsResponse) ProtoMessage() {} +func (*LookupProductByIdResponse) ProtoMessage() {} -func (x *QueryTypeWithMultipleFilterFieldsResponse) ProtoReflect() protoreflect.Message { +func (x *LookupProductByIdResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -891,40 +891,41 @@ func (x *QueryTypeWithMultipleFilterFieldsResponse) ProtoReflect() protoreflect. return mi.MessageOf(x) } -// Deprecated: Use QueryTypeWithMultipleFilterFieldsResponse.ProtoReflect.Descriptor instead. -func (*QueryTypeWithMultipleFilterFieldsResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use LookupProductByIdResponse.ProtoReflect.Descriptor instead. +func (*LookupProductByIdResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{17} } -func (x *QueryTypeWithMultipleFilterFieldsResponse) GetTypeWithMultipleFilterFields() []*TypeWithMultipleFilterFields { +func (x *LookupProductByIdResponse) GetResult() []*Product { if x != nil { - return x.TypeWithMultipleFilterFields + return x.Result } return nil } -// Request message for complexFilterType operation. -type QueryComplexFilterTypeRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Filter *ComplexFilterTypeInput `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` +// Key message for Storage entity lookup +type LookupStorageByIdRequestKey struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Key field for Storage entity lookup. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryComplexFilterTypeRequest) Reset() { - *x = QueryComplexFilterTypeRequest{} +func (x *LookupStorageByIdRequestKey) Reset() { + *x = LookupStorageByIdRequestKey{} mi := &file_product_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryComplexFilterTypeRequest) String() string { +func (x *LookupStorageByIdRequestKey) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryComplexFilterTypeRequest) ProtoMessage() {} +func (*LookupStorageByIdRequestKey) ProtoMessage() {} -func (x *QueryComplexFilterTypeRequest) ProtoReflect() protoreflect.Message { +func (x *LookupStorageByIdRequestKey) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -936,40 +937,42 @@ func (x *QueryComplexFilterTypeRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryComplexFilterTypeRequest.ProtoReflect.Descriptor instead. -func (*QueryComplexFilterTypeRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use LookupStorageByIdRequestKey.ProtoReflect.Descriptor instead. +func (*LookupStorageByIdRequestKey) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{18} } -func (x *QueryComplexFilterTypeRequest) GetFilter() *ComplexFilterTypeInput { +func (x *LookupStorageByIdRequestKey) GetId() string { if x != nil { - return x.Filter + return x.Id } - return nil + return "" } -// Response message for complexFilterType operation. -type QueryComplexFilterTypeResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ComplexFilterType []*TypeWithComplexFilterInput `protobuf:"bytes,1,rep,name=complex_filter_type,json=complexFilterType,proto3" json:"complex_filter_type,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Request message for Storage entity lookup. +type LookupStorageByIdRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // List of keys to look up Storage entities. + // Order matters - each key maps to one entity in LookupStorageByIdResponse. + Keys []*LookupStorageByIdRequestKey `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *QueryComplexFilterTypeResponse) Reset() { - *x = QueryComplexFilterTypeResponse{} +func (x *LookupStorageByIdRequest) Reset() { + *x = LookupStorageByIdRequest{} mi := &file_product_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryComplexFilterTypeResponse) String() string { +func (x *LookupStorageByIdRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryComplexFilterTypeResponse) ProtoMessage() {} +func (*LookupStorageByIdRequest) ProtoMessage() {} -func (x *QueryComplexFilterTypeResponse) ProtoReflect() protoreflect.Message { +func (x *LookupStorageByIdRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -981,40 +984,53 @@ func (x *QueryComplexFilterTypeResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryComplexFilterTypeResponse.ProtoReflect.Descriptor instead. -func (*QueryComplexFilterTypeResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use LookupStorageByIdRequest.ProtoReflect.Descriptor instead. +func (*LookupStorageByIdRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{19} } -func (x *QueryComplexFilterTypeResponse) GetComplexFilterType() []*TypeWithComplexFilterInput { +func (x *LookupStorageByIdRequest) GetKeys() []*LookupStorageByIdRequestKey { if x != nil { - return x.ComplexFilterType + return x.Keys } return nil } -// Request message for calculateTotals operation. -type QueryCalculateTotalsRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Orders []*OrderInput `protobuf:"bytes,1,rep,name=orders,proto3" json:"orders,omitempty"` +// Response message for Storage entity lookup. +type LookupStorageByIdResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // List of Storage entities in the same order as the keys in LookupStorageByIdRequest. + // Always return the same number of entities as keys. Use null for entities that cannot be found. + // + // Example: + // + // LookupUserByIdRequest: + // keys: + // - id: 1 + // - id: 2 + // LookupUserByIdResponse: + // result: + // - id: 1 # User with id 1 found + // - null # User with id 2 not found + Result []*Storage `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryCalculateTotalsRequest) Reset() { - *x = QueryCalculateTotalsRequest{} +func (x *LookupStorageByIdResponse) Reset() { + *x = LookupStorageByIdResponse{} mi := &file_product_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryCalculateTotalsRequest) String() string { +func (x *LookupStorageByIdResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryCalculateTotalsRequest) ProtoMessage() {} +func (*LookupStorageByIdResponse) ProtoMessage() {} -func (x *QueryCalculateTotalsRequest) ProtoReflect() protoreflect.Message { +func (x *LookupStorageByIdResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1026,40 +1042,39 @@ func (x *QueryCalculateTotalsRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryCalculateTotalsRequest.ProtoReflect.Descriptor instead. -func (*QueryCalculateTotalsRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use LookupStorageByIdResponse.ProtoReflect.Descriptor instead. +func (*LookupStorageByIdResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{20} } -func (x *QueryCalculateTotalsRequest) GetOrders() []*OrderInput { +func (x *LookupStorageByIdResponse) GetResult() []*Storage { if x != nil { - return x.Orders + return x.Result } return nil } -// Response message for calculateTotals operation. -type QueryCalculateTotalsResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - CalculateTotals []*Order `protobuf:"bytes,1,rep,name=calculate_totals,json=calculateTotals,proto3" json:"calculate_totals,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Request message for users operation. +type QueryUsersRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *QueryCalculateTotalsResponse) Reset() { - *x = QueryCalculateTotalsResponse{} +func (x *QueryUsersRequest) Reset() { + *x = QueryUsersRequest{} mi := &file_product_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryCalculateTotalsResponse) String() string { +func (x *QueryUsersRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryCalculateTotalsResponse) ProtoMessage() {} +func (*QueryUsersRequest) ProtoMessage() {} -func (x *QueryCalculateTotalsResponse) ProtoReflect() protoreflect.Message { +func (x *QueryUsersRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1071,39 +1086,33 @@ func (x *QueryCalculateTotalsResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryCalculateTotalsResponse.ProtoReflect.Descriptor instead. -func (*QueryCalculateTotalsResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryUsersRequest.ProtoReflect.Descriptor instead. +func (*QueryUsersRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{21} } -func (x *QueryCalculateTotalsResponse) GetCalculateTotals() []*Order { - if x != nil { - return x.CalculateTotals - } - return nil -} - -// Request message for categories operation. -type QueryCategoriesRequest struct { +// Response message for users operation. +type QueryUsersResponse struct { state protoimpl.MessageState `protogen:"open.v1"` + Users []*User `protobuf:"bytes,1,rep,name=users,proto3" json:"users,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryCategoriesRequest) Reset() { - *x = QueryCategoriesRequest{} +func (x *QueryUsersResponse) Reset() { + *x = QueryUsersResponse{} mi := &file_product_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryCategoriesRequest) String() string { +func (x *QueryUsersResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryCategoriesRequest) ProtoMessage() {} +func (*QueryUsersResponse) ProtoMessage() {} -func (x *QueryCategoriesRequest) ProtoReflect() protoreflect.Message { +func (x *QueryUsersResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1115,33 +1124,40 @@ func (x *QueryCategoriesRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryCategoriesRequest.ProtoReflect.Descriptor instead. -func (*QueryCategoriesRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryUsersResponse.ProtoReflect.Descriptor instead. +func (*QueryUsersResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{22} } -// Response message for categories operation. -type QueryCategoriesResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Categories []*Category `protobuf:"bytes,1,rep,name=categories,proto3" json:"categories,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *QueryCategoriesResponse) Reset() { - *x = QueryCategoriesResponse{} +func (x *QueryUsersResponse) GetUsers() []*User { + if x != nil { + return x.Users + } + return nil +} + +// Request message for user operation. +type QueryUserRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QueryUserRequest) Reset() { + *x = QueryUserRequest{} mi := &file_product_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryCategoriesResponse) String() string { +func (x *QueryUserRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryCategoriesResponse) ProtoMessage() {} +func (*QueryUserRequest) ProtoMessage() {} -func (x *QueryCategoriesResponse) ProtoReflect() protoreflect.Message { +func (x *QueryUserRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1153,40 +1169,40 @@ func (x *QueryCategoriesResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryCategoriesResponse.ProtoReflect.Descriptor instead. -func (*QueryCategoriesResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryUserRequest.ProtoReflect.Descriptor instead. +func (*QueryUserRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{23} } -func (x *QueryCategoriesResponse) GetCategories() []*Category { +func (x *QueryUserRequest) GetId() string { if x != nil { - return x.Categories + return x.Id } - return nil + return "" } -// Request message for categoriesByKind operation. -type QueryCategoriesByKindRequest struct { +// Response message for user operation. +type QueryUserResponse struct { state protoimpl.MessageState `protogen:"open.v1"` - Kind CategoryKind `protobuf:"varint,1,opt,name=kind,proto3,enum=productv1.CategoryKind" json:"kind,omitempty"` + User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryCategoriesByKindRequest) Reset() { - *x = QueryCategoriesByKindRequest{} +func (x *QueryUserResponse) Reset() { + *x = QueryUserResponse{} mi := &file_product_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryCategoriesByKindRequest) String() string { +func (x *QueryUserResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryCategoriesByKindRequest) ProtoMessage() {} +func (*QueryUserResponse) ProtoMessage() {} -func (x *QueryCategoriesByKindRequest) ProtoReflect() protoreflect.Message { +func (x *QueryUserResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1198,40 +1214,39 @@ func (x *QueryCategoriesByKindRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryCategoriesByKindRequest.ProtoReflect.Descriptor instead. -func (*QueryCategoriesByKindRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryUserResponse.ProtoReflect.Descriptor instead. +func (*QueryUserResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{24} } -func (x *QueryCategoriesByKindRequest) GetKind() CategoryKind { +func (x *QueryUserResponse) GetUser() *User { if x != nil { - return x.Kind + return x.User } - return CategoryKind_CATEGORY_KIND_UNSPECIFIED + return nil } -// Response message for categoriesByKind operation. -type QueryCategoriesByKindResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - CategoriesByKind []*Category `protobuf:"bytes,1,rep,name=categories_by_kind,json=categoriesByKind,proto3" json:"categories_by_kind,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Request message for nestedType operation. +type QueryNestedTypeRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *QueryCategoriesByKindResponse) Reset() { - *x = QueryCategoriesByKindResponse{} +func (x *QueryNestedTypeRequest) Reset() { + *x = QueryNestedTypeRequest{} mi := &file_product_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryCategoriesByKindResponse) String() string { +func (x *QueryNestedTypeRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryCategoriesByKindResponse) ProtoMessage() {} +func (*QueryNestedTypeRequest) ProtoMessage() {} -func (x *QueryCategoriesByKindResponse) ProtoReflect() protoreflect.Message { +func (x *QueryNestedTypeRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1243,40 +1258,33 @@ func (x *QueryCategoriesByKindResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryCategoriesByKindResponse.ProtoReflect.Descriptor instead. -func (*QueryCategoriesByKindResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryNestedTypeRequest.ProtoReflect.Descriptor instead. +func (*QueryNestedTypeRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{25} } -func (x *QueryCategoriesByKindResponse) GetCategoriesByKind() []*Category { - if x != nil { - return x.CategoriesByKind - } - return nil -} - -// Request message for categoriesByKinds operation. -type QueryCategoriesByKindsRequest struct { +// Response message for nestedType operation. +type QueryNestedTypeResponse struct { state protoimpl.MessageState `protogen:"open.v1"` - Kinds []CategoryKind `protobuf:"varint,1,rep,packed,name=kinds,proto3,enum=productv1.CategoryKind" json:"kinds,omitempty"` + NestedType []*NestedTypeA `protobuf:"bytes,1,rep,name=nested_type,json=nestedType,proto3" json:"nested_type,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryCategoriesByKindsRequest) Reset() { - *x = QueryCategoriesByKindsRequest{} +func (x *QueryNestedTypeResponse) Reset() { + *x = QueryNestedTypeResponse{} mi := &file_product_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryCategoriesByKindsRequest) String() string { +func (x *QueryNestedTypeResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryCategoriesByKindsRequest) ProtoMessage() {} +func (*QueryNestedTypeResponse) ProtoMessage() {} -func (x *QueryCategoriesByKindsRequest) ProtoReflect() protoreflect.Message { +func (x *QueryNestedTypeResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1288,40 +1296,39 @@ func (x *QueryCategoriesByKindsRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryCategoriesByKindsRequest.ProtoReflect.Descriptor instead. -func (*QueryCategoriesByKindsRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryNestedTypeResponse.ProtoReflect.Descriptor instead. +func (*QueryNestedTypeResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{26} } -func (x *QueryCategoriesByKindsRequest) GetKinds() []CategoryKind { +func (x *QueryNestedTypeResponse) GetNestedType() []*NestedTypeA { if x != nil { - return x.Kinds + return x.NestedType } return nil } -// Response message for categoriesByKinds operation. -type QueryCategoriesByKindsResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - CategoriesByKinds []*Category `protobuf:"bytes,1,rep,name=categories_by_kinds,json=categoriesByKinds,proto3" json:"categories_by_kinds,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Request message for recursiveType operation. +type QueryRecursiveTypeRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *QueryCategoriesByKindsResponse) Reset() { - *x = QueryCategoriesByKindsResponse{} +func (x *QueryRecursiveTypeRequest) Reset() { + *x = QueryRecursiveTypeRequest{} mi := &file_product_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryCategoriesByKindsResponse) String() string { +func (x *QueryRecursiveTypeRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryCategoriesByKindsResponse) ProtoMessage() {} +func (*QueryRecursiveTypeRequest) ProtoMessage() {} -func (x *QueryCategoriesByKindsResponse) ProtoReflect() protoreflect.Message { +func (x *QueryRecursiveTypeRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1333,40 +1340,33 @@ func (x *QueryCategoriesByKindsResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryCategoriesByKindsResponse.ProtoReflect.Descriptor instead. -func (*QueryCategoriesByKindsResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryRecursiveTypeRequest.ProtoReflect.Descriptor instead. +func (*QueryRecursiveTypeRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{27} } -func (x *QueryCategoriesByKindsResponse) GetCategoriesByKinds() []*Category { - if x != nil { - return x.CategoriesByKinds - } - return nil -} - -// Request message for filterCategories operation. -type QueryFilterCategoriesRequest struct { +// Response message for recursiveType operation. +type QueryRecursiveTypeResponse struct { state protoimpl.MessageState `protogen:"open.v1"` - Filter *CategoryFilter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` + RecursiveType *RecursiveType `protobuf:"bytes,1,opt,name=recursive_type,json=recursiveType,proto3" json:"recursive_type,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryFilterCategoriesRequest) Reset() { - *x = QueryFilterCategoriesRequest{} +func (x *QueryRecursiveTypeResponse) Reset() { + *x = QueryRecursiveTypeResponse{} mi := &file_product_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryFilterCategoriesRequest) String() string { +func (x *QueryRecursiveTypeResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryFilterCategoriesRequest) ProtoMessage() {} +func (*QueryRecursiveTypeResponse) ProtoMessage() {} -func (x *QueryFilterCategoriesRequest) ProtoReflect() protoreflect.Message { +func (x *QueryRecursiveTypeResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1378,40 +1378,41 @@ func (x *QueryFilterCategoriesRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryFilterCategoriesRequest.ProtoReflect.Descriptor instead. -func (*QueryFilterCategoriesRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryRecursiveTypeResponse.ProtoReflect.Descriptor instead. +func (*QueryRecursiveTypeResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{28} } -func (x *QueryFilterCategoriesRequest) GetFilter() *CategoryFilter { +func (x *QueryRecursiveTypeResponse) GetRecursiveType() *RecursiveType { if x != nil { - return x.Filter + return x.RecursiveType } return nil } -// Response message for filterCategories operation. -type QueryFilterCategoriesResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - FilterCategories []*Category `protobuf:"bytes,1,rep,name=filter_categories,json=filterCategories,proto3" json:"filter_categories,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Request message for typeFilterWithArguments operation. +type QueryTypeFilterWithArgumentsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + FilterField_1 string `protobuf:"bytes,1,opt,name=filter_field_1,json=filterField1,proto3" json:"filter_field_1,omitempty"` + FilterField_2 string `protobuf:"bytes,2,opt,name=filter_field_2,json=filterField2,proto3" json:"filter_field_2,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *QueryFilterCategoriesResponse) Reset() { - *x = QueryFilterCategoriesResponse{} +func (x *QueryTypeFilterWithArgumentsRequest) Reset() { + *x = QueryTypeFilterWithArgumentsRequest{} mi := &file_product_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryFilterCategoriesResponse) String() string { +func (x *QueryTypeFilterWithArgumentsRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryFilterCategoriesResponse) ProtoMessage() {} +func (*QueryTypeFilterWithArgumentsRequest) ProtoMessage() {} -func (x *QueryFilterCategoriesResponse) ProtoReflect() protoreflect.Message { +func (x *QueryTypeFilterWithArgumentsRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1423,39 +1424,47 @@ func (x *QueryFilterCategoriesResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryFilterCategoriesResponse.ProtoReflect.Descriptor instead. -func (*QueryFilterCategoriesResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryTypeFilterWithArgumentsRequest.ProtoReflect.Descriptor instead. +func (*QueryTypeFilterWithArgumentsRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{29} } -func (x *QueryFilterCategoriesResponse) GetFilterCategories() []*Category { +func (x *QueryTypeFilterWithArgumentsRequest) GetFilterField_1() string { if x != nil { - return x.FilterCategories + return x.FilterField_1 } - return nil + return "" } -// Request message for randomPet operation. -type QueryRandomPetRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +func (x *QueryTypeFilterWithArgumentsRequest) GetFilterField_2() string { + if x != nil { + return x.FilterField_2 + } + return "" } -func (x *QueryRandomPetRequest) Reset() { - *x = QueryRandomPetRequest{} +// Response message for typeFilterWithArguments operation. +type QueryTypeFilterWithArgumentsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + TypeFilterWithArguments []*TypeWithMultipleFilterFields `protobuf:"bytes,1,rep,name=type_filter_with_arguments,json=typeFilterWithArguments,proto3" json:"type_filter_with_arguments,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QueryTypeFilterWithArgumentsResponse) Reset() { + *x = QueryTypeFilterWithArgumentsResponse{} mi := &file_product_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryRandomPetRequest) String() string { +func (x *QueryTypeFilterWithArgumentsResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryRandomPetRequest) ProtoMessage() {} +func (*QueryTypeFilterWithArgumentsResponse) ProtoMessage() {} -func (x *QueryRandomPetRequest) ProtoReflect() protoreflect.Message { +func (x *QueryTypeFilterWithArgumentsResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1467,33 +1476,40 @@ func (x *QueryRandomPetRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryRandomPetRequest.ProtoReflect.Descriptor instead. -func (*QueryRandomPetRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryTypeFilterWithArgumentsResponse.ProtoReflect.Descriptor instead. +func (*QueryTypeFilterWithArgumentsResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{30} } -// Response message for randomPet operation. -type QueryRandomPetResponse struct { +func (x *QueryTypeFilterWithArgumentsResponse) GetTypeFilterWithArguments() []*TypeWithMultipleFilterFields { + if x != nil { + return x.TypeFilterWithArguments + } + return nil +} + +// Request message for typeWithMultipleFilterFields operation. +type QueryTypeWithMultipleFilterFieldsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - RandomPet *Animal `protobuf:"bytes,1,opt,name=random_pet,json=randomPet,proto3" json:"random_pet,omitempty"` + Filter *FilterTypeInput `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryRandomPetResponse) Reset() { - *x = QueryRandomPetResponse{} +func (x *QueryTypeWithMultipleFilterFieldsRequest) Reset() { + *x = QueryTypeWithMultipleFilterFieldsRequest{} mi := &file_product_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryRandomPetResponse) String() string { +func (x *QueryTypeWithMultipleFilterFieldsRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryRandomPetResponse) ProtoMessage() {} +func (*QueryTypeWithMultipleFilterFieldsRequest) ProtoMessage() {} -func (x *QueryRandomPetResponse) ProtoReflect() protoreflect.Message { +func (x *QueryTypeWithMultipleFilterFieldsRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1505,39 +1521,40 @@ func (x *QueryRandomPetResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryRandomPetResponse.ProtoReflect.Descriptor instead. -func (*QueryRandomPetResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryTypeWithMultipleFilterFieldsRequest.ProtoReflect.Descriptor instead. +func (*QueryTypeWithMultipleFilterFieldsRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{31} } -func (x *QueryRandomPetResponse) GetRandomPet() *Animal { +func (x *QueryTypeWithMultipleFilterFieldsRequest) GetFilter() *FilterTypeInput { if x != nil { - return x.RandomPet + return x.Filter } return nil } -// Request message for allPets operation. -type QueryAllPetsRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Response message for typeWithMultipleFilterFields operation. +type QueryTypeWithMultipleFilterFieldsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + TypeWithMultipleFilterFields []*TypeWithMultipleFilterFields `protobuf:"bytes,1,rep,name=type_with_multiple_filter_fields,json=typeWithMultipleFilterFields,proto3" json:"type_with_multiple_filter_fields,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *QueryAllPetsRequest) Reset() { - *x = QueryAllPetsRequest{} +func (x *QueryTypeWithMultipleFilterFieldsResponse) Reset() { + *x = QueryTypeWithMultipleFilterFieldsResponse{} mi := &file_product_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryAllPetsRequest) String() string { +func (x *QueryTypeWithMultipleFilterFieldsResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryAllPetsRequest) ProtoMessage() {} +func (*QueryTypeWithMultipleFilterFieldsResponse) ProtoMessage() {} -func (x *QueryAllPetsRequest) ProtoReflect() protoreflect.Message { +func (x *QueryTypeWithMultipleFilterFieldsResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1549,33 +1566,40 @@ func (x *QueryAllPetsRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryAllPetsRequest.ProtoReflect.Descriptor instead. -func (*QueryAllPetsRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryTypeWithMultipleFilterFieldsResponse.ProtoReflect.Descriptor instead. +func (*QueryTypeWithMultipleFilterFieldsResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{32} } -// Response message for allPets operation. -type QueryAllPetsResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - AllPets []*Animal `protobuf:"bytes,1,rep,name=all_pets,json=allPets,proto3" json:"all_pets,omitempty"` +func (x *QueryTypeWithMultipleFilterFieldsResponse) GetTypeWithMultipleFilterFields() []*TypeWithMultipleFilterFields { + if x != nil { + return x.TypeWithMultipleFilterFields + } + return nil +} + +// Request message for complexFilterType operation. +type QueryComplexFilterTypeRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Filter *ComplexFilterTypeInput `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryAllPetsResponse) Reset() { - *x = QueryAllPetsResponse{} +func (x *QueryComplexFilterTypeRequest) Reset() { + *x = QueryComplexFilterTypeRequest{} mi := &file_product_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryAllPetsResponse) String() string { +func (x *QueryComplexFilterTypeRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryAllPetsResponse) ProtoMessage() {} +func (*QueryComplexFilterTypeRequest) ProtoMessage() {} -func (x *QueryAllPetsResponse) ProtoReflect() protoreflect.Message { +func (x *QueryComplexFilterTypeRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1587,40 +1611,40 @@ func (x *QueryAllPetsResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryAllPetsResponse.ProtoReflect.Descriptor instead. -func (*QueryAllPetsResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryComplexFilterTypeRequest.ProtoReflect.Descriptor instead. +func (*QueryComplexFilterTypeRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{33} } -func (x *QueryAllPetsResponse) GetAllPets() []*Animal { +func (x *QueryComplexFilterTypeRequest) GetFilter() *ComplexFilterTypeInput { if x != nil { - return x.AllPets + return x.Filter } return nil } -// Request message for search operation. -type QuerySearchRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Input *SearchInput `protobuf:"bytes,1,opt,name=input,proto3" json:"input,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Response message for complexFilterType operation. +type QueryComplexFilterTypeResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + ComplexFilterType []*TypeWithComplexFilterInput `protobuf:"bytes,1,rep,name=complex_filter_type,json=complexFilterType,proto3" json:"complex_filter_type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *QuerySearchRequest) Reset() { - *x = QuerySearchRequest{} +func (x *QueryComplexFilterTypeResponse) Reset() { + *x = QueryComplexFilterTypeResponse{} mi := &file_product_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QuerySearchRequest) String() string { +func (x *QueryComplexFilterTypeResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QuerySearchRequest) ProtoMessage() {} +func (*QueryComplexFilterTypeResponse) ProtoMessage() {} -func (x *QuerySearchRequest) ProtoReflect() protoreflect.Message { +func (x *QueryComplexFilterTypeResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1632,40 +1656,40 @@ func (x *QuerySearchRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QuerySearchRequest.ProtoReflect.Descriptor instead. -func (*QuerySearchRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryComplexFilterTypeResponse.ProtoReflect.Descriptor instead. +func (*QueryComplexFilterTypeResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{34} } -func (x *QuerySearchRequest) GetInput() *SearchInput { +func (x *QueryComplexFilterTypeResponse) GetComplexFilterType() []*TypeWithComplexFilterInput { if x != nil { - return x.Input + return x.ComplexFilterType } return nil } -// Response message for search operation. -type QuerySearchResponse struct { +// Request message for calculateTotals operation. +type QueryCalculateTotalsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - Search []*SearchResult `protobuf:"bytes,1,rep,name=search,proto3" json:"search,omitempty"` + Orders []*OrderInput `protobuf:"bytes,1,rep,name=orders,proto3" json:"orders,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QuerySearchResponse) Reset() { - *x = QuerySearchResponse{} +func (x *QueryCalculateTotalsRequest) Reset() { + *x = QueryCalculateTotalsRequest{} mi := &file_product_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QuerySearchResponse) String() string { +func (x *QueryCalculateTotalsRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QuerySearchResponse) ProtoMessage() {} +func (*QueryCalculateTotalsRequest) ProtoMessage() {} -func (x *QuerySearchResponse) ProtoReflect() protoreflect.Message { +func (x *QueryCalculateTotalsRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1677,39 +1701,40 @@ func (x *QuerySearchResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QuerySearchResponse.ProtoReflect.Descriptor instead. -func (*QuerySearchResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryCalculateTotalsRequest.ProtoReflect.Descriptor instead. +func (*QueryCalculateTotalsRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{35} } -func (x *QuerySearchResponse) GetSearch() []*SearchResult { +func (x *QueryCalculateTotalsRequest) GetOrders() []*OrderInput { if x != nil { - return x.Search + return x.Orders } return nil } -// Request message for randomSearchResult operation. -type QueryRandomSearchResultRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Response message for calculateTotals operation. +type QueryCalculateTotalsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + CalculateTotals []*Order `protobuf:"bytes,1,rep,name=calculate_totals,json=calculateTotals,proto3" json:"calculate_totals,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *QueryRandomSearchResultRequest) Reset() { - *x = QueryRandomSearchResultRequest{} +func (x *QueryCalculateTotalsResponse) Reset() { + *x = QueryCalculateTotalsResponse{} mi := &file_product_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryRandomSearchResultRequest) String() string { +func (x *QueryCalculateTotalsResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryRandomSearchResultRequest) ProtoMessage() {} +func (*QueryCalculateTotalsResponse) ProtoMessage() {} -func (x *QueryRandomSearchResultRequest) ProtoReflect() protoreflect.Message { +func (x *QueryCalculateTotalsResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1721,33 +1746,39 @@ func (x *QueryRandomSearchResultRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryRandomSearchResultRequest.ProtoReflect.Descriptor instead. -func (*QueryRandomSearchResultRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryCalculateTotalsResponse.ProtoReflect.Descriptor instead. +func (*QueryCalculateTotalsResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{36} } -// Response message for randomSearchResult operation. -type QueryRandomSearchResultResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - RandomSearchResult *SearchResult `protobuf:"bytes,1,opt,name=random_search_result,json=randomSearchResult,proto3" json:"random_search_result,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +func (x *QueryCalculateTotalsResponse) GetCalculateTotals() []*Order { + if x != nil { + return x.CalculateTotals + } + return nil } -func (x *QueryRandomSearchResultResponse) Reset() { - *x = QueryRandomSearchResultResponse{} +// Request message for categories operation. +type QueryCategoriesRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QueryCategoriesRequest) Reset() { + *x = QueryCategoriesRequest{} mi := &file_product_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryRandomSearchResultResponse) String() string { +func (x *QueryCategoriesRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryRandomSearchResultResponse) ProtoMessage() {} +func (*QueryCategoriesRequest) ProtoMessage() {} -func (x *QueryRandomSearchResultResponse) ProtoReflect() protoreflect.Message { +func (x *QueryCategoriesRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1759,40 +1790,33 @@ func (x *QueryRandomSearchResultResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryRandomSearchResultResponse.ProtoReflect.Descriptor instead. -func (*QueryRandomSearchResultResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryCategoriesRequest.ProtoReflect.Descriptor instead. +func (*QueryCategoriesRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{37} } -func (x *QueryRandomSearchResultResponse) GetRandomSearchResult() *SearchResult { - if x != nil { - return x.RandomSearchResult - } - return nil -} - -// Request message for createUser operation. -type MutationCreateUserRequest struct { +// Response message for categories operation. +type QueryCategoriesResponse struct { state protoimpl.MessageState `protogen:"open.v1"` - Input *UserInput `protobuf:"bytes,1,opt,name=input,proto3" json:"input,omitempty"` + Categories []*Category `protobuf:"bytes,1,rep,name=categories,proto3" json:"categories,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *MutationCreateUserRequest) Reset() { - *x = MutationCreateUserRequest{} +func (x *QueryCategoriesResponse) Reset() { + *x = QueryCategoriesResponse{} mi := &file_product_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *MutationCreateUserRequest) String() string { +func (x *QueryCategoriesResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*MutationCreateUserRequest) ProtoMessage() {} +func (*QueryCategoriesResponse) ProtoMessage() {} -func (x *MutationCreateUserRequest) ProtoReflect() protoreflect.Message { +func (x *QueryCategoriesResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1804,40 +1828,40 @@ func (x *MutationCreateUserRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use MutationCreateUserRequest.ProtoReflect.Descriptor instead. -func (*MutationCreateUserRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryCategoriesResponse.ProtoReflect.Descriptor instead. +func (*QueryCategoriesResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{38} } -func (x *MutationCreateUserRequest) GetInput() *UserInput { +func (x *QueryCategoriesResponse) GetCategories() []*Category { if x != nil { - return x.Input + return x.Categories } return nil } -// Response message for createUser operation. -type MutationCreateUserResponse struct { +// Request message for categoriesByKind operation. +type QueryCategoriesByKindRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - CreateUser *User `protobuf:"bytes,1,opt,name=create_user,json=createUser,proto3" json:"create_user,omitempty"` + Kind CategoryKind `protobuf:"varint,1,opt,name=kind,proto3,enum=productv1.CategoryKind" json:"kind,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *MutationCreateUserResponse) Reset() { - *x = MutationCreateUserResponse{} +func (x *QueryCategoriesByKindRequest) Reset() { + *x = QueryCategoriesByKindRequest{} mi := &file_product_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *MutationCreateUserResponse) String() string { +func (x *QueryCategoriesByKindRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*MutationCreateUserResponse) ProtoMessage() {} +func (*QueryCategoriesByKindRequest) ProtoMessage() {} -func (x *MutationCreateUserResponse) ProtoReflect() protoreflect.Message { +func (x *QueryCategoriesByKindRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1849,40 +1873,40 @@ func (x *MutationCreateUserResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use MutationCreateUserResponse.ProtoReflect.Descriptor instead. -func (*MutationCreateUserResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryCategoriesByKindRequest.ProtoReflect.Descriptor instead. +func (*QueryCategoriesByKindRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{39} } -func (x *MutationCreateUserResponse) GetCreateUser() *User { +func (x *QueryCategoriesByKindRequest) GetKind() CategoryKind { if x != nil { - return x.CreateUser + return x.Kind } - return nil + return CategoryKind_CATEGORY_KIND_UNSPECIFIED } -// Request message for performAction operation. -type MutationPerformActionRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Input *ActionInput `protobuf:"bytes,1,opt,name=input,proto3" json:"input,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Response message for categoriesByKind operation. +type QueryCategoriesByKindResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + CategoriesByKind []*Category `protobuf:"bytes,1,rep,name=categories_by_kind,json=categoriesByKind,proto3" json:"categories_by_kind,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *MutationPerformActionRequest) Reset() { - *x = MutationPerformActionRequest{} +func (x *QueryCategoriesByKindResponse) Reset() { + *x = QueryCategoriesByKindResponse{} mi := &file_product_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *MutationPerformActionRequest) String() string { +func (x *QueryCategoriesByKindResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*MutationPerformActionRequest) ProtoMessage() {} +func (*QueryCategoriesByKindResponse) ProtoMessage() {} -func (x *MutationPerformActionRequest) ProtoReflect() protoreflect.Message { +func (x *QueryCategoriesByKindResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1894,40 +1918,40 @@ func (x *MutationPerformActionRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use MutationPerformActionRequest.ProtoReflect.Descriptor instead. -func (*MutationPerformActionRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryCategoriesByKindResponse.ProtoReflect.Descriptor instead. +func (*QueryCategoriesByKindResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{40} } -func (x *MutationPerformActionRequest) GetInput() *ActionInput { +func (x *QueryCategoriesByKindResponse) GetCategoriesByKind() []*Category { if x != nil { - return x.Input + return x.CategoriesByKind } return nil } -// Response message for performAction operation. -type MutationPerformActionResponse struct { +// Request message for categoriesByKinds operation. +type QueryCategoriesByKindsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - PerformAction *ActionResult `protobuf:"bytes,1,opt,name=perform_action,json=performAction,proto3" json:"perform_action,omitempty"` + Kinds []CategoryKind `protobuf:"varint,1,rep,packed,name=kinds,proto3,enum=productv1.CategoryKind" json:"kinds,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *MutationPerformActionResponse) Reset() { - *x = MutationPerformActionResponse{} +func (x *QueryCategoriesByKindsRequest) Reset() { + *x = QueryCategoriesByKindsRequest{} mi := &file_product_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *MutationPerformActionResponse) String() string { +func (x *QueryCategoriesByKindsRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*MutationPerformActionResponse) ProtoMessage() {} +func (*QueryCategoriesByKindsRequest) ProtoMessage() {} -func (x *MutationPerformActionResponse) ProtoReflect() protoreflect.Message { +func (x *QueryCategoriesByKindsRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1939,39 +1963,40 @@ func (x *MutationPerformActionResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use MutationPerformActionResponse.ProtoReflect.Descriptor instead. -func (*MutationPerformActionResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryCategoriesByKindsRequest.ProtoReflect.Descriptor instead. +func (*QueryCategoriesByKindsRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{41} } -func (x *MutationPerformActionResponse) GetPerformAction() *ActionResult { +func (x *QueryCategoriesByKindsRequest) GetKinds() []CategoryKind { if x != nil { - return x.PerformAction + return x.Kinds } return nil } -// Request message for nullableFieldsType operation. -type QueryNullableFieldsTypeRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Response message for categoriesByKinds operation. +type QueryCategoriesByKindsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + CategoriesByKinds []*Category `protobuf:"bytes,1,rep,name=categories_by_kinds,json=categoriesByKinds,proto3" json:"categories_by_kinds,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *QueryNullableFieldsTypeRequest) Reset() { - *x = QueryNullableFieldsTypeRequest{} +func (x *QueryCategoriesByKindsResponse) Reset() { + *x = QueryCategoriesByKindsResponse{} mi := &file_product_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryNullableFieldsTypeRequest) String() string { +func (x *QueryCategoriesByKindsResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryNullableFieldsTypeRequest) ProtoMessage() {} +func (*QueryCategoriesByKindsResponse) ProtoMessage() {} -func (x *QueryNullableFieldsTypeRequest) ProtoReflect() protoreflect.Message { +func (x *QueryCategoriesByKindsResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1983,33 +2008,40 @@ func (x *QueryNullableFieldsTypeRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryNullableFieldsTypeRequest.ProtoReflect.Descriptor instead. -func (*QueryNullableFieldsTypeRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryCategoriesByKindsResponse.ProtoReflect.Descriptor instead. +func (*QueryCategoriesByKindsResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{42} } -// Response message for nullableFieldsType operation. -type QueryNullableFieldsTypeResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - NullableFieldsType *NullableFieldsType `protobuf:"bytes,1,opt,name=nullable_fields_type,json=nullableFieldsType,proto3" json:"nullable_fields_type,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +func (x *QueryCategoriesByKindsResponse) GetCategoriesByKinds() []*Category { + if x != nil { + return x.CategoriesByKinds + } + return nil } -func (x *QueryNullableFieldsTypeResponse) Reset() { - *x = QueryNullableFieldsTypeResponse{} +// Request message for filterCategories operation. +type QueryFilterCategoriesRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Filter *CategoryFilter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QueryFilterCategoriesRequest) Reset() { + *x = QueryFilterCategoriesRequest{} mi := &file_product_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryNullableFieldsTypeResponse) String() string { +func (x *QueryFilterCategoriesRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryNullableFieldsTypeResponse) ProtoMessage() {} +func (*QueryFilterCategoriesRequest) ProtoMessage() {} -func (x *QueryNullableFieldsTypeResponse) ProtoReflect() protoreflect.Message { +func (x *QueryFilterCategoriesRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2021,40 +2053,40 @@ func (x *QueryNullableFieldsTypeResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use QueryNullableFieldsTypeResponse.ProtoReflect.Descriptor instead. -func (*QueryNullableFieldsTypeResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryFilterCategoriesRequest.ProtoReflect.Descriptor instead. +func (*QueryFilterCategoriesRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{43} } -func (x *QueryNullableFieldsTypeResponse) GetNullableFieldsType() *NullableFieldsType { +func (x *QueryFilterCategoriesRequest) GetFilter() *CategoryFilter { if x != nil { - return x.NullableFieldsType + return x.Filter } return nil } -// Request message for nullableFieldsTypeById operation. -type QueryNullableFieldsTypeByIdRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Response message for filterCategories operation. +type QueryFilterCategoriesResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + FilterCategories []*Category `protobuf:"bytes,1,rep,name=filter_categories,json=filterCategories,proto3" json:"filter_categories,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *QueryNullableFieldsTypeByIdRequest) Reset() { - *x = QueryNullableFieldsTypeByIdRequest{} +func (x *QueryFilterCategoriesResponse) Reset() { + *x = QueryFilterCategoriesResponse{} mi := &file_product_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryNullableFieldsTypeByIdRequest) String() string { +func (x *QueryFilterCategoriesResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryNullableFieldsTypeByIdRequest) ProtoMessage() {} +func (*QueryFilterCategoriesResponse) ProtoMessage() {} -func (x *QueryNullableFieldsTypeByIdRequest) ProtoReflect() protoreflect.Message { +func (x *QueryFilterCategoriesResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2066,40 +2098,39 @@ func (x *QueryNullableFieldsTypeByIdRequest) ProtoReflect() protoreflect.Message return mi.MessageOf(x) } -// Deprecated: Use QueryNullableFieldsTypeByIdRequest.ProtoReflect.Descriptor instead. -func (*QueryNullableFieldsTypeByIdRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryFilterCategoriesResponse.ProtoReflect.Descriptor instead. +func (*QueryFilterCategoriesResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{44} } -func (x *QueryNullableFieldsTypeByIdRequest) GetId() string { +func (x *QueryFilterCategoriesResponse) GetFilterCategories() []*Category { if x != nil { - return x.Id + return x.FilterCategories } - return "" + return nil } -// Response message for nullableFieldsTypeById operation. -type QueryNullableFieldsTypeByIdResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - NullableFieldsTypeById *NullableFieldsType `protobuf:"bytes,1,opt,name=nullable_fields_type_by_id,json=nullableFieldsTypeById,proto3" json:"nullable_fields_type_by_id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Request message for randomPet operation. +type QueryRandomPetRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *QueryNullableFieldsTypeByIdResponse) Reset() { - *x = QueryNullableFieldsTypeByIdResponse{} +func (x *QueryRandomPetRequest) Reset() { + *x = QueryRandomPetRequest{} mi := &file_product_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryNullableFieldsTypeByIdResponse) String() string { +func (x *QueryRandomPetRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryNullableFieldsTypeByIdResponse) ProtoMessage() {} +func (*QueryRandomPetRequest) ProtoMessage() {} -func (x *QueryNullableFieldsTypeByIdResponse) ProtoReflect() protoreflect.Message { +func (x *QueryRandomPetRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2111,40 +2142,33 @@ func (x *QueryNullableFieldsTypeByIdResponse) ProtoReflect() protoreflect.Messag return mi.MessageOf(x) } -// Deprecated: Use QueryNullableFieldsTypeByIdResponse.ProtoReflect.Descriptor instead. -func (*QueryNullableFieldsTypeByIdResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryRandomPetRequest.ProtoReflect.Descriptor instead. +func (*QueryRandomPetRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{45} } -func (x *QueryNullableFieldsTypeByIdResponse) GetNullableFieldsTypeById() *NullableFieldsType { - if x != nil { - return x.NullableFieldsTypeById - } - return nil -} - -// Request message for nullableFieldsTypeWithFilter operation. -type QueryNullableFieldsTypeWithFilterRequest struct { +// Response message for randomPet operation. +type QueryRandomPetResponse struct { state protoimpl.MessageState `protogen:"open.v1"` - Filter *NullableFieldsFilter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` + RandomPet *Animal `protobuf:"bytes,1,opt,name=random_pet,json=randomPet,proto3" json:"random_pet,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryNullableFieldsTypeWithFilterRequest) Reset() { - *x = QueryNullableFieldsTypeWithFilterRequest{} +func (x *QueryRandomPetResponse) Reset() { + *x = QueryRandomPetResponse{} mi := &file_product_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryNullableFieldsTypeWithFilterRequest) String() string { +func (x *QueryRandomPetResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryNullableFieldsTypeWithFilterRequest) ProtoMessage() {} +func (*QueryRandomPetResponse) ProtoMessage() {} -func (x *QueryNullableFieldsTypeWithFilterRequest) ProtoReflect() protoreflect.Message { +func (x *QueryRandomPetResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2156,40 +2180,39 @@ func (x *QueryNullableFieldsTypeWithFilterRequest) ProtoReflect() protoreflect.M return mi.MessageOf(x) } -// Deprecated: Use QueryNullableFieldsTypeWithFilterRequest.ProtoReflect.Descriptor instead. -func (*QueryNullableFieldsTypeWithFilterRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryRandomPetResponse.ProtoReflect.Descriptor instead. +func (*QueryRandomPetResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{46} } -func (x *QueryNullableFieldsTypeWithFilterRequest) GetFilter() *NullableFieldsFilter { +func (x *QueryRandomPetResponse) GetRandomPet() *Animal { if x != nil { - return x.Filter + return x.RandomPet } return nil } -// Response message for nullableFieldsTypeWithFilter operation. -type QueryNullableFieldsTypeWithFilterResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - NullableFieldsTypeWithFilter []*NullableFieldsType `protobuf:"bytes,1,rep,name=nullable_fields_type_with_filter,json=nullableFieldsTypeWithFilter,proto3" json:"nullable_fields_type_with_filter,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Request message for allPets operation. +type QueryAllPetsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *QueryNullableFieldsTypeWithFilterResponse) Reset() { - *x = QueryNullableFieldsTypeWithFilterResponse{} +func (x *QueryAllPetsRequest) Reset() { + *x = QueryAllPetsRequest{} mi := &file_product_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryNullableFieldsTypeWithFilterResponse) String() string { +func (x *QueryAllPetsRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryNullableFieldsTypeWithFilterResponse) ProtoMessage() {} +func (*QueryAllPetsRequest) ProtoMessage() {} -func (x *QueryNullableFieldsTypeWithFilterResponse) ProtoReflect() protoreflect.Message { +func (x *QueryAllPetsRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2201,39 +2224,33 @@ func (x *QueryNullableFieldsTypeWithFilterResponse) ProtoReflect() protoreflect. return mi.MessageOf(x) } -// Deprecated: Use QueryNullableFieldsTypeWithFilterResponse.ProtoReflect.Descriptor instead. -func (*QueryNullableFieldsTypeWithFilterResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryAllPetsRequest.ProtoReflect.Descriptor instead. +func (*QueryAllPetsRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{47} } -func (x *QueryNullableFieldsTypeWithFilterResponse) GetNullableFieldsTypeWithFilter() []*NullableFieldsType { - if x != nil { - return x.NullableFieldsTypeWithFilter - } - return nil -} - -// Request message for allNullableFieldsTypes operation. -type QueryAllNullableFieldsTypesRequest struct { +// Response message for allPets operation. +type QueryAllPetsResponse struct { state protoimpl.MessageState `protogen:"open.v1"` + AllPets []*Animal `protobuf:"bytes,1,rep,name=all_pets,json=allPets,proto3" json:"all_pets,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *QueryAllNullableFieldsTypesRequest) Reset() { - *x = QueryAllNullableFieldsTypesRequest{} +func (x *QueryAllPetsResponse) Reset() { + *x = QueryAllPetsResponse{} mi := &file_product_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *QueryAllNullableFieldsTypesRequest) String() string { +func (x *QueryAllPetsResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*QueryAllNullableFieldsTypesRequest) ProtoMessage() {} +func (*QueryAllPetsResponse) ProtoMessage() {} -func (x *QueryAllNullableFieldsTypesRequest) ProtoReflect() protoreflect.Message { +func (x *QueryAllPetsResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2245,33 +2262,40 @@ func (x *QueryAllNullableFieldsTypesRequest) ProtoReflect() protoreflect.Message return mi.MessageOf(x) } -// Deprecated: Use QueryAllNullableFieldsTypesRequest.ProtoReflect.Descriptor instead. -func (*QueryAllNullableFieldsTypesRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryAllPetsResponse.ProtoReflect.Descriptor instead. +func (*QueryAllPetsResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{48} } -// Response message for allNullableFieldsTypes operation. -type QueryAllNullableFieldsTypesResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - AllNullableFieldsTypes []*NullableFieldsType `protobuf:"bytes,1,rep,name=all_nullable_fields_types,json=allNullableFieldsTypes,proto3" json:"all_nullable_fields_types,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *QueryAllNullableFieldsTypesResponse) Reset() { - *x = QueryAllNullableFieldsTypesResponse{} - mi := &file_product_proto_msgTypes[49] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) +func (x *QueryAllPetsResponse) GetAllPets() []*Animal { + if x != nil { + return x.AllPets + } + return nil } -func (x *QueryAllNullableFieldsTypesResponse) String() string { - return protoimpl.X.MessageStringOf(x) +// Request message for search operation. +type QuerySearchRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Input *SearchInput `protobuf:"bytes,1,opt,name=input,proto3" json:"input,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (*QueryAllNullableFieldsTypesResponse) ProtoMessage() {} +func (x *QuerySearchRequest) Reset() { + *x = QuerySearchRequest{} + mi := &file_product_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} -func (x *QueryAllNullableFieldsTypesResponse) ProtoReflect() protoreflect.Message { +func (x *QuerySearchRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QuerySearchRequest) ProtoMessage() {} + +func (x *QuerySearchRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2283,40 +2307,40 @@ func (x *QueryAllNullableFieldsTypesResponse) ProtoReflect() protoreflect.Messag return mi.MessageOf(x) } -// Deprecated: Use QueryAllNullableFieldsTypesResponse.ProtoReflect.Descriptor instead. -func (*QueryAllNullableFieldsTypesResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QuerySearchRequest.ProtoReflect.Descriptor instead. +func (*QuerySearchRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{49} } -func (x *QueryAllNullableFieldsTypesResponse) GetAllNullableFieldsTypes() []*NullableFieldsType { +func (x *QuerySearchRequest) GetInput() *SearchInput { if x != nil { - return x.AllNullableFieldsTypes + return x.Input } return nil } -// Request message for createNullableFieldsType operation. -type MutationCreateNullableFieldsTypeRequest struct { +// Response message for search operation. +type QuerySearchResponse struct { state protoimpl.MessageState `protogen:"open.v1"` - Input *NullableFieldsInput `protobuf:"bytes,1,opt,name=input,proto3" json:"input,omitempty"` + Search []*SearchResult `protobuf:"bytes,1,rep,name=search,proto3" json:"search,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *MutationCreateNullableFieldsTypeRequest) Reset() { - *x = MutationCreateNullableFieldsTypeRequest{} +func (x *QuerySearchResponse) Reset() { + *x = QuerySearchResponse{} mi := &file_product_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *MutationCreateNullableFieldsTypeRequest) String() string { +func (x *QuerySearchResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*MutationCreateNullableFieldsTypeRequest) ProtoMessage() {} +func (*QuerySearchResponse) ProtoMessage() {} -func (x *MutationCreateNullableFieldsTypeRequest) ProtoReflect() protoreflect.Message { +func (x *QuerySearchResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2328,40 +2352,39 @@ func (x *MutationCreateNullableFieldsTypeRequest) ProtoReflect() protoreflect.Me return mi.MessageOf(x) } -// Deprecated: Use MutationCreateNullableFieldsTypeRequest.ProtoReflect.Descriptor instead. -func (*MutationCreateNullableFieldsTypeRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QuerySearchResponse.ProtoReflect.Descriptor instead. +func (*QuerySearchResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{50} } -func (x *MutationCreateNullableFieldsTypeRequest) GetInput() *NullableFieldsInput { +func (x *QuerySearchResponse) GetSearch() []*SearchResult { if x != nil { - return x.Input + return x.Search } return nil } -// Response message for createNullableFieldsType operation. -type MutationCreateNullableFieldsTypeResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - CreateNullableFieldsType *NullableFieldsType `protobuf:"bytes,1,opt,name=create_nullable_fields_type,json=createNullableFieldsType,proto3" json:"create_nullable_fields_type,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Request message for randomSearchResult operation. +type QueryRandomSearchResultRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *MutationCreateNullableFieldsTypeResponse) Reset() { - *x = MutationCreateNullableFieldsTypeResponse{} +func (x *QueryRandomSearchResultRequest) Reset() { + *x = QueryRandomSearchResultRequest{} mi := &file_product_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *MutationCreateNullableFieldsTypeResponse) String() string { +func (x *QueryRandomSearchResultRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*MutationCreateNullableFieldsTypeResponse) ProtoMessage() {} +func (*QueryRandomSearchResultRequest) ProtoMessage() {} -func (x *MutationCreateNullableFieldsTypeResponse) ProtoReflect() protoreflect.Message { +func (x *QueryRandomSearchResultRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2373,41 +2396,33 @@ func (x *MutationCreateNullableFieldsTypeResponse) ProtoReflect() protoreflect.M return mi.MessageOf(x) } -// Deprecated: Use MutationCreateNullableFieldsTypeResponse.ProtoReflect.Descriptor instead. -func (*MutationCreateNullableFieldsTypeResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryRandomSearchResultRequest.ProtoReflect.Descriptor instead. +func (*QueryRandomSearchResultRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{51} } -func (x *MutationCreateNullableFieldsTypeResponse) GetCreateNullableFieldsType() *NullableFieldsType { - if x != nil { - return x.CreateNullableFieldsType - } - return nil -} - -// Request message for updateNullableFieldsType operation. -type MutationUpdateNullableFieldsTypeRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Input *NullableFieldsInput `protobuf:"bytes,2,opt,name=input,proto3" json:"input,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Response message for randomSearchResult operation. +type QueryRandomSearchResultResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + RandomSearchResult *SearchResult `protobuf:"bytes,1,opt,name=random_search_result,json=randomSearchResult,proto3" json:"random_search_result,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *MutationUpdateNullableFieldsTypeRequest) Reset() { - *x = MutationUpdateNullableFieldsTypeRequest{} +func (x *QueryRandomSearchResultResponse) Reset() { + *x = QueryRandomSearchResultResponse{} mi := &file_product_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *MutationUpdateNullableFieldsTypeRequest) String() string { +func (x *QueryRandomSearchResultResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*MutationUpdateNullableFieldsTypeRequest) ProtoMessage() {} +func (*QueryRandomSearchResultResponse) ProtoMessage() {} -func (x *MutationUpdateNullableFieldsTypeRequest) ProtoReflect() protoreflect.Message { +func (x *QueryRandomSearchResultResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2419,47 +2434,39 @@ func (x *MutationUpdateNullableFieldsTypeRequest) ProtoReflect() protoreflect.Me return mi.MessageOf(x) } -// Deprecated: Use MutationUpdateNullableFieldsTypeRequest.ProtoReflect.Descriptor instead. -func (*MutationUpdateNullableFieldsTypeRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryRandomSearchResultResponse.ProtoReflect.Descriptor instead. +func (*QueryRandomSearchResultResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{52} } -func (x *MutationUpdateNullableFieldsTypeRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *MutationUpdateNullableFieldsTypeRequest) GetInput() *NullableFieldsInput { +func (x *QueryRandomSearchResultResponse) GetRandomSearchResult() *SearchResult { if x != nil { - return x.Input + return x.RandomSearchResult } return nil } -// Response message for updateNullableFieldsType operation. -type MutationUpdateNullableFieldsTypeResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - UpdateNullableFieldsType *NullableFieldsType `protobuf:"bytes,1,opt,name=update_nullable_fields_type,json=updateNullableFieldsType,proto3" json:"update_nullable_fields_type,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Request message for nullableFieldsType operation. +type QueryNullableFieldsTypeRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *MutationUpdateNullableFieldsTypeResponse) Reset() { - *x = MutationUpdateNullableFieldsTypeResponse{} +func (x *QueryNullableFieldsTypeRequest) Reset() { + *x = QueryNullableFieldsTypeRequest{} mi := &file_product_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *MutationUpdateNullableFieldsTypeResponse) String() string { +func (x *QueryNullableFieldsTypeRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*MutationUpdateNullableFieldsTypeResponse) ProtoMessage() {} +func (*QueryNullableFieldsTypeRequest) ProtoMessage() {} -func (x *MutationUpdateNullableFieldsTypeResponse) ProtoReflect() protoreflect.Message { +func (x *QueryNullableFieldsTypeRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2471,41 +2478,33 @@ func (x *MutationUpdateNullableFieldsTypeResponse) ProtoReflect() protoreflect.M return mi.MessageOf(x) } -// Deprecated: Use MutationUpdateNullableFieldsTypeResponse.ProtoReflect.Descriptor instead. -func (*MutationUpdateNullableFieldsTypeResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryNullableFieldsTypeRequest.ProtoReflect.Descriptor instead. +func (*QueryNullableFieldsTypeRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{53} } -func (x *MutationUpdateNullableFieldsTypeResponse) GetUpdateNullableFieldsType() *NullableFieldsType { - if x != nil { - return x.UpdateNullableFieldsType - } - return nil -} - -type Product struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Price float64 `protobuf:"fixed64,3,opt,name=price,proto3" json:"price,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Response message for nullableFieldsType operation. +type QueryNullableFieldsTypeResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + NullableFieldsType *NullableFieldsType `protobuf:"bytes,1,opt,name=nullable_fields_type,json=nullableFieldsType,proto3" json:"nullable_fields_type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *Product) Reset() { - *x = Product{} +func (x *QueryNullableFieldsTypeResponse) Reset() { + *x = QueryNullableFieldsTypeResponse{} mi := &file_product_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Product) String() string { +func (x *QueryNullableFieldsTypeResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Product) ProtoMessage() {} +func (*QueryNullableFieldsTypeResponse) ProtoMessage() {} -func (x *Product) ProtoReflect() protoreflect.Message { +func (x *QueryNullableFieldsTypeResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2517,55 +2516,40 @@ func (x *Product) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Product.ProtoReflect.Descriptor instead. -func (*Product) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryNullableFieldsTypeResponse.ProtoReflect.Descriptor instead. +func (*QueryNullableFieldsTypeResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{54} } -func (x *Product) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Product) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Product) GetPrice() float64 { +func (x *QueryNullableFieldsTypeResponse) GetNullableFieldsType() *NullableFieldsType { if x != nil { - return x.Price + return x.NullableFieldsType } - return 0 + return nil } -type Storage struct { +// Request message for nullableFieldsTypeById operation. +type QueryNullableFieldsTypeByIdRequest struct { state protoimpl.MessageState `protogen:"open.v1"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Location string `protobuf:"bytes,3,opt,name=location,proto3" json:"location,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Storage) Reset() { - *x = Storage{} +func (x *QueryNullableFieldsTypeByIdRequest) Reset() { + *x = QueryNullableFieldsTypeByIdRequest{} mi := &file_product_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Storage) String() string { +func (x *QueryNullableFieldsTypeByIdRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Storage) ProtoMessage() {} +func (*QueryNullableFieldsTypeByIdRequest) ProtoMessage() {} -func (x *Storage) ProtoReflect() protoreflect.Message { +func (x *QueryNullableFieldsTypeByIdRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2577,54 +2561,40 @@ func (x *Storage) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Storage.ProtoReflect.Descriptor instead. -func (*Storage) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryNullableFieldsTypeByIdRequest.ProtoReflect.Descriptor instead. +func (*QueryNullableFieldsTypeByIdRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{55} } -func (x *Storage) GetId() string { +func (x *QueryNullableFieldsTypeByIdRequest) GetId() string { if x != nil { return x.Id } return "" } -func (x *Storage) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Storage) GetLocation() string { - if x != nil { - return x.Location - } - return "" -} - -type User struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Response message for nullableFieldsTypeById operation. +type QueryNullableFieldsTypeByIdResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + NullableFieldsTypeById *NullableFieldsType `protobuf:"bytes,1,opt,name=nullable_fields_type_by_id,json=nullableFieldsTypeById,proto3" json:"nullable_fields_type_by_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *User) Reset() { - *x = User{} +func (x *QueryNullableFieldsTypeByIdResponse) Reset() { + *x = QueryNullableFieldsTypeByIdResponse{} mi := &file_product_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *User) String() string { +func (x *QueryNullableFieldsTypeByIdResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*User) ProtoMessage() {} +func (*QueryNullableFieldsTypeByIdResponse) ProtoMessage() {} -func (x *User) ProtoReflect() protoreflect.Message { +func (x *QueryNullableFieldsTypeByIdResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2636,48 +2606,40 @@ func (x *User) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use User.ProtoReflect.Descriptor instead. -func (*User) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryNullableFieldsTypeByIdResponse.ProtoReflect.Descriptor instead. +func (*QueryNullableFieldsTypeByIdResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{56} } -func (x *User) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *User) GetName() string { +func (x *QueryNullableFieldsTypeByIdResponse) GetNullableFieldsTypeById() *NullableFieldsType { if x != nil { - return x.Name + return x.NullableFieldsTypeById } - return "" + return nil } -type NestedTypeA struct { +// Request message for nullableFieldsTypeWithFilter operation. +type QueryNullableFieldsTypeWithFilterRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - B *NestedTypeB `protobuf:"bytes,3,opt,name=b,proto3" json:"b,omitempty"` + Filter *NullableFieldsFilter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *NestedTypeA) Reset() { - *x = NestedTypeA{} +func (x *QueryNullableFieldsTypeWithFilterRequest) Reset() { + *x = QueryNullableFieldsTypeWithFilterRequest{} mi := &file_product_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *NestedTypeA) String() string { +func (x *QueryNullableFieldsTypeWithFilterRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*NestedTypeA) ProtoMessage() {} +func (*QueryNullableFieldsTypeWithFilterRequest) ProtoMessage() {} -func (x *NestedTypeA) ProtoReflect() protoreflect.Message { +func (x *QueryNullableFieldsTypeWithFilterRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2689,55 +2651,40 @@ func (x *NestedTypeA) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use NestedTypeA.ProtoReflect.Descriptor instead. -func (*NestedTypeA) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryNullableFieldsTypeWithFilterRequest.ProtoReflect.Descriptor instead. +func (*QueryNullableFieldsTypeWithFilterRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{57} } -func (x *NestedTypeA) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *NestedTypeA) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *NestedTypeA) GetB() *NestedTypeB { +func (x *QueryNullableFieldsTypeWithFilterRequest) GetFilter() *NullableFieldsFilter { if x != nil { - return x.B + return x.Filter } return nil } -type RecursiveType struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - RecursiveType *RecursiveType `protobuf:"bytes,3,opt,name=recursive_type,json=recursiveType,proto3" json:"recursive_type,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Response message for nullableFieldsTypeWithFilter operation. +type QueryNullableFieldsTypeWithFilterResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + NullableFieldsTypeWithFilter []*NullableFieldsType `protobuf:"bytes,1,rep,name=nullable_fields_type_with_filter,json=nullableFieldsTypeWithFilter,proto3" json:"nullable_fields_type_with_filter,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *RecursiveType) Reset() { - *x = RecursiveType{} +func (x *QueryNullableFieldsTypeWithFilterResponse) Reset() { + *x = QueryNullableFieldsTypeWithFilterResponse{} mi := &file_product_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *RecursiveType) String() string { +func (x *QueryNullableFieldsTypeWithFilterResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*RecursiveType) ProtoMessage() {} +func (*QueryNullableFieldsTypeWithFilterResponse) ProtoMessage() {} -func (x *RecursiveType) ProtoReflect() protoreflect.Message { +func (x *QueryNullableFieldsTypeWithFilterResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2749,56 +2696,39 @@ func (x *RecursiveType) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use RecursiveType.ProtoReflect.Descriptor instead. -func (*RecursiveType) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryNullableFieldsTypeWithFilterResponse.ProtoReflect.Descriptor instead. +func (*QueryNullableFieldsTypeWithFilterResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{58} } -func (x *RecursiveType) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *RecursiveType) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *RecursiveType) GetRecursiveType() *RecursiveType { +func (x *QueryNullableFieldsTypeWithFilterResponse) GetNullableFieldsTypeWithFilter() []*NullableFieldsType { if x != nil { - return x.RecursiveType + return x.NullableFieldsTypeWithFilter } return nil } -type TypeWithMultipleFilterFields struct { +// Request message for allNullableFieldsTypes operation. +type QueryAllNullableFieldsTypesRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - FilterField_1 string `protobuf:"bytes,3,opt,name=filter_field_1,json=filterField1,proto3" json:"filter_field_1,omitempty"` - FilterField_2 string `protobuf:"bytes,4,opt,name=filter_field_2,json=filterField2,proto3" json:"filter_field_2,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *TypeWithMultipleFilterFields) Reset() { - *x = TypeWithMultipleFilterFields{} +func (x *QueryAllNullableFieldsTypesRequest) Reset() { + *x = QueryAllNullableFieldsTypesRequest{} mi := &file_product_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *TypeWithMultipleFilterFields) String() string { +func (x *QueryAllNullableFieldsTypesRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*TypeWithMultipleFilterFields) ProtoMessage() {} +func (*QueryAllNullableFieldsTypesRequest) ProtoMessage() {} -func (x *TypeWithMultipleFilterFields) ProtoReflect() protoreflect.Message { +func (x *QueryAllNullableFieldsTypesRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2810,61 +2740,33 @@ func (x *TypeWithMultipleFilterFields) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use TypeWithMultipleFilterFields.ProtoReflect.Descriptor instead. -func (*TypeWithMultipleFilterFields) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryAllNullableFieldsTypesRequest.ProtoReflect.Descriptor instead. +func (*QueryAllNullableFieldsTypesRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{59} } -func (x *TypeWithMultipleFilterFields) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *TypeWithMultipleFilterFields) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *TypeWithMultipleFilterFields) GetFilterField_1() string { - if x != nil { - return x.FilterField_1 - } - return "" -} - -func (x *TypeWithMultipleFilterFields) GetFilterField_2() string { - if x != nil { - return x.FilterField_2 - } - return "" -} - -type FilterTypeInput struct { - state protoimpl.MessageState `protogen:"open.v1"` - FilterField_1 string `protobuf:"bytes,1,opt,name=filter_field_1,json=filterField1,proto3" json:"filter_field_1,omitempty"` - FilterField_2 string `protobuf:"bytes,2,opt,name=filter_field_2,json=filterField2,proto3" json:"filter_field_2,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Response message for allNullableFieldsTypes operation. +type QueryAllNullableFieldsTypesResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + AllNullableFieldsTypes []*NullableFieldsType `protobuf:"bytes,1,rep,name=all_nullable_fields_types,json=allNullableFieldsTypes,proto3" json:"all_nullable_fields_types,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *FilterTypeInput) Reset() { - *x = FilterTypeInput{} +func (x *QueryAllNullableFieldsTypesResponse) Reset() { + *x = QueryAllNullableFieldsTypesResponse{} mi := &file_product_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *FilterTypeInput) String() string { +func (x *QueryAllNullableFieldsTypesResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*FilterTypeInput) ProtoMessage() {} +func (*QueryAllNullableFieldsTypesResponse) ProtoMessage() {} -func (x *FilterTypeInput) ProtoReflect() protoreflect.Message { +func (x *QueryAllNullableFieldsTypesResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2876,46 +2778,39 @@ func (x *FilterTypeInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use FilterTypeInput.ProtoReflect.Descriptor instead. -func (*FilterTypeInput) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryAllNullableFieldsTypesResponse.ProtoReflect.Descriptor instead. +func (*QueryAllNullableFieldsTypesResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{60} } -func (x *FilterTypeInput) GetFilterField_1() string { - if x != nil { - return x.FilterField_1 - } - return "" -} - -func (x *FilterTypeInput) GetFilterField_2() string { +func (x *QueryAllNullableFieldsTypesResponse) GetAllNullableFieldsTypes() []*NullableFieldsType { if x != nil { - return x.FilterField_2 + return x.AllNullableFieldsTypes } - return "" + return nil } -type ComplexFilterTypeInput struct { +// Request message for blogPost operation. +type QueryBlogPostRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - Filter *FilterType `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ComplexFilterTypeInput) Reset() { - *x = ComplexFilterTypeInput{} +func (x *QueryBlogPostRequest) Reset() { + *x = QueryBlogPostRequest{} mi := &file_product_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ComplexFilterTypeInput) String() string { +func (x *QueryBlogPostRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ComplexFilterTypeInput) ProtoMessage() {} +func (*QueryBlogPostRequest) ProtoMessage() {} -func (x *ComplexFilterTypeInput) ProtoReflect() protoreflect.Message { +func (x *QueryBlogPostRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2927,40 +2822,33 @@ func (x *ComplexFilterTypeInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ComplexFilterTypeInput.ProtoReflect.Descriptor instead. -func (*ComplexFilterTypeInput) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryBlogPostRequest.ProtoReflect.Descriptor instead. +func (*QueryBlogPostRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{61} } -func (x *ComplexFilterTypeInput) GetFilter() *FilterType { - if x != nil { - return x.Filter - } - return nil -} - -type TypeWithComplexFilterInput struct { +// Response message for blogPost operation. +type QueryBlogPostResponse struct { state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + BlogPost *BlogPost `protobuf:"bytes,1,opt,name=blog_post,json=blogPost,proto3" json:"blog_post,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *TypeWithComplexFilterInput) Reset() { - *x = TypeWithComplexFilterInput{} +func (x *QueryBlogPostResponse) Reset() { + *x = QueryBlogPostResponse{} mi := &file_product_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *TypeWithComplexFilterInput) String() string { +func (x *QueryBlogPostResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*TypeWithComplexFilterInput) ProtoMessage() {} +func (*QueryBlogPostResponse) ProtoMessage() {} -func (x *TypeWithComplexFilterInput) ProtoReflect() protoreflect.Message { +func (x *QueryBlogPostResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2972,48 +2860,40 @@ func (x *TypeWithComplexFilterInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use TypeWithComplexFilterInput.ProtoReflect.Descriptor instead. -func (*TypeWithComplexFilterInput) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryBlogPostResponse.ProtoReflect.Descriptor instead. +func (*QueryBlogPostResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{62} } -func (x *TypeWithComplexFilterInput) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *TypeWithComplexFilterInput) GetName() string { +func (x *QueryBlogPostResponse) GetBlogPost() *BlogPost { if x != nil { - return x.Name + return x.BlogPost } - return "" + return nil } -type OrderInput struct { +// Request message for blogPostById operation. +type QueryBlogPostByIdRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` - CustomerName string `protobuf:"bytes,2,opt,name=customer_name,json=customerName,proto3" json:"customer_name,omitempty"` - Lines []*OrderLineInput `protobuf:"bytes,3,rep,name=lines,proto3" json:"lines,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *OrderInput) Reset() { - *x = OrderInput{} +func (x *QueryBlogPostByIdRequest) Reset() { + *x = QueryBlogPostByIdRequest{} mi := &file_product_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *OrderInput) String() string { +func (x *QueryBlogPostByIdRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*OrderInput) ProtoMessage() {} +func (*QueryBlogPostByIdRequest) ProtoMessage() {} -func (x *OrderInput) ProtoReflect() protoreflect.Message { +func (x *QueryBlogPostByIdRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -3025,56 +2905,40 @@ func (x *OrderInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use OrderInput.ProtoReflect.Descriptor instead. -func (*OrderInput) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryBlogPostByIdRequest.ProtoReflect.Descriptor instead. +func (*QueryBlogPostByIdRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{63} } -func (x *OrderInput) GetOrderId() string { +func (x *QueryBlogPostByIdRequest) GetId() string { if x != nil { - return x.OrderId + return x.Id } return "" } -func (x *OrderInput) GetCustomerName() string { - if x != nil { - return x.CustomerName - } - return "" +// Response message for blogPostById operation. +type QueryBlogPostByIdResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + BlogPostById *BlogPost `protobuf:"bytes,1,opt,name=blog_post_by_id,json=blogPostById,proto3" json:"blog_post_by_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *OrderInput) GetLines() []*OrderLineInput { - if x != nil { - return x.Lines - } - return nil -} - -type Order struct { - state protoimpl.MessageState `protogen:"open.v1"` - OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` - CustomerName string `protobuf:"bytes,2,opt,name=customer_name,json=customerName,proto3" json:"customer_name,omitempty"` - TotalItems int32 `protobuf:"varint,3,opt,name=total_items,json=totalItems,proto3" json:"total_items,omitempty"` - OrderLines []*OrderLine `protobuf:"bytes,4,rep,name=order_lines,json=orderLines,proto3" json:"order_lines,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Order) Reset() { - *x = Order{} +func (x *QueryBlogPostByIdResponse) Reset() { + *x = QueryBlogPostByIdResponse{} mi := &file_product_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Order) String() string { +func (x *QueryBlogPostByIdResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Order) ProtoMessage() {} +func (*QueryBlogPostByIdResponse) ProtoMessage() {} -func (x *Order) ProtoReflect() protoreflect.Message { +func (x *QueryBlogPostByIdResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -3086,62 +2950,40 @@ func (x *Order) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Order.ProtoReflect.Descriptor instead. -func (*Order) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryBlogPostByIdResponse.ProtoReflect.Descriptor instead. +func (*QueryBlogPostByIdResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{64} } -func (x *Order) GetOrderId() string { - if x != nil { - return x.OrderId - } - return "" -} - -func (x *Order) GetCustomerName() string { - if x != nil { - return x.CustomerName - } - return "" -} - -func (x *Order) GetTotalItems() int32 { - if x != nil { - return x.TotalItems - } - return 0 -} - -func (x *Order) GetOrderLines() []*OrderLine { +func (x *QueryBlogPostByIdResponse) GetBlogPostById() *BlogPost { if x != nil { - return x.OrderLines + return x.BlogPostById } return nil } -type Category struct { +// Request message for blogPostsWithFilter operation. +type QueryBlogPostsWithFilterRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Kind CategoryKind `protobuf:"varint,3,opt,name=kind,proto3,enum=productv1.CategoryKind" json:"kind,omitempty"` + Filter *BlogPostFilter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Category) Reset() { - *x = Category{} +func (x *QueryBlogPostsWithFilterRequest) Reset() { + *x = QueryBlogPostsWithFilterRequest{} mi := &file_product_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Category) String() string { +func (x *QueryBlogPostsWithFilterRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Category) ProtoMessage() {} +func (*QueryBlogPostsWithFilterRequest) ProtoMessage() {} -func (x *Category) ProtoReflect() protoreflect.Message { +func (x *QueryBlogPostsWithFilterRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -3153,54 +2995,40 @@ func (x *Category) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Category.ProtoReflect.Descriptor instead. -func (*Category) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryBlogPostsWithFilterRequest.ProtoReflect.Descriptor instead. +func (*QueryBlogPostsWithFilterRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{65} } -func (x *Category) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Category) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Category) GetKind() CategoryKind { +func (x *QueryBlogPostsWithFilterRequest) GetFilter() *BlogPostFilter { if x != nil { - return x.Kind + return x.Filter } - return CategoryKind_CATEGORY_KIND_UNSPECIFIED + return nil } -type CategoryFilter struct { - state protoimpl.MessageState `protogen:"open.v1"` - Category CategoryKind `protobuf:"varint,1,opt,name=category,proto3,enum=productv1.CategoryKind" json:"category,omitempty"` - Pagination *Pagination `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Response message for blogPostsWithFilter operation. +type QueryBlogPostsWithFilterResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + BlogPostsWithFilter []*BlogPost `protobuf:"bytes,1,rep,name=blog_posts_with_filter,json=blogPostsWithFilter,proto3" json:"blog_posts_with_filter,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *CategoryFilter) Reset() { - *x = CategoryFilter{} +func (x *QueryBlogPostsWithFilterResponse) Reset() { + *x = QueryBlogPostsWithFilterResponse{} mi := &file_product_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *CategoryFilter) String() string { +func (x *QueryBlogPostsWithFilterResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CategoryFilter) ProtoMessage() {} +func (*QueryBlogPostsWithFilterResponse) ProtoMessage() {} -func (x *CategoryFilter) ProtoReflect() protoreflect.Message { +func (x *QueryBlogPostsWithFilterResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -3212,50 +3040,39 @@ func (x *CategoryFilter) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use CategoryFilter.ProtoReflect.Descriptor instead. -func (*CategoryFilter) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryBlogPostsWithFilterResponse.ProtoReflect.Descriptor instead. +func (*QueryBlogPostsWithFilterResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{66} } -func (x *CategoryFilter) GetCategory() CategoryKind { - if x != nil { - return x.Category - } - return CategoryKind_CATEGORY_KIND_UNSPECIFIED -} - -func (x *CategoryFilter) GetPagination() *Pagination { +func (x *QueryBlogPostsWithFilterResponse) GetBlogPostsWithFilter() []*BlogPost { if x != nil { - return x.Pagination + return x.BlogPostsWithFilter } return nil } -type Animal struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Instance: - // - // *Animal_Cat - // *Animal_Dog - Instance isAnimal_Instance `protobuf_oneof:"instance"` +// Request message for allBlogPosts operation. +type QueryAllBlogPostsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Animal) Reset() { - *x = Animal{} +func (x *QueryAllBlogPostsRequest) Reset() { + *x = QueryAllBlogPostsRequest{} mi := &file_product_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Animal) String() string { +func (x *QueryAllBlogPostsRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Animal) ProtoMessage() {} +func (*QueryAllBlogPostsRequest) ProtoMessage() {} -func (x *Animal) ProtoReflect() protoreflect.Message { +func (x *QueryAllBlogPostsRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -3267,74 +3084,33 @@ func (x *Animal) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Animal.ProtoReflect.Descriptor instead. -func (*Animal) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryAllBlogPostsRequest.ProtoReflect.Descriptor instead. +func (*QueryAllBlogPostsRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{67} } -func (x *Animal) GetInstance() isAnimal_Instance { - if x != nil { - return x.Instance - } - return nil -} - -func (x *Animal) GetCat() *Cat { - if x != nil { - if x, ok := x.Instance.(*Animal_Cat); ok { - return x.Cat - } - } - return nil -} - -func (x *Animal) GetDog() *Dog { - if x != nil { - if x, ok := x.Instance.(*Animal_Dog); ok { - return x.Dog - } - } - return nil -} - -type isAnimal_Instance interface { - isAnimal_Instance() -} - -type Animal_Cat struct { - Cat *Cat `protobuf:"bytes,1,opt,name=cat,proto3,oneof"` -} - -type Animal_Dog struct { - Dog *Dog `protobuf:"bytes,2,opt,name=dog,proto3,oneof"` -} - -func (*Animal_Cat) isAnimal_Instance() {} - -func (*Animal_Dog) isAnimal_Instance() {} - -type SearchInput struct { +// Response message for allBlogPosts operation. +type QueryAllBlogPostsResponse struct { state protoimpl.MessageState `protogen:"open.v1"` - Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` - Limit int32 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` + AllBlogPosts []*BlogPost `protobuf:"bytes,1,rep,name=all_blog_posts,json=allBlogPosts,proto3" json:"all_blog_posts,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *SearchInput) Reset() { - *x = SearchInput{} +func (x *QueryAllBlogPostsResponse) Reset() { + *x = QueryAllBlogPostsResponse{} mi := &file_product_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *SearchInput) String() string { +func (x *QueryAllBlogPostsResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SearchInput) ProtoMessage() {} +func (*QueryAllBlogPostsResponse) ProtoMessage() {} -func (x *SearchInput) ProtoReflect() protoreflect.Message { +func (x *QueryAllBlogPostsResponse) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -3346,51 +3122,39 @@ func (x *SearchInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SearchInput.ProtoReflect.Descriptor instead. -func (*SearchInput) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryAllBlogPostsResponse.ProtoReflect.Descriptor instead. +func (*QueryAllBlogPostsResponse) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{68} } -func (x *SearchInput) GetQuery() string { - if x != nil { - return x.Query - } - return "" -} - -func (x *SearchInput) GetLimit() int32 { +func (x *QueryAllBlogPostsResponse) GetAllBlogPosts() []*BlogPost { if x != nil { - return x.Limit + return x.AllBlogPosts } - return 0 + return nil } -type SearchResult struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Value: - // - // *SearchResult_Product - // *SearchResult_User - // *SearchResult_Category - Value isSearchResult_Value `protobuf_oneof:"value"` +// Request message for author operation. +type QueryAuthorRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *SearchResult) Reset() { - *x = SearchResult{} +func (x *QueryAuthorRequest) Reset() { + *x = QueryAuthorRequest{} mi := &file_product_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *SearchResult) String() string { +func (x *QueryAuthorRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SearchResult) ProtoMessage() {} +func (*QueryAuthorRequest) ProtoMessage() {} -func (x *SearchResult) ProtoReflect() protoreflect.Message { +func (x *QueryAuthorRequest) ProtoReflect() protoreflect.Message { mi := &file_product_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -3402,89 +3166,79 @@ func (x *SearchResult) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SearchResult.ProtoReflect.Descriptor instead. -func (*SearchResult) Descriptor() ([]byte, []int) { +// Deprecated: Use QueryAuthorRequest.ProtoReflect.Descriptor instead. +func (*QueryAuthorRequest) Descriptor() ([]byte, []int) { return file_product_proto_rawDescGZIP(), []int{69} } -func (x *SearchResult) GetValue() isSearchResult_Value { - if x != nil { - return x.Value - } - return nil +// Response message for author operation. +type QueryAuthorResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Author *Author `protobuf:"bytes,1,opt,name=author,proto3" json:"author,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *SearchResult) GetProduct() *Product { - if x != nil { - if x, ok := x.Value.(*SearchResult_Product); ok { - return x.Product - } - } - return nil +func (x *QueryAuthorResponse) Reset() { + *x = QueryAuthorResponse{} + mi := &file_product_proto_msgTypes[70] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *SearchResult) GetUser() *User { - if x != nil { - if x, ok := x.Value.(*SearchResult_User); ok { - return x.User - } - } - return nil +func (x *QueryAuthorResponse) String() string { + return protoimpl.X.MessageStringOf(x) } -func (x *SearchResult) GetCategory() *Category { +func (*QueryAuthorResponse) ProtoMessage() {} + +func (x *QueryAuthorResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[70] if x != nil { - if x, ok := x.Value.(*SearchResult_Category); ok { - return x.Category + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) } + return ms } - return nil -} - -type isSearchResult_Value interface { - isSearchResult_Value() -} - -type SearchResult_Product struct { - Product *Product `protobuf:"bytes,1,opt,name=product,proto3,oneof"` + return mi.MessageOf(x) } -type SearchResult_User struct { - User *User `protobuf:"bytes,2,opt,name=user,proto3,oneof"` +// Deprecated: Use QueryAuthorResponse.ProtoReflect.Descriptor instead. +func (*QueryAuthorResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{70} } -type SearchResult_Category struct { - Category *Category `protobuf:"bytes,3,opt,name=category,proto3,oneof"` +func (x *QueryAuthorResponse) GetAuthor() *Author { + if x != nil { + return x.Author + } + return nil } -func (*SearchResult_Product) isSearchResult_Value() {} - -func (*SearchResult_User) isSearchResult_Value() {} - -func (*SearchResult_Category) isSearchResult_Value() {} - -type UserInput struct { +// Request message for authorById operation. +type QueryAuthorByIdRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *UserInput) Reset() { - *x = UserInput{} - mi := &file_product_proto_msgTypes[70] +func (x *QueryAuthorByIdRequest) Reset() { + *x = QueryAuthorByIdRequest{} + mi := &file_product_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *UserInput) String() string { +func (x *QueryAuthorByIdRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*UserInput) ProtoMessage() {} +func (*QueryAuthorByIdRequest) ProtoMessage() {} -func (x *UserInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[70] +func (x *QueryAuthorByIdRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3495,41 +3249,3457 @@ func (x *UserInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use UserInput.ProtoReflect.Descriptor instead. +// Deprecated: Use QueryAuthorByIdRequest.ProtoReflect.Descriptor instead. +func (*QueryAuthorByIdRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{71} +} + +func (x *QueryAuthorByIdRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// Response message for authorById operation. +type QueryAuthorByIdResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + AuthorById *Author `protobuf:"bytes,1,opt,name=author_by_id,json=authorById,proto3" json:"author_by_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QueryAuthorByIdResponse) Reset() { + *x = QueryAuthorByIdResponse{} + mi := &file_product_proto_msgTypes[72] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *QueryAuthorByIdResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryAuthorByIdResponse) ProtoMessage() {} + +func (x *QueryAuthorByIdResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[72] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryAuthorByIdResponse.ProtoReflect.Descriptor instead. +func (*QueryAuthorByIdResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{72} +} + +func (x *QueryAuthorByIdResponse) GetAuthorById() *Author { + if x != nil { + return x.AuthorById + } + return nil +} + +// Request message for authorsWithFilter operation. +type QueryAuthorsWithFilterRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Filter *AuthorFilter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QueryAuthorsWithFilterRequest) Reset() { + *x = QueryAuthorsWithFilterRequest{} + mi := &file_product_proto_msgTypes[73] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *QueryAuthorsWithFilterRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryAuthorsWithFilterRequest) ProtoMessage() {} + +func (x *QueryAuthorsWithFilterRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[73] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryAuthorsWithFilterRequest.ProtoReflect.Descriptor instead. +func (*QueryAuthorsWithFilterRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{73} +} + +func (x *QueryAuthorsWithFilterRequest) GetFilter() *AuthorFilter { + if x != nil { + return x.Filter + } + return nil +} + +// Response message for authorsWithFilter operation. +type QueryAuthorsWithFilterResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + AuthorsWithFilter []*Author `protobuf:"bytes,1,rep,name=authors_with_filter,json=authorsWithFilter,proto3" json:"authors_with_filter,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QueryAuthorsWithFilterResponse) Reset() { + *x = QueryAuthorsWithFilterResponse{} + mi := &file_product_proto_msgTypes[74] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *QueryAuthorsWithFilterResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryAuthorsWithFilterResponse) ProtoMessage() {} + +func (x *QueryAuthorsWithFilterResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[74] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryAuthorsWithFilterResponse.ProtoReflect.Descriptor instead. +func (*QueryAuthorsWithFilterResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{74} +} + +func (x *QueryAuthorsWithFilterResponse) GetAuthorsWithFilter() []*Author { + if x != nil { + return x.AuthorsWithFilter + } + return nil +} + +// Request message for allAuthors operation. +type QueryAllAuthorsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QueryAllAuthorsRequest) Reset() { + *x = QueryAllAuthorsRequest{} + mi := &file_product_proto_msgTypes[75] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *QueryAllAuthorsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryAllAuthorsRequest) ProtoMessage() {} + +func (x *QueryAllAuthorsRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[75] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryAllAuthorsRequest.ProtoReflect.Descriptor instead. +func (*QueryAllAuthorsRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{75} +} + +// Response message for allAuthors operation. +type QueryAllAuthorsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + AllAuthors []*Author `protobuf:"bytes,1,rep,name=all_authors,json=allAuthors,proto3" json:"all_authors,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QueryAllAuthorsResponse) Reset() { + *x = QueryAllAuthorsResponse{} + mi := &file_product_proto_msgTypes[76] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *QueryAllAuthorsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryAllAuthorsResponse) ProtoMessage() {} + +func (x *QueryAllAuthorsResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[76] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryAllAuthorsResponse.ProtoReflect.Descriptor instead. +func (*QueryAllAuthorsResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{76} +} + +func (x *QueryAllAuthorsResponse) GetAllAuthors() []*Author { + if x != nil { + return x.AllAuthors + } + return nil +} + +// Request message for createUser operation. +type MutationCreateUserRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Input *UserInput `protobuf:"bytes,1,opt,name=input,proto3" json:"input,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutationCreateUserRequest) Reset() { + *x = MutationCreateUserRequest{} + mi := &file_product_proto_msgTypes[77] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutationCreateUserRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationCreateUserRequest) ProtoMessage() {} + +func (x *MutationCreateUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[77] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationCreateUserRequest.ProtoReflect.Descriptor instead. +func (*MutationCreateUserRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{77} +} + +func (x *MutationCreateUserRequest) GetInput() *UserInput { + if x != nil { + return x.Input + } + return nil +} + +// Response message for createUser operation. +type MutationCreateUserResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + CreateUser *User `protobuf:"bytes,1,opt,name=create_user,json=createUser,proto3" json:"create_user,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutationCreateUserResponse) Reset() { + *x = MutationCreateUserResponse{} + mi := &file_product_proto_msgTypes[78] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutationCreateUserResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationCreateUserResponse) ProtoMessage() {} + +func (x *MutationCreateUserResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[78] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationCreateUserResponse.ProtoReflect.Descriptor instead. +func (*MutationCreateUserResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{78} +} + +func (x *MutationCreateUserResponse) GetCreateUser() *User { + if x != nil { + return x.CreateUser + } + return nil +} + +// Request message for performAction operation. +type MutationPerformActionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Input *ActionInput `protobuf:"bytes,1,opt,name=input,proto3" json:"input,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutationPerformActionRequest) Reset() { + *x = MutationPerformActionRequest{} + mi := &file_product_proto_msgTypes[79] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutationPerformActionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationPerformActionRequest) ProtoMessage() {} + +func (x *MutationPerformActionRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[79] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationPerformActionRequest.ProtoReflect.Descriptor instead. +func (*MutationPerformActionRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{79} +} + +func (x *MutationPerformActionRequest) GetInput() *ActionInput { + if x != nil { + return x.Input + } + return nil +} + +// Response message for performAction operation. +type MutationPerformActionResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + PerformAction *ActionResult `protobuf:"bytes,1,opt,name=perform_action,json=performAction,proto3" json:"perform_action,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutationPerformActionResponse) Reset() { + *x = MutationPerformActionResponse{} + mi := &file_product_proto_msgTypes[80] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutationPerformActionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationPerformActionResponse) ProtoMessage() {} + +func (x *MutationPerformActionResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[80] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationPerformActionResponse.ProtoReflect.Descriptor instead. +func (*MutationPerformActionResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{80} +} + +func (x *MutationPerformActionResponse) GetPerformAction() *ActionResult { + if x != nil { + return x.PerformAction + } + return nil +} + +// Request message for createNullableFieldsType operation. +type MutationCreateNullableFieldsTypeRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Input *NullableFieldsInput `protobuf:"bytes,1,opt,name=input,proto3" json:"input,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutationCreateNullableFieldsTypeRequest) Reset() { + *x = MutationCreateNullableFieldsTypeRequest{} + mi := &file_product_proto_msgTypes[81] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutationCreateNullableFieldsTypeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationCreateNullableFieldsTypeRequest) ProtoMessage() {} + +func (x *MutationCreateNullableFieldsTypeRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[81] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationCreateNullableFieldsTypeRequest.ProtoReflect.Descriptor instead. +func (*MutationCreateNullableFieldsTypeRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{81} +} + +func (x *MutationCreateNullableFieldsTypeRequest) GetInput() *NullableFieldsInput { + if x != nil { + return x.Input + } + return nil +} + +// Response message for createNullableFieldsType operation. +type MutationCreateNullableFieldsTypeResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + CreateNullableFieldsType *NullableFieldsType `protobuf:"bytes,1,opt,name=create_nullable_fields_type,json=createNullableFieldsType,proto3" json:"create_nullable_fields_type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutationCreateNullableFieldsTypeResponse) Reset() { + *x = MutationCreateNullableFieldsTypeResponse{} + mi := &file_product_proto_msgTypes[82] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutationCreateNullableFieldsTypeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationCreateNullableFieldsTypeResponse) ProtoMessage() {} + +func (x *MutationCreateNullableFieldsTypeResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[82] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationCreateNullableFieldsTypeResponse.ProtoReflect.Descriptor instead. +func (*MutationCreateNullableFieldsTypeResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{82} +} + +func (x *MutationCreateNullableFieldsTypeResponse) GetCreateNullableFieldsType() *NullableFieldsType { + if x != nil { + return x.CreateNullableFieldsType + } + return nil +} + +// Request message for updateNullableFieldsType operation. +type MutationUpdateNullableFieldsTypeRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Input *NullableFieldsInput `protobuf:"bytes,2,opt,name=input,proto3" json:"input,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutationUpdateNullableFieldsTypeRequest) Reset() { + *x = MutationUpdateNullableFieldsTypeRequest{} + mi := &file_product_proto_msgTypes[83] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutationUpdateNullableFieldsTypeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationUpdateNullableFieldsTypeRequest) ProtoMessage() {} + +func (x *MutationUpdateNullableFieldsTypeRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[83] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationUpdateNullableFieldsTypeRequest.ProtoReflect.Descriptor instead. +func (*MutationUpdateNullableFieldsTypeRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{83} +} + +func (x *MutationUpdateNullableFieldsTypeRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *MutationUpdateNullableFieldsTypeRequest) GetInput() *NullableFieldsInput { + if x != nil { + return x.Input + } + return nil +} + +// Response message for updateNullableFieldsType operation. +type MutationUpdateNullableFieldsTypeResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdateNullableFieldsType *NullableFieldsType `protobuf:"bytes,1,opt,name=update_nullable_fields_type,json=updateNullableFieldsType,proto3" json:"update_nullable_fields_type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutationUpdateNullableFieldsTypeResponse) Reset() { + *x = MutationUpdateNullableFieldsTypeResponse{} + mi := &file_product_proto_msgTypes[84] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutationUpdateNullableFieldsTypeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationUpdateNullableFieldsTypeResponse) ProtoMessage() {} + +func (x *MutationUpdateNullableFieldsTypeResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[84] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationUpdateNullableFieldsTypeResponse.ProtoReflect.Descriptor instead. +func (*MutationUpdateNullableFieldsTypeResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{84} +} + +func (x *MutationUpdateNullableFieldsTypeResponse) GetUpdateNullableFieldsType() *NullableFieldsType { + if x != nil { + return x.UpdateNullableFieldsType + } + return nil +} + +// Request message for createBlogPost operation. +type MutationCreateBlogPostRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Input *BlogPostInput `protobuf:"bytes,1,opt,name=input,proto3" json:"input,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutationCreateBlogPostRequest) Reset() { + *x = MutationCreateBlogPostRequest{} + mi := &file_product_proto_msgTypes[85] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutationCreateBlogPostRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationCreateBlogPostRequest) ProtoMessage() {} + +func (x *MutationCreateBlogPostRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[85] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationCreateBlogPostRequest.ProtoReflect.Descriptor instead. +func (*MutationCreateBlogPostRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{85} +} + +func (x *MutationCreateBlogPostRequest) GetInput() *BlogPostInput { + if x != nil { + return x.Input + } + return nil +} + +// Response message for createBlogPost operation. +type MutationCreateBlogPostResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + CreateBlogPost *BlogPost `protobuf:"bytes,1,opt,name=create_blog_post,json=createBlogPost,proto3" json:"create_blog_post,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutationCreateBlogPostResponse) Reset() { + *x = MutationCreateBlogPostResponse{} + mi := &file_product_proto_msgTypes[86] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutationCreateBlogPostResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationCreateBlogPostResponse) ProtoMessage() {} + +func (x *MutationCreateBlogPostResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[86] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationCreateBlogPostResponse.ProtoReflect.Descriptor instead. +func (*MutationCreateBlogPostResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{86} +} + +func (x *MutationCreateBlogPostResponse) GetCreateBlogPost() *BlogPost { + if x != nil { + return x.CreateBlogPost + } + return nil +} + +// Request message for updateBlogPost operation. +type MutationUpdateBlogPostRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Input *BlogPostInput `protobuf:"bytes,2,opt,name=input,proto3" json:"input,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutationUpdateBlogPostRequest) Reset() { + *x = MutationUpdateBlogPostRequest{} + mi := &file_product_proto_msgTypes[87] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutationUpdateBlogPostRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationUpdateBlogPostRequest) ProtoMessage() {} + +func (x *MutationUpdateBlogPostRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[87] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationUpdateBlogPostRequest.ProtoReflect.Descriptor instead. +func (*MutationUpdateBlogPostRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{87} +} + +func (x *MutationUpdateBlogPostRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *MutationUpdateBlogPostRequest) GetInput() *BlogPostInput { + if x != nil { + return x.Input + } + return nil +} + +// Response message for updateBlogPost operation. +type MutationUpdateBlogPostResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdateBlogPost *BlogPost `protobuf:"bytes,1,opt,name=update_blog_post,json=updateBlogPost,proto3" json:"update_blog_post,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutationUpdateBlogPostResponse) Reset() { + *x = MutationUpdateBlogPostResponse{} + mi := &file_product_proto_msgTypes[88] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutationUpdateBlogPostResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationUpdateBlogPostResponse) ProtoMessage() {} + +func (x *MutationUpdateBlogPostResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[88] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationUpdateBlogPostResponse.ProtoReflect.Descriptor instead. +func (*MutationUpdateBlogPostResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{88} +} + +func (x *MutationUpdateBlogPostResponse) GetUpdateBlogPost() *BlogPost { + if x != nil { + return x.UpdateBlogPost + } + return nil +} + +// Request message for createAuthor operation. +type MutationCreateAuthorRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Input *AuthorInput `protobuf:"bytes,1,opt,name=input,proto3" json:"input,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutationCreateAuthorRequest) Reset() { + *x = MutationCreateAuthorRequest{} + mi := &file_product_proto_msgTypes[89] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutationCreateAuthorRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationCreateAuthorRequest) ProtoMessage() {} + +func (x *MutationCreateAuthorRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[89] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationCreateAuthorRequest.ProtoReflect.Descriptor instead. +func (*MutationCreateAuthorRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{89} +} + +func (x *MutationCreateAuthorRequest) GetInput() *AuthorInput { + if x != nil { + return x.Input + } + return nil +} + +// Response message for createAuthor operation. +type MutationCreateAuthorResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + CreateAuthor *Author `protobuf:"bytes,1,opt,name=create_author,json=createAuthor,proto3" json:"create_author,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutationCreateAuthorResponse) Reset() { + *x = MutationCreateAuthorResponse{} + mi := &file_product_proto_msgTypes[90] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutationCreateAuthorResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationCreateAuthorResponse) ProtoMessage() {} + +func (x *MutationCreateAuthorResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[90] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationCreateAuthorResponse.ProtoReflect.Descriptor instead. +func (*MutationCreateAuthorResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{90} +} + +func (x *MutationCreateAuthorResponse) GetCreateAuthor() *Author { + if x != nil { + return x.CreateAuthor + } + return nil +} + +// Request message for updateAuthor operation. +type MutationUpdateAuthorRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Input *AuthorInput `protobuf:"bytes,2,opt,name=input,proto3" json:"input,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutationUpdateAuthorRequest) Reset() { + *x = MutationUpdateAuthorRequest{} + mi := &file_product_proto_msgTypes[91] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutationUpdateAuthorRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationUpdateAuthorRequest) ProtoMessage() {} + +func (x *MutationUpdateAuthorRequest) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[91] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationUpdateAuthorRequest.ProtoReflect.Descriptor instead. +func (*MutationUpdateAuthorRequest) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{91} +} + +func (x *MutationUpdateAuthorRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *MutationUpdateAuthorRequest) GetInput() *AuthorInput { + if x != nil { + return x.Input + } + return nil +} + +// Response message for updateAuthor operation. +type MutationUpdateAuthorResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdateAuthor *Author `protobuf:"bytes,1,opt,name=update_author,json=updateAuthor,proto3" json:"update_author,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutationUpdateAuthorResponse) Reset() { + *x = MutationUpdateAuthorResponse{} + mi := &file_product_proto_msgTypes[92] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutationUpdateAuthorResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutationUpdateAuthorResponse) ProtoMessage() {} + +func (x *MutationUpdateAuthorResponse) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[92] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutationUpdateAuthorResponse.ProtoReflect.Descriptor instead. +func (*MutationUpdateAuthorResponse) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{92} +} + +func (x *MutationUpdateAuthorResponse) GetUpdateAuthor() *Author { + if x != nil { + return x.UpdateAuthor + } + return nil +} + +type Product struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Price float64 `protobuf:"fixed64,3,opt,name=price,proto3" json:"price,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Product) Reset() { + *x = Product{} + mi := &file_product_proto_msgTypes[93] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Product) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Product) ProtoMessage() {} + +func (x *Product) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[93] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Product.ProtoReflect.Descriptor instead. +func (*Product) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{93} +} + +func (x *Product) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Product) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Product) GetPrice() float64 { + if x != nil { + return x.Price + } + return 0 +} + +type Storage struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Location string `protobuf:"bytes,3,opt,name=location,proto3" json:"location,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Storage) Reset() { + *x = Storage{} + mi := &file_product_proto_msgTypes[94] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Storage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Storage) ProtoMessage() {} + +func (x *Storage) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[94] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Storage.ProtoReflect.Descriptor instead. +func (*Storage) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{94} +} + +func (x *Storage) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Storage) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Storage) GetLocation() string { + if x != nil { + return x.Location + } + return "" +} + +type User struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *User) Reset() { + *x = User{} + mi := &file_product_proto_msgTypes[95] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *User) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*User) ProtoMessage() {} + +func (x *User) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[95] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use User.ProtoReflect.Descriptor instead. +func (*User) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{95} +} + +func (x *User) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *User) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type NestedTypeA struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + B *NestedTypeB `protobuf:"bytes,3,opt,name=b,proto3" json:"b,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NestedTypeA) Reset() { + *x = NestedTypeA{} + mi := &file_product_proto_msgTypes[96] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NestedTypeA) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NestedTypeA) ProtoMessage() {} + +func (x *NestedTypeA) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[96] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NestedTypeA.ProtoReflect.Descriptor instead. +func (*NestedTypeA) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{96} +} + +func (x *NestedTypeA) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *NestedTypeA) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *NestedTypeA) GetB() *NestedTypeB { + if x != nil { + return x.B + } + return nil +} + +type RecursiveType struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + RecursiveType *RecursiveType `protobuf:"bytes,3,opt,name=recursive_type,json=recursiveType,proto3" json:"recursive_type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RecursiveType) Reset() { + *x = RecursiveType{} + mi := &file_product_proto_msgTypes[97] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RecursiveType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RecursiveType) ProtoMessage() {} + +func (x *RecursiveType) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[97] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RecursiveType.ProtoReflect.Descriptor instead. +func (*RecursiveType) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{97} +} + +func (x *RecursiveType) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *RecursiveType) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RecursiveType) GetRecursiveType() *RecursiveType { + if x != nil { + return x.RecursiveType + } + return nil +} + +type TypeWithMultipleFilterFields struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + FilterField_1 string `protobuf:"bytes,3,opt,name=filter_field_1,json=filterField1,proto3" json:"filter_field_1,omitempty"` + FilterField_2 string `protobuf:"bytes,4,opt,name=filter_field_2,json=filterField2,proto3" json:"filter_field_2,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TypeWithMultipleFilterFields) Reset() { + *x = TypeWithMultipleFilterFields{} + mi := &file_product_proto_msgTypes[98] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TypeWithMultipleFilterFields) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TypeWithMultipleFilterFields) ProtoMessage() {} + +func (x *TypeWithMultipleFilterFields) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[98] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TypeWithMultipleFilterFields.ProtoReflect.Descriptor instead. +func (*TypeWithMultipleFilterFields) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{98} +} + +func (x *TypeWithMultipleFilterFields) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *TypeWithMultipleFilterFields) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *TypeWithMultipleFilterFields) GetFilterField_1() string { + if x != nil { + return x.FilterField_1 + } + return "" +} + +func (x *TypeWithMultipleFilterFields) GetFilterField_2() string { + if x != nil { + return x.FilterField_2 + } + return "" +} + +type FilterTypeInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + FilterField_1 string `protobuf:"bytes,1,opt,name=filter_field_1,json=filterField1,proto3" json:"filter_field_1,omitempty"` + FilterField_2 string `protobuf:"bytes,2,opt,name=filter_field_2,json=filterField2,proto3" json:"filter_field_2,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FilterTypeInput) Reset() { + *x = FilterTypeInput{} + mi := &file_product_proto_msgTypes[99] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FilterTypeInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FilterTypeInput) ProtoMessage() {} + +func (x *FilterTypeInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[99] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FilterTypeInput.ProtoReflect.Descriptor instead. +func (*FilterTypeInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{99} +} + +func (x *FilterTypeInput) GetFilterField_1() string { + if x != nil { + return x.FilterField_1 + } + return "" +} + +func (x *FilterTypeInput) GetFilterField_2() string { + if x != nil { + return x.FilterField_2 + } + return "" +} + +type ComplexFilterTypeInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + Filter *FilterType `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ComplexFilterTypeInput) Reset() { + *x = ComplexFilterTypeInput{} + mi := &file_product_proto_msgTypes[100] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ComplexFilterTypeInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ComplexFilterTypeInput) ProtoMessage() {} + +func (x *ComplexFilterTypeInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[100] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ComplexFilterTypeInput.ProtoReflect.Descriptor instead. +func (*ComplexFilterTypeInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{100} +} + +func (x *ComplexFilterTypeInput) GetFilter() *FilterType { + if x != nil { + return x.Filter + } + return nil +} + +type TypeWithComplexFilterInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TypeWithComplexFilterInput) Reset() { + *x = TypeWithComplexFilterInput{} + mi := &file_product_proto_msgTypes[101] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TypeWithComplexFilterInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TypeWithComplexFilterInput) ProtoMessage() {} + +func (x *TypeWithComplexFilterInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[101] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TypeWithComplexFilterInput.ProtoReflect.Descriptor instead. +func (*TypeWithComplexFilterInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{101} +} + +func (x *TypeWithComplexFilterInput) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *TypeWithComplexFilterInput) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type OrderInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` + CustomerName string `protobuf:"bytes,2,opt,name=customer_name,json=customerName,proto3" json:"customer_name,omitempty"` + Lines []*OrderLineInput `protobuf:"bytes,3,rep,name=lines,proto3" json:"lines,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *OrderInput) Reset() { + *x = OrderInput{} + mi := &file_product_proto_msgTypes[102] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *OrderInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OrderInput) ProtoMessage() {} + +func (x *OrderInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[102] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OrderInput.ProtoReflect.Descriptor instead. +func (*OrderInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{102} +} + +func (x *OrderInput) GetOrderId() string { + if x != nil { + return x.OrderId + } + return "" +} + +func (x *OrderInput) GetCustomerName() string { + if x != nil { + return x.CustomerName + } + return "" +} + +func (x *OrderInput) GetLines() []*OrderLineInput { + if x != nil { + return x.Lines + } + return nil +} + +type Order struct { + state protoimpl.MessageState `protogen:"open.v1"` + OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` + CustomerName string `protobuf:"bytes,2,opt,name=customer_name,json=customerName,proto3" json:"customer_name,omitempty"` + TotalItems int32 `protobuf:"varint,3,opt,name=total_items,json=totalItems,proto3" json:"total_items,omitempty"` + OrderLines *ListOfOrderLine `protobuf:"bytes,4,opt,name=order_lines,json=orderLines,proto3" json:"order_lines,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Order) Reset() { + *x = Order{} + mi := &file_product_proto_msgTypes[103] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Order) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Order) ProtoMessage() {} + +func (x *Order) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[103] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Order.ProtoReflect.Descriptor instead. +func (*Order) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{103} +} + +func (x *Order) GetOrderId() string { + if x != nil { + return x.OrderId + } + return "" +} + +func (x *Order) GetCustomerName() string { + if x != nil { + return x.CustomerName + } + return "" +} + +func (x *Order) GetTotalItems() int32 { + if x != nil { + return x.TotalItems + } + return 0 +} + +func (x *Order) GetOrderLines() *ListOfOrderLine { + if x != nil { + return x.OrderLines + } + return nil +} + +type Category struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Kind CategoryKind `protobuf:"varint,3,opt,name=kind,proto3,enum=productv1.CategoryKind" json:"kind,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Category) Reset() { + *x = Category{} + mi := &file_product_proto_msgTypes[104] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Category) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Category) ProtoMessage() {} + +func (x *Category) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[104] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Category.ProtoReflect.Descriptor instead. +func (*Category) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{104} +} + +func (x *Category) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Category) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Category) GetKind() CategoryKind { + if x != nil { + return x.Kind + } + return CategoryKind_CATEGORY_KIND_UNSPECIFIED +} + +type CategoryFilter struct { + state protoimpl.MessageState `protogen:"open.v1"` + Category CategoryKind `protobuf:"varint,1,opt,name=category,proto3,enum=productv1.CategoryKind" json:"category,omitempty"` + Pagination *Pagination `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CategoryFilter) Reset() { + *x = CategoryFilter{} + mi := &file_product_proto_msgTypes[105] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CategoryFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CategoryFilter) ProtoMessage() {} + +func (x *CategoryFilter) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[105] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CategoryFilter.ProtoReflect.Descriptor instead. +func (*CategoryFilter) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{105} +} + +func (x *CategoryFilter) GetCategory() CategoryKind { + if x != nil { + return x.Category + } + return CategoryKind_CATEGORY_KIND_UNSPECIFIED +} + +func (x *CategoryFilter) GetPagination() *Pagination { + if x != nil { + return x.Pagination + } + return nil +} + +type Animal struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Instance: + // + // *Animal_Cat + // *Animal_Dog + Instance isAnimal_Instance `protobuf_oneof:"instance"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Animal) Reset() { + *x = Animal{} + mi := &file_product_proto_msgTypes[106] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Animal) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Animal) ProtoMessage() {} + +func (x *Animal) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[106] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Animal.ProtoReflect.Descriptor instead. +func (*Animal) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{106} +} + +func (x *Animal) GetInstance() isAnimal_Instance { + if x != nil { + return x.Instance + } + return nil +} + +func (x *Animal) GetCat() *Cat { + if x != nil { + if x, ok := x.Instance.(*Animal_Cat); ok { + return x.Cat + } + } + return nil +} + +func (x *Animal) GetDog() *Dog { + if x != nil { + if x, ok := x.Instance.(*Animal_Dog); ok { + return x.Dog + } + } + return nil +} + +type isAnimal_Instance interface { + isAnimal_Instance() +} + +type Animal_Cat struct { + Cat *Cat `protobuf:"bytes,1,opt,name=cat,proto3,oneof"` +} + +type Animal_Dog struct { + Dog *Dog `protobuf:"bytes,2,opt,name=dog,proto3,oneof"` +} + +func (*Animal_Cat) isAnimal_Instance() {} + +func (*Animal_Dog) isAnimal_Instance() {} + +type SearchInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` + Limit *wrapperspb.Int32Value `protobuf:"bytes,2,opt,name=limit,proto3" json:"limit,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SearchInput) Reset() { + *x = SearchInput{} + mi := &file_product_proto_msgTypes[107] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SearchInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SearchInput) ProtoMessage() {} + +func (x *SearchInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[107] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SearchInput.ProtoReflect.Descriptor instead. +func (*SearchInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{107} +} + +func (x *SearchInput) GetQuery() string { + if x != nil { + return x.Query + } + return "" +} + +func (x *SearchInput) GetLimit() *wrapperspb.Int32Value { + if x != nil { + return x.Limit + } + return nil +} + +type SearchResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Value: + // + // *SearchResult_Product + // *SearchResult_User + // *SearchResult_Category + Value isSearchResult_Value `protobuf_oneof:"value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SearchResult) Reset() { + *x = SearchResult{} + mi := &file_product_proto_msgTypes[108] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SearchResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SearchResult) ProtoMessage() {} + +func (x *SearchResult) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[108] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SearchResult.ProtoReflect.Descriptor instead. +func (*SearchResult) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{108} +} + +func (x *SearchResult) GetValue() isSearchResult_Value { + if x != nil { + return x.Value + } + return nil +} + +func (x *SearchResult) GetProduct() *Product { + if x != nil { + if x, ok := x.Value.(*SearchResult_Product); ok { + return x.Product + } + } + return nil +} + +func (x *SearchResult) GetUser() *User { + if x != nil { + if x, ok := x.Value.(*SearchResult_User); ok { + return x.User + } + } + return nil +} + +func (x *SearchResult) GetCategory() *Category { + if x != nil { + if x, ok := x.Value.(*SearchResult_Category); ok { + return x.Category + } + } + return nil +} + +type isSearchResult_Value interface { + isSearchResult_Value() +} + +type SearchResult_Product struct { + Product *Product `protobuf:"bytes,1,opt,name=product,proto3,oneof"` +} + +type SearchResult_User struct { + User *User `protobuf:"bytes,2,opt,name=user,proto3,oneof"` +} + +type SearchResult_Category struct { + Category *Category `protobuf:"bytes,3,opt,name=category,proto3,oneof"` +} + +func (*SearchResult_Product) isSearchResult_Value() {} + +func (*SearchResult_User) isSearchResult_Value() {} + +func (*SearchResult_Category) isSearchResult_Value() {} + +type NullableFieldsType struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + OptionalString *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=optional_string,json=optionalString,proto3" json:"optional_string,omitempty"` + OptionalInt *wrapperspb.Int32Value `protobuf:"bytes,4,opt,name=optional_int,json=optionalInt,proto3" json:"optional_int,omitempty"` + OptionalFloat *wrapperspb.DoubleValue `protobuf:"bytes,5,opt,name=optional_float,json=optionalFloat,proto3" json:"optional_float,omitempty"` + OptionalBoolean *wrapperspb.BoolValue `protobuf:"bytes,6,opt,name=optional_boolean,json=optionalBoolean,proto3" json:"optional_boolean,omitempty"` + RequiredString string `protobuf:"bytes,7,opt,name=required_string,json=requiredString,proto3" json:"required_string,omitempty"` + RequiredInt int32 `protobuf:"varint,8,opt,name=required_int,json=requiredInt,proto3" json:"required_int,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NullableFieldsType) Reset() { + *x = NullableFieldsType{} + mi := &file_product_proto_msgTypes[109] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NullableFieldsType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NullableFieldsType) ProtoMessage() {} + +func (x *NullableFieldsType) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[109] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NullableFieldsType.ProtoReflect.Descriptor instead. +func (*NullableFieldsType) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{109} +} + +func (x *NullableFieldsType) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *NullableFieldsType) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *NullableFieldsType) GetOptionalString() *wrapperspb.StringValue { + if x != nil { + return x.OptionalString + } + return nil +} + +func (x *NullableFieldsType) GetOptionalInt() *wrapperspb.Int32Value { + if x != nil { + return x.OptionalInt + } + return nil +} + +func (x *NullableFieldsType) GetOptionalFloat() *wrapperspb.DoubleValue { + if x != nil { + return x.OptionalFloat + } + return nil +} + +func (x *NullableFieldsType) GetOptionalBoolean() *wrapperspb.BoolValue { + if x != nil { + return x.OptionalBoolean + } + return nil +} + +func (x *NullableFieldsType) GetRequiredString() string { + if x != nil { + return x.RequiredString + } + return "" +} + +func (x *NullableFieldsType) GetRequiredInt() int32 { + if x != nil { + return x.RequiredInt + } + return 0 +} + +type NullableFieldsFilter struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name *wrapperspb.StringValue `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + OptionalString *wrapperspb.StringValue `protobuf:"bytes,2,opt,name=optional_string,json=optionalString,proto3" json:"optional_string,omitempty"` + IncludeNulls *wrapperspb.BoolValue `protobuf:"bytes,3,opt,name=include_nulls,json=includeNulls,proto3" json:"include_nulls,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NullableFieldsFilter) Reset() { + *x = NullableFieldsFilter{} + mi := &file_product_proto_msgTypes[110] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NullableFieldsFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NullableFieldsFilter) ProtoMessage() {} + +func (x *NullableFieldsFilter) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[110] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NullableFieldsFilter.ProtoReflect.Descriptor instead. +func (*NullableFieldsFilter) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{110} +} + +func (x *NullableFieldsFilter) GetName() *wrapperspb.StringValue { + if x != nil { + return x.Name + } + return nil +} + +func (x *NullableFieldsFilter) GetOptionalString() *wrapperspb.StringValue { + if x != nil { + return x.OptionalString + } + return nil +} + +func (x *NullableFieldsFilter) GetIncludeNulls() *wrapperspb.BoolValue { + if x != nil { + return x.IncludeNulls + } + return nil +} + +type BlogPost struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + Content string `protobuf:"bytes,3,opt,name=content,proto3" json:"content,omitempty"` + Tags []string `protobuf:"bytes,4,rep,name=tags,proto3" json:"tags,omitempty"` + OptionalTags *ListOfString `protobuf:"bytes,5,opt,name=optional_tags,json=optionalTags,proto3" json:"optional_tags,omitempty"` + Categories []string `protobuf:"bytes,6,rep,name=categories,proto3" json:"categories,omitempty"` + Keywords *ListOfString `protobuf:"bytes,7,opt,name=keywords,proto3" json:"keywords,omitempty"` + ViewCounts []int32 `protobuf:"varint,8,rep,packed,name=view_counts,json=viewCounts,proto3" json:"view_counts,omitempty"` + Ratings *ListOfFloat `protobuf:"bytes,9,opt,name=ratings,proto3" json:"ratings,omitempty"` + IsPublished *ListOfBoolean `protobuf:"bytes,10,opt,name=is_published,json=isPublished,proto3" json:"is_published,omitempty"` + TagGroups *ListOfListOfString `protobuf:"bytes,11,opt,name=tag_groups,json=tagGroups,proto3" json:"tag_groups,omitempty"` + RelatedTopics *ListOfListOfString `protobuf:"bytes,12,opt,name=related_topics,json=relatedTopics,proto3" json:"related_topics,omitempty"` + CommentThreads *ListOfListOfString `protobuf:"bytes,13,opt,name=comment_threads,json=commentThreads,proto3" json:"comment_threads,omitempty"` + Suggestions *ListOfListOfString `protobuf:"bytes,14,opt,name=suggestions,proto3" json:"suggestions,omitempty"` + RelatedCategories []*Category `protobuf:"bytes,15,rep,name=related_categories,json=relatedCategories,proto3" json:"related_categories,omitempty"` + Contributors []*User `protobuf:"bytes,16,rep,name=contributors,proto3" json:"contributors,omitempty"` + MentionedProducts *ListOfProduct `protobuf:"bytes,17,opt,name=mentioned_products,json=mentionedProducts,proto3" json:"mentioned_products,omitempty"` + MentionedUsers *ListOfUser `protobuf:"bytes,18,opt,name=mentioned_users,json=mentionedUsers,proto3" json:"mentioned_users,omitempty"` + CategoryGroups *ListOfListOfCategory `protobuf:"bytes,19,opt,name=category_groups,json=categoryGroups,proto3" json:"category_groups,omitempty"` + ContributorTeams *ListOfListOfUser `protobuf:"bytes,20,opt,name=contributor_teams,json=contributorTeams,proto3" json:"contributor_teams,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BlogPost) Reset() { + *x = BlogPost{} + mi := &file_product_proto_msgTypes[111] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BlogPost) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlogPost) ProtoMessage() {} + +func (x *BlogPost) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[111] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BlogPost.ProtoReflect.Descriptor instead. +func (*BlogPost) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{111} +} + +func (x *BlogPost) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *BlogPost) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *BlogPost) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +func (x *BlogPost) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *BlogPost) GetOptionalTags() *ListOfString { + if x != nil { + return x.OptionalTags + } + return nil +} + +func (x *BlogPost) GetCategories() []string { + if x != nil { + return x.Categories + } + return nil +} + +func (x *BlogPost) GetKeywords() *ListOfString { + if x != nil { + return x.Keywords + } + return nil +} + +func (x *BlogPost) GetViewCounts() []int32 { + if x != nil { + return x.ViewCounts + } + return nil +} + +func (x *BlogPost) GetRatings() *ListOfFloat { + if x != nil { + return x.Ratings + } + return nil +} + +func (x *BlogPost) GetIsPublished() *ListOfBoolean { + if x != nil { + return x.IsPublished + } + return nil +} + +func (x *BlogPost) GetTagGroups() *ListOfListOfString { + if x != nil { + return x.TagGroups + } + return nil +} + +func (x *BlogPost) GetRelatedTopics() *ListOfListOfString { + if x != nil { + return x.RelatedTopics + } + return nil +} + +func (x *BlogPost) GetCommentThreads() *ListOfListOfString { + if x != nil { + return x.CommentThreads + } + return nil +} + +func (x *BlogPost) GetSuggestions() *ListOfListOfString { + if x != nil { + return x.Suggestions + } + return nil +} + +func (x *BlogPost) GetRelatedCategories() []*Category { + if x != nil { + return x.RelatedCategories + } + return nil +} + +func (x *BlogPost) GetContributors() []*User { + if x != nil { + return x.Contributors + } + return nil +} + +func (x *BlogPost) GetMentionedProducts() *ListOfProduct { + if x != nil { + return x.MentionedProducts + } + return nil +} + +func (x *BlogPost) GetMentionedUsers() *ListOfUser { + if x != nil { + return x.MentionedUsers + } + return nil +} + +func (x *BlogPost) GetCategoryGroups() *ListOfListOfCategory { + if x != nil { + return x.CategoryGroups + } + return nil +} + +func (x *BlogPost) GetContributorTeams() *ListOfListOfUser { + if x != nil { + return x.ContributorTeams + } + return nil +} + +type BlogPostFilter struct { + state protoimpl.MessageState `protogen:"open.v1"` + Title *wrapperspb.StringValue `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + HasCategories *wrapperspb.BoolValue `protobuf:"bytes,2,opt,name=has_categories,json=hasCategories,proto3" json:"has_categories,omitempty"` + MinTags *wrapperspb.Int32Value `protobuf:"bytes,3,opt,name=min_tags,json=minTags,proto3" json:"min_tags,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BlogPostFilter) Reset() { + *x = BlogPostFilter{} + mi := &file_product_proto_msgTypes[112] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BlogPostFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlogPostFilter) ProtoMessage() {} + +func (x *BlogPostFilter) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[112] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BlogPostFilter.ProtoReflect.Descriptor instead. +func (*BlogPostFilter) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{112} +} + +func (x *BlogPostFilter) GetTitle() *wrapperspb.StringValue { + if x != nil { + return x.Title + } + return nil +} + +func (x *BlogPostFilter) GetHasCategories() *wrapperspb.BoolValue { + if x != nil { + return x.HasCategories + } + return nil +} + +func (x *BlogPostFilter) GetMinTags() *wrapperspb.Int32Value { + if x != nil { + return x.MinTags + } + return nil +} + +type Author struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Email *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` + Skills []string `protobuf:"bytes,4,rep,name=skills,proto3" json:"skills,omitempty"` + Languages []string `protobuf:"bytes,5,rep,name=languages,proto3" json:"languages,omitempty"` + SocialLinks *ListOfString `protobuf:"bytes,6,opt,name=social_links,json=socialLinks,proto3" json:"social_links,omitempty"` + TeamsByProject *ListOfListOfString `protobuf:"bytes,7,opt,name=teams_by_project,json=teamsByProject,proto3" json:"teams_by_project,omitempty"` + Collaborations *ListOfListOfString `protobuf:"bytes,8,opt,name=collaborations,proto3" json:"collaborations,omitempty"` + WrittenPosts *ListOfBlogPost `protobuf:"bytes,9,opt,name=written_posts,json=writtenPosts,proto3" json:"written_posts,omitempty"` + FavoriteCategories []*Category `protobuf:"bytes,10,rep,name=favorite_categories,json=favoriteCategories,proto3" json:"favorite_categories,omitempty"` + RelatedAuthors *ListOfUser `protobuf:"bytes,11,opt,name=related_authors,json=relatedAuthors,proto3" json:"related_authors,omitempty"` + ProductReviews *ListOfProduct `protobuf:"bytes,12,opt,name=product_reviews,json=productReviews,proto3" json:"product_reviews,omitempty"` + AuthorGroups *ListOfListOfUser `protobuf:"bytes,13,opt,name=author_groups,json=authorGroups,proto3" json:"author_groups,omitempty"` + CategoryPreferences *ListOfListOfCategory `protobuf:"bytes,14,opt,name=category_preferences,json=categoryPreferences,proto3" json:"category_preferences,omitempty"` + ProjectTeams *ListOfListOfUser `protobuf:"bytes,15,opt,name=project_teams,json=projectTeams,proto3" json:"project_teams,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Author) Reset() { + *x = Author{} + mi := &file_product_proto_msgTypes[113] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Author) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Author) ProtoMessage() {} + +func (x *Author) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[113] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Author.ProtoReflect.Descriptor instead. +func (*Author) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{113} +} + +func (x *Author) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Author) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Author) GetEmail() *wrapperspb.StringValue { + if x != nil { + return x.Email + } + return nil +} + +func (x *Author) GetSkills() []string { + if x != nil { + return x.Skills + } + return nil +} + +func (x *Author) GetLanguages() []string { + if x != nil { + return x.Languages + } + return nil +} + +func (x *Author) GetSocialLinks() *ListOfString { + if x != nil { + return x.SocialLinks + } + return nil +} + +func (x *Author) GetTeamsByProject() *ListOfListOfString { + if x != nil { + return x.TeamsByProject + } + return nil +} + +func (x *Author) GetCollaborations() *ListOfListOfString { + if x != nil { + return x.Collaborations + } + return nil +} + +func (x *Author) GetWrittenPosts() *ListOfBlogPost { + if x != nil { + return x.WrittenPosts + } + return nil +} + +func (x *Author) GetFavoriteCategories() []*Category { + if x != nil { + return x.FavoriteCategories + } + return nil +} + +func (x *Author) GetRelatedAuthors() *ListOfUser { + if x != nil { + return x.RelatedAuthors + } + return nil +} + +func (x *Author) GetProductReviews() *ListOfProduct { + if x != nil { + return x.ProductReviews + } + return nil +} + +func (x *Author) GetAuthorGroups() *ListOfListOfUser { + if x != nil { + return x.AuthorGroups + } + return nil +} + +func (x *Author) GetCategoryPreferences() *ListOfListOfCategory { + if x != nil { + return x.CategoryPreferences + } + return nil +} + +func (x *Author) GetProjectTeams() *ListOfListOfUser { + if x != nil { + return x.ProjectTeams + } + return nil +} + +type AuthorFilter struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name *wrapperspb.StringValue `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + HasTeams *wrapperspb.BoolValue `protobuf:"bytes,2,opt,name=has_teams,json=hasTeams,proto3" json:"has_teams,omitempty"` + SkillCount *wrapperspb.Int32Value `protobuf:"bytes,3,opt,name=skill_count,json=skillCount,proto3" json:"skill_count,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AuthorFilter) Reset() { + *x = AuthorFilter{} + mi := &file_product_proto_msgTypes[114] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AuthorFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthorFilter) ProtoMessage() {} + +func (x *AuthorFilter) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[114] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AuthorFilter.ProtoReflect.Descriptor instead. +func (*AuthorFilter) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{114} +} + +func (x *AuthorFilter) GetName() *wrapperspb.StringValue { + if x != nil { + return x.Name + } + return nil +} + +func (x *AuthorFilter) GetHasTeams() *wrapperspb.BoolValue { + if x != nil { + return x.HasTeams + } + return nil +} + +func (x *AuthorFilter) GetSkillCount() *wrapperspb.Int32Value { + if x != nil { + return x.SkillCount + } + return nil +} + +type UserInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UserInput) Reset() { + *x = UserInput{} + mi := &file_product_proto_msgTypes[115] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UserInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserInput) ProtoMessage() {} + +func (x *UserInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[115] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UserInput.ProtoReflect.Descriptor instead. func (*UserInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{70} + return file_product_proto_rawDescGZIP(), []int{115} +} + +func (x *UserInput) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type ActionInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Payload string `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ActionInput) Reset() { + *x = ActionInput{} + mi := &file_product_proto_msgTypes[116] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ActionInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ActionInput) ProtoMessage() {} + +func (x *ActionInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[116] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ActionInput.ProtoReflect.Descriptor instead. +func (*ActionInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{116} +} + +func (x *ActionInput) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *ActionInput) GetPayload() string { + if x != nil { + return x.Payload + } + return "" +} + +type ActionResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Value: + // + // *ActionResult_ActionSuccess + // *ActionResult_ActionError + Value isActionResult_Value `protobuf_oneof:"value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ActionResult) Reset() { + *x = ActionResult{} + mi := &file_product_proto_msgTypes[117] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ActionResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ActionResult) ProtoMessage() {} + +func (x *ActionResult) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[117] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ActionResult.ProtoReflect.Descriptor instead. +func (*ActionResult) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{117} +} + +func (x *ActionResult) GetValue() isActionResult_Value { + if x != nil { + return x.Value + } + return nil +} + +func (x *ActionResult) GetActionSuccess() *ActionSuccess { + if x != nil { + if x, ok := x.Value.(*ActionResult_ActionSuccess); ok { + return x.ActionSuccess + } + } + return nil +} + +func (x *ActionResult) GetActionError() *ActionError { + if x != nil { + if x, ok := x.Value.(*ActionResult_ActionError); ok { + return x.ActionError + } + } + return nil +} + +type isActionResult_Value interface { + isActionResult_Value() +} + +type ActionResult_ActionSuccess struct { + ActionSuccess *ActionSuccess `protobuf:"bytes,1,opt,name=action_success,json=actionSuccess,proto3,oneof"` +} + +type ActionResult_ActionError struct { + ActionError *ActionError `protobuf:"bytes,2,opt,name=action_error,json=actionError,proto3,oneof"` +} + +func (*ActionResult_ActionSuccess) isActionResult_Value() {} + +func (*ActionResult_ActionError) isActionResult_Value() {} + +type NullableFieldsInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + OptionalString *wrapperspb.StringValue `protobuf:"bytes,2,opt,name=optional_string,json=optionalString,proto3" json:"optional_string,omitempty"` + OptionalInt *wrapperspb.Int32Value `protobuf:"bytes,3,opt,name=optional_int,json=optionalInt,proto3" json:"optional_int,omitempty"` + OptionalFloat *wrapperspb.DoubleValue `protobuf:"bytes,4,opt,name=optional_float,json=optionalFloat,proto3" json:"optional_float,omitempty"` + OptionalBoolean *wrapperspb.BoolValue `protobuf:"bytes,5,opt,name=optional_boolean,json=optionalBoolean,proto3" json:"optional_boolean,omitempty"` + RequiredString string `protobuf:"bytes,6,opt,name=required_string,json=requiredString,proto3" json:"required_string,omitempty"` + RequiredInt int32 `protobuf:"varint,7,opt,name=required_int,json=requiredInt,proto3" json:"required_int,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NullableFieldsInput) Reset() { + *x = NullableFieldsInput{} + mi := &file_product_proto_msgTypes[118] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NullableFieldsInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NullableFieldsInput) ProtoMessage() {} + +func (x *NullableFieldsInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[118] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NullableFieldsInput.ProtoReflect.Descriptor instead. +func (*NullableFieldsInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{118} +} + +func (x *NullableFieldsInput) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *NullableFieldsInput) GetOptionalString() *wrapperspb.StringValue { + if x != nil { + return x.OptionalString + } + return nil +} + +func (x *NullableFieldsInput) GetOptionalInt() *wrapperspb.Int32Value { + if x != nil { + return x.OptionalInt + } + return nil +} + +func (x *NullableFieldsInput) GetOptionalFloat() *wrapperspb.DoubleValue { + if x != nil { + return x.OptionalFloat + } + return nil +} + +func (x *NullableFieldsInput) GetOptionalBoolean() *wrapperspb.BoolValue { + if x != nil { + return x.OptionalBoolean + } + return nil +} + +func (x *NullableFieldsInput) GetRequiredString() string { + if x != nil { + return x.RequiredString + } + return "" +} + +func (x *NullableFieldsInput) GetRequiredInt() int32 { + if x != nil { + return x.RequiredInt + } + return 0 +} + +type BlogPostInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` + Tags []string `protobuf:"bytes,3,rep,name=tags,proto3" json:"tags,omitempty"` + OptionalTags *ListOfString `protobuf:"bytes,4,opt,name=optional_tags,json=optionalTags,proto3" json:"optional_tags,omitempty"` + Categories []string `protobuf:"bytes,5,rep,name=categories,proto3" json:"categories,omitempty"` + Keywords *ListOfString `protobuf:"bytes,6,opt,name=keywords,proto3" json:"keywords,omitempty"` + ViewCounts []int32 `protobuf:"varint,7,rep,packed,name=view_counts,json=viewCounts,proto3" json:"view_counts,omitempty"` + Ratings *ListOfFloat `protobuf:"bytes,8,opt,name=ratings,proto3" json:"ratings,omitempty"` + IsPublished *ListOfBoolean `protobuf:"bytes,9,opt,name=is_published,json=isPublished,proto3" json:"is_published,omitempty"` + TagGroups *ListOfListOfString `protobuf:"bytes,10,opt,name=tag_groups,json=tagGroups,proto3" json:"tag_groups,omitempty"` + RelatedTopics *ListOfListOfString `protobuf:"bytes,11,opt,name=related_topics,json=relatedTopics,proto3" json:"related_topics,omitempty"` + CommentThreads *ListOfListOfString `protobuf:"bytes,12,opt,name=comment_threads,json=commentThreads,proto3" json:"comment_threads,omitempty"` + Suggestions *ListOfListOfString `protobuf:"bytes,13,opt,name=suggestions,proto3" json:"suggestions,omitempty"` + RelatedCategories *ListOfCategoryInput `protobuf:"bytes,14,opt,name=related_categories,json=relatedCategories,proto3" json:"related_categories,omitempty"` + Contributors *ListOfUserInput `protobuf:"bytes,15,opt,name=contributors,proto3" json:"contributors,omitempty"` + CategoryGroups *ListOfListOfCategoryInput `protobuf:"bytes,16,opt,name=category_groups,json=categoryGroups,proto3" json:"category_groups,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BlogPostInput) Reset() { + *x = BlogPostInput{} + mi := &file_product_proto_msgTypes[119] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BlogPostInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlogPostInput) ProtoMessage() {} + +func (x *BlogPostInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[119] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BlogPostInput.ProtoReflect.Descriptor instead. +func (*BlogPostInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{119} +} + +func (x *BlogPostInput) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *BlogPostInput) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +func (x *BlogPostInput) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *BlogPostInput) GetOptionalTags() *ListOfString { + if x != nil { + return x.OptionalTags + } + return nil +} + +func (x *BlogPostInput) GetCategories() []string { + if x != nil { + return x.Categories + } + return nil +} + +func (x *BlogPostInput) GetKeywords() *ListOfString { + if x != nil { + return x.Keywords + } + return nil +} + +func (x *BlogPostInput) GetViewCounts() []int32 { + if x != nil { + return x.ViewCounts + } + return nil +} + +func (x *BlogPostInput) GetRatings() *ListOfFloat { + if x != nil { + return x.Ratings + } + return nil +} + +func (x *BlogPostInput) GetIsPublished() *ListOfBoolean { + if x != nil { + return x.IsPublished + } + return nil +} + +func (x *BlogPostInput) GetTagGroups() *ListOfListOfString { + if x != nil { + return x.TagGroups + } + return nil +} + +func (x *BlogPostInput) GetRelatedTopics() *ListOfListOfString { + if x != nil { + return x.RelatedTopics + } + return nil +} + +func (x *BlogPostInput) GetCommentThreads() *ListOfListOfString { + if x != nil { + return x.CommentThreads + } + return nil +} + +func (x *BlogPostInput) GetSuggestions() *ListOfListOfString { + if x != nil { + return x.Suggestions + } + return nil +} + +func (x *BlogPostInput) GetRelatedCategories() *ListOfCategoryInput { + if x != nil { + return x.RelatedCategories + } + return nil +} + +func (x *BlogPostInput) GetContributors() *ListOfUserInput { + if x != nil { + return x.Contributors + } + return nil +} + +func (x *BlogPostInput) GetCategoryGroups() *ListOfListOfCategoryInput { + if x != nil { + return x.CategoryGroups + } + return nil +} + +type AuthorInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Email *wrapperspb.StringValue `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` + Skills []string `protobuf:"bytes,3,rep,name=skills,proto3" json:"skills,omitempty"` + Languages []string `protobuf:"bytes,4,rep,name=languages,proto3" json:"languages,omitempty"` + SocialLinks *ListOfString `protobuf:"bytes,5,opt,name=social_links,json=socialLinks,proto3" json:"social_links,omitempty"` + TeamsByProject *ListOfListOfString `protobuf:"bytes,6,opt,name=teams_by_project,json=teamsByProject,proto3" json:"teams_by_project,omitempty"` + Collaborations *ListOfListOfString `protobuf:"bytes,7,opt,name=collaborations,proto3" json:"collaborations,omitempty"` + FavoriteCategories []*CategoryInput `protobuf:"bytes,8,rep,name=favorite_categories,json=favoriteCategories,proto3" json:"favorite_categories,omitempty"` + AuthorGroups *ListOfListOfUserInput `protobuf:"bytes,9,opt,name=author_groups,json=authorGroups,proto3" json:"author_groups,omitempty"` + ProjectTeams *ListOfListOfUserInput `protobuf:"bytes,10,opt,name=project_teams,json=projectTeams,proto3" json:"project_teams,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AuthorInput) Reset() { + *x = AuthorInput{} + mi := &file_product_proto_msgTypes[120] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AuthorInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthorInput) ProtoMessage() {} + +func (x *AuthorInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[120] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AuthorInput.ProtoReflect.Descriptor instead. +func (*AuthorInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{120} +} + +func (x *AuthorInput) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *AuthorInput) GetEmail() *wrapperspb.StringValue { + if x != nil { + return x.Email + } + return nil +} + +func (x *AuthorInput) GetSkills() []string { + if x != nil { + return x.Skills + } + return nil +} + +func (x *AuthorInput) GetLanguages() []string { + if x != nil { + return x.Languages + } + return nil +} + +func (x *AuthorInput) GetSocialLinks() *ListOfString { + if x != nil { + return x.SocialLinks + } + return nil +} + +func (x *AuthorInput) GetTeamsByProject() *ListOfListOfString { + if x != nil { + return x.TeamsByProject + } + return nil +} + +func (x *AuthorInput) GetCollaborations() *ListOfListOfString { + if x != nil { + return x.Collaborations + } + return nil +} + +func (x *AuthorInput) GetFavoriteCategories() []*CategoryInput { + if x != nil { + return x.FavoriteCategories + } + return nil +} + +func (x *AuthorInput) GetAuthorGroups() *ListOfListOfUserInput { + if x != nil { + return x.AuthorGroups + } + return nil +} + +func (x *AuthorInput) GetProjectTeams() *ListOfListOfUserInput { + if x != nil { + return x.ProjectTeams + } + return nil +} + +type NestedTypeB struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + C *NestedTypeC `protobuf:"bytes,3,opt,name=c,proto3" json:"c,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NestedTypeB) Reset() { + *x = NestedTypeB{} + mi := &file_product_proto_msgTypes[121] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NestedTypeB) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NestedTypeB) ProtoMessage() {} + +func (x *NestedTypeB) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[121] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NestedTypeB.ProtoReflect.Descriptor instead. +func (*NestedTypeB) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{121} +} + +func (x *NestedTypeB) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *NestedTypeB) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *NestedTypeB) GetC() *NestedTypeC { + if x != nil { + return x.C + } + return nil +} + +type NestedTypeC struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NestedTypeC) Reset() { + *x = NestedTypeC{} + mi := &file_product_proto_msgTypes[122] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NestedTypeC) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NestedTypeC) ProtoMessage() {} + +func (x *NestedTypeC) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[122] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NestedTypeC.ProtoReflect.Descriptor instead. +func (*NestedTypeC) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{122} +} + +func (x *NestedTypeC) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *NestedTypeC) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type FilterType struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + FilterField_1 string `protobuf:"bytes,2,opt,name=filter_field_1,json=filterField1,proto3" json:"filter_field_1,omitempty"` + FilterField_2 string `protobuf:"bytes,3,opt,name=filter_field_2,json=filterField2,proto3" json:"filter_field_2,omitempty"` + Pagination *Pagination `protobuf:"bytes,4,opt,name=pagination,proto3" json:"pagination,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FilterType) Reset() { + *x = FilterType{} + mi := &file_product_proto_msgTypes[123] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FilterType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FilterType) ProtoMessage() {} + +func (x *FilterType) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[123] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FilterType.ProtoReflect.Descriptor instead. +func (*FilterType) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{123} +} + +func (x *FilterType) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *FilterType) GetFilterField_1() string { + if x != nil { + return x.FilterField_1 + } + return "" +} + +func (x *FilterType) GetFilterField_2() string { + if x != nil { + return x.FilterField_2 + } + return "" +} + +func (x *FilterType) GetPagination() *Pagination { + if x != nil { + return x.Pagination + } + return nil +} + +type Pagination struct { + state protoimpl.MessageState `protogen:"open.v1"` + Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` + PerPage int32 `protobuf:"varint,2,opt,name=per_page,json=perPage,proto3" json:"per_page,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Pagination) Reset() { + *x = Pagination{} + mi := &file_product_proto_msgTypes[124] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Pagination) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Pagination) ProtoMessage() {} + +func (x *Pagination) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[124] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Pagination.ProtoReflect.Descriptor instead. +func (*Pagination) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{124} +} + +func (x *Pagination) GetPage() int32 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *Pagination) GetPerPage() int32 { + if x != nil { + return x.PerPage + } + return 0 +} + +type OrderLineInput struct { + state protoimpl.MessageState `protogen:"open.v1"` + ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + Quantity int32 `protobuf:"varint,2,opt,name=quantity,proto3" json:"quantity,omitempty"` + Modifiers *ListOfString `protobuf:"bytes,3,opt,name=modifiers,proto3" json:"modifiers,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *OrderLineInput) Reset() { + *x = OrderLineInput{} + mi := &file_product_proto_msgTypes[125] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *OrderLineInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OrderLineInput) ProtoMessage() {} + +func (x *OrderLineInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[125] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OrderLineInput.ProtoReflect.Descriptor instead. +func (*OrderLineInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{125} +} + +func (x *OrderLineInput) GetProductId() string { + if x != nil { + return x.ProductId + } + return "" +} + +func (x *OrderLineInput) GetQuantity() int32 { + if x != nil { + return x.Quantity + } + return 0 } -func (x *UserInput) GetName() string { +func (x *OrderLineInput) GetModifiers() *ListOfString { if x != nil { - return x.Name + return x.Modifiers } - return "" + return nil } -type ActionInput struct { +type OrderLine struct { state protoimpl.MessageState `protogen:"open.v1"` - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - Payload string `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` + ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + Quantity int32 `protobuf:"varint,2,opt,name=quantity,proto3" json:"quantity,omitempty"` + Modifiers *ListOfString `protobuf:"bytes,3,opt,name=modifiers,proto3" json:"modifiers,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ActionInput) Reset() { - *x = ActionInput{} - mi := &file_product_proto_msgTypes[71] +func (x *OrderLine) Reset() { + *x = OrderLine{} + mi := &file_product_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ActionInput) String() string { +func (x *OrderLine) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ActionInput) ProtoMessage() {} +func (*OrderLine) ProtoMessage() {} -func (x *ActionInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[71] +func (x *OrderLine) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[126] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3540,51 +6710,57 @@ func (x *ActionInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ActionInput.ProtoReflect.Descriptor instead. -func (*ActionInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{71} +// Deprecated: Use OrderLine.ProtoReflect.Descriptor instead. +func (*OrderLine) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{126} } -func (x *ActionInput) GetType() string { +func (x *OrderLine) GetProductId() string { if x != nil { - return x.Type + return x.ProductId } return "" } -func (x *ActionInput) GetPayload() string { +func (x *OrderLine) GetQuantity() int32 { if x != nil { - return x.Payload + return x.Quantity } - return "" + return 0 } -type ActionResult struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Value: - // - // *ActionResult_ActionSuccess - // *ActionResult_ActionError - Value isActionResult_Value `protobuf_oneof:"value"` +func (x *OrderLine) GetModifiers() *ListOfString { + if x != nil { + return x.Modifiers + } + return nil +} + +type Cat struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Kind string `protobuf:"bytes,3,opt,name=kind,proto3" json:"kind,omitempty"` + MeowVolume int32 `protobuf:"varint,4,opt,name=meow_volume,json=meowVolume,proto3" json:"meow_volume,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ActionResult) Reset() { - *x = ActionResult{} - mi := &file_product_proto_msgTypes[72] +func (x *Cat) Reset() { + *x = Cat{} + mi := &file_product_proto_msgTypes[127] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ActionResult) String() string { +func (x *Cat) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ActionResult) ProtoMessage() {} +func (*Cat) ProtoMessage() {} -func (x *ActionResult) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[72] +func (x *Cat) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[127] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3595,76 +6771,130 @@ func (x *ActionResult) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ActionResult.ProtoReflect.Descriptor instead. -func (*ActionResult) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{72} +// Deprecated: Use Cat.ProtoReflect.Descriptor instead. +func (*Cat) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{127} } -func (x *ActionResult) GetValue() isActionResult_Value { +func (x *Cat) GetId() string { if x != nil { - return x.Value + return x.Id } - return nil + return "" } -func (x *ActionResult) GetActionSuccess() *ActionSuccess { +func (x *Cat) GetName() string { if x != nil { - if x, ok := x.Value.(*ActionResult_ActionSuccess); ok { - return x.ActionSuccess - } + return x.Name } - return nil + return "" } -func (x *ActionResult) GetActionError() *ActionError { +func (x *Cat) GetKind() string { if x != nil { - if x, ok := x.Value.(*ActionResult_ActionError); ok { - return x.ActionError + return x.Kind + } + return "" +} + +func (x *Cat) GetMeowVolume() int32 { + if x != nil { + return x.MeowVolume + } + return 0 +} + +type Dog struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Kind string `protobuf:"bytes,3,opt,name=kind,proto3" json:"kind,omitempty"` + BarkVolume int32 `protobuf:"varint,4,opt,name=bark_volume,json=barkVolume,proto3" json:"bark_volume,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Dog) Reset() { + *x = Dog{} + mi := &file_product_proto_msgTypes[128] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Dog) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Dog) ProtoMessage() {} + +func (x *Dog) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[128] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) } + return ms } - return nil + return mi.MessageOf(x) } -type isActionResult_Value interface { - isActionResult_Value() +// Deprecated: Use Dog.ProtoReflect.Descriptor instead. +func (*Dog) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{128} } -type ActionResult_ActionSuccess struct { - ActionSuccess *ActionSuccess `protobuf:"bytes,1,opt,name=action_success,json=actionSuccess,proto3,oneof"` +func (x *Dog) GetId() string { + if x != nil { + return x.Id + } + return "" } -type ActionResult_ActionError struct { - ActionError *ActionError `protobuf:"bytes,2,opt,name=action_error,json=actionError,proto3,oneof"` +func (x *Dog) GetName() string { + if x != nil { + return x.Name + } + return "" } -func (*ActionResult_ActionSuccess) isActionResult_Value() {} +func (x *Dog) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} -func (*ActionResult_ActionError) isActionResult_Value() {} +func (x *Dog) GetBarkVolume() int32 { + if x != nil { + return x.BarkVolume + } + return 0 +} -type NestedTypeB struct { +type ActionSuccess struct { state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - C *NestedTypeC `protobuf:"bytes,3,opt,name=c,proto3" json:"c,omitempty"` + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + Timestamp string `protobuf:"bytes,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *NestedTypeB) Reset() { - *x = NestedTypeB{} - mi := &file_product_proto_msgTypes[73] +func (x *ActionSuccess) Reset() { + *x = ActionSuccess{} + mi := &file_product_proto_msgTypes[129] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *NestedTypeB) String() string { +func (x *ActionSuccess) String() string { return protoimpl.X.MessageStringOf(x) } -func (*NestedTypeB) ProtoMessage() {} +func (*ActionSuccess) ProtoMessage() {} -func (x *NestedTypeB) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[73] +func (x *ActionSuccess) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[129] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3675,55 +6905,100 @@ func (x *NestedTypeB) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use NestedTypeB.ProtoReflect.Descriptor instead. -func (*NestedTypeB) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{73} +// Deprecated: Use ActionSuccess.ProtoReflect.Descriptor instead. +func (*ActionSuccess) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{129} } -func (x *NestedTypeB) GetId() string { +func (x *ActionSuccess) GetMessage() string { if x != nil { - return x.Id + return x.Message } return "" } -func (x *NestedTypeB) GetName() string { +func (x *ActionSuccess) GetTimestamp() string { if x != nil { - return x.Name + return x.Timestamp } return "" } -func (x *NestedTypeB) GetC() *NestedTypeC { +type ActionError struct { + state protoimpl.MessageState `protogen:"open.v1"` + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ActionError) Reset() { + *x = ActionError{} + mi := &file_product_proto_msgTypes[130] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ActionError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ActionError) ProtoMessage() {} + +func (x *ActionError) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[130] if x != nil { - return x.C + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return nil + return mi.MessageOf(x) } -type NestedTypeC struct { +// Deprecated: Use ActionError.ProtoReflect.Descriptor instead. +func (*ActionError) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{130} +} + +func (x *ActionError) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *ActionError) GetCode() string { + if x != nil { + return x.Code + } + return "" +} + +type CategoryInput struct { state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Kind CategoryKind `protobuf:"varint,2,opt,name=kind,proto3,enum=productv1.CategoryKind" json:"kind,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *NestedTypeC) Reset() { - *x = NestedTypeC{} - mi := &file_product_proto_msgTypes[74] +func (x *CategoryInput) Reset() { + *x = CategoryInput{} + mi := &file_product_proto_msgTypes[131] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *NestedTypeC) String() string { +func (x *CategoryInput) String() string { return protoimpl.X.MessageStringOf(x) } -func (*NestedTypeC) ProtoMessage() {} +func (*CategoryInput) ProtoMessage() {} -func (x *NestedTypeC) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[74] +func (x *CategoryInput) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[131] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3734,50 +7009,47 @@ func (x *NestedTypeC) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use NestedTypeC.ProtoReflect.Descriptor instead. -func (*NestedTypeC) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{74} +// Deprecated: Use CategoryInput.ProtoReflect.Descriptor instead. +func (*CategoryInput) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{131} } -func (x *NestedTypeC) GetId() string { +func (x *CategoryInput) GetName() string { if x != nil { - return x.Id + return x.Name } return "" } -func (x *NestedTypeC) GetName() string { +func (x *CategoryInput) GetKind() CategoryKind { if x != nil { - return x.Name + return x.Kind } - return "" + return CategoryKind_CATEGORY_KIND_UNSPECIFIED } -type FilterType struct { +type ListOfBlogPost_List struct { state protoimpl.MessageState `protogen:"open.v1"` - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - FilterField_1 string `protobuf:"bytes,2,opt,name=filter_field_1,json=filterField1,proto3" json:"filter_field_1,omitempty"` - FilterField_2 string `protobuf:"bytes,3,opt,name=filter_field_2,json=filterField2,proto3" json:"filter_field_2,omitempty"` - Pagination *Pagination `protobuf:"bytes,4,opt,name=pagination,proto3" json:"pagination,omitempty"` + Items []*BlogPost `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *FilterType) Reset() { - *x = FilterType{} - mi := &file_product_proto_msgTypes[75] +func (x *ListOfBlogPost_List) Reset() { + *x = ListOfBlogPost_List{} + mi := &file_product_proto_msgTypes[132] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *FilterType) String() string { +func (x *ListOfBlogPost_List) String() string { return protoimpl.X.MessageStringOf(x) } -func (*FilterType) ProtoMessage() {} +func (*ListOfBlogPost_List) ProtoMessage() {} -func (x *FilterType) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[75] +func (x *ListOfBlogPost_List) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[132] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3788,62 +7060,40 @@ func (x *FilterType) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use FilterType.ProtoReflect.Descriptor instead. -func (*FilterType) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{75} -} - -func (x *FilterType) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *FilterType) GetFilterField_1() string { - if x != nil { - return x.FilterField_1 - } - return "" -} - -func (x *FilterType) GetFilterField_2() string { - if x != nil { - return x.FilterField_2 - } - return "" +// Deprecated: Use ListOfBlogPost_List.ProtoReflect.Descriptor instead. +func (*ListOfBlogPost_List) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{0, 0} } -func (x *FilterType) GetPagination() *Pagination { +func (x *ListOfBlogPost_List) GetItems() []*BlogPost { if x != nil { - return x.Pagination + return x.Items } return nil } -type Pagination struct { +type ListOfBoolean_List struct { state protoimpl.MessageState `protogen:"open.v1"` - Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` - PerPage int32 `protobuf:"varint,2,opt,name=per_page,json=perPage,proto3" json:"per_page,omitempty"` + Items []bool `protobuf:"varint,1,rep,packed,name=items,proto3" json:"items,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Pagination) Reset() { - *x = Pagination{} - mi := &file_product_proto_msgTypes[76] +func (x *ListOfBoolean_List) Reset() { + *x = ListOfBoolean_List{} + mi := &file_product_proto_msgTypes[133] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Pagination) String() string { +func (x *ListOfBoolean_List) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Pagination) ProtoMessage() {} +func (*ListOfBoolean_List) ProtoMessage() {} -func (x *Pagination) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[76] +func (x *ListOfBoolean_List) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[133] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3854,49 +7104,40 @@ func (x *Pagination) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Pagination.ProtoReflect.Descriptor instead. -func (*Pagination) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{76} -} - -func (x *Pagination) GetPage() int32 { - if x != nil { - return x.Page - } - return 0 +// Deprecated: Use ListOfBoolean_List.ProtoReflect.Descriptor instead. +func (*ListOfBoolean_List) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{1, 0} } -func (x *Pagination) GetPerPage() int32 { +func (x *ListOfBoolean_List) GetItems() []bool { if x != nil { - return x.PerPage + return x.Items } - return 0 + return nil } -type OrderLineInput struct { +type ListOfCategory_List struct { state protoimpl.MessageState `protogen:"open.v1"` - ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` - Quantity int32 `protobuf:"varint,2,opt,name=quantity,proto3" json:"quantity,omitempty"` - Modifiers []string `protobuf:"bytes,3,rep,name=modifiers,proto3" json:"modifiers,omitempty"` + Items []*Category `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *OrderLineInput) Reset() { - *x = OrderLineInput{} - mi := &file_product_proto_msgTypes[77] +func (x *ListOfCategory_List) Reset() { + *x = ListOfCategory_List{} + mi := &file_product_proto_msgTypes[134] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *OrderLineInput) String() string { +func (x *ListOfCategory_List) String() string { return protoimpl.X.MessageStringOf(x) } -func (*OrderLineInput) ProtoMessage() {} +func (*ListOfCategory_List) ProtoMessage() {} -func (x *OrderLineInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[77] +func (x *ListOfCategory_List) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[134] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3907,56 +7148,40 @@ func (x *OrderLineInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use OrderLineInput.ProtoReflect.Descriptor instead. -func (*OrderLineInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{77} -} - -func (x *OrderLineInput) GetProductId() string { - if x != nil { - return x.ProductId - } - return "" -} - -func (x *OrderLineInput) GetQuantity() int32 { - if x != nil { - return x.Quantity - } - return 0 +// Deprecated: Use ListOfCategory_List.ProtoReflect.Descriptor instead. +func (*ListOfCategory_List) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{2, 0} } -func (x *OrderLineInput) GetModifiers() []string { +func (x *ListOfCategory_List) GetItems() []*Category { if x != nil { - return x.Modifiers + return x.Items } return nil } -type OrderLine struct { +type ListOfCategoryInput_List struct { state protoimpl.MessageState `protogen:"open.v1"` - ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` - Quantity int32 `protobuf:"varint,2,opt,name=quantity,proto3" json:"quantity,omitempty"` - Modifiers []string `protobuf:"bytes,3,rep,name=modifiers,proto3" json:"modifiers,omitempty"` + Items []*CategoryInput `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *OrderLine) Reset() { - *x = OrderLine{} - mi := &file_product_proto_msgTypes[78] +func (x *ListOfCategoryInput_List) Reset() { + *x = ListOfCategoryInput_List{} + mi := &file_product_proto_msgTypes[135] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *OrderLine) String() string { +func (x *ListOfCategoryInput_List) String() string { return protoimpl.X.MessageStringOf(x) } -func (*OrderLine) ProtoMessage() {} +func (*ListOfCategoryInput_List) ProtoMessage() {} -func (x *OrderLine) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[78] +func (x *ListOfCategoryInput_List) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[135] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3967,57 +7192,40 @@ func (x *OrderLine) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use OrderLine.ProtoReflect.Descriptor instead. -func (*OrderLine) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{78} -} - -func (x *OrderLine) GetProductId() string { - if x != nil { - return x.ProductId - } - return "" -} - -func (x *OrderLine) GetQuantity() int32 { - if x != nil { - return x.Quantity - } - return 0 +// Deprecated: Use ListOfCategoryInput_List.ProtoReflect.Descriptor instead. +func (*ListOfCategoryInput_List) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{3, 0} } -func (x *OrderLine) GetModifiers() []string { +func (x *ListOfCategoryInput_List) GetItems() []*CategoryInput { if x != nil { - return x.Modifiers + return x.Items } return nil } -type Cat struct { +type ListOfFloat_List struct { state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Kind string `protobuf:"bytes,3,opt,name=kind,proto3" json:"kind,omitempty"` - MeowVolume int32 `protobuf:"varint,4,opt,name=meow_volume,json=meowVolume,proto3" json:"meow_volume,omitempty"` + Items []float64 `protobuf:"fixed64,1,rep,packed,name=items,proto3" json:"items,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Cat) Reset() { - *x = Cat{} - mi := &file_product_proto_msgTypes[79] +func (x *ListOfFloat_List) Reset() { + *x = ListOfFloat_List{} + mi := &file_product_proto_msgTypes[136] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Cat) String() string { +func (x *ListOfFloat_List) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Cat) ProtoMessage() {} +func (*ListOfFloat_List) ProtoMessage() {} -func (x *Cat) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[79] +func (x *ListOfFloat_List) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[136] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4028,64 +7236,84 @@ func (x *Cat) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Cat.ProtoReflect.Descriptor instead. -func (*Cat) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{79} +// Deprecated: Use ListOfFloat_List.ProtoReflect.Descriptor instead. +func (*ListOfFloat_List) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{4, 0} } -func (x *Cat) GetId() string { +func (x *ListOfFloat_List) GetItems() []float64 { if x != nil { - return x.Id + return x.Items } - return "" + return nil } -func (x *Cat) GetName() string { - if x != nil { - return x.Name - } - return "" +type ListOfListOfCategory_List struct { + state protoimpl.MessageState `protogen:"open.v1"` + Items []*ListOfCategory `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *Cat) GetKind() string { +func (x *ListOfListOfCategory_List) Reset() { + *x = ListOfListOfCategory_List{} + mi := &file_product_proto_msgTypes[137] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListOfListOfCategory_List) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListOfListOfCategory_List) ProtoMessage() {} + +func (x *ListOfListOfCategory_List) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[137] if x != nil { - return x.Kind + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return "" + return mi.MessageOf(x) } -func (x *Cat) GetMeowVolume() int32 { +// Deprecated: Use ListOfListOfCategory_List.ProtoReflect.Descriptor instead. +func (*ListOfListOfCategory_List) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{5, 0} +} + +func (x *ListOfListOfCategory_List) GetItems() []*ListOfCategory { if x != nil { - return x.MeowVolume + return x.Items } - return 0 + return nil } -type Dog struct { +type ListOfListOfCategoryInput_List struct { state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Kind string `protobuf:"bytes,3,opt,name=kind,proto3" json:"kind,omitempty"` - BarkVolume int32 `protobuf:"varint,4,opt,name=bark_volume,json=barkVolume,proto3" json:"bark_volume,omitempty"` + Items []*ListOfCategoryInput `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Dog) Reset() { - *x = Dog{} - mi := &file_product_proto_msgTypes[80] +func (x *ListOfListOfCategoryInput_List) Reset() { + *x = ListOfListOfCategoryInput_List{} + mi := &file_product_proto_msgTypes[138] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Dog) String() string { +func (x *ListOfListOfCategoryInput_List) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Dog) ProtoMessage() {} +func (*ListOfListOfCategoryInput_List) ProtoMessage() {} -func (x *Dog) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[80] +func (x *ListOfListOfCategoryInput_List) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[138] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4096,62 +7324,84 @@ func (x *Dog) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Dog.ProtoReflect.Descriptor instead. -func (*Dog) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{80} +// Deprecated: Use ListOfListOfCategoryInput_List.ProtoReflect.Descriptor instead. +func (*ListOfListOfCategoryInput_List) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{6, 0} } -func (x *Dog) GetId() string { +func (x *ListOfListOfCategoryInput_List) GetItems() []*ListOfCategoryInput { if x != nil { - return x.Id + return x.Items } - return "" + return nil } -func (x *Dog) GetName() string { - if x != nil { - return x.Name - } - return "" +type ListOfListOfString_List struct { + state protoimpl.MessageState `protogen:"open.v1"` + Items []*ListOfString `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *Dog) GetKind() string { +func (x *ListOfListOfString_List) Reset() { + *x = ListOfListOfString_List{} + mi := &file_product_proto_msgTypes[139] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListOfListOfString_List) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListOfListOfString_List) ProtoMessage() {} + +func (x *ListOfListOfString_List) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[139] if x != nil { - return x.Kind + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return "" + return mi.MessageOf(x) } -func (x *Dog) GetBarkVolume() int32 { +// Deprecated: Use ListOfListOfString_List.ProtoReflect.Descriptor instead. +func (*ListOfListOfString_List) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{7, 0} +} + +func (x *ListOfListOfString_List) GetItems() []*ListOfString { if x != nil { - return x.BarkVolume + return x.Items } - return 0 + return nil } -type ActionSuccess struct { +type ListOfListOfUser_List struct { state protoimpl.MessageState `protogen:"open.v1"` - Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` - Timestamp string `protobuf:"bytes,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Items []*ListOfUser `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ActionSuccess) Reset() { - *x = ActionSuccess{} - mi := &file_product_proto_msgTypes[81] +func (x *ListOfListOfUser_List) Reset() { + *x = ListOfListOfUser_List{} + mi := &file_product_proto_msgTypes[140] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ActionSuccess) String() string { +func (x *ListOfListOfUser_List) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ActionSuccess) ProtoMessage() {} +func (*ListOfListOfUser_List) ProtoMessage() {} -func (x *ActionSuccess) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[81] +func (x *ListOfListOfUser_List) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[140] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4162,48 +7412,40 @@ func (x *ActionSuccess) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ActionSuccess.ProtoReflect.Descriptor instead. -func (*ActionSuccess) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{81} -} - -func (x *ActionSuccess) GetMessage() string { - if x != nil { - return x.Message - } - return "" +// Deprecated: Use ListOfListOfUser_List.ProtoReflect.Descriptor instead. +func (*ListOfListOfUser_List) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{8, 0} } -func (x *ActionSuccess) GetTimestamp() string { +func (x *ListOfListOfUser_List) GetItems() []*ListOfUser { if x != nil { - return x.Timestamp + return x.Items } - return "" + return nil } -type ActionError struct { +type ListOfListOfUserInput_List struct { state protoimpl.MessageState `protogen:"open.v1"` - Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` - Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"` + Items []*ListOfUserInput `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ActionError) Reset() { - *x = ActionError{} - mi := &file_product_proto_msgTypes[82] +func (x *ListOfListOfUserInput_List) Reset() { + *x = ListOfListOfUserInput_List{} + mi := &file_product_proto_msgTypes[141] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ActionError) String() string { +func (x *ListOfListOfUserInput_List) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ActionError) ProtoMessage() {} +func (*ListOfListOfUserInput_List) ProtoMessage() {} -func (x *ActionError) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[82] +func (x *ListOfListOfUserInput_List) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[141] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4214,55 +7456,40 @@ func (x *ActionError) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ActionError.ProtoReflect.Descriptor instead. -func (*ActionError) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{82} -} - -func (x *ActionError) GetMessage() string { - if x != nil { - return x.Message - } - return "" +// Deprecated: Use ListOfListOfUserInput_List.ProtoReflect.Descriptor instead. +func (*ListOfListOfUserInput_List) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{9, 0} } -func (x *ActionError) GetCode() string { +func (x *ListOfListOfUserInput_List) GetItems() []*ListOfUserInput { if x != nil { - return x.Code + return x.Items } - return "" + return nil } -// New messages for testing nullable fields -type NullableFieldsType struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - OptionalString *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=optional_string,json=optionalString,proto3" json:"optional_string,omitempty"` - OptionalInt *wrapperspb.Int32Value `protobuf:"bytes,4,opt,name=optional_int,json=optionalInt,proto3" json:"optional_int,omitempty"` - OptionalFloat *wrapperspb.FloatValue `protobuf:"bytes,5,opt,name=optional_float,json=optionalFloat,proto3" json:"optional_float,omitempty"` - OptionalBoolean *wrapperspb.BoolValue `protobuf:"bytes,6,opt,name=optional_boolean,json=optionalBoolean,proto3" json:"optional_boolean,omitempty"` - RequiredString string `protobuf:"bytes,7,opt,name=required_string,json=requiredString,proto3" json:"required_string,omitempty"` - RequiredInt int32 `protobuf:"varint,8,opt,name=required_int,json=requiredInt,proto3" json:"required_int,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type ListOfOrderLine_List struct { + state protoimpl.MessageState `protogen:"open.v1"` + Items []*OrderLine `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *NullableFieldsType) Reset() { - *x = NullableFieldsType{} - mi := &file_product_proto_msgTypes[83] +func (x *ListOfOrderLine_List) Reset() { + *x = ListOfOrderLine_List{} + mi := &file_product_proto_msgTypes[142] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *NullableFieldsType) String() string { +func (x *ListOfOrderLine_List) String() string { return protoimpl.X.MessageStringOf(x) } -func (*NullableFieldsType) ProtoMessage() {} +func (*ListOfOrderLine_List) ProtoMessage() {} -func (x *NullableFieldsType) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[83] +func (x *ListOfOrderLine_List) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[142] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4273,95 +7500,84 @@ func (x *NullableFieldsType) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use NullableFieldsType.ProtoReflect.Descriptor instead. -func (*NullableFieldsType) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{83} +// Deprecated: Use ListOfOrderLine_List.ProtoReflect.Descriptor instead. +func (*ListOfOrderLine_List) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{10, 0} } -func (x *NullableFieldsType) GetId() string { +func (x *ListOfOrderLine_List) GetItems() []*OrderLine { if x != nil { - return x.Id + return x.Items } - return "" + return nil } -func (x *NullableFieldsType) GetName() string { - if x != nil { - return x.Name - } - return "" +type ListOfProduct_List struct { + state protoimpl.MessageState `protogen:"open.v1"` + Items []*Product `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *NullableFieldsType) GetOptionalString() *wrapperspb.StringValue { - if x != nil { - return x.OptionalString - } - return nil +func (x *ListOfProduct_List) Reset() { + *x = ListOfProduct_List{} + mi := &file_product_proto_msgTypes[143] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *NullableFieldsType) GetOptionalInt() *wrapperspb.Int32Value { - if x != nil { - return x.OptionalInt - } - return nil +func (x *ListOfProduct_List) String() string { + return protoimpl.X.MessageStringOf(x) } -func (x *NullableFieldsType) GetOptionalFloat() *wrapperspb.FloatValue { - if x != nil { - return x.OptionalFloat - } - return nil -} +func (*ListOfProduct_List) ProtoMessage() {} -func (x *NullableFieldsType) GetOptionalBoolean() *wrapperspb.BoolValue { +func (x *ListOfProduct_List) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[143] if x != nil { - return x.OptionalBoolean + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return nil + return mi.MessageOf(x) } -func (x *NullableFieldsType) GetRequiredString() string { - if x != nil { - return x.RequiredString - } - return "" +// Deprecated: Use ListOfProduct_List.ProtoReflect.Descriptor instead. +func (*ListOfProduct_List) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{11, 0} } -func (x *NullableFieldsType) GetRequiredInt() int32 { +func (x *ListOfProduct_List) GetItems() []*Product { if x != nil { - return x.RequiredInt + return x.Items } - return 0 + return nil } -type NullableFieldsInput struct { - state protoimpl.MessageState `protogen:"open.v1"` - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - OptionalString *wrapperspb.StringValue `protobuf:"bytes,2,opt,name=optional_string,json=optionalString,proto3" json:"optional_string,omitempty"` - OptionalInt *wrapperspb.Int32Value `protobuf:"bytes,3,opt,name=optional_int,json=optionalInt,proto3" json:"optional_int,omitempty"` - OptionalFloat *wrapperspb.FloatValue `protobuf:"bytes,4,opt,name=optional_float,json=optionalFloat,proto3" json:"optional_float,omitempty"` - OptionalBoolean *wrapperspb.BoolValue `protobuf:"bytes,5,opt,name=optional_boolean,json=optionalBoolean,proto3" json:"optional_boolean,omitempty"` - RequiredString string `protobuf:"bytes,6,opt,name=required_string,json=requiredString,proto3" json:"required_string,omitempty"` - RequiredInt int32 `protobuf:"varint,7,opt,name=required_int,json=requiredInt,proto3" json:"required_int,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type ListOfString_List struct { + state protoimpl.MessageState `protogen:"open.v1"` + Items []string `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *NullableFieldsInput) Reset() { - *x = NullableFieldsInput{} - mi := &file_product_proto_msgTypes[84] +func (x *ListOfString_List) Reset() { + *x = ListOfString_List{} + mi := &file_product_proto_msgTypes[144] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *NullableFieldsInput) String() string { +func (x *ListOfString_List) String() string { return protoimpl.X.MessageStringOf(x) } -func (*NullableFieldsInput) ProtoMessage() {} +func (*ListOfString_List) ProtoMessage() {} -func (x *NullableFieldsInput) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[84] +func (x *ListOfString_List) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[144] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4372,84 +7588,84 @@ func (x *NullableFieldsInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use NullableFieldsInput.ProtoReflect.Descriptor instead. -func (*NullableFieldsInput) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{84} +// Deprecated: Use ListOfString_List.ProtoReflect.Descriptor instead. +func (*ListOfString_List) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{12, 0} } -func (x *NullableFieldsInput) GetName() string { +func (x *ListOfString_List) GetItems() []string { if x != nil { - return x.Name + return x.Items } - return "" + return nil } -func (x *NullableFieldsInput) GetOptionalString() *wrapperspb.StringValue { - if x != nil { - return x.OptionalString - } - return nil +type ListOfUser_List struct { + state protoimpl.MessageState `protogen:"open.v1"` + Items []*User `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *NullableFieldsInput) GetOptionalInt() *wrapperspb.Int32Value { - if x != nil { - return x.OptionalInt - } - return nil +func (x *ListOfUser_List) Reset() { + *x = ListOfUser_List{} + mi := &file_product_proto_msgTypes[145] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *NullableFieldsInput) GetOptionalFloat() *wrapperspb.FloatValue { - if x != nil { - return x.OptionalFloat - } - return nil +func (x *ListOfUser_List) String() string { + return protoimpl.X.MessageStringOf(x) } -func (x *NullableFieldsInput) GetOptionalBoolean() *wrapperspb.BoolValue { +func (*ListOfUser_List) ProtoMessage() {} + +func (x *ListOfUser_List) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[145] if x != nil { - return x.OptionalBoolean + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return nil + return mi.MessageOf(x) } -func (x *NullableFieldsInput) GetRequiredString() string { - if x != nil { - return x.RequiredString - } - return "" +// Deprecated: Use ListOfUser_List.ProtoReflect.Descriptor instead. +func (*ListOfUser_List) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{13, 0} } -func (x *NullableFieldsInput) GetRequiredInt() int32 { +func (x *ListOfUser_List) GetItems() []*User { if x != nil { - return x.RequiredInt + return x.Items } - return 0 + return nil } -type NullableFieldsFilter struct { - state protoimpl.MessageState `protogen:"open.v1"` - Name *wrapperspb.StringValue `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - OptionalString *wrapperspb.StringValue `protobuf:"bytes,2,opt,name=optional_string,json=optionalString,proto3" json:"optional_string,omitempty"` - IncludeNulls *wrapperspb.BoolValue `protobuf:"bytes,3,opt,name=include_nulls,json=includeNulls,proto3" json:"include_nulls,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type ListOfUserInput_List struct { + state protoimpl.MessageState `protogen:"open.v1"` + Items []*UserInput `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *NullableFieldsFilter) Reset() { - *x = NullableFieldsFilter{} - mi := &file_product_proto_msgTypes[85] +func (x *ListOfUserInput_List) Reset() { + *x = ListOfUserInput_List{} + mi := &file_product_proto_msgTypes[146] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *NullableFieldsFilter) String() string { +func (x *ListOfUserInput_List) String() string { return protoimpl.X.MessageStringOf(x) } -func (*NullableFieldsFilter) ProtoMessage() {} +func (*ListOfUserInput_List) ProtoMessage() {} -func (x *NullableFieldsFilter) ProtoReflect() protoreflect.Message { - mi := &file_product_proto_msgTypes[85] +func (x *ListOfUserInput_List) ProtoReflect() protoreflect.Message { + mi := &file_product_proto_msgTypes[146] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4460,28 +7676,14 @@ func (x *NullableFieldsFilter) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use NullableFieldsFilter.ProtoReflect.Descriptor instead. -func (*NullableFieldsFilter) Descriptor() ([]byte, []int) { - return file_product_proto_rawDescGZIP(), []int{85} -} - -func (x *NullableFieldsFilter) GetName() *wrapperspb.StringValue { - if x != nil { - return x.Name - } - return nil -} - -func (x *NullableFieldsFilter) GetOptionalString() *wrapperspb.StringValue { - if x != nil { - return x.OptionalString - } - return nil +// Deprecated: Use ListOfUserInput_List.ProtoReflect.Descriptor instead. +func (*ListOfUserInput_List) Descriptor() ([]byte, []int) { + return file_product_proto_rawDescGZIP(), []int{14, 0} } -func (x *NullableFieldsFilter) GetIncludeNulls() *wrapperspb.BoolValue { +func (x *ListOfUserInput_List) GetItems() []*UserInput { if x != nil { - return x.IncludeNulls + return x.Items } return nil } @@ -4490,7 +7692,68 @@ var File_product_proto protoreflect.FileDescriptor const file_product_proto_rawDesc = "" + "\n" + - "\rproduct.proto\x12\tproductv1\x1a\x1egoogle/protobuf/wrappers.proto\"-\n" + + "\rproduct.proto\x12\tproductv1\x1a\x1egoogle/protobuf/wrappers.proto\"w\n" + + "\x0eListOfBlogPost\x122\n" + + "\x04list\x18\x01 \x01(\v2\x1e.productv1.ListOfBlogPost.ListR\x04list\x1a1\n" + + "\x04List\x12)\n" + + "\x05items\x18\x01 \x03(\v2\x13.productv1.BlogPostR\x05items\"`\n" + + "\rListOfBoolean\x121\n" + + "\x04list\x18\x01 \x01(\v2\x1d.productv1.ListOfBoolean.ListR\x04list\x1a\x1c\n" + + "\x04List\x12\x14\n" + + "\x05items\x18\x01 \x03(\bR\x05items\"w\n" + + "\x0eListOfCategory\x122\n" + + "\x04list\x18\x01 \x01(\v2\x1e.productv1.ListOfCategory.ListR\x04list\x1a1\n" + + "\x04List\x12)\n" + + "\x05items\x18\x01 \x03(\v2\x13.productv1.CategoryR\x05items\"\x86\x01\n" + + "\x13ListOfCategoryInput\x127\n" + + "\x04list\x18\x01 \x01(\v2#.productv1.ListOfCategoryInput.ListR\x04list\x1a6\n" + + "\x04List\x12.\n" + + "\x05items\x18\x01 \x03(\v2\x18.productv1.CategoryInputR\x05items\"\\\n" + + "\vListOfFloat\x12/\n" + + "\x04list\x18\x01 \x01(\v2\x1b.productv1.ListOfFloat.ListR\x04list\x1a\x1c\n" + + "\x04List\x12\x14\n" + + "\x05items\x18\x01 \x03(\x01R\x05items\"\x89\x01\n" + + "\x14ListOfListOfCategory\x128\n" + + "\x04list\x18\x01 \x01(\v2$.productv1.ListOfListOfCategory.ListR\x04list\x1a7\n" + + "\x04List\x12/\n" + + "\x05items\x18\x01 \x03(\v2\x19.productv1.ListOfCategoryR\x05items\"\x98\x01\n" + + "\x19ListOfListOfCategoryInput\x12=\n" + + "\x04list\x18\x01 \x01(\v2).productv1.ListOfListOfCategoryInput.ListR\x04list\x1a<\n" + + "\x04List\x124\n" + + "\x05items\x18\x01 \x03(\v2\x1e.productv1.ListOfCategoryInputR\x05items\"\x83\x01\n" + + "\x12ListOfListOfString\x126\n" + + "\x04list\x18\x01 \x01(\v2\".productv1.ListOfListOfString.ListR\x04list\x1a5\n" + + "\x04List\x12-\n" + + "\x05items\x18\x01 \x03(\v2\x17.productv1.ListOfStringR\x05items\"}\n" + + "\x10ListOfListOfUser\x124\n" + + "\x04list\x18\x01 \x01(\v2 .productv1.ListOfListOfUser.ListR\x04list\x1a3\n" + + "\x04List\x12+\n" + + "\x05items\x18\x01 \x03(\v2\x15.productv1.ListOfUserR\x05items\"\x8c\x01\n" + + "\x15ListOfListOfUserInput\x129\n" + + "\x04list\x18\x01 \x01(\v2%.productv1.ListOfListOfUserInput.ListR\x04list\x1a8\n" + + "\x04List\x120\n" + + "\x05items\x18\x01 \x03(\v2\x1a.productv1.ListOfUserInputR\x05items\"z\n" + + "\x0fListOfOrderLine\x123\n" + + "\x04list\x18\x01 \x01(\v2\x1f.productv1.ListOfOrderLine.ListR\x04list\x1a2\n" + + "\x04List\x12*\n" + + "\x05items\x18\x01 \x03(\v2\x14.productv1.OrderLineR\x05items\"t\n" + + "\rListOfProduct\x121\n" + + "\x04list\x18\x01 \x01(\v2\x1d.productv1.ListOfProduct.ListR\x04list\x1a0\n" + + "\x04List\x12(\n" + + "\x05items\x18\x01 \x03(\v2\x12.productv1.ProductR\x05items\"^\n" + + "\fListOfString\x120\n" + + "\x04list\x18\x01 \x01(\v2\x1c.productv1.ListOfString.ListR\x04list\x1a\x1c\n" + + "\x04List\x12\x14\n" + + "\x05items\x18\x01 \x03(\tR\x05items\"k\n" + + "\n" + + "ListOfUser\x12.\n" + + "\x04list\x18\x01 \x01(\v2\x1a.productv1.ListOfUser.ListR\x04list\x1a-\n" + + "\x04List\x12%\n" + + "\x05items\x18\x01 \x03(\v2\x0f.productv1.UserR\x05items\"z\n" + + "\x0fListOfUserInput\x123\n" + + "\x04list\x18\x01 \x01(\v2\x1f.productv1.ListOfUserInput.ListR\x04list\x1a2\n" + + "\x04List\x12*\n" + + "\x05items\x18\x01 \x03(\v2\x14.productv1.UserInputR\x05items\"-\n" + "\x1bLookupProductByIdRequestKey\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\"V\n" + "\x18LookupProductByIdRequest\x12:\n" + @@ -4564,16 +7827,7 @@ const file_product_proto_rawDesc = "" + "\x06search\x18\x01 \x03(\v2\x17.productv1.SearchResultR\x06search\" \n" + "\x1eQueryRandomSearchResultRequest\"l\n" + "\x1fQueryRandomSearchResultResponse\x12I\n" + - "\x14random_search_result\x18\x01 \x01(\v2\x17.productv1.SearchResultR\x12randomSearchResult\"G\n" + - "\x19MutationCreateUserRequest\x12*\n" + - "\x05input\x18\x01 \x01(\v2\x14.productv1.UserInputR\x05input\"N\n" + - "\x1aMutationCreateUserResponse\x120\n" + - "\vcreate_user\x18\x01 \x01(\v2\x0f.productv1.UserR\n" + - "createUser\"L\n" + - "\x1cMutationPerformActionRequest\x12,\n" + - "\x05input\x18\x01 \x01(\v2\x16.productv1.ActionInputR\x05input\"_\n" + - "\x1dMutationPerformActionResponse\x12>\n" + - "\x0eperform_action\x18\x01 \x01(\v2\x17.productv1.ActionResultR\rperformAction\" \n" + + "\x14random_search_result\x18\x01 \x01(\v2\x17.productv1.SearchResultR\x12randomSearchResult\" \n" + "\x1eQueryNullableFieldsTypeRequest\"r\n" + "\x1fQueryNullableFieldsTypeResponse\x12O\n" + "\x14nullable_fields_type\x18\x01 \x01(\v2\x1d.productv1.NullableFieldsTypeR\x12nullableFieldsType\"4\n" + @@ -4587,7 +7841,46 @@ const file_product_proto_rawDesc = "" + " nullable_fields_type_with_filter\x18\x01 \x03(\v2\x1d.productv1.NullableFieldsTypeR\x1cnullableFieldsTypeWithFilter\"$\n" + "\"QueryAllNullableFieldsTypesRequest\"\x7f\n" + "#QueryAllNullableFieldsTypesResponse\x12X\n" + - "\x19all_nullable_fields_types\x18\x01 \x03(\v2\x1d.productv1.NullableFieldsTypeR\x16allNullableFieldsTypes\"_\n" + + "\x19all_nullable_fields_types\x18\x01 \x03(\v2\x1d.productv1.NullableFieldsTypeR\x16allNullableFieldsTypes\"\x16\n" + + "\x14QueryBlogPostRequest\"I\n" + + "\x15QueryBlogPostResponse\x120\n" + + "\tblog_post\x18\x01 \x01(\v2\x13.productv1.BlogPostR\bblogPost\"*\n" + + "\x18QueryBlogPostByIdRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"W\n" + + "\x19QueryBlogPostByIdResponse\x12:\n" + + "\x0fblog_post_by_id\x18\x01 \x01(\v2\x13.productv1.BlogPostR\fblogPostById\"T\n" + + "\x1fQueryBlogPostsWithFilterRequest\x121\n" + + "\x06filter\x18\x01 \x01(\v2\x19.productv1.BlogPostFilterR\x06filter\"l\n" + + " QueryBlogPostsWithFilterResponse\x12H\n" + + "\x16blog_posts_with_filter\x18\x01 \x03(\v2\x13.productv1.BlogPostR\x13blogPostsWithFilter\"\x1a\n" + + "\x18QueryAllBlogPostsRequest\"V\n" + + "\x19QueryAllBlogPostsResponse\x129\n" + + "\x0eall_blog_posts\x18\x01 \x03(\v2\x13.productv1.BlogPostR\fallBlogPosts\"\x14\n" + + "\x12QueryAuthorRequest\"@\n" + + "\x13QueryAuthorResponse\x12)\n" + + "\x06author\x18\x01 \x01(\v2\x11.productv1.AuthorR\x06author\"(\n" + + "\x16QueryAuthorByIdRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"N\n" + + "\x17QueryAuthorByIdResponse\x123\n" + + "\fauthor_by_id\x18\x01 \x01(\v2\x11.productv1.AuthorR\n" + + "authorById\"P\n" + + "\x1dQueryAuthorsWithFilterRequest\x12/\n" + + "\x06filter\x18\x01 \x01(\v2\x17.productv1.AuthorFilterR\x06filter\"c\n" + + "\x1eQueryAuthorsWithFilterResponse\x12A\n" + + "\x13authors_with_filter\x18\x01 \x03(\v2\x11.productv1.AuthorR\x11authorsWithFilter\"\x18\n" + + "\x16QueryAllAuthorsRequest\"M\n" + + "\x17QueryAllAuthorsResponse\x122\n" + + "\vall_authors\x18\x01 \x03(\v2\x11.productv1.AuthorR\n" + + "allAuthors\"G\n" + + "\x19MutationCreateUserRequest\x12*\n" + + "\x05input\x18\x01 \x01(\v2\x14.productv1.UserInputR\x05input\"N\n" + + "\x1aMutationCreateUserResponse\x120\n" + + "\vcreate_user\x18\x01 \x01(\v2\x0f.productv1.UserR\n" + + "createUser\"L\n" + + "\x1cMutationPerformActionRequest\x12,\n" + + "\x05input\x18\x01 \x01(\v2\x16.productv1.ActionInputR\x05input\"_\n" + + "\x1dMutationPerformActionResponse\x12>\n" + + "\x0eperform_action\x18\x01 \x01(\v2\x17.productv1.ActionResultR\rperformAction\"_\n" + "'MutationCreateNullableFieldsTypeRequest\x124\n" + "\x05input\x18\x01 \x01(\v2\x1e.productv1.NullableFieldsInputR\x05input\"\x88\x01\n" + "(MutationCreateNullableFieldsTypeResponse\x12\\\n" + @@ -4596,7 +7889,25 @@ const file_product_proto_rawDesc = "" + "\x02id\x18\x01 \x01(\tR\x02id\x124\n" + "\x05input\x18\x02 \x01(\v2\x1e.productv1.NullableFieldsInputR\x05input\"\x88\x01\n" + "(MutationUpdateNullableFieldsTypeResponse\x12\\\n" + - "\x1bupdate_nullable_fields_type\x18\x01 \x01(\v2\x1d.productv1.NullableFieldsTypeR\x18updateNullableFieldsType\"C\n" + + "\x1bupdate_nullable_fields_type\x18\x01 \x01(\v2\x1d.productv1.NullableFieldsTypeR\x18updateNullableFieldsType\"O\n" + + "\x1dMutationCreateBlogPostRequest\x12.\n" + + "\x05input\x18\x01 \x01(\v2\x18.productv1.BlogPostInputR\x05input\"_\n" + + "\x1eMutationCreateBlogPostResponse\x12=\n" + + "\x10create_blog_post\x18\x01 \x01(\v2\x13.productv1.BlogPostR\x0ecreateBlogPost\"_\n" + + "\x1dMutationUpdateBlogPostRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12.\n" + + "\x05input\x18\x02 \x01(\v2\x18.productv1.BlogPostInputR\x05input\"_\n" + + "\x1eMutationUpdateBlogPostResponse\x12=\n" + + "\x10update_blog_post\x18\x01 \x01(\v2\x13.productv1.BlogPostR\x0eupdateBlogPost\"K\n" + + "\x1bMutationCreateAuthorRequest\x12,\n" + + "\x05input\x18\x01 \x01(\v2\x16.productv1.AuthorInputR\x05input\"V\n" + + "\x1cMutationCreateAuthorResponse\x126\n" + + "\rcreate_author\x18\x01 \x01(\v2\x11.productv1.AuthorR\fcreateAuthor\"[\n" + + "\x1bMutationUpdateAuthorRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12,\n" + + "\x05input\x18\x02 \x01(\v2\x16.productv1.AuthorInputR\x05input\"V\n" + + "\x1cMutationUpdateAuthorResponse\x126\n" + + "\rupdate_author\x18\x01 \x01(\v2\x11.productv1.AuthorR\fupdateAuthor\"C\n" + "\aProduct\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12\x14\n" + @@ -4633,13 +7944,13 @@ const file_product_proto_rawDesc = "" + "OrderInput\x12\x19\n" + "\border_id\x18\x01 \x01(\tR\aorderId\x12#\n" + "\rcustomer_name\x18\x02 \x01(\tR\fcustomerName\x12/\n" + - "\x05lines\x18\x03 \x03(\v2\x19.productv1.OrderLineInputR\x05lines\"\x9f\x01\n" + + "\x05lines\x18\x03 \x03(\v2\x19.productv1.OrderLineInputR\x05lines\"\xa5\x01\n" + "\x05Order\x12\x19\n" + "\border_id\x18\x01 \x01(\tR\aorderId\x12#\n" + "\rcustomer_name\x18\x02 \x01(\tR\fcustomerName\x12\x1f\n" + "\vtotal_items\x18\x03 \x01(\x05R\n" + - "totalItems\x125\n" + - "\vorder_lines\x18\x04 \x03(\v2\x14.productv1.OrderLineR\n" + + "totalItems\x12;\n" + + "\vorder_lines\x18\x04 \x01(\v2\x1a.productv1.ListOfOrderLineR\n" + "orderLines\"[\n" + "\bCategory\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + @@ -4654,15 +7965,80 @@ const file_product_proto_rawDesc = "" + "\x03cat\x18\x01 \x01(\v2\x0e.productv1.CatH\x00R\x03cat\x12\"\n" + "\x03dog\x18\x02 \x01(\v2\x0e.productv1.DogH\x00R\x03dogB\n" + "\n" + - "\binstance\"9\n" + + "\binstance\"V\n" + "\vSearchInput\x12\x14\n" + - "\x05query\x18\x01 \x01(\tR\x05query\x12\x14\n" + - "\x05limit\x18\x02 \x01(\x05R\x05limit\"\xa1\x01\n" + + "\x05query\x18\x01 \x01(\tR\x05query\x121\n" + + "\x05limit\x18\x02 \x01(\v2\x1b.google.protobuf.Int32ValueR\x05limit\"\xa1\x01\n" + "\fSearchResult\x12.\n" + "\aproduct\x18\x01 \x01(\v2\x12.productv1.ProductH\x00R\aproduct\x12%\n" + "\x04user\x18\x02 \x01(\v2\x0f.productv1.UserH\x00R\x04user\x121\n" + "\bcategory\x18\x03 \x01(\v2\x13.productv1.CategoryH\x00R\bcategoryB\a\n" + - "\x05value\"\x1f\n" + + "\x05value\"\x97\x03\n" + + "\x12NullableFieldsType\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12E\n" + + "\x0foptional_string\x18\x03 \x01(\v2\x1c.google.protobuf.StringValueR\x0eoptionalString\x12>\n" + + "\foptional_int\x18\x04 \x01(\v2\x1b.google.protobuf.Int32ValueR\voptionalInt\x12C\n" + + "\x0eoptional_float\x18\x05 \x01(\v2\x1c.google.protobuf.DoubleValueR\roptionalFloat\x12E\n" + + "\x10optional_boolean\x18\x06 \x01(\v2\x1a.google.protobuf.BoolValueR\x0foptionalBoolean\x12'\n" + + "\x0frequired_string\x18\a \x01(\tR\x0erequiredString\x12!\n" + + "\frequired_int\x18\b \x01(\x05R\vrequiredInt\"\xd0\x01\n" + + "\x14NullableFieldsFilter\x120\n" + + "\x04name\x18\x01 \x01(\v2\x1c.google.protobuf.StringValueR\x04name\x12E\n" + + "\x0foptional_string\x18\x02 \x01(\v2\x1c.google.protobuf.StringValueR\x0eoptionalString\x12?\n" + + "\rinclude_nulls\x18\x03 \x01(\v2\x1a.google.protobuf.BoolValueR\fincludeNulls\"\xa4\b\n" + + "\bBlogPost\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x14\n" + + "\x05title\x18\x02 \x01(\tR\x05title\x12\x18\n" + + "\acontent\x18\x03 \x01(\tR\acontent\x12\x12\n" + + "\x04tags\x18\x04 \x03(\tR\x04tags\x12<\n" + + "\roptional_tags\x18\x05 \x01(\v2\x17.productv1.ListOfStringR\foptionalTags\x12\x1e\n" + + "\n" + + "categories\x18\x06 \x03(\tR\n" + + "categories\x123\n" + + "\bkeywords\x18\a \x01(\v2\x17.productv1.ListOfStringR\bkeywords\x12\x1f\n" + + "\vview_counts\x18\b \x03(\x05R\n" + + "viewCounts\x120\n" + + "\aratings\x18\t \x01(\v2\x16.productv1.ListOfFloatR\aratings\x12;\n" + + "\fis_published\x18\n" + + " \x01(\v2\x18.productv1.ListOfBooleanR\visPublished\x12<\n" + + "\n" + + "tag_groups\x18\v \x01(\v2\x1d.productv1.ListOfListOfStringR\ttagGroups\x12D\n" + + "\x0erelated_topics\x18\f \x01(\v2\x1d.productv1.ListOfListOfStringR\rrelatedTopics\x12F\n" + + "\x0fcomment_threads\x18\r \x01(\v2\x1d.productv1.ListOfListOfStringR\x0ecommentThreads\x12?\n" + + "\vsuggestions\x18\x0e \x01(\v2\x1d.productv1.ListOfListOfStringR\vsuggestions\x12B\n" + + "\x12related_categories\x18\x0f \x03(\v2\x13.productv1.CategoryR\x11relatedCategories\x123\n" + + "\fcontributors\x18\x10 \x03(\v2\x0f.productv1.UserR\fcontributors\x12G\n" + + "\x12mentioned_products\x18\x11 \x01(\v2\x18.productv1.ListOfProductR\x11mentionedProducts\x12>\n" + + "\x0fmentioned_users\x18\x12 \x01(\v2\x15.productv1.ListOfUserR\x0ementionedUsers\x12H\n" + + "\x0fcategory_groups\x18\x13 \x01(\v2\x1f.productv1.ListOfListOfCategoryR\x0ecategoryGroups\x12H\n" + + "\x11contributor_teams\x18\x14 \x01(\v2\x1b.productv1.ListOfListOfUserR\x10contributorTeams\"\xbf\x01\n" + + "\x0eBlogPostFilter\x122\n" + + "\x05title\x18\x01 \x01(\v2\x1c.google.protobuf.StringValueR\x05title\x12A\n" + + "\x0ehas_categories\x18\x02 \x01(\v2\x1a.google.protobuf.BoolValueR\rhasCategories\x126\n" + + "\bmin_tags\x18\x03 \x01(\v2\x1b.google.protobuf.Int32ValueR\aminTags\"\xc3\x06\n" + + "\x06Author\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x122\n" + + "\x05email\x18\x03 \x01(\v2\x1c.google.protobuf.StringValueR\x05email\x12\x16\n" + + "\x06skills\x18\x04 \x03(\tR\x06skills\x12\x1c\n" + + "\tlanguages\x18\x05 \x03(\tR\tlanguages\x12:\n" + + "\fsocial_links\x18\x06 \x01(\v2\x17.productv1.ListOfStringR\vsocialLinks\x12G\n" + + "\x10teams_by_project\x18\a \x01(\v2\x1d.productv1.ListOfListOfStringR\x0eteamsByProject\x12E\n" + + "\x0ecollaborations\x18\b \x01(\v2\x1d.productv1.ListOfListOfStringR\x0ecollaborations\x12>\n" + + "\rwritten_posts\x18\t \x01(\v2\x19.productv1.ListOfBlogPostR\fwrittenPosts\x12D\n" + + "\x13favorite_categories\x18\n" + + " \x03(\v2\x13.productv1.CategoryR\x12favoriteCategories\x12>\n" + + "\x0frelated_authors\x18\v \x01(\v2\x15.productv1.ListOfUserR\x0erelatedAuthors\x12A\n" + + "\x0fproduct_reviews\x18\f \x01(\v2\x18.productv1.ListOfProductR\x0eproductReviews\x12@\n" + + "\rauthor_groups\x18\r \x01(\v2\x1b.productv1.ListOfListOfUserR\fauthorGroups\x12R\n" + + "\x14category_preferences\x18\x0e \x01(\v2\x1f.productv1.ListOfListOfCategoryR\x13categoryPreferences\x12@\n" + + "\rproject_teams\x18\x0f \x01(\v2\x1b.productv1.ListOfListOfUserR\fprojectTeams\"\xb7\x01\n" + + "\fAuthorFilter\x120\n" + + "\x04name\x18\x01 \x01(\v2\x1c.google.protobuf.StringValueR\x04name\x127\n" + + "\thas_teams\x18\x02 \x01(\v2\x1a.google.protobuf.BoolValueR\bhasTeams\x12<\n" + + "\vskill_count\x18\x03 \x01(\v2\x1b.google.protobuf.Int32ValueR\n" + + "skillCount\"\x1f\n" + "\tUserInput\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\";\n" + "\vActionInput\x12\x12\n" + @@ -4671,7 +8047,49 @@ const file_product_proto_rawDesc = "" + "\fActionResult\x12A\n" + "\x0eaction_success\x18\x01 \x01(\v2\x18.productv1.ActionSuccessH\x00R\ractionSuccess\x12;\n" + "\faction_error\x18\x02 \x01(\v2\x16.productv1.ActionErrorH\x00R\vactionErrorB\a\n" + - "\x05value\"W\n" + + "\x05value\"\x88\x03\n" + + "\x13NullableFieldsInput\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12E\n" + + "\x0foptional_string\x18\x02 \x01(\v2\x1c.google.protobuf.StringValueR\x0eoptionalString\x12>\n" + + "\foptional_int\x18\x03 \x01(\v2\x1b.google.protobuf.Int32ValueR\voptionalInt\x12C\n" + + "\x0eoptional_float\x18\x04 \x01(\v2\x1c.google.protobuf.DoubleValueR\roptionalFloat\x12E\n" + + "\x10optional_boolean\x18\x05 \x01(\v2\x1a.google.protobuf.BoolValueR\x0foptionalBoolean\x12'\n" + + "\x0frequired_string\x18\x06 \x01(\tR\x0erequiredString\x12!\n" + + "\frequired_int\x18\a \x01(\x05R\vrequiredInt\"\xe1\x06\n" + + "\rBlogPostInput\x12\x14\n" + + "\x05title\x18\x01 \x01(\tR\x05title\x12\x18\n" + + "\acontent\x18\x02 \x01(\tR\acontent\x12\x12\n" + + "\x04tags\x18\x03 \x03(\tR\x04tags\x12<\n" + + "\roptional_tags\x18\x04 \x01(\v2\x17.productv1.ListOfStringR\foptionalTags\x12\x1e\n" + + "\n" + + "categories\x18\x05 \x03(\tR\n" + + "categories\x123\n" + + "\bkeywords\x18\x06 \x01(\v2\x17.productv1.ListOfStringR\bkeywords\x12\x1f\n" + + "\vview_counts\x18\a \x03(\x05R\n" + + "viewCounts\x120\n" + + "\aratings\x18\b \x01(\v2\x16.productv1.ListOfFloatR\aratings\x12;\n" + + "\fis_published\x18\t \x01(\v2\x18.productv1.ListOfBooleanR\visPublished\x12<\n" + + "\n" + + "tag_groups\x18\n" + + " \x01(\v2\x1d.productv1.ListOfListOfStringR\ttagGroups\x12D\n" + + "\x0erelated_topics\x18\v \x01(\v2\x1d.productv1.ListOfListOfStringR\rrelatedTopics\x12F\n" + + "\x0fcomment_threads\x18\f \x01(\v2\x1d.productv1.ListOfListOfStringR\x0ecommentThreads\x12?\n" + + "\vsuggestions\x18\r \x01(\v2\x1d.productv1.ListOfListOfStringR\vsuggestions\x12M\n" + + "\x12related_categories\x18\x0e \x01(\v2\x1e.productv1.ListOfCategoryInputR\x11relatedCategories\x12>\n" + + "\fcontributors\x18\x0f \x01(\v2\x1a.productv1.ListOfUserInputR\fcontributors\x12M\n" + + "\x0fcategory_groups\x18\x10 \x01(\v2$.productv1.ListOfListOfCategoryInputR\x0ecategoryGroups\"\xb0\x04\n" + + "\vAuthorInput\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x122\n" + + "\x05email\x18\x02 \x01(\v2\x1c.google.protobuf.StringValueR\x05email\x12\x16\n" + + "\x06skills\x18\x03 \x03(\tR\x06skills\x12\x1c\n" + + "\tlanguages\x18\x04 \x03(\tR\tlanguages\x12:\n" + + "\fsocial_links\x18\x05 \x01(\v2\x17.productv1.ListOfStringR\vsocialLinks\x12G\n" + + "\x10teams_by_project\x18\x06 \x01(\v2\x1d.productv1.ListOfListOfStringR\x0eteamsByProject\x12E\n" + + "\x0ecollaborations\x18\a \x01(\v2\x1d.productv1.ListOfListOfStringR\x0ecollaborations\x12I\n" + + "\x13favorite_categories\x18\b \x03(\v2\x18.productv1.CategoryInputR\x12favoriteCategories\x12E\n" + + "\rauthor_groups\x18\t \x01(\v2 .productv1.ListOfListOfUserInputR\fauthorGroups\x12E\n" + + "\rproject_teams\x18\n" + + " \x01(\v2 .productv1.ListOfListOfUserInputR\fprojectTeams\"W\n" + "\vNestedTypeB\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12$\n" + @@ -4690,17 +8108,17 @@ const file_product_proto_rawDesc = "" + "\n" + "Pagination\x12\x12\n" + "\x04page\x18\x01 \x01(\x05R\x04page\x12\x19\n" + - "\bper_page\x18\x02 \x01(\x05R\aperPage\"i\n" + + "\bper_page\x18\x02 \x01(\x05R\aperPage\"\x82\x01\n" + "\x0eOrderLineInput\x12\x1d\n" + "\n" + "product_id\x18\x01 \x01(\tR\tproductId\x12\x1a\n" + - "\bquantity\x18\x02 \x01(\x05R\bquantity\x12\x1c\n" + - "\tmodifiers\x18\x03 \x03(\tR\tmodifiers\"d\n" + + "\bquantity\x18\x02 \x01(\x05R\bquantity\x125\n" + + "\tmodifiers\x18\x03 \x01(\v2\x17.productv1.ListOfStringR\tmodifiers\"}\n" + "\tOrderLine\x12\x1d\n" + "\n" + "product_id\x18\x01 \x01(\tR\tproductId\x12\x1a\n" + - "\bquantity\x18\x02 \x01(\x05R\bquantity\x12\x1c\n" + - "\tmodifiers\x18\x03 \x03(\tR\tmodifiers\"^\n" + + "\bquantity\x18\x02 \x01(\x05R\bquantity\x125\n" + + "\tmodifiers\x18\x03 \x01(\v2\x17.productv1.ListOfStringR\tmodifiers\"^\n" + "\x03Cat\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12\x12\n" + @@ -4718,47 +8136,47 @@ const file_product_proto_rawDesc = "" + "\ttimestamp\x18\x02 \x01(\tR\ttimestamp\";\n" + "\vActionError\x12\x18\n" + "\amessage\x18\x01 \x01(\tR\amessage\x12\x12\n" + - "\x04code\x18\x02 \x01(\tR\x04code\"\x96\x03\n" + - "\x12NullableFieldsType\x12\x0e\n" + - "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + - "\x04name\x18\x02 \x01(\tR\x04name\x12E\n" + - "\x0foptional_string\x18\x03 \x01(\v2\x1c.google.protobuf.StringValueR\x0eoptionalString\x12>\n" + - "\foptional_int\x18\x04 \x01(\v2\x1b.google.protobuf.Int32ValueR\voptionalInt\x12B\n" + - "\x0eoptional_float\x18\x05 \x01(\v2\x1b.google.protobuf.FloatValueR\roptionalFloat\x12E\n" + - "\x10optional_boolean\x18\x06 \x01(\v2\x1a.google.protobuf.BoolValueR\x0foptionalBoolean\x12'\n" + - "\x0frequired_string\x18\a \x01(\tR\x0erequiredString\x12!\n" + - "\frequired_int\x18\b \x01(\x05R\vrequiredInt\"\x87\x03\n" + - "\x13NullableFieldsInput\x12\x12\n" + - "\x04name\x18\x01 \x01(\tR\x04name\x12E\n" + - "\x0foptional_string\x18\x02 \x01(\v2\x1c.google.protobuf.StringValueR\x0eoptionalString\x12>\n" + - "\foptional_int\x18\x03 \x01(\v2\x1b.google.protobuf.Int32ValueR\voptionalInt\x12B\n" + - "\x0eoptional_float\x18\x04 \x01(\v2\x1b.google.protobuf.FloatValueR\roptionalFloat\x12E\n" + - "\x10optional_boolean\x18\x05 \x01(\v2\x1a.google.protobuf.BoolValueR\x0foptionalBoolean\x12'\n" + - "\x0frequired_string\x18\x06 \x01(\tR\x0erequiredString\x12!\n" + - "\frequired_int\x18\a \x01(\x05R\vrequiredInt\"\xd0\x01\n" + - "\x14NullableFieldsFilter\x120\n" + - "\x04name\x18\x01 \x01(\v2\x1c.google.protobuf.StringValueR\x04name\x12E\n" + - "\x0foptional_string\x18\x02 \x01(\v2\x1c.google.protobuf.StringValueR\x0eoptionalString\x12?\n" + - "\rinclude_nulls\x18\x03 \x01(\v2\x1a.google.protobuf.BoolValueR\fincludeNulls*\x9a\x01\n" + + "\x04code\x18\x02 \x01(\tR\x04code\"P\n" + + "\rCategoryInput\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12+\n" + + "\x04kind\x18\x02 \x01(\x0e2\x17.productv1.CategoryKindR\x04kind*\x9a\x01\n" + "\fCategoryKind\x12\x1d\n" + "\x19CATEGORY_KIND_UNSPECIFIED\x10\x00\x12\x16\n" + "\x12CATEGORY_KIND_BOOK\x10\x01\x12\x1d\n" + "\x19CATEGORY_KIND_ELECTRONICS\x10\x02\x12\x1b\n" + "\x17CATEGORY_KIND_FURNITURE\x10\x03\x12\x17\n" + - "\x13CATEGORY_KIND_OTHER\x10\x042\xb2\x16\n" + + "\x13CATEGORY_KIND_OTHER\x10\x042\xf4\x1f\n" + "\x0eProductService\x12`\n" + "\x11LookupProductById\x12#.productv1.LookupProductByIdRequest\x1a$.productv1.LookupProductByIdResponse\"\x00\x12`\n" + - "\x11LookupStorageById\x12#.productv1.LookupStorageByIdRequest\x1a$.productv1.LookupStorageByIdResponse\"\x00\x12c\n" + + "\x11LookupStorageById\x12#.productv1.LookupStorageByIdRequest\x1a$.productv1.LookupStorageByIdResponse\"\x00\x12i\n" + + "\x14MutationCreateAuthor\x12&.productv1.MutationCreateAuthorRequest\x1a'.productv1.MutationCreateAuthorResponse\"\x00\x12o\n" + + "\x16MutationCreateBlogPost\x12(.productv1.MutationCreateBlogPostRequest\x1a).productv1.MutationCreateBlogPostResponse\"\x00\x12\x8d\x01\n" + + " MutationCreateNullableFieldsType\x122.productv1.MutationCreateNullableFieldsTypeRequest\x1a3.productv1.MutationCreateNullableFieldsTypeResponse\"\x00\x12c\n" + "\x12MutationCreateUser\x12$.productv1.MutationCreateUserRequest\x1a%.productv1.MutationCreateUserResponse\"\x00\x12l\n" + - "\x15MutationPerformAction\x12'.productv1.MutationPerformActionRequest\x1a(.productv1.MutationPerformActionResponse\"\x00\x12Q\n" + - "\fQueryAllPets\x12\x1e.productv1.QueryAllPetsRequest\x1a\x1f.productv1.QueryAllPetsResponse\"\x00\x12i\n" + + "\x15MutationPerformAction\x12'.productv1.MutationPerformActionRequest\x1a(.productv1.MutationPerformActionResponse\"\x00\x12i\n" + + "\x14MutationUpdateAuthor\x12&.productv1.MutationUpdateAuthorRequest\x1a'.productv1.MutationUpdateAuthorResponse\"\x00\x12o\n" + + "\x16MutationUpdateBlogPost\x12(.productv1.MutationUpdateBlogPostRequest\x1a).productv1.MutationUpdateBlogPostResponse\"\x00\x12\x8d\x01\n" + + " MutationUpdateNullableFieldsType\x122.productv1.MutationUpdateNullableFieldsTypeRequest\x1a3.productv1.MutationUpdateNullableFieldsTypeResponse\"\x00\x12Z\n" + + "\x0fQueryAllAuthors\x12!.productv1.QueryAllAuthorsRequest\x1a\".productv1.QueryAllAuthorsResponse\"\x00\x12`\n" + + "\x11QueryAllBlogPosts\x12#.productv1.QueryAllBlogPostsRequest\x1a$.productv1.QueryAllBlogPostsResponse\"\x00\x12~\n" + + "\x1bQueryAllNullableFieldsTypes\x12-.productv1.QueryAllNullableFieldsTypesRequest\x1a..productv1.QueryAllNullableFieldsTypesResponse\"\x00\x12Q\n" + + "\fQueryAllPets\x12\x1e.productv1.QueryAllPetsRequest\x1a\x1f.productv1.QueryAllPetsResponse\"\x00\x12N\n" + + "\vQueryAuthor\x12\x1d.productv1.QueryAuthorRequest\x1a\x1e.productv1.QueryAuthorResponse\"\x00\x12Z\n" + + "\x0fQueryAuthorById\x12!.productv1.QueryAuthorByIdRequest\x1a\".productv1.QueryAuthorByIdResponse\"\x00\x12o\n" + + "\x16QueryAuthorsWithFilter\x12(.productv1.QueryAuthorsWithFilterRequest\x1a).productv1.QueryAuthorsWithFilterResponse\"\x00\x12T\n" + + "\rQueryBlogPost\x12\x1f.productv1.QueryBlogPostRequest\x1a .productv1.QueryBlogPostResponse\"\x00\x12`\n" + + "\x11QueryBlogPostById\x12#.productv1.QueryBlogPostByIdRequest\x1a$.productv1.QueryBlogPostByIdResponse\"\x00\x12u\n" + + "\x18QueryBlogPostsWithFilter\x12*.productv1.QueryBlogPostsWithFilterRequest\x1a+.productv1.QueryBlogPostsWithFilterResponse\"\x00\x12i\n" + "\x14QueryCalculateTotals\x12&.productv1.QueryCalculateTotalsRequest\x1a'.productv1.QueryCalculateTotalsResponse\"\x00\x12Z\n" + "\x0fQueryCategories\x12!.productv1.QueryCategoriesRequest\x1a\".productv1.QueryCategoriesResponse\"\x00\x12l\n" + "\x15QueryCategoriesByKind\x12'.productv1.QueryCategoriesByKindRequest\x1a(.productv1.QueryCategoriesByKindResponse\"\x00\x12o\n" + "\x16QueryCategoriesByKinds\x12(.productv1.QueryCategoriesByKindsRequest\x1a).productv1.QueryCategoriesByKindsResponse\"\x00\x12o\n" + "\x16QueryComplexFilterType\x12(.productv1.QueryComplexFilterTypeRequest\x1a).productv1.QueryComplexFilterTypeResponse\"\x00\x12l\n" + "\x15QueryFilterCategories\x12'.productv1.QueryFilterCategoriesRequest\x1a(.productv1.QueryFilterCategoriesResponse\"\x00\x12Z\n" + - "\x0fQueryNestedType\x12!.productv1.QueryNestedTypeRequest\x1a\".productv1.QueryNestedTypeResponse\"\x00\x12W\n" + + "\x0fQueryNestedType\x12!.productv1.QueryNestedTypeRequest\x1a\".productv1.QueryNestedTypeResponse\"\x00\x12r\n" + + "\x17QueryNullableFieldsType\x12).productv1.QueryNullableFieldsTypeRequest\x1a*.productv1.QueryNullableFieldsTypeResponse\"\x00\x12~\n" + + "\x1bQueryNullableFieldsTypeById\x12-.productv1.QueryNullableFieldsTypeByIdRequest\x1a..productv1.QueryNullableFieldsTypeByIdResponse\"\x00\x12\x90\x01\n" + + "!QueryNullableFieldsTypeWithFilter\x123.productv1.QueryNullableFieldsTypeWithFilterRequest\x1a4.productv1.QueryNullableFieldsTypeWithFilterResponse\"\x00\x12W\n" + "\x0eQueryRandomPet\x12 .productv1.QueryRandomPetRequest\x1a!.productv1.QueryRandomPetResponse\"\x00\x12r\n" + "\x17QueryRandomSearchResult\x12).productv1.QueryRandomSearchResultRequest\x1a*.productv1.QueryRandomSearchResultResponse\"\x00\x12c\n" + "\x12QueryRecursiveType\x12$.productv1.QueryRecursiveTypeRequest\x1a%.productv1.QueryRecursiveTypeResponse\"\x00\x12N\n" + @@ -4767,13 +8185,7 @@ const file_product_proto_rawDesc = "" + "!QueryTypeWithMultipleFilterFields\x123.productv1.QueryTypeWithMultipleFilterFieldsRequest\x1a4.productv1.QueryTypeWithMultipleFilterFieldsResponse\"\x00\x12H\n" + "\tQueryUser\x12\x1b.productv1.QueryUserRequest\x1a\x1c.productv1.QueryUserResponse\"\x00\x12K\n" + "\n" + - "QueryUsers\x12\x1c.productv1.QueryUsersRequest\x1a\x1d.productv1.QueryUsersResponse\"\x00\x12r\n" + - "\x17QueryNullableFieldsType\x12).productv1.QueryNullableFieldsTypeRequest\x1a*.productv1.QueryNullableFieldsTypeResponse\"\x00\x12~\n" + - "\x1bQueryNullableFieldsTypeById\x12-.productv1.QueryNullableFieldsTypeByIdRequest\x1a..productv1.QueryNullableFieldsTypeByIdResponse\"\x00\x12\x90\x01\n" + - "!QueryNullableFieldsTypeWithFilter\x123.productv1.QueryNullableFieldsTypeWithFilterRequest\x1a4.productv1.QueryNullableFieldsTypeWithFilterResponse\"\x00\x12~\n" + - "\x1bQueryAllNullableFieldsTypes\x12-.productv1.QueryAllNullableFieldsTypesRequest\x1a..productv1.QueryAllNullableFieldsTypesResponse\"\x00\x12\x8d\x01\n" + - " MutationCreateNullableFieldsType\x122.productv1.MutationCreateNullableFieldsTypeRequest\x1a3.productv1.MutationCreateNullableFieldsTypeResponse\"\x00\x12\x8d\x01\n" + - " MutationUpdateNullableFieldsType\x122.productv1.MutationUpdateNullableFieldsTypeRequest\x1a3.productv1.MutationUpdateNullableFieldsTypeResponse\"\x00B%Z#cosmo/pkg/proto/productv1;productv1b\x06proto3" + "QueryUsers\x12\x1c.productv1.QueryUsersRequest\x1a\x1d.productv1.QueryUsersResponse\"\x00B%Z#cosmo/pkg/proto/productv1;productv1b\x06proto3" var ( file_product_proto_rawDescOnce sync.Once @@ -4788,226 +8200,409 @@ func file_product_proto_rawDescGZIP() []byte { } var file_product_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_product_proto_msgTypes = make([]protoimpl.MessageInfo, 86) +var file_product_proto_msgTypes = make([]protoimpl.MessageInfo, 147) var file_product_proto_goTypes = []any{ (CategoryKind)(0), // 0: productv1.CategoryKind - (*LookupProductByIdRequestKey)(nil), // 1: productv1.LookupProductByIdRequestKey - (*LookupProductByIdRequest)(nil), // 2: productv1.LookupProductByIdRequest - (*LookupProductByIdResponse)(nil), // 3: productv1.LookupProductByIdResponse - (*LookupStorageByIdRequestKey)(nil), // 4: productv1.LookupStorageByIdRequestKey - (*LookupStorageByIdRequest)(nil), // 5: productv1.LookupStorageByIdRequest - (*LookupStorageByIdResponse)(nil), // 6: productv1.LookupStorageByIdResponse - (*QueryUsersRequest)(nil), // 7: productv1.QueryUsersRequest - (*QueryUsersResponse)(nil), // 8: productv1.QueryUsersResponse - (*QueryUserRequest)(nil), // 9: productv1.QueryUserRequest - (*QueryUserResponse)(nil), // 10: productv1.QueryUserResponse - (*QueryNestedTypeRequest)(nil), // 11: productv1.QueryNestedTypeRequest - (*QueryNestedTypeResponse)(nil), // 12: productv1.QueryNestedTypeResponse - (*QueryRecursiveTypeRequest)(nil), // 13: productv1.QueryRecursiveTypeRequest - (*QueryRecursiveTypeResponse)(nil), // 14: productv1.QueryRecursiveTypeResponse - (*QueryTypeFilterWithArgumentsRequest)(nil), // 15: productv1.QueryTypeFilterWithArgumentsRequest - (*QueryTypeFilterWithArgumentsResponse)(nil), // 16: productv1.QueryTypeFilterWithArgumentsResponse - (*QueryTypeWithMultipleFilterFieldsRequest)(nil), // 17: productv1.QueryTypeWithMultipleFilterFieldsRequest - (*QueryTypeWithMultipleFilterFieldsResponse)(nil), // 18: productv1.QueryTypeWithMultipleFilterFieldsResponse - (*QueryComplexFilterTypeRequest)(nil), // 19: productv1.QueryComplexFilterTypeRequest - (*QueryComplexFilterTypeResponse)(nil), // 20: productv1.QueryComplexFilterTypeResponse - (*QueryCalculateTotalsRequest)(nil), // 21: productv1.QueryCalculateTotalsRequest - (*QueryCalculateTotalsResponse)(nil), // 22: productv1.QueryCalculateTotalsResponse - (*QueryCategoriesRequest)(nil), // 23: productv1.QueryCategoriesRequest - (*QueryCategoriesResponse)(nil), // 24: productv1.QueryCategoriesResponse - (*QueryCategoriesByKindRequest)(nil), // 25: productv1.QueryCategoriesByKindRequest - (*QueryCategoriesByKindResponse)(nil), // 26: productv1.QueryCategoriesByKindResponse - (*QueryCategoriesByKindsRequest)(nil), // 27: productv1.QueryCategoriesByKindsRequest - (*QueryCategoriesByKindsResponse)(nil), // 28: productv1.QueryCategoriesByKindsResponse - (*QueryFilterCategoriesRequest)(nil), // 29: productv1.QueryFilterCategoriesRequest - (*QueryFilterCategoriesResponse)(nil), // 30: productv1.QueryFilterCategoriesResponse - (*QueryRandomPetRequest)(nil), // 31: productv1.QueryRandomPetRequest - (*QueryRandomPetResponse)(nil), // 32: productv1.QueryRandomPetResponse - (*QueryAllPetsRequest)(nil), // 33: productv1.QueryAllPetsRequest - (*QueryAllPetsResponse)(nil), // 34: productv1.QueryAllPetsResponse - (*QuerySearchRequest)(nil), // 35: productv1.QuerySearchRequest - (*QuerySearchResponse)(nil), // 36: productv1.QuerySearchResponse - (*QueryRandomSearchResultRequest)(nil), // 37: productv1.QueryRandomSearchResultRequest - (*QueryRandomSearchResultResponse)(nil), // 38: productv1.QueryRandomSearchResultResponse - (*MutationCreateUserRequest)(nil), // 39: productv1.MutationCreateUserRequest - (*MutationCreateUserResponse)(nil), // 40: productv1.MutationCreateUserResponse - (*MutationPerformActionRequest)(nil), // 41: productv1.MutationPerformActionRequest - (*MutationPerformActionResponse)(nil), // 42: productv1.MutationPerformActionResponse - (*QueryNullableFieldsTypeRequest)(nil), // 43: productv1.QueryNullableFieldsTypeRequest - (*QueryNullableFieldsTypeResponse)(nil), // 44: productv1.QueryNullableFieldsTypeResponse - (*QueryNullableFieldsTypeByIdRequest)(nil), // 45: productv1.QueryNullableFieldsTypeByIdRequest - (*QueryNullableFieldsTypeByIdResponse)(nil), // 46: productv1.QueryNullableFieldsTypeByIdResponse - (*QueryNullableFieldsTypeWithFilterRequest)(nil), // 47: productv1.QueryNullableFieldsTypeWithFilterRequest - (*QueryNullableFieldsTypeWithFilterResponse)(nil), // 48: productv1.QueryNullableFieldsTypeWithFilterResponse - (*QueryAllNullableFieldsTypesRequest)(nil), // 49: productv1.QueryAllNullableFieldsTypesRequest - (*QueryAllNullableFieldsTypesResponse)(nil), // 50: productv1.QueryAllNullableFieldsTypesResponse - (*MutationCreateNullableFieldsTypeRequest)(nil), // 51: productv1.MutationCreateNullableFieldsTypeRequest - (*MutationCreateNullableFieldsTypeResponse)(nil), // 52: productv1.MutationCreateNullableFieldsTypeResponse - (*MutationUpdateNullableFieldsTypeRequest)(nil), // 53: productv1.MutationUpdateNullableFieldsTypeRequest - (*MutationUpdateNullableFieldsTypeResponse)(nil), // 54: productv1.MutationUpdateNullableFieldsTypeResponse - (*Product)(nil), // 55: productv1.Product - (*Storage)(nil), // 56: productv1.Storage - (*User)(nil), // 57: productv1.User - (*NestedTypeA)(nil), // 58: productv1.NestedTypeA - (*RecursiveType)(nil), // 59: productv1.RecursiveType - (*TypeWithMultipleFilterFields)(nil), // 60: productv1.TypeWithMultipleFilterFields - (*FilterTypeInput)(nil), // 61: productv1.FilterTypeInput - (*ComplexFilterTypeInput)(nil), // 62: productv1.ComplexFilterTypeInput - (*TypeWithComplexFilterInput)(nil), // 63: productv1.TypeWithComplexFilterInput - (*OrderInput)(nil), // 64: productv1.OrderInput - (*Order)(nil), // 65: productv1.Order - (*Category)(nil), // 66: productv1.Category - (*CategoryFilter)(nil), // 67: productv1.CategoryFilter - (*Animal)(nil), // 68: productv1.Animal - (*SearchInput)(nil), // 69: productv1.SearchInput - (*SearchResult)(nil), // 70: productv1.SearchResult - (*UserInput)(nil), // 71: productv1.UserInput - (*ActionInput)(nil), // 72: productv1.ActionInput - (*ActionResult)(nil), // 73: productv1.ActionResult - (*NestedTypeB)(nil), // 74: productv1.NestedTypeB - (*NestedTypeC)(nil), // 75: productv1.NestedTypeC - (*FilterType)(nil), // 76: productv1.FilterType - (*Pagination)(nil), // 77: productv1.Pagination - (*OrderLineInput)(nil), // 78: productv1.OrderLineInput - (*OrderLine)(nil), // 79: productv1.OrderLine - (*Cat)(nil), // 80: productv1.Cat - (*Dog)(nil), // 81: productv1.Dog - (*ActionSuccess)(nil), // 82: productv1.ActionSuccess - (*ActionError)(nil), // 83: productv1.ActionError - (*NullableFieldsType)(nil), // 84: productv1.NullableFieldsType - (*NullableFieldsInput)(nil), // 85: productv1.NullableFieldsInput - (*NullableFieldsFilter)(nil), // 86: productv1.NullableFieldsFilter - (*wrapperspb.StringValue)(nil), // 87: google.protobuf.StringValue - (*wrapperspb.Int32Value)(nil), // 88: google.protobuf.Int32Value - (*wrapperspb.FloatValue)(nil), // 89: google.protobuf.FloatValue - (*wrapperspb.BoolValue)(nil), // 90: google.protobuf.BoolValue + (*ListOfBlogPost)(nil), // 1: productv1.ListOfBlogPost + (*ListOfBoolean)(nil), // 2: productv1.ListOfBoolean + (*ListOfCategory)(nil), // 3: productv1.ListOfCategory + (*ListOfCategoryInput)(nil), // 4: productv1.ListOfCategoryInput + (*ListOfFloat)(nil), // 5: productv1.ListOfFloat + (*ListOfListOfCategory)(nil), // 6: productv1.ListOfListOfCategory + (*ListOfListOfCategoryInput)(nil), // 7: productv1.ListOfListOfCategoryInput + (*ListOfListOfString)(nil), // 8: productv1.ListOfListOfString + (*ListOfListOfUser)(nil), // 9: productv1.ListOfListOfUser + (*ListOfListOfUserInput)(nil), // 10: productv1.ListOfListOfUserInput + (*ListOfOrderLine)(nil), // 11: productv1.ListOfOrderLine + (*ListOfProduct)(nil), // 12: productv1.ListOfProduct + (*ListOfString)(nil), // 13: productv1.ListOfString + (*ListOfUser)(nil), // 14: productv1.ListOfUser + (*ListOfUserInput)(nil), // 15: productv1.ListOfUserInput + (*LookupProductByIdRequestKey)(nil), // 16: productv1.LookupProductByIdRequestKey + (*LookupProductByIdRequest)(nil), // 17: productv1.LookupProductByIdRequest + (*LookupProductByIdResponse)(nil), // 18: productv1.LookupProductByIdResponse + (*LookupStorageByIdRequestKey)(nil), // 19: productv1.LookupStorageByIdRequestKey + (*LookupStorageByIdRequest)(nil), // 20: productv1.LookupStorageByIdRequest + (*LookupStorageByIdResponse)(nil), // 21: productv1.LookupStorageByIdResponse + (*QueryUsersRequest)(nil), // 22: productv1.QueryUsersRequest + (*QueryUsersResponse)(nil), // 23: productv1.QueryUsersResponse + (*QueryUserRequest)(nil), // 24: productv1.QueryUserRequest + (*QueryUserResponse)(nil), // 25: productv1.QueryUserResponse + (*QueryNestedTypeRequest)(nil), // 26: productv1.QueryNestedTypeRequest + (*QueryNestedTypeResponse)(nil), // 27: productv1.QueryNestedTypeResponse + (*QueryRecursiveTypeRequest)(nil), // 28: productv1.QueryRecursiveTypeRequest + (*QueryRecursiveTypeResponse)(nil), // 29: productv1.QueryRecursiveTypeResponse + (*QueryTypeFilterWithArgumentsRequest)(nil), // 30: productv1.QueryTypeFilterWithArgumentsRequest + (*QueryTypeFilterWithArgumentsResponse)(nil), // 31: productv1.QueryTypeFilterWithArgumentsResponse + (*QueryTypeWithMultipleFilterFieldsRequest)(nil), // 32: productv1.QueryTypeWithMultipleFilterFieldsRequest + (*QueryTypeWithMultipleFilterFieldsResponse)(nil), // 33: productv1.QueryTypeWithMultipleFilterFieldsResponse + (*QueryComplexFilterTypeRequest)(nil), // 34: productv1.QueryComplexFilterTypeRequest + (*QueryComplexFilterTypeResponse)(nil), // 35: productv1.QueryComplexFilterTypeResponse + (*QueryCalculateTotalsRequest)(nil), // 36: productv1.QueryCalculateTotalsRequest + (*QueryCalculateTotalsResponse)(nil), // 37: productv1.QueryCalculateTotalsResponse + (*QueryCategoriesRequest)(nil), // 38: productv1.QueryCategoriesRequest + (*QueryCategoriesResponse)(nil), // 39: productv1.QueryCategoriesResponse + (*QueryCategoriesByKindRequest)(nil), // 40: productv1.QueryCategoriesByKindRequest + (*QueryCategoriesByKindResponse)(nil), // 41: productv1.QueryCategoriesByKindResponse + (*QueryCategoriesByKindsRequest)(nil), // 42: productv1.QueryCategoriesByKindsRequest + (*QueryCategoriesByKindsResponse)(nil), // 43: productv1.QueryCategoriesByKindsResponse + (*QueryFilterCategoriesRequest)(nil), // 44: productv1.QueryFilterCategoriesRequest + (*QueryFilterCategoriesResponse)(nil), // 45: productv1.QueryFilterCategoriesResponse + (*QueryRandomPetRequest)(nil), // 46: productv1.QueryRandomPetRequest + (*QueryRandomPetResponse)(nil), // 47: productv1.QueryRandomPetResponse + (*QueryAllPetsRequest)(nil), // 48: productv1.QueryAllPetsRequest + (*QueryAllPetsResponse)(nil), // 49: productv1.QueryAllPetsResponse + (*QuerySearchRequest)(nil), // 50: productv1.QuerySearchRequest + (*QuerySearchResponse)(nil), // 51: productv1.QuerySearchResponse + (*QueryRandomSearchResultRequest)(nil), // 52: productv1.QueryRandomSearchResultRequest + (*QueryRandomSearchResultResponse)(nil), // 53: productv1.QueryRandomSearchResultResponse + (*QueryNullableFieldsTypeRequest)(nil), // 54: productv1.QueryNullableFieldsTypeRequest + (*QueryNullableFieldsTypeResponse)(nil), // 55: productv1.QueryNullableFieldsTypeResponse + (*QueryNullableFieldsTypeByIdRequest)(nil), // 56: productv1.QueryNullableFieldsTypeByIdRequest + (*QueryNullableFieldsTypeByIdResponse)(nil), // 57: productv1.QueryNullableFieldsTypeByIdResponse + (*QueryNullableFieldsTypeWithFilterRequest)(nil), // 58: productv1.QueryNullableFieldsTypeWithFilterRequest + (*QueryNullableFieldsTypeWithFilterResponse)(nil), // 59: productv1.QueryNullableFieldsTypeWithFilterResponse + (*QueryAllNullableFieldsTypesRequest)(nil), // 60: productv1.QueryAllNullableFieldsTypesRequest + (*QueryAllNullableFieldsTypesResponse)(nil), // 61: productv1.QueryAllNullableFieldsTypesResponse + (*QueryBlogPostRequest)(nil), // 62: productv1.QueryBlogPostRequest + (*QueryBlogPostResponse)(nil), // 63: productv1.QueryBlogPostResponse + (*QueryBlogPostByIdRequest)(nil), // 64: productv1.QueryBlogPostByIdRequest + (*QueryBlogPostByIdResponse)(nil), // 65: productv1.QueryBlogPostByIdResponse + (*QueryBlogPostsWithFilterRequest)(nil), // 66: productv1.QueryBlogPostsWithFilterRequest + (*QueryBlogPostsWithFilterResponse)(nil), // 67: productv1.QueryBlogPostsWithFilterResponse + (*QueryAllBlogPostsRequest)(nil), // 68: productv1.QueryAllBlogPostsRequest + (*QueryAllBlogPostsResponse)(nil), // 69: productv1.QueryAllBlogPostsResponse + (*QueryAuthorRequest)(nil), // 70: productv1.QueryAuthorRequest + (*QueryAuthorResponse)(nil), // 71: productv1.QueryAuthorResponse + (*QueryAuthorByIdRequest)(nil), // 72: productv1.QueryAuthorByIdRequest + (*QueryAuthorByIdResponse)(nil), // 73: productv1.QueryAuthorByIdResponse + (*QueryAuthorsWithFilterRequest)(nil), // 74: productv1.QueryAuthorsWithFilterRequest + (*QueryAuthorsWithFilterResponse)(nil), // 75: productv1.QueryAuthorsWithFilterResponse + (*QueryAllAuthorsRequest)(nil), // 76: productv1.QueryAllAuthorsRequest + (*QueryAllAuthorsResponse)(nil), // 77: productv1.QueryAllAuthorsResponse + (*MutationCreateUserRequest)(nil), // 78: productv1.MutationCreateUserRequest + (*MutationCreateUserResponse)(nil), // 79: productv1.MutationCreateUserResponse + (*MutationPerformActionRequest)(nil), // 80: productv1.MutationPerformActionRequest + (*MutationPerformActionResponse)(nil), // 81: productv1.MutationPerformActionResponse + (*MutationCreateNullableFieldsTypeRequest)(nil), // 82: productv1.MutationCreateNullableFieldsTypeRequest + (*MutationCreateNullableFieldsTypeResponse)(nil), // 83: productv1.MutationCreateNullableFieldsTypeResponse + (*MutationUpdateNullableFieldsTypeRequest)(nil), // 84: productv1.MutationUpdateNullableFieldsTypeRequest + (*MutationUpdateNullableFieldsTypeResponse)(nil), // 85: productv1.MutationUpdateNullableFieldsTypeResponse + (*MutationCreateBlogPostRequest)(nil), // 86: productv1.MutationCreateBlogPostRequest + (*MutationCreateBlogPostResponse)(nil), // 87: productv1.MutationCreateBlogPostResponse + (*MutationUpdateBlogPostRequest)(nil), // 88: productv1.MutationUpdateBlogPostRequest + (*MutationUpdateBlogPostResponse)(nil), // 89: productv1.MutationUpdateBlogPostResponse + (*MutationCreateAuthorRequest)(nil), // 90: productv1.MutationCreateAuthorRequest + (*MutationCreateAuthorResponse)(nil), // 91: productv1.MutationCreateAuthorResponse + (*MutationUpdateAuthorRequest)(nil), // 92: productv1.MutationUpdateAuthorRequest + (*MutationUpdateAuthorResponse)(nil), // 93: productv1.MutationUpdateAuthorResponse + (*Product)(nil), // 94: productv1.Product + (*Storage)(nil), // 95: productv1.Storage + (*User)(nil), // 96: productv1.User + (*NestedTypeA)(nil), // 97: productv1.NestedTypeA + (*RecursiveType)(nil), // 98: productv1.RecursiveType + (*TypeWithMultipleFilterFields)(nil), // 99: productv1.TypeWithMultipleFilterFields + (*FilterTypeInput)(nil), // 100: productv1.FilterTypeInput + (*ComplexFilterTypeInput)(nil), // 101: productv1.ComplexFilterTypeInput + (*TypeWithComplexFilterInput)(nil), // 102: productv1.TypeWithComplexFilterInput + (*OrderInput)(nil), // 103: productv1.OrderInput + (*Order)(nil), // 104: productv1.Order + (*Category)(nil), // 105: productv1.Category + (*CategoryFilter)(nil), // 106: productv1.CategoryFilter + (*Animal)(nil), // 107: productv1.Animal + (*SearchInput)(nil), // 108: productv1.SearchInput + (*SearchResult)(nil), // 109: productv1.SearchResult + (*NullableFieldsType)(nil), // 110: productv1.NullableFieldsType + (*NullableFieldsFilter)(nil), // 111: productv1.NullableFieldsFilter + (*BlogPost)(nil), // 112: productv1.BlogPost + (*BlogPostFilter)(nil), // 113: productv1.BlogPostFilter + (*Author)(nil), // 114: productv1.Author + (*AuthorFilter)(nil), // 115: productv1.AuthorFilter + (*UserInput)(nil), // 116: productv1.UserInput + (*ActionInput)(nil), // 117: productv1.ActionInput + (*ActionResult)(nil), // 118: productv1.ActionResult + (*NullableFieldsInput)(nil), // 119: productv1.NullableFieldsInput + (*BlogPostInput)(nil), // 120: productv1.BlogPostInput + (*AuthorInput)(nil), // 121: productv1.AuthorInput + (*NestedTypeB)(nil), // 122: productv1.NestedTypeB + (*NestedTypeC)(nil), // 123: productv1.NestedTypeC + (*FilterType)(nil), // 124: productv1.FilterType + (*Pagination)(nil), // 125: productv1.Pagination + (*OrderLineInput)(nil), // 126: productv1.OrderLineInput + (*OrderLine)(nil), // 127: productv1.OrderLine + (*Cat)(nil), // 128: productv1.Cat + (*Dog)(nil), // 129: productv1.Dog + (*ActionSuccess)(nil), // 130: productv1.ActionSuccess + (*ActionError)(nil), // 131: productv1.ActionError + (*CategoryInput)(nil), // 132: productv1.CategoryInput + (*ListOfBlogPost_List)(nil), // 133: productv1.ListOfBlogPost.List + (*ListOfBoolean_List)(nil), // 134: productv1.ListOfBoolean.List + (*ListOfCategory_List)(nil), // 135: productv1.ListOfCategory.List + (*ListOfCategoryInput_List)(nil), // 136: productv1.ListOfCategoryInput.List + (*ListOfFloat_List)(nil), // 137: productv1.ListOfFloat.List + (*ListOfListOfCategory_List)(nil), // 138: productv1.ListOfListOfCategory.List + (*ListOfListOfCategoryInput_List)(nil), // 139: productv1.ListOfListOfCategoryInput.List + (*ListOfListOfString_List)(nil), // 140: productv1.ListOfListOfString.List + (*ListOfListOfUser_List)(nil), // 141: productv1.ListOfListOfUser.List + (*ListOfListOfUserInput_List)(nil), // 142: productv1.ListOfListOfUserInput.List + (*ListOfOrderLine_List)(nil), // 143: productv1.ListOfOrderLine.List + (*ListOfProduct_List)(nil), // 144: productv1.ListOfProduct.List + (*ListOfString_List)(nil), // 145: productv1.ListOfString.List + (*ListOfUser_List)(nil), // 146: productv1.ListOfUser.List + (*ListOfUserInput_List)(nil), // 147: productv1.ListOfUserInput.List + (*wrapperspb.Int32Value)(nil), // 148: google.protobuf.Int32Value + (*wrapperspb.StringValue)(nil), // 149: google.protobuf.StringValue + (*wrapperspb.DoubleValue)(nil), // 150: google.protobuf.DoubleValue + (*wrapperspb.BoolValue)(nil), // 151: google.protobuf.BoolValue } var file_product_proto_depIdxs = []int32{ - 1, // 0: productv1.LookupProductByIdRequest.keys:type_name -> productv1.LookupProductByIdRequestKey - 55, // 1: productv1.LookupProductByIdResponse.result:type_name -> productv1.Product - 4, // 2: productv1.LookupStorageByIdRequest.keys:type_name -> productv1.LookupStorageByIdRequestKey - 56, // 3: productv1.LookupStorageByIdResponse.result:type_name -> productv1.Storage - 57, // 4: productv1.QueryUsersResponse.users:type_name -> productv1.User - 57, // 5: productv1.QueryUserResponse.user:type_name -> productv1.User - 58, // 6: productv1.QueryNestedTypeResponse.nested_type:type_name -> productv1.NestedTypeA - 59, // 7: productv1.QueryRecursiveTypeResponse.recursive_type:type_name -> productv1.RecursiveType - 60, // 8: productv1.QueryTypeFilterWithArgumentsResponse.type_filter_with_arguments:type_name -> productv1.TypeWithMultipleFilterFields - 61, // 9: productv1.QueryTypeWithMultipleFilterFieldsRequest.filter:type_name -> productv1.FilterTypeInput - 60, // 10: productv1.QueryTypeWithMultipleFilterFieldsResponse.type_with_multiple_filter_fields:type_name -> productv1.TypeWithMultipleFilterFields - 62, // 11: productv1.QueryComplexFilterTypeRequest.filter:type_name -> productv1.ComplexFilterTypeInput - 63, // 12: productv1.QueryComplexFilterTypeResponse.complex_filter_type:type_name -> productv1.TypeWithComplexFilterInput - 64, // 13: productv1.QueryCalculateTotalsRequest.orders:type_name -> productv1.OrderInput - 65, // 14: productv1.QueryCalculateTotalsResponse.calculate_totals:type_name -> productv1.Order - 66, // 15: productv1.QueryCategoriesResponse.categories:type_name -> productv1.Category - 0, // 16: productv1.QueryCategoriesByKindRequest.kind:type_name -> productv1.CategoryKind - 66, // 17: productv1.QueryCategoriesByKindResponse.categories_by_kind:type_name -> productv1.Category - 0, // 18: productv1.QueryCategoriesByKindsRequest.kinds:type_name -> productv1.CategoryKind - 66, // 19: productv1.QueryCategoriesByKindsResponse.categories_by_kinds:type_name -> productv1.Category - 67, // 20: productv1.QueryFilterCategoriesRequest.filter:type_name -> productv1.CategoryFilter - 66, // 21: productv1.QueryFilterCategoriesResponse.filter_categories:type_name -> productv1.Category - 68, // 22: productv1.QueryRandomPetResponse.random_pet:type_name -> productv1.Animal - 68, // 23: productv1.QueryAllPetsResponse.all_pets:type_name -> productv1.Animal - 69, // 24: productv1.QuerySearchRequest.input:type_name -> productv1.SearchInput - 70, // 25: productv1.QuerySearchResponse.search:type_name -> productv1.SearchResult - 70, // 26: productv1.QueryRandomSearchResultResponse.random_search_result:type_name -> productv1.SearchResult - 71, // 27: productv1.MutationCreateUserRequest.input:type_name -> productv1.UserInput - 57, // 28: productv1.MutationCreateUserResponse.create_user:type_name -> productv1.User - 72, // 29: productv1.MutationPerformActionRequest.input:type_name -> productv1.ActionInput - 73, // 30: productv1.MutationPerformActionResponse.perform_action:type_name -> productv1.ActionResult - 84, // 31: productv1.QueryNullableFieldsTypeResponse.nullable_fields_type:type_name -> productv1.NullableFieldsType - 84, // 32: productv1.QueryNullableFieldsTypeByIdResponse.nullable_fields_type_by_id:type_name -> productv1.NullableFieldsType - 86, // 33: productv1.QueryNullableFieldsTypeWithFilterRequest.filter:type_name -> productv1.NullableFieldsFilter - 84, // 34: productv1.QueryNullableFieldsTypeWithFilterResponse.nullable_fields_type_with_filter:type_name -> productv1.NullableFieldsType - 84, // 35: productv1.QueryAllNullableFieldsTypesResponse.all_nullable_fields_types:type_name -> productv1.NullableFieldsType - 85, // 36: productv1.MutationCreateNullableFieldsTypeRequest.input:type_name -> productv1.NullableFieldsInput - 84, // 37: productv1.MutationCreateNullableFieldsTypeResponse.create_nullable_fields_type:type_name -> productv1.NullableFieldsType - 85, // 38: productv1.MutationUpdateNullableFieldsTypeRequest.input:type_name -> productv1.NullableFieldsInput - 84, // 39: productv1.MutationUpdateNullableFieldsTypeResponse.update_nullable_fields_type:type_name -> productv1.NullableFieldsType - 74, // 40: productv1.NestedTypeA.b:type_name -> productv1.NestedTypeB - 59, // 41: productv1.RecursiveType.recursive_type:type_name -> productv1.RecursiveType - 76, // 42: productv1.ComplexFilterTypeInput.filter:type_name -> productv1.FilterType - 78, // 43: productv1.OrderInput.lines:type_name -> productv1.OrderLineInput - 79, // 44: productv1.Order.order_lines:type_name -> productv1.OrderLine - 0, // 45: productv1.Category.kind:type_name -> productv1.CategoryKind - 0, // 46: productv1.CategoryFilter.category:type_name -> productv1.CategoryKind - 77, // 47: productv1.CategoryFilter.pagination:type_name -> productv1.Pagination - 80, // 48: productv1.Animal.cat:type_name -> productv1.Cat - 81, // 49: productv1.Animal.dog:type_name -> productv1.Dog - 55, // 50: productv1.SearchResult.product:type_name -> productv1.Product - 57, // 51: productv1.SearchResult.user:type_name -> productv1.User - 66, // 52: productv1.SearchResult.category:type_name -> productv1.Category - 82, // 53: productv1.ActionResult.action_success:type_name -> productv1.ActionSuccess - 83, // 54: productv1.ActionResult.action_error:type_name -> productv1.ActionError - 75, // 55: productv1.NestedTypeB.c:type_name -> productv1.NestedTypeC - 77, // 56: productv1.FilterType.pagination:type_name -> productv1.Pagination - 87, // 57: productv1.NullableFieldsType.optional_string:type_name -> google.protobuf.StringValue - 88, // 58: productv1.NullableFieldsType.optional_int:type_name -> google.protobuf.Int32Value - 89, // 59: productv1.NullableFieldsType.optional_float:type_name -> google.protobuf.FloatValue - 90, // 60: productv1.NullableFieldsType.optional_boolean:type_name -> google.protobuf.BoolValue - 87, // 61: productv1.NullableFieldsInput.optional_string:type_name -> google.protobuf.StringValue - 88, // 62: productv1.NullableFieldsInput.optional_int:type_name -> google.protobuf.Int32Value - 89, // 63: productv1.NullableFieldsInput.optional_float:type_name -> google.protobuf.FloatValue - 90, // 64: productv1.NullableFieldsInput.optional_boolean:type_name -> google.protobuf.BoolValue - 87, // 65: productv1.NullableFieldsFilter.name:type_name -> google.protobuf.StringValue - 87, // 66: productv1.NullableFieldsFilter.optional_string:type_name -> google.protobuf.StringValue - 90, // 67: productv1.NullableFieldsFilter.include_nulls:type_name -> google.protobuf.BoolValue - 2, // 68: productv1.ProductService.LookupProductById:input_type -> productv1.LookupProductByIdRequest - 5, // 69: productv1.ProductService.LookupStorageById:input_type -> productv1.LookupStorageByIdRequest - 39, // 70: productv1.ProductService.MutationCreateUser:input_type -> productv1.MutationCreateUserRequest - 41, // 71: productv1.ProductService.MutationPerformAction:input_type -> productv1.MutationPerformActionRequest - 33, // 72: productv1.ProductService.QueryAllPets:input_type -> productv1.QueryAllPetsRequest - 21, // 73: productv1.ProductService.QueryCalculateTotals:input_type -> productv1.QueryCalculateTotalsRequest - 23, // 74: productv1.ProductService.QueryCategories:input_type -> productv1.QueryCategoriesRequest - 25, // 75: productv1.ProductService.QueryCategoriesByKind:input_type -> productv1.QueryCategoriesByKindRequest - 27, // 76: productv1.ProductService.QueryCategoriesByKinds:input_type -> productv1.QueryCategoriesByKindsRequest - 19, // 77: productv1.ProductService.QueryComplexFilterType:input_type -> productv1.QueryComplexFilterTypeRequest - 29, // 78: productv1.ProductService.QueryFilterCategories:input_type -> productv1.QueryFilterCategoriesRequest - 11, // 79: productv1.ProductService.QueryNestedType:input_type -> productv1.QueryNestedTypeRequest - 31, // 80: productv1.ProductService.QueryRandomPet:input_type -> productv1.QueryRandomPetRequest - 37, // 81: productv1.ProductService.QueryRandomSearchResult:input_type -> productv1.QueryRandomSearchResultRequest - 13, // 82: productv1.ProductService.QueryRecursiveType:input_type -> productv1.QueryRecursiveTypeRequest - 35, // 83: productv1.ProductService.QuerySearch:input_type -> productv1.QuerySearchRequest - 15, // 84: productv1.ProductService.QueryTypeFilterWithArguments:input_type -> productv1.QueryTypeFilterWithArgumentsRequest - 17, // 85: productv1.ProductService.QueryTypeWithMultipleFilterFields:input_type -> productv1.QueryTypeWithMultipleFilterFieldsRequest - 9, // 86: productv1.ProductService.QueryUser:input_type -> productv1.QueryUserRequest - 7, // 87: productv1.ProductService.QueryUsers:input_type -> productv1.QueryUsersRequest - 43, // 88: productv1.ProductService.QueryNullableFieldsType:input_type -> productv1.QueryNullableFieldsTypeRequest - 45, // 89: productv1.ProductService.QueryNullableFieldsTypeById:input_type -> productv1.QueryNullableFieldsTypeByIdRequest - 47, // 90: productv1.ProductService.QueryNullableFieldsTypeWithFilter:input_type -> productv1.QueryNullableFieldsTypeWithFilterRequest - 49, // 91: productv1.ProductService.QueryAllNullableFieldsTypes:input_type -> productv1.QueryAllNullableFieldsTypesRequest - 51, // 92: productv1.ProductService.MutationCreateNullableFieldsType:input_type -> productv1.MutationCreateNullableFieldsTypeRequest - 53, // 93: productv1.ProductService.MutationUpdateNullableFieldsType:input_type -> productv1.MutationUpdateNullableFieldsTypeRequest - 3, // 94: productv1.ProductService.LookupProductById:output_type -> productv1.LookupProductByIdResponse - 6, // 95: productv1.ProductService.LookupStorageById:output_type -> productv1.LookupStorageByIdResponse - 40, // 96: productv1.ProductService.MutationCreateUser:output_type -> productv1.MutationCreateUserResponse - 42, // 97: productv1.ProductService.MutationPerformAction:output_type -> productv1.MutationPerformActionResponse - 34, // 98: productv1.ProductService.QueryAllPets:output_type -> productv1.QueryAllPetsResponse - 22, // 99: productv1.ProductService.QueryCalculateTotals:output_type -> productv1.QueryCalculateTotalsResponse - 24, // 100: productv1.ProductService.QueryCategories:output_type -> productv1.QueryCategoriesResponse - 26, // 101: productv1.ProductService.QueryCategoriesByKind:output_type -> productv1.QueryCategoriesByKindResponse - 28, // 102: productv1.ProductService.QueryCategoriesByKinds:output_type -> productv1.QueryCategoriesByKindsResponse - 20, // 103: productv1.ProductService.QueryComplexFilterType:output_type -> productv1.QueryComplexFilterTypeResponse - 30, // 104: productv1.ProductService.QueryFilterCategories:output_type -> productv1.QueryFilterCategoriesResponse - 12, // 105: productv1.ProductService.QueryNestedType:output_type -> productv1.QueryNestedTypeResponse - 32, // 106: productv1.ProductService.QueryRandomPet:output_type -> productv1.QueryRandomPetResponse - 38, // 107: productv1.ProductService.QueryRandomSearchResult:output_type -> productv1.QueryRandomSearchResultResponse - 14, // 108: productv1.ProductService.QueryRecursiveType:output_type -> productv1.QueryRecursiveTypeResponse - 36, // 109: productv1.ProductService.QuerySearch:output_type -> productv1.QuerySearchResponse - 16, // 110: productv1.ProductService.QueryTypeFilterWithArguments:output_type -> productv1.QueryTypeFilterWithArgumentsResponse - 18, // 111: productv1.ProductService.QueryTypeWithMultipleFilterFields:output_type -> productv1.QueryTypeWithMultipleFilterFieldsResponse - 10, // 112: productv1.ProductService.QueryUser:output_type -> productv1.QueryUserResponse - 8, // 113: productv1.ProductService.QueryUsers:output_type -> productv1.QueryUsersResponse - 44, // 114: productv1.ProductService.QueryNullableFieldsType:output_type -> productv1.QueryNullableFieldsTypeResponse - 46, // 115: productv1.ProductService.QueryNullableFieldsTypeById:output_type -> productv1.QueryNullableFieldsTypeByIdResponse - 48, // 116: productv1.ProductService.QueryNullableFieldsTypeWithFilter:output_type -> productv1.QueryNullableFieldsTypeWithFilterResponse - 50, // 117: productv1.ProductService.QueryAllNullableFieldsTypes:output_type -> productv1.QueryAllNullableFieldsTypesResponse - 52, // 118: productv1.ProductService.MutationCreateNullableFieldsType:output_type -> productv1.MutationCreateNullableFieldsTypeResponse - 54, // 119: productv1.ProductService.MutationUpdateNullableFieldsType:output_type -> productv1.MutationUpdateNullableFieldsTypeResponse - 94, // [94:120] is the sub-list for method output_type - 68, // [68:94] is the sub-list for method input_type - 68, // [68:68] is the sub-list for extension type_name - 68, // [68:68] is the sub-list for extension extendee - 0, // [0:68] is the sub-list for field type_name + 133, // 0: productv1.ListOfBlogPost.list:type_name -> productv1.ListOfBlogPost.List + 134, // 1: productv1.ListOfBoolean.list:type_name -> productv1.ListOfBoolean.List + 135, // 2: productv1.ListOfCategory.list:type_name -> productv1.ListOfCategory.List + 136, // 3: productv1.ListOfCategoryInput.list:type_name -> productv1.ListOfCategoryInput.List + 137, // 4: productv1.ListOfFloat.list:type_name -> productv1.ListOfFloat.List + 138, // 5: productv1.ListOfListOfCategory.list:type_name -> productv1.ListOfListOfCategory.List + 139, // 6: productv1.ListOfListOfCategoryInput.list:type_name -> productv1.ListOfListOfCategoryInput.List + 140, // 7: productv1.ListOfListOfString.list:type_name -> productv1.ListOfListOfString.List + 141, // 8: productv1.ListOfListOfUser.list:type_name -> productv1.ListOfListOfUser.List + 142, // 9: productv1.ListOfListOfUserInput.list:type_name -> productv1.ListOfListOfUserInput.List + 143, // 10: productv1.ListOfOrderLine.list:type_name -> productv1.ListOfOrderLine.List + 144, // 11: productv1.ListOfProduct.list:type_name -> productv1.ListOfProduct.List + 145, // 12: productv1.ListOfString.list:type_name -> productv1.ListOfString.List + 146, // 13: productv1.ListOfUser.list:type_name -> productv1.ListOfUser.List + 147, // 14: productv1.ListOfUserInput.list:type_name -> productv1.ListOfUserInput.List + 16, // 15: productv1.LookupProductByIdRequest.keys:type_name -> productv1.LookupProductByIdRequestKey + 94, // 16: productv1.LookupProductByIdResponse.result:type_name -> productv1.Product + 19, // 17: productv1.LookupStorageByIdRequest.keys:type_name -> productv1.LookupStorageByIdRequestKey + 95, // 18: productv1.LookupStorageByIdResponse.result:type_name -> productv1.Storage + 96, // 19: productv1.QueryUsersResponse.users:type_name -> productv1.User + 96, // 20: productv1.QueryUserResponse.user:type_name -> productv1.User + 97, // 21: productv1.QueryNestedTypeResponse.nested_type:type_name -> productv1.NestedTypeA + 98, // 22: productv1.QueryRecursiveTypeResponse.recursive_type:type_name -> productv1.RecursiveType + 99, // 23: productv1.QueryTypeFilterWithArgumentsResponse.type_filter_with_arguments:type_name -> productv1.TypeWithMultipleFilterFields + 100, // 24: productv1.QueryTypeWithMultipleFilterFieldsRequest.filter:type_name -> productv1.FilterTypeInput + 99, // 25: productv1.QueryTypeWithMultipleFilterFieldsResponse.type_with_multiple_filter_fields:type_name -> productv1.TypeWithMultipleFilterFields + 101, // 26: productv1.QueryComplexFilterTypeRequest.filter:type_name -> productv1.ComplexFilterTypeInput + 102, // 27: productv1.QueryComplexFilterTypeResponse.complex_filter_type:type_name -> productv1.TypeWithComplexFilterInput + 103, // 28: productv1.QueryCalculateTotalsRequest.orders:type_name -> productv1.OrderInput + 104, // 29: productv1.QueryCalculateTotalsResponse.calculate_totals:type_name -> productv1.Order + 105, // 30: productv1.QueryCategoriesResponse.categories:type_name -> productv1.Category + 0, // 31: productv1.QueryCategoriesByKindRequest.kind:type_name -> productv1.CategoryKind + 105, // 32: productv1.QueryCategoriesByKindResponse.categories_by_kind:type_name -> productv1.Category + 0, // 33: productv1.QueryCategoriesByKindsRequest.kinds:type_name -> productv1.CategoryKind + 105, // 34: productv1.QueryCategoriesByKindsResponse.categories_by_kinds:type_name -> productv1.Category + 106, // 35: productv1.QueryFilterCategoriesRequest.filter:type_name -> productv1.CategoryFilter + 105, // 36: productv1.QueryFilterCategoriesResponse.filter_categories:type_name -> productv1.Category + 107, // 37: productv1.QueryRandomPetResponse.random_pet:type_name -> productv1.Animal + 107, // 38: productv1.QueryAllPetsResponse.all_pets:type_name -> productv1.Animal + 108, // 39: productv1.QuerySearchRequest.input:type_name -> productv1.SearchInput + 109, // 40: productv1.QuerySearchResponse.search:type_name -> productv1.SearchResult + 109, // 41: productv1.QueryRandomSearchResultResponse.random_search_result:type_name -> productv1.SearchResult + 110, // 42: productv1.QueryNullableFieldsTypeResponse.nullable_fields_type:type_name -> productv1.NullableFieldsType + 110, // 43: productv1.QueryNullableFieldsTypeByIdResponse.nullable_fields_type_by_id:type_name -> productv1.NullableFieldsType + 111, // 44: productv1.QueryNullableFieldsTypeWithFilterRequest.filter:type_name -> productv1.NullableFieldsFilter + 110, // 45: productv1.QueryNullableFieldsTypeWithFilterResponse.nullable_fields_type_with_filter:type_name -> productv1.NullableFieldsType + 110, // 46: productv1.QueryAllNullableFieldsTypesResponse.all_nullable_fields_types:type_name -> productv1.NullableFieldsType + 112, // 47: productv1.QueryBlogPostResponse.blog_post:type_name -> productv1.BlogPost + 112, // 48: productv1.QueryBlogPostByIdResponse.blog_post_by_id:type_name -> productv1.BlogPost + 113, // 49: productv1.QueryBlogPostsWithFilterRequest.filter:type_name -> productv1.BlogPostFilter + 112, // 50: productv1.QueryBlogPostsWithFilterResponse.blog_posts_with_filter:type_name -> productv1.BlogPost + 112, // 51: productv1.QueryAllBlogPostsResponse.all_blog_posts:type_name -> productv1.BlogPost + 114, // 52: productv1.QueryAuthorResponse.author:type_name -> productv1.Author + 114, // 53: productv1.QueryAuthorByIdResponse.author_by_id:type_name -> productv1.Author + 115, // 54: productv1.QueryAuthorsWithFilterRequest.filter:type_name -> productv1.AuthorFilter + 114, // 55: productv1.QueryAuthorsWithFilterResponse.authors_with_filter:type_name -> productv1.Author + 114, // 56: productv1.QueryAllAuthorsResponse.all_authors:type_name -> productv1.Author + 116, // 57: productv1.MutationCreateUserRequest.input:type_name -> productv1.UserInput + 96, // 58: productv1.MutationCreateUserResponse.create_user:type_name -> productv1.User + 117, // 59: productv1.MutationPerformActionRequest.input:type_name -> productv1.ActionInput + 118, // 60: productv1.MutationPerformActionResponse.perform_action:type_name -> productv1.ActionResult + 119, // 61: productv1.MutationCreateNullableFieldsTypeRequest.input:type_name -> productv1.NullableFieldsInput + 110, // 62: productv1.MutationCreateNullableFieldsTypeResponse.create_nullable_fields_type:type_name -> productv1.NullableFieldsType + 119, // 63: productv1.MutationUpdateNullableFieldsTypeRequest.input:type_name -> productv1.NullableFieldsInput + 110, // 64: productv1.MutationUpdateNullableFieldsTypeResponse.update_nullable_fields_type:type_name -> productv1.NullableFieldsType + 120, // 65: productv1.MutationCreateBlogPostRequest.input:type_name -> productv1.BlogPostInput + 112, // 66: productv1.MutationCreateBlogPostResponse.create_blog_post:type_name -> productv1.BlogPost + 120, // 67: productv1.MutationUpdateBlogPostRequest.input:type_name -> productv1.BlogPostInput + 112, // 68: productv1.MutationUpdateBlogPostResponse.update_blog_post:type_name -> productv1.BlogPost + 121, // 69: productv1.MutationCreateAuthorRequest.input:type_name -> productv1.AuthorInput + 114, // 70: productv1.MutationCreateAuthorResponse.create_author:type_name -> productv1.Author + 121, // 71: productv1.MutationUpdateAuthorRequest.input:type_name -> productv1.AuthorInput + 114, // 72: productv1.MutationUpdateAuthorResponse.update_author:type_name -> productv1.Author + 122, // 73: productv1.NestedTypeA.b:type_name -> productv1.NestedTypeB + 98, // 74: productv1.RecursiveType.recursive_type:type_name -> productv1.RecursiveType + 124, // 75: productv1.ComplexFilterTypeInput.filter:type_name -> productv1.FilterType + 126, // 76: productv1.OrderInput.lines:type_name -> productv1.OrderLineInput + 11, // 77: productv1.Order.order_lines:type_name -> productv1.ListOfOrderLine + 0, // 78: productv1.Category.kind:type_name -> productv1.CategoryKind + 0, // 79: productv1.CategoryFilter.category:type_name -> productv1.CategoryKind + 125, // 80: productv1.CategoryFilter.pagination:type_name -> productv1.Pagination + 128, // 81: productv1.Animal.cat:type_name -> productv1.Cat + 129, // 82: productv1.Animal.dog:type_name -> productv1.Dog + 148, // 83: productv1.SearchInput.limit:type_name -> google.protobuf.Int32Value + 94, // 84: productv1.SearchResult.product:type_name -> productv1.Product + 96, // 85: productv1.SearchResult.user:type_name -> productv1.User + 105, // 86: productv1.SearchResult.category:type_name -> productv1.Category + 149, // 87: productv1.NullableFieldsType.optional_string:type_name -> google.protobuf.StringValue + 148, // 88: productv1.NullableFieldsType.optional_int:type_name -> google.protobuf.Int32Value + 150, // 89: productv1.NullableFieldsType.optional_float:type_name -> google.protobuf.DoubleValue + 151, // 90: productv1.NullableFieldsType.optional_boolean:type_name -> google.protobuf.BoolValue + 149, // 91: productv1.NullableFieldsFilter.name:type_name -> google.protobuf.StringValue + 149, // 92: productv1.NullableFieldsFilter.optional_string:type_name -> google.protobuf.StringValue + 151, // 93: productv1.NullableFieldsFilter.include_nulls:type_name -> google.protobuf.BoolValue + 13, // 94: productv1.BlogPost.optional_tags:type_name -> productv1.ListOfString + 13, // 95: productv1.BlogPost.keywords:type_name -> productv1.ListOfString + 5, // 96: productv1.BlogPost.ratings:type_name -> productv1.ListOfFloat + 2, // 97: productv1.BlogPost.is_published:type_name -> productv1.ListOfBoolean + 8, // 98: productv1.BlogPost.tag_groups:type_name -> productv1.ListOfListOfString + 8, // 99: productv1.BlogPost.related_topics:type_name -> productv1.ListOfListOfString + 8, // 100: productv1.BlogPost.comment_threads:type_name -> productv1.ListOfListOfString + 8, // 101: productv1.BlogPost.suggestions:type_name -> productv1.ListOfListOfString + 105, // 102: productv1.BlogPost.related_categories:type_name -> productv1.Category + 96, // 103: productv1.BlogPost.contributors:type_name -> productv1.User + 12, // 104: productv1.BlogPost.mentioned_products:type_name -> productv1.ListOfProduct + 14, // 105: productv1.BlogPost.mentioned_users:type_name -> productv1.ListOfUser + 6, // 106: productv1.BlogPost.category_groups:type_name -> productv1.ListOfListOfCategory + 9, // 107: productv1.BlogPost.contributor_teams:type_name -> productv1.ListOfListOfUser + 149, // 108: productv1.BlogPostFilter.title:type_name -> google.protobuf.StringValue + 151, // 109: productv1.BlogPostFilter.has_categories:type_name -> google.protobuf.BoolValue + 148, // 110: productv1.BlogPostFilter.min_tags:type_name -> google.protobuf.Int32Value + 149, // 111: productv1.Author.email:type_name -> google.protobuf.StringValue + 13, // 112: productv1.Author.social_links:type_name -> productv1.ListOfString + 8, // 113: productv1.Author.teams_by_project:type_name -> productv1.ListOfListOfString + 8, // 114: productv1.Author.collaborations:type_name -> productv1.ListOfListOfString + 1, // 115: productv1.Author.written_posts:type_name -> productv1.ListOfBlogPost + 105, // 116: productv1.Author.favorite_categories:type_name -> productv1.Category + 14, // 117: productv1.Author.related_authors:type_name -> productv1.ListOfUser + 12, // 118: productv1.Author.product_reviews:type_name -> productv1.ListOfProduct + 9, // 119: productv1.Author.author_groups:type_name -> productv1.ListOfListOfUser + 6, // 120: productv1.Author.category_preferences:type_name -> productv1.ListOfListOfCategory + 9, // 121: productv1.Author.project_teams:type_name -> productv1.ListOfListOfUser + 149, // 122: productv1.AuthorFilter.name:type_name -> google.protobuf.StringValue + 151, // 123: productv1.AuthorFilter.has_teams:type_name -> google.protobuf.BoolValue + 148, // 124: productv1.AuthorFilter.skill_count:type_name -> google.protobuf.Int32Value + 130, // 125: productv1.ActionResult.action_success:type_name -> productv1.ActionSuccess + 131, // 126: productv1.ActionResult.action_error:type_name -> productv1.ActionError + 149, // 127: productv1.NullableFieldsInput.optional_string:type_name -> google.protobuf.StringValue + 148, // 128: productv1.NullableFieldsInput.optional_int:type_name -> google.protobuf.Int32Value + 150, // 129: productv1.NullableFieldsInput.optional_float:type_name -> google.protobuf.DoubleValue + 151, // 130: productv1.NullableFieldsInput.optional_boolean:type_name -> google.protobuf.BoolValue + 13, // 131: productv1.BlogPostInput.optional_tags:type_name -> productv1.ListOfString + 13, // 132: productv1.BlogPostInput.keywords:type_name -> productv1.ListOfString + 5, // 133: productv1.BlogPostInput.ratings:type_name -> productv1.ListOfFloat + 2, // 134: productv1.BlogPostInput.is_published:type_name -> productv1.ListOfBoolean + 8, // 135: productv1.BlogPostInput.tag_groups:type_name -> productv1.ListOfListOfString + 8, // 136: productv1.BlogPostInput.related_topics:type_name -> productv1.ListOfListOfString + 8, // 137: productv1.BlogPostInput.comment_threads:type_name -> productv1.ListOfListOfString + 8, // 138: productv1.BlogPostInput.suggestions:type_name -> productv1.ListOfListOfString + 4, // 139: productv1.BlogPostInput.related_categories:type_name -> productv1.ListOfCategoryInput + 15, // 140: productv1.BlogPostInput.contributors:type_name -> productv1.ListOfUserInput + 7, // 141: productv1.BlogPostInput.category_groups:type_name -> productv1.ListOfListOfCategoryInput + 149, // 142: productv1.AuthorInput.email:type_name -> google.protobuf.StringValue + 13, // 143: productv1.AuthorInput.social_links:type_name -> productv1.ListOfString + 8, // 144: productv1.AuthorInput.teams_by_project:type_name -> productv1.ListOfListOfString + 8, // 145: productv1.AuthorInput.collaborations:type_name -> productv1.ListOfListOfString + 132, // 146: productv1.AuthorInput.favorite_categories:type_name -> productv1.CategoryInput + 10, // 147: productv1.AuthorInput.author_groups:type_name -> productv1.ListOfListOfUserInput + 10, // 148: productv1.AuthorInput.project_teams:type_name -> productv1.ListOfListOfUserInput + 123, // 149: productv1.NestedTypeB.c:type_name -> productv1.NestedTypeC + 125, // 150: productv1.FilterType.pagination:type_name -> productv1.Pagination + 13, // 151: productv1.OrderLineInput.modifiers:type_name -> productv1.ListOfString + 13, // 152: productv1.OrderLine.modifiers:type_name -> productv1.ListOfString + 0, // 153: productv1.CategoryInput.kind:type_name -> productv1.CategoryKind + 112, // 154: productv1.ListOfBlogPost.List.items:type_name -> productv1.BlogPost + 105, // 155: productv1.ListOfCategory.List.items:type_name -> productv1.Category + 132, // 156: productv1.ListOfCategoryInput.List.items:type_name -> productv1.CategoryInput + 3, // 157: productv1.ListOfListOfCategory.List.items:type_name -> productv1.ListOfCategory + 4, // 158: productv1.ListOfListOfCategoryInput.List.items:type_name -> productv1.ListOfCategoryInput + 13, // 159: productv1.ListOfListOfString.List.items:type_name -> productv1.ListOfString + 14, // 160: productv1.ListOfListOfUser.List.items:type_name -> productv1.ListOfUser + 15, // 161: productv1.ListOfListOfUserInput.List.items:type_name -> productv1.ListOfUserInput + 127, // 162: productv1.ListOfOrderLine.List.items:type_name -> productv1.OrderLine + 94, // 163: productv1.ListOfProduct.List.items:type_name -> productv1.Product + 96, // 164: productv1.ListOfUser.List.items:type_name -> productv1.User + 116, // 165: productv1.ListOfUserInput.List.items:type_name -> productv1.UserInput + 17, // 166: productv1.ProductService.LookupProductById:input_type -> productv1.LookupProductByIdRequest + 20, // 167: productv1.ProductService.LookupStorageById:input_type -> productv1.LookupStorageByIdRequest + 90, // 168: productv1.ProductService.MutationCreateAuthor:input_type -> productv1.MutationCreateAuthorRequest + 86, // 169: productv1.ProductService.MutationCreateBlogPost:input_type -> productv1.MutationCreateBlogPostRequest + 82, // 170: productv1.ProductService.MutationCreateNullableFieldsType:input_type -> productv1.MutationCreateNullableFieldsTypeRequest + 78, // 171: productv1.ProductService.MutationCreateUser:input_type -> productv1.MutationCreateUserRequest + 80, // 172: productv1.ProductService.MutationPerformAction:input_type -> productv1.MutationPerformActionRequest + 92, // 173: productv1.ProductService.MutationUpdateAuthor:input_type -> productv1.MutationUpdateAuthorRequest + 88, // 174: productv1.ProductService.MutationUpdateBlogPost:input_type -> productv1.MutationUpdateBlogPostRequest + 84, // 175: productv1.ProductService.MutationUpdateNullableFieldsType:input_type -> productv1.MutationUpdateNullableFieldsTypeRequest + 76, // 176: productv1.ProductService.QueryAllAuthors:input_type -> productv1.QueryAllAuthorsRequest + 68, // 177: productv1.ProductService.QueryAllBlogPosts:input_type -> productv1.QueryAllBlogPostsRequest + 60, // 178: productv1.ProductService.QueryAllNullableFieldsTypes:input_type -> productv1.QueryAllNullableFieldsTypesRequest + 48, // 179: productv1.ProductService.QueryAllPets:input_type -> productv1.QueryAllPetsRequest + 70, // 180: productv1.ProductService.QueryAuthor:input_type -> productv1.QueryAuthorRequest + 72, // 181: productv1.ProductService.QueryAuthorById:input_type -> productv1.QueryAuthorByIdRequest + 74, // 182: productv1.ProductService.QueryAuthorsWithFilter:input_type -> productv1.QueryAuthorsWithFilterRequest + 62, // 183: productv1.ProductService.QueryBlogPost:input_type -> productv1.QueryBlogPostRequest + 64, // 184: productv1.ProductService.QueryBlogPostById:input_type -> productv1.QueryBlogPostByIdRequest + 66, // 185: productv1.ProductService.QueryBlogPostsWithFilter:input_type -> productv1.QueryBlogPostsWithFilterRequest + 36, // 186: productv1.ProductService.QueryCalculateTotals:input_type -> productv1.QueryCalculateTotalsRequest + 38, // 187: productv1.ProductService.QueryCategories:input_type -> productv1.QueryCategoriesRequest + 40, // 188: productv1.ProductService.QueryCategoriesByKind:input_type -> productv1.QueryCategoriesByKindRequest + 42, // 189: productv1.ProductService.QueryCategoriesByKinds:input_type -> productv1.QueryCategoriesByKindsRequest + 34, // 190: productv1.ProductService.QueryComplexFilterType:input_type -> productv1.QueryComplexFilterTypeRequest + 44, // 191: productv1.ProductService.QueryFilterCategories:input_type -> productv1.QueryFilterCategoriesRequest + 26, // 192: productv1.ProductService.QueryNestedType:input_type -> productv1.QueryNestedTypeRequest + 54, // 193: productv1.ProductService.QueryNullableFieldsType:input_type -> productv1.QueryNullableFieldsTypeRequest + 56, // 194: productv1.ProductService.QueryNullableFieldsTypeById:input_type -> productv1.QueryNullableFieldsTypeByIdRequest + 58, // 195: productv1.ProductService.QueryNullableFieldsTypeWithFilter:input_type -> productv1.QueryNullableFieldsTypeWithFilterRequest + 46, // 196: productv1.ProductService.QueryRandomPet:input_type -> productv1.QueryRandomPetRequest + 52, // 197: productv1.ProductService.QueryRandomSearchResult:input_type -> productv1.QueryRandomSearchResultRequest + 28, // 198: productv1.ProductService.QueryRecursiveType:input_type -> productv1.QueryRecursiveTypeRequest + 50, // 199: productv1.ProductService.QuerySearch:input_type -> productv1.QuerySearchRequest + 30, // 200: productv1.ProductService.QueryTypeFilterWithArguments:input_type -> productv1.QueryTypeFilterWithArgumentsRequest + 32, // 201: productv1.ProductService.QueryTypeWithMultipleFilterFields:input_type -> productv1.QueryTypeWithMultipleFilterFieldsRequest + 24, // 202: productv1.ProductService.QueryUser:input_type -> productv1.QueryUserRequest + 22, // 203: productv1.ProductService.QueryUsers:input_type -> productv1.QueryUsersRequest + 18, // 204: productv1.ProductService.LookupProductById:output_type -> productv1.LookupProductByIdResponse + 21, // 205: productv1.ProductService.LookupStorageById:output_type -> productv1.LookupStorageByIdResponse + 91, // 206: productv1.ProductService.MutationCreateAuthor:output_type -> productv1.MutationCreateAuthorResponse + 87, // 207: productv1.ProductService.MutationCreateBlogPost:output_type -> productv1.MutationCreateBlogPostResponse + 83, // 208: productv1.ProductService.MutationCreateNullableFieldsType:output_type -> productv1.MutationCreateNullableFieldsTypeResponse + 79, // 209: productv1.ProductService.MutationCreateUser:output_type -> productv1.MutationCreateUserResponse + 81, // 210: productv1.ProductService.MutationPerformAction:output_type -> productv1.MutationPerformActionResponse + 93, // 211: productv1.ProductService.MutationUpdateAuthor:output_type -> productv1.MutationUpdateAuthorResponse + 89, // 212: productv1.ProductService.MutationUpdateBlogPost:output_type -> productv1.MutationUpdateBlogPostResponse + 85, // 213: productv1.ProductService.MutationUpdateNullableFieldsType:output_type -> productv1.MutationUpdateNullableFieldsTypeResponse + 77, // 214: productv1.ProductService.QueryAllAuthors:output_type -> productv1.QueryAllAuthorsResponse + 69, // 215: productv1.ProductService.QueryAllBlogPosts:output_type -> productv1.QueryAllBlogPostsResponse + 61, // 216: productv1.ProductService.QueryAllNullableFieldsTypes:output_type -> productv1.QueryAllNullableFieldsTypesResponse + 49, // 217: productv1.ProductService.QueryAllPets:output_type -> productv1.QueryAllPetsResponse + 71, // 218: productv1.ProductService.QueryAuthor:output_type -> productv1.QueryAuthorResponse + 73, // 219: productv1.ProductService.QueryAuthorById:output_type -> productv1.QueryAuthorByIdResponse + 75, // 220: productv1.ProductService.QueryAuthorsWithFilter:output_type -> productv1.QueryAuthorsWithFilterResponse + 63, // 221: productv1.ProductService.QueryBlogPost:output_type -> productv1.QueryBlogPostResponse + 65, // 222: productv1.ProductService.QueryBlogPostById:output_type -> productv1.QueryBlogPostByIdResponse + 67, // 223: productv1.ProductService.QueryBlogPostsWithFilter:output_type -> productv1.QueryBlogPostsWithFilterResponse + 37, // 224: productv1.ProductService.QueryCalculateTotals:output_type -> productv1.QueryCalculateTotalsResponse + 39, // 225: productv1.ProductService.QueryCategories:output_type -> productv1.QueryCategoriesResponse + 41, // 226: productv1.ProductService.QueryCategoriesByKind:output_type -> productv1.QueryCategoriesByKindResponse + 43, // 227: productv1.ProductService.QueryCategoriesByKinds:output_type -> productv1.QueryCategoriesByKindsResponse + 35, // 228: productv1.ProductService.QueryComplexFilterType:output_type -> productv1.QueryComplexFilterTypeResponse + 45, // 229: productv1.ProductService.QueryFilterCategories:output_type -> productv1.QueryFilterCategoriesResponse + 27, // 230: productv1.ProductService.QueryNestedType:output_type -> productv1.QueryNestedTypeResponse + 55, // 231: productv1.ProductService.QueryNullableFieldsType:output_type -> productv1.QueryNullableFieldsTypeResponse + 57, // 232: productv1.ProductService.QueryNullableFieldsTypeById:output_type -> productv1.QueryNullableFieldsTypeByIdResponse + 59, // 233: productv1.ProductService.QueryNullableFieldsTypeWithFilter:output_type -> productv1.QueryNullableFieldsTypeWithFilterResponse + 47, // 234: productv1.ProductService.QueryRandomPet:output_type -> productv1.QueryRandomPetResponse + 53, // 235: productv1.ProductService.QueryRandomSearchResult:output_type -> productv1.QueryRandomSearchResultResponse + 29, // 236: productv1.ProductService.QueryRecursiveType:output_type -> productv1.QueryRecursiveTypeResponse + 51, // 237: productv1.ProductService.QuerySearch:output_type -> productv1.QuerySearchResponse + 31, // 238: productv1.ProductService.QueryTypeFilterWithArguments:output_type -> productv1.QueryTypeFilterWithArgumentsResponse + 33, // 239: productv1.ProductService.QueryTypeWithMultipleFilterFields:output_type -> productv1.QueryTypeWithMultipleFilterFieldsResponse + 25, // 240: productv1.ProductService.QueryUser:output_type -> productv1.QueryUserResponse + 23, // 241: productv1.ProductService.QueryUsers:output_type -> productv1.QueryUsersResponse + 204, // [204:242] is the sub-list for method output_type + 166, // [166:204] is the sub-list for method input_type + 166, // [166:166] is the sub-list for extension type_name + 166, // [166:166] is the sub-list for extension extendee + 0, // [0:166] is the sub-list for field type_name } func init() { file_product_proto_init() } @@ -5015,16 +8610,16 @@ func file_product_proto_init() { if File_product_proto != nil { return } - file_product_proto_msgTypes[67].OneofWrappers = []any{ + file_product_proto_msgTypes[106].OneofWrappers = []any{ (*Animal_Cat)(nil), (*Animal_Dog)(nil), } - file_product_proto_msgTypes[69].OneofWrappers = []any{ + file_product_proto_msgTypes[108].OneofWrappers = []any{ (*SearchResult_Product)(nil), (*SearchResult_User)(nil), (*SearchResult_Category)(nil), } - file_product_proto_msgTypes[72].OneofWrappers = []any{ + file_product_proto_msgTypes[117].OneofWrappers = []any{ (*ActionResult_ActionSuccess)(nil), (*ActionResult_ActionError)(nil), } @@ -5034,7 +8629,7 @@ func file_product_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_product_proto_rawDesc), len(file_product_proto_rawDesc)), NumEnums: 1, - NumMessages: 86, + NumMessages: 147, NumExtensions: 0, NumServices: 1, }, diff --git a/v2/pkg/grpctest/productv1/product_grpc.pb.go b/v2/pkg/grpctest/productv1/product_grpc.pb.go index 6ce5c39e95..431976d8f2 100644 --- a/v2/pkg/grpctest/productv1/product_grpc.pb.go +++ b/v2/pkg/grpctest/productv1/product_grpc.pb.go @@ -21,9 +21,24 @@ const _ = grpc.SupportPackageIsVersion9 const ( ProductService_LookupProductById_FullMethodName = "/productv1.ProductService/LookupProductById" ProductService_LookupStorageById_FullMethodName = "/productv1.ProductService/LookupStorageById" + ProductService_MutationCreateAuthor_FullMethodName = "/productv1.ProductService/MutationCreateAuthor" + ProductService_MutationCreateBlogPost_FullMethodName = "/productv1.ProductService/MutationCreateBlogPost" + ProductService_MutationCreateNullableFieldsType_FullMethodName = "/productv1.ProductService/MutationCreateNullableFieldsType" ProductService_MutationCreateUser_FullMethodName = "/productv1.ProductService/MutationCreateUser" ProductService_MutationPerformAction_FullMethodName = "/productv1.ProductService/MutationPerformAction" + ProductService_MutationUpdateAuthor_FullMethodName = "/productv1.ProductService/MutationUpdateAuthor" + ProductService_MutationUpdateBlogPost_FullMethodName = "/productv1.ProductService/MutationUpdateBlogPost" + ProductService_MutationUpdateNullableFieldsType_FullMethodName = "/productv1.ProductService/MutationUpdateNullableFieldsType" + ProductService_QueryAllAuthors_FullMethodName = "/productv1.ProductService/QueryAllAuthors" + ProductService_QueryAllBlogPosts_FullMethodName = "/productv1.ProductService/QueryAllBlogPosts" + ProductService_QueryAllNullableFieldsTypes_FullMethodName = "/productv1.ProductService/QueryAllNullableFieldsTypes" ProductService_QueryAllPets_FullMethodName = "/productv1.ProductService/QueryAllPets" + ProductService_QueryAuthor_FullMethodName = "/productv1.ProductService/QueryAuthor" + ProductService_QueryAuthorById_FullMethodName = "/productv1.ProductService/QueryAuthorById" + ProductService_QueryAuthorsWithFilter_FullMethodName = "/productv1.ProductService/QueryAuthorsWithFilter" + ProductService_QueryBlogPost_FullMethodName = "/productv1.ProductService/QueryBlogPost" + ProductService_QueryBlogPostById_FullMethodName = "/productv1.ProductService/QueryBlogPostById" + ProductService_QueryBlogPostsWithFilter_FullMethodName = "/productv1.ProductService/QueryBlogPostsWithFilter" ProductService_QueryCalculateTotals_FullMethodName = "/productv1.ProductService/QueryCalculateTotals" ProductService_QueryCategories_FullMethodName = "/productv1.ProductService/QueryCategories" ProductService_QueryCategoriesByKind_FullMethodName = "/productv1.ProductService/QueryCategoriesByKind" @@ -31,6 +46,9 @@ const ( ProductService_QueryComplexFilterType_FullMethodName = "/productv1.ProductService/QueryComplexFilterType" ProductService_QueryFilterCategories_FullMethodName = "/productv1.ProductService/QueryFilterCategories" ProductService_QueryNestedType_FullMethodName = "/productv1.ProductService/QueryNestedType" + ProductService_QueryNullableFieldsType_FullMethodName = "/productv1.ProductService/QueryNullableFieldsType" + ProductService_QueryNullableFieldsTypeById_FullMethodName = "/productv1.ProductService/QueryNullableFieldsTypeById" + ProductService_QueryNullableFieldsTypeWithFilter_FullMethodName = "/productv1.ProductService/QueryNullableFieldsTypeWithFilter" ProductService_QueryRandomPet_FullMethodName = "/productv1.ProductService/QueryRandomPet" ProductService_QueryRandomSearchResult_FullMethodName = "/productv1.ProductService/QueryRandomSearchResult" ProductService_QueryRecursiveType_FullMethodName = "/productv1.ProductService/QueryRecursiveType" @@ -39,12 +57,6 @@ const ( ProductService_QueryTypeWithMultipleFilterFields_FullMethodName = "/productv1.ProductService/QueryTypeWithMultipleFilterFields" ProductService_QueryUser_FullMethodName = "/productv1.ProductService/QueryUser" ProductService_QueryUsers_FullMethodName = "/productv1.ProductService/QueryUsers" - ProductService_QueryNullableFieldsType_FullMethodName = "/productv1.ProductService/QueryNullableFieldsType" - ProductService_QueryNullableFieldsTypeById_FullMethodName = "/productv1.ProductService/QueryNullableFieldsTypeById" - ProductService_QueryNullableFieldsTypeWithFilter_FullMethodName = "/productv1.ProductService/QueryNullableFieldsTypeWithFilter" - ProductService_QueryAllNullableFieldsTypes_FullMethodName = "/productv1.ProductService/QueryAllNullableFieldsTypes" - ProductService_MutationCreateNullableFieldsType_FullMethodName = "/productv1.ProductService/MutationCreateNullableFieldsType" - ProductService_MutationUpdateNullableFieldsType_FullMethodName = "/productv1.ProductService/MutationUpdateNullableFieldsType" ) // ProductServiceClient is the client API for ProductService service. @@ -57,9 +69,24 @@ type ProductServiceClient interface { LookupProductById(ctx context.Context, in *LookupProductByIdRequest, opts ...grpc.CallOption) (*LookupProductByIdResponse, error) // Lookup Storage entity by id LookupStorageById(ctx context.Context, in *LookupStorageByIdRequest, opts ...grpc.CallOption) (*LookupStorageByIdResponse, error) + MutationCreateAuthor(ctx context.Context, in *MutationCreateAuthorRequest, opts ...grpc.CallOption) (*MutationCreateAuthorResponse, error) + MutationCreateBlogPost(ctx context.Context, in *MutationCreateBlogPostRequest, opts ...grpc.CallOption) (*MutationCreateBlogPostResponse, error) + MutationCreateNullableFieldsType(ctx context.Context, in *MutationCreateNullableFieldsTypeRequest, opts ...grpc.CallOption) (*MutationCreateNullableFieldsTypeResponse, error) MutationCreateUser(ctx context.Context, in *MutationCreateUserRequest, opts ...grpc.CallOption) (*MutationCreateUserResponse, error) MutationPerformAction(ctx context.Context, in *MutationPerformActionRequest, opts ...grpc.CallOption) (*MutationPerformActionResponse, error) + MutationUpdateAuthor(ctx context.Context, in *MutationUpdateAuthorRequest, opts ...grpc.CallOption) (*MutationUpdateAuthorResponse, error) + MutationUpdateBlogPost(ctx context.Context, in *MutationUpdateBlogPostRequest, opts ...grpc.CallOption) (*MutationUpdateBlogPostResponse, error) + MutationUpdateNullableFieldsType(ctx context.Context, in *MutationUpdateNullableFieldsTypeRequest, opts ...grpc.CallOption) (*MutationUpdateNullableFieldsTypeResponse, error) + QueryAllAuthors(ctx context.Context, in *QueryAllAuthorsRequest, opts ...grpc.CallOption) (*QueryAllAuthorsResponse, error) + QueryAllBlogPosts(ctx context.Context, in *QueryAllBlogPostsRequest, opts ...grpc.CallOption) (*QueryAllBlogPostsResponse, error) + QueryAllNullableFieldsTypes(ctx context.Context, in *QueryAllNullableFieldsTypesRequest, opts ...grpc.CallOption) (*QueryAllNullableFieldsTypesResponse, error) QueryAllPets(ctx context.Context, in *QueryAllPetsRequest, opts ...grpc.CallOption) (*QueryAllPetsResponse, error) + QueryAuthor(ctx context.Context, in *QueryAuthorRequest, opts ...grpc.CallOption) (*QueryAuthorResponse, error) + QueryAuthorById(ctx context.Context, in *QueryAuthorByIdRequest, opts ...grpc.CallOption) (*QueryAuthorByIdResponse, error) + QueryAuthorsWithFilter(ctx context.Context, in *QueryAuthorsWithFilterRequest, opts ...grpc.CallOption) (*QueryAuthorsWithFilterResponse, error) + QueryBlogPost(ctx context.Context, in *QueryBlogPostRequest, opts ...grpc.CallOption) (*QueryBlogPostResponse, error) + QueryBlogPostById(ctx context.Context, in *QueryBlogPostByIdRequest, opts ...grpc.CallOption) (*QueryBlogPostByIdResponse, error) + QueryBlogPostsWithFilter(ctx context.Context, in *QueryBlogPostsWithFilterRequest, opts ...grpc.CallOption) (*QueryBlogPostsWithFilterResponse, error) QueryCalculateTotals(ctx context.Context, in *QueryCalculateTotalsRequest, opts ...grpc.CallOption) (*QueryCalculateTotalsResponse, error) QueryCategories(ctx context.Context, in *QueryCategoriesRequest, opts ...grpc.CallOption) (*QueryCategoriesResponse, error) QueryCategoriesByKind(ctx context.Context, in *QueryCategoriesByKindRequest, opts ...grpc.CallOption) (*QueryCategoriesByKindResponse, error) @@ -67,6 +94,9 @@ type ProductServiceClient interface { QueryComplexFilterType(ctx context.Context, in *QueryComplexFilterTypeRequest, opts ...grpc.CallOption) (*QueryComplexFilterTypeResponse, error) QueryFilterCategories(ctx context.Context, in *QueryFilterCategoriesRequest, opts ...grpc.CallOption) (*QueryFilterCategoriesResponse, error) QueryNestedType(ctx context.Context, in *QueryNestedTypeRequest, opts ...grpc.CallOption) (*QueryNestedTypeResponse, error) + QueryNullableFieldsType(ctx context.Context, in *QueryNullableFieldsTypeRequest, opts ...grpc.CallOption) (*QueryNullableFieldsTypeResponse, error) + QueryNullableFieldsTypeById(ctx context.Context, in *QueryNullableFieldsTypeByIdRequest, opts ...grpc.CallOption) (*QueryNullableFieldsTypeByIdResponse, error) + QueryNullableFieldsTypeWithFilter(ctx context.Context, in *QueryNullableFieldsTypeWithFilterRequest, opts ...grpc.CallOption) (*QueryNullableFieldsTypeWithFilterResponse, error) QueryRandomPet(ctx context.Context, in *QueryRandomPetRequest, opts ...grpc.CallOption) (*QueryRandomPetResponse, error) QueryRandomSearchResult(ctx context.Context, in *QueryRandomSearchResultRequest, opts ...grpc.CallOption) (*QueryRandomSearchResultResponse, error) QueryRecursiveType(ctx context.Context, in *QueryRecursiveTypeRequest, opts ...grpc.CallOption) (*QueryRecursiveTypeResponse, error) @@ -75,13 +105,6 @@ type ProductServiceClient interface { QueryTypeWithMultipleFilterFields(ctx context.Context, in *QueryTypeWithMultipleFilterFieldsRequest, opts ...grpc.CallOption) (*QueryTypeWithMultipleFilterFieldsResponse, error) QueryUser(ctx context.Context, in *QueryUserRequest, opts ...grpc.CallOption) (*QueryUserResponse, error) QueryUsers(ctx context.Context, in *QueryUsersRequest, opts ...grpc.CallOption) (*QueryUsersResponse, error) - // Nullable fields RPCs - QueryNullableFieldsType(ctx context.Context, in *QueryNullableFieldsTypeRequest, opts ...grpc.CallOption) (*QueryNullableFieldsTypeResponse, error) - QueryNullableFieldsTypeById(ctx context.Context, in *QueryNullableFieldsTypeByIdRequest, opts ...grpc.CallOption) (*QueryNullableFieldsTypeByIdResponse, error) - QueryNullableFieldsTypeWithFilter(ctx context.Context, in *QueryNullableFieldsTypeWithFilterRequest, opts ...grpc.CallOption) (*QueryNullableFieldsTypeWithFilterResponse, error) - QueryAllNullableFieldsTypes(ctx context.Context, in *QueryAllNullableFieldsTypesRequest, opts ...grpc.CallOption) (*QueryAllNullableFieldsTypesResponse, error) - MutationCreateNullableFieldsType(ctx context.Context, in *MutationCreateNullableFieldsTypeRequest, opts ...grpc.CallOption) (*MutationCreateNullableFieldsTypeResponse, error) - MutationUpdateNullableFieldsType(ctx context.Context, in *MutationUpdateNullableFieldsTypeRequest, opts ...grpc.CallOption) (*MutationUpdateNullableFieldsTypeResponse, error) } type productServiceClient struct { @@ -112,6 +135,36 @@ func (c *productServiceClient) LookupStorageById(ctx context.Context, in *Lookup return out, nil } +func (c *productServiceClient) MutationCreateAuthor(ctx context.Context, in *MutationCreateAuthorRequest, opts ...grpc.CallOption) (*MutationCreateAuthorResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(MutationCreateAuthorResponse) + err := c.cc.Invoke(ctx, ProductService_MutationCreateAuthor_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) MutationCreateBlogPost(ctx context.Context, in *MutationCreateBlogPostRequest, opts ...grpc.CallOption) (*MutationCreateBlogPostResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(MutationCreateBlogPostResponse) + err := c.cc.Invoke(ctx, ProductService_MutationCreateBlogPost_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) MutationCreateNullableFieldsType(ctx context.Context, in *MutationCreateNullableFieldsTypeRequest, opts ...grpc.CallOption) (*MutationCreateNullableFieldsTypeResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(MutationCreateNullableFieldsTypeResponse) + err := c.cc.Invoke(ctx, ProductService_MutationCreateNullableFieldsType_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *productServiceClient) MutationCreateUser(ctx context.Context, in *MutationCreateUserRequest, opts ...grpc.CallOption) (*MutationCreateUserResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(MutationCreateUserResponse) @@ -132,160 +185,200 @@ func (c *productServiceClient) MutationPerformAction(ctx context.Context, in *Mu return out, nil } -func (c *productServiceClient) QueryAllPets(ctx context.Context, in *QueryAllPetsRequest, opts ...grpc.CallOption) (*QueryAllPetsResponse, error) { +func (c *productServiceClient) MutationUpdateAuthor(ctx context.Context, in *MutationUpdateAuthorRequest, opts ...grpc.CallOption) (*MutationUpdateAuthorResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryAllPetsResponse) - err := c.cc.Invoke(ctx, ProductService_QueryAllPets_FullMethodName, in, out, cOpts...) + out := new(MutationUpdateAuthorResponse) + err := c.cc.Invoke(ctx, ProductService_MutationUpdateAuthor_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) QueryCalculateTotals(ctx context.Context, in *QueryCalculateTotalsRequest, opts ...grpc.CallOption) (*QueryCalculateTotalsResponse, error) { +func (c *productServiceClient) MutationUpdateBlogPost(ctx context.Context, in *MutationUpdateBlogPostRequest, opts ...grpc.CallOption) (*MutationUpdateBlogPostResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryCalculateTotalsResponse) - err := c.cc.Invoke(ctx, ProductService_QueryCalculateTotals_FullMethodName, in, out, cOpts...) + out := new(MutationUpdateBlogPostResponse) + err := c.cc.Invoke(ctx, ProductService_MutationUpdateBlogPost_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) QueryCategories(ctx context.Context, in *QueryCategoriesRequest, opts ...grpc.CallOption) (*QueryCategoriesResponse, error) { +func (c *productServiceClient) MutationUpdateNullableFieldsType(ctx context.Context, in *MutationUpdateNullableFieldsTypeRequest, opts ...grpc.CallOption) (*MutationUpdateNullableFieldsTypeResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryCategoriesResponse) - err := c.cc.Invoke(ctx, ProductService_QueryCategories_FullMethodName, in, out, cOpts...) + out := new(MutationUpdateNullableFieldsTypeResponse) + err := c.cc.Invoke(ctx, ProductService_MutationUpdateNullableFieldsType_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) QueryCategoriesByKind(ctx context.Context, in *QueryCategoriesByKindRequest, opts ...grpc.CallOption) (*QueryCategoriesByKindResponse, error) { +func (c *productServiceClient) QueryAllAuthors(ctx context.Context, in *QueryAllAuthorsRequest, opts ...grpc.CallOption) (*QueryAllAuthorsResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryCategoriesByKindResponse) - err := c.cc.Invoke(ctx, ProductService_QueryCategoriesByKind_FullMethodName, in, out, cOpts...) + out := new(QueryAllAuthorsResponse) + err := c.cc.Invoke(ctx, ProductService_QueryAllAuthors_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) QueryCategoriesByKinds(ctx context.Context, in *QueryCategoriesByKindsRequest, opts ...grpc.CallOption) (*QueryCategoriesByKindsResponse, error) { +func (c *productServiceClient) QueryAllBlogPosts(ctx context.Context, in *QueryAllBlogPostsRequest, opts ...grpc.CallOption) (*QueryAllBlogPostsResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryCategoriesByKindsResponse) - err := c.cc.Invoke(ctx, ProductService_QueryCategoriesByKinds_FullMethodName, in, out, cOpts...) + out := new(QueryAllBlogPostsResponse) + err := c.cc.Invoke(ctx, ProductService_QueryAllBlogPosts_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) QueryComplexFilterType(ctx context.Context, in *QueryComplexFilterTypeRequest, opts ...grpc.CallOption) (*QueryComplexFilterTypeResponse, error) { +func (c *productServiceClient) QueryAllNullableFieldsTypes(ctx context.Context, in *QueryAllNullableFieldsTypesRequest, opts ...grpc.CallOption) (*QueryAllNullableFieldsTypesResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryComplexFilterTypeResponse) - err := c.cc.Invoke(ctx, ProductService_QueryComplexFilterType_FullMethodName, in, out, cOpts...) + out := new(QueryAllNullableFieldsTypesResponse) + err := c.cc.Invoke(ctx, ProductService_QueryAllNullableFieldsTypes_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) QueryFilterCategories(ctx context.Context, in *QueryFilterCategoriesRequest, opts ...grpc.CallOption) (*QueryFilterCategoriesResponse, error) { +func (c *productServiceClient) QueryAllPets(ctx context.Context, in *QueryAllPetsRequest, opts ...grpc.CallOption) (*QueryAllPetsResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryFilterCategoriesResponse) - err := c.cc.Invoke(ctx, ProductService_QueryFilterCategories_FullMethodName, in, out, cOpts...) + out := new(QueryAllPetsResponse) + err := c.cc.Invoke(ctx, ProductService_QueryAllPets_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) QueryNestedType(ctx context.Context, in *QueryNestedTypeRequest, opts ...grpc.CallOption) (*QueryNestedTypeResponse, error) { +func (c *productServiceClient) QueryAuthor(ctx context.Context, in *QueryAuthorRequest, opts ...grpc.CallOption) (*QueryAuthorResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryNestedTypeResponse) - err := c.cc.Invoke(ctx, ProductService_QueryNestedType_FullMethodName, in, out, cOpts...) + out := new(QueryAuthorResponse) + err := c.cc.Invoke(ctx, ProductService_QueryAuthor_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) QueryRandomPet(ctx context.Context, in *QueryRandomPetRequest, opts ...grpc.CallOption) (*QueryRandomPetResponse, error) { +func (c *productServiceClient) QueryAuthorById(ctx context.Context, in *QueryAuthorByIdRequest, opts ...grpc.CallOption) (*QueryAuthorByIdResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryRandomPetResponse) - err := c.cc.Invoke(ctx, ProductService_QueryRandomPet_FullMethodName, in, out, cOpts...) + out := new(QueryAuthorByIdResponse) + err := c.cc.Invoke(ctx, ProductService_QueryAuthorById_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) QueryRandomSearchResult(ctx context.Context, in *QueryRandomSearchResultRequest, opts ...grpc.CallOption) (*QueryRandomSearchResultResponse, error) { +func (c *productServiceClient) QueryAuthorsWithFilter(ctx context.Context, in *QueryAuthorsWithFilterRequest, opts ...grpc.CallOption) (*QueryAuthorsWithFilterResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryRandomSearchResultResponse) - err := c.cc.Invoke(ctx, ProductService_QueryRandomSearchResult_FullMethodName, in, out, cOpts...) + out := new(QueryAuthorsWithFilterResponse) + err := c.cc.Invoke(ctx, ProductService_QueryAuthorsWithFilter_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) QueryRecursiveType(ctx context.Context, in *QueryRecursiveTypeRequest, opts ...grpc.CallOption) (*QueryRecursiveTypeResponse, error) { +func (c *productServiceClient) QueryBlogPost(ctx context.Context, in *QueryBlogPostRequest, opts ...grpc.CallOption) (*QueryBlogPostResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryRecursiveTypeResponse) - err := c.cc.Invoke(ctx, ProductService_QueryRecursiveType_FullMethodName, in, out, cOpts...) + out := new(QueryBlogPostResponse) + err := c.cc.Invoke(ctx, ProductService_QueryBlogPost_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) QuerySearch(ctx context.Context, in *QuerySearchRequest, opts ...grpc.CallOption) (*QuerySearchResponse, error) { +func (c *productServiceClient) QueryBlogPostById(ctx context.Context, in *QueryBlogPostByIdRequest, opts ...grpc.CallOption) (*QueryBlogPostByIdResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QuerySearchResponse) - err := c.cc.Invoke(ctx, ProductService_QuerySearch_FullMethodName, in, out, cOpts...) + out := new(QueryBlogPostByIdResponse) + err := c.cc.Invoke(ctx, ProductService_QueryBlogPostById_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) QueryTypeFilterWithArguments(ctx context.Context, in *QueryTypeFilterWithArgumentsRequest, opts ...grpc.CallOption) (*QueryTypeFilterWithArgumentsResponse, error) { +func (c *productServiceClient) QueryBlogPostsWithFilter(ctx context.Context, in *QueryBlogPostsWithFilterRequest, opts ...grpc.CallOption) (*QueryBlogPostsWithFilterResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryTypeFilterWithArgumentsResponse) - err := c.cc.Invoke(ctx, ProductService_QueryTypeFilterWithArguments_FullMethodName, in, out, cOpts...) + out := new(QueryBlogPostsWithFilterResponse) + err := c.cc.Invoke(ctx, ProductService_QueryBlogPostsWithFilter_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) QueryTypeWithMultipleFilterFields(ctx context.Context, in *QueryTypeWithMultipleFilterFieldsRequest, opts ...grpc.CallOption) (*QueryTypeWithMultipleFilterFieldsResponse, error) { +func (c *productServiceClient) QueryCalculateTotals(ctx context.Context, in *QueryCalculateTotalsRequest, opts ...grpc.CallOption) (*QueryCalculateTotalsResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryTypeWithMultipleFilterFieldsResponse) - err := c.cc.Invoke(ctx, ProductService_QueryTypeWithMultipleFilterFields_FullMethodName, in, out, cOpts...) + out := new(QueryCalculateTotalsResponse) + err := c.cc.Invoke(ctx, ProductService_QueryCalculateTotals_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) QueryUser(ctx context.Context, in *QueryUserRequest, opts ...grpc.CallOption) (*QueryUserResponse, error) { +func (c *productServiceClient) QueryCategories(ctx context.Context, in *QueryCategoriesRequest, opts ...grpc.CallOption) (*QueryCategoriesResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryUserResponse) - err := c.cc.Invoke(ctx, ProductService_QueryUser_FullMethodName, in, out, cOpts...) + out := new(QueryCategoriesResponse) + err := c.cc.Invoke(ctx, ProductService_QueryCategories_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) QueryUsers(ctx context.Context, in *QueryUsersRequest, opts ...grpc.CallOption) (*QueryUsersResponse, error) { +func (c *productServiceClient) QueryCategoriesByKind(ctx context.Context, in *QueryCategoriesByKindRequest, opts ...grpc.CallOption) (*QueryCategoriesByKindResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryUsersResponse) - err := c.cc.Invoke(ctx, ProductService_QueryUsers_FullMethodName, in, out, cOpts...) + out := new(QueryCategoriesByKindResponse) + err := c.cc.Invoke(ctx, ProductService_QueryCategoriesByKind_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) QueryCategoriesByKinds(ctx context.Context, in *QueryCategoriesByKindsRequest, opts ...grpc.CallOption) (*QueryCategoriesByKindsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QueryCategoriesByKindsResponse) + err := c.cc.Invoke(ctx, ProductService_QueryCategoriesByKinds_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) QueryComplexFilterType(ctx context.Context, in *QueryComplexFilterTypeRequest, opts ...grpc.CallOption) (*QueryComplexFilterTypeResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QueryComplexFilterTypeResponse) + err := c.cc.Invoke(ctx, ProductService_QueryComplexFilterType_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) QueryFilterCategories(ctx context.Context, in *QueryFilterCategoriesRequest, opts ...grpc.CallOption) (*QueryFilterCategoriesResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QueryFilterCategoriesResponse) + err := c.cc.Invoke(ctx, ProductService_QueryFilterCategories_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) QueryNestedType(ctx context.Context, in *QueryNestedTypeRequest, opts ...grpc.CallOption) (*QueryNestedTypeResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QueryNestedTypeResponse) + err := c.cc.Invoke(ctx, ProductService_QueryNestedType_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -322,30 +415,80 @@ func (c *productServiceClient) QueryNullableFieldsTypeWithFilter(ctx context.Con return out, nil } -func (c *productServiceClient) QueryAllNullableFieldsTypes(ctx context.Context, in *QueryAllNullableFieldsTypesRequest, opts ...grpc.CallOption) (*QueryAllNullableFieldsTypesResponse, error) { +func (c *productServiceClient) QueryRandomPet(ctx context.Context, in *QueryRandomPetRequest, opts ...grpc.CallOption) (*QueryRandomPetResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryAllNullableFieldsTypesResponse) - err := c.cc.Invoke(ctx, ProductService_QueryAllNullableFieldsTypes_FullMethodName, in, out, cOpts...) + out := new(QueryRandomPetResponse) + err := c.cc.Invoke(ctx, ProductService_QueryRandomPet_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) MutationCreateNullableFieldsType(ctx context.Context, in *MutationCreateNullableFieldsTypeRequest, opts ...grpc.CallOption) (*MutationCreateNullableFieldsTypeResponse, error) { +func (c *productServiceClient) QueryRandomSearchResult(ctx context.Context, in *QueryRandomSearchResultRequest, opts ...grpc.CallOption) (*QueryRandomSearchResultResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(MutationCreateNullableFieldsTypeResponse) - err := c.cc.Invoke(ctx, ProductService_MutationCreateNullableFieldsType_FullMethodName, in, out, cOpts...) + out := new(QueryRandomSearchResultResponse) + err := c.cc.Invoke(ctx, ProductService_QueryRandomSearchResult_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *productServiceClient) MutationUpdateNullableFieldsType(ctx context.Context, in *MutationUpdateNullableFieldsTypeRequest, opts ...grpc.CallOption) (*MutationUpdateNullableFieldsTypeResponse, error) { +func (c *productServiceClient) QueryRecursiveType(ctx context.Context, in *QueryRecursiveTypeRequest, opts ...grpc.CallOption) (*QueryRecursiveTypeResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(MutationUpdateNullableFieldsTypeResponse) - err := c.cc.Invoke(ctx, ProductService_MutationUpdateNullableFieldsType_FullMethodName, in, out, cOpts...) + out := new(QueryRecursiveTypeResponse) + err := c.cc.Invoke(ctx, ProductService_QueryRecursiveType_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) QuerySearch(ctx context.Context, in *QuerySearchRequest, opts ...grpc.CallOption) (*QuerySearchResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QuerySearchResponse) + err := c.cc.Invoke(ctx, ProductService_QuerySearch_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) QueryTypeFilterWithArguments(ctx context.Context, in *QueryTypeFilterWithArgumentsRequest, opts ...grpc.CallOption) (*QueryTypeFilterWithArgumentsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QueryTypeFilterWithArgumentsResponse) + err := c.cc.Invoke(ctx, ProductService_QueryTypeFilterWithArguments_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) QueryTypeWithMultipleFilterFields(ctx context.Context, in *QueryTypeWithMultipleFilterFieldsRequest, opts ...grpc.CallOption) (*QueryTypeWithMultipleFilterFieldsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QueryTypeWithMultipleFilterFieldsResponse) + err := c.cc.Invoke(ctx, ProductService_QueryTypeWithMultipleFilterFields_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) QueryUser(ctx context.Context, in *QueryUserRequest, opts ...grpc.CallOption) (*QueryUserResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QueryUserResponse) + err := c.cc.Invoke(ctx, ProductService_QueryUser_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *productServiceClient) QueryUsers(ctx context.Context, in *QueryUsersRequest, opts ...grpc.CallOption) (*QueryUsersResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(QueryUsersResponse) + err := c.cc.Invoke(ctx, ProductService_QueryUsers_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -362,9 +505,24 @@ type ProductServiceServer interface { LookupProductById(context.Context, *LookupProductByIdRequest) (*LookupProductByIdResponse, error) // Lookup Storage entity by id LookupStorageById(context.Context, *LookupStorageByIdRequest) (*LookupStorageByIdResponse, error) + MutationCreateAuthor(context.Context, *MutationCreateAuthorRequest) (*MutationCreateAuthorResponse, error) + MutationCreateBlogPost(context.Context, *MutationCreateBlogPostRequest) (*MutationCreateBlogPostResponse, error) + MutationCreateNullableFieldsType(context.Context, *MutationCreateNullableFieldsTypeRequest) (*MutationCreateNullableFieldsTypeResponse, error) MutationCreateUser(context.Context, *MutationCreateUserRequest) (*MutationCreateUserResponse, error) MutationPerformAction(context.Context, *MutationPerformActionRequest) (*MutationPerformActionResponse, error) + MutationUpdateAuthor(context.Context, *MutationUpdateAuthorRequest) (*MutationUpdateAuthorResponse, error) + MutationUpdateBlogPost(context.Context, *MutationUpdateBlogPostRequest) (*MutationUpdateBlogPostResponse, error) + MutationUpdateNullableFieldsType(context.Context, *MutationUpdateNullableFieldsTypeRequest) (*MutationUpdateNullableFieldsTypeResponse, error) + QueryAllAuthors(context.Context, *QueryAllAuthorsRequest) (*QueryAllAuthorsResponse, error) + QueryAllBlogPosts(context.Context, *QueryAllBlogPostsRequest) (*QueryAllBlogPostsResponse, error) + QueryAllNullableFieldsTypes(context.Context, *QueryAllNullableFieldsTypesRequest) (*QueryAllNullableFieldsTypesResponse, error) QueryAllPets(context.Context, *QueryAllPetsRequest) (*QueryAllPetsResponse, error) + QueryAuthor(context.Context, *QueryAuthorRequest) (*QueryAuthorResponse, error) + QueryAuthorById(context.Context, *QueryAuthorByIdRequest) (*QueryAuthorByIdResponse, error) + QueryAuthorsWithFilter(context.Context, *QueryAuthorsWithFilterRequest) (*QueryAuthorsWithFilterResponse, error) + QueryBlogPost(context.Context, *QueryBlogPostRequest) (*QueryBlogPostResponse, error) + QueryBlogPostById(context.Context, *QueryBlogPostByIdRequest) (*QueryBlogPostByIdResponse, error) + QueryBlogPostsWithFilter(context.Context, *QueryBlogPostsWithFilterRequest) (*QueryBlogPostsWithFilterResponse, error) QueryCalculateTotals(context.Context, *QueryCalculateTotalsRequest) (*QueryCalculateTotalsResponse, error) QueryCategories(context.Context, *QueryCategoriesRequest) (*QueryCategoriesResponse, error) QueryCategoriesByKind(context.Context, *QueryCategoriesByKindRequest) (*QueryCategoriesByKindResponse, error) @@ -372,6 +530,9 @@ type ProductServiceServer interface { QueryComplexFilterType(context.Context, *QueryComplexFilterTypeRequest) (*QueryComplexFilterTypeResponse, error) QueryFilterCategories(context.Context, *QueryFilterCategoriesRequest) (*QueryFilterCategoriesResponse, error) QueryNestedType(context.Context, *QueryNestedTypeRequest) (*QueryNestedTypeResponse, error) + QueryNullableFieldsType(context.Context, *QueryNullableFieldsTypeRequest) (*QueryNullableFieldsTypeResponse, error) + QueryNullableFieldsTypeById(context.Context, *QueryNullableFieldsTypeByIdRequest) (*QueryNullableFieldsTypeByIdResponse, error) + QueryNullableFieldsTypeWithFilter(context.Context, *QueryNullableFieldsTypeWithFilterRequest) (*QueryNullableFieldsTypeWithFilterResponse, error) QueryRandomPet(context.Context, *QueryRandomPetRequest) (*QueryRandomPetResponse, error) QueryRandomSearchResult(context.Context, *QueryRandomSearchResultRequest) (*QueryRandomSearchResultResponse, error) QueryRecursiveType(context.Context, *QueryRecursiveTypeRequest) (*QueryRecursiveTypeResponse, error) @@ -380,13 +541,6 @@ type ProductServiceServer interface { QueryTypeWithMultipleFilterFields(context.Context, *QueryTypeWithMultipleFilterFieldsRequest) (*QueryTypeWithMultipleFilterFieldsResponse, error) QueryUser(context.Context, *QueryUserRequest) (*QueryUserResponse, error) QueryUsers(context.Context, *QueryUsersRequest) (*QueryUsersResponse, error) - // Nullable fields RPCs - QueryNullableFieldsType(context.Context, *QueryNullableFieldsTypeRequest) (*QueryNullableFieldsTypeResponse, error) - QueryNullableFieldsTypeById(context.Context, *QueryNullableFieldsTypeByIdRequest) (*QueryNullableFieldsTypeByIdResponse, error) - QueryNullableFieldsTypeWithFilter(context.Context, *QueryNullableFieldsTypeWithFilterRequest) (*QueryNullableFieldsTypeWithFilterResponse, error) - QueryAllNullableFieldsTypes(context.Context, *QueryAllNullableFieldsTypesRequest) (*QueryAllNullableFieldsTypesResponse, error) - MutationCreateNullableFieldsType(context.Context, *MutationCreateNullableFieldsTypeRequest) (*MutationCreateNullableFieldsTypeResponse, error) - MutationUpdateNullableFieldsType(context.Context, *MutationUpdateNullableFieldsTypeRequest) (*MutationUpdateNullableFieldsTypeResponse, error) mustEmbedUnimplementedProductServiceServer() } @@ -403,15 +557,60 @@ func (UnimplementedProductServiceServer) LookupProductById(context.Context, *Loo func (UnimplementedProductServiceServer) LookupStorageById(context.Context, *LookupStorageByIdRequest) (*LookupStorageByIdResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method LookupStorageById not implemented") } +func (UnimplementedProductServiceServer) MutationCreateAuthor(context.Context, *MutationCreateAuthorRequest) (*MutationCreateAuthorResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MutationCreateAuthor not implemented") +} +func (UnimplementedProductServiceServer) MutationCreateBlogPost(context.Context, *MutationCreateBlogPostRequest) (*MutationCreateBlogPostResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MutationCreateBlogPost not implemented") +} +func (UnimplementedProductServiceServer) MutationCreateNullableFieldsType(context.Context, *MutationCreateNullableFieldsTypeRequest) (*MutationCreateNullableFieldsTypeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MutationCreateNullableFieldsType not implemented") +} func (UnimplementedProductServiceServer) MutationCreateUser(context.Context, *MutationCreateUserRequest) (*MutationCreateUserResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method MutationCreateUser not implemented") } func (UnimplementedProductServiceServer) MutationPerformAction(context.Context, *MutationPerformActionRequest) (*MutationPerformActionResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method MutationPerformAction not implemented") } +func (UnimplementedProductServiceServer) MutationUpdateAuthor(context.Context, *MutationUpdateAuthorRequest) (*MutationUpdateAuthorResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MutationUpdateAuthor not implemented") +} +func (UnimplementedProductServiceServer) MutationUpdateBlogPost(context.Context, *MutationUpdateBlogPostRequest) (*MutationUpdateBlogPostResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MutationUpdateBlogPost not implemented") +} +func (UnimplementedProductServiceServer) MutationUpdateNullableFieldsType(context.Context, *MutationUpdateNullableFieldsTypeRequest) (*MutationUpdateNullableFieldsTypeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MutationUpdateNullableFieldsType not implemented") +} +func (UnimplementedProductServiceServer) QueryAllAuthors(context.Context, *QueryAllAuthorsRequest) (*QueryAllAuthorsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryAllAuthors not implemented") +} +func (UnimplementedProductServiceServer) QueryAllBlogPosts(context.Context, *QueryAllBlogPostsRequest) (*QueryAllBlogPostsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryAllBlogPosts not implemented") +} +func (UnimplementedProductServiceServer) QueryAllNullableFieldsTypes(context.Context, *QueryAllNullableFieldsTypesRequest) (*QueryAllNullableFieldsTypesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryAllNullableFieldsTypes not implemented") +} func (UnimplementedProductServiceServer) QueryAllPets(context.Context, *QueryAllPetsRequest) (*QueryAllPetsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryAllPets not implemented") } +func (UnimplementedProductServiceServer) QueryAuthor(context.Context, *QueryAuthorRequest) (*QueryAuthorResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryAuthor not implemented") +} +func (UnimplementedProductServiceServer) QueryAuthorById(context.Context, *QueryAuthorByIdRequest) (*QueryAuthorByIdResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryAuthorById not implemented") +} +func (UnimplementedProductServiceServer) QueryAuthorsWithFilter(context.Context, *QueryAuthorsWithFilterRequest) (*QueryAuthorsWithFilterResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryAuthorsWithFilter not implemented") +} +func (UnimplementedProductServiceServer) QueryBlogPost(context.Context, *QueryBlogPostRequest) (*QueryBlogPostResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryBlogPost not implemented") +} +func (UnimplementedProductServiceServer) QueryBlogPostById(context.Context, *QueryBlogPostByIdRequest) (*QueryBlogPostByIdResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryBlogPostById not implemented") +} +func (UnimplementedProductServiceServer) QueryBlogPostsWithFilter(context.Context, *QueryBlogPostsWithFilterRequest) (*QueryBlogPostsWithFilterResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryBlogPostsWithFilter not implemented") +} func (UnimplementedProductServiceServer) QueryCalculateTotals(context.Context, *QueryCalculateTotalsRequest) (*QueryCalculateTotalsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryCalculateTotals not implemented") } @@ -433,7 +632,16 @@ func (UnimplementedProductServiceServer) QueryFilterCategories(context.Context, func (UnimplementedProductServiceServer) QueryNestedType(context.Context, *QueryNestedTypeRequest) (*QueryNestedTypeResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryNestedType not implemented") } -func (UnimplementedProductServiceServer) QueryRandomPet(context.Context, *QueryRandomPetRequest) (*QueryRandomPetResponse, error) { +func (UnimplementedProductServiceServer) QueryNullableFieldsType(context.Context, *QueryNullableFieldsTypeRequest) (*QueryNullableFieldsTypeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryNullableFieldsType not implemented") +} +func (UnimplementedProductServiceServer) QueryNullableFieldsTypeById(context.Context, *QueryNullableFieldsTypeByIdRequest) (*QueryNullableFieldsTypeByIdResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryNullableFieldsTypeById not implemented") +} +func (UnimplementedProductServiceServer) QueryNullableFieldsTypeWithFilter(context.Context, *QueryNullableFieldsTypeWithFilterRequest) (*QueryNullableFieldsTypeWithFilterResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryNullableFieldsTypeWithFilter not implemented") +} +func (UnimplementedProductServiceServer) QueryRandomPet(context.Context, *QueryRandomPetRequest) (*QueryRandomPetResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryRandomPet not implemented") } func (UnimplementedProductServiceServer) QueryRandomSearchResult(context.Context, *QueryRandomSearchResultRequest) (*QueryRandomSearchResultResponse, error) { @@ -457,24 +665,6 @@ func (UnimplementedProductServiceServer) QueryUser(context.Context, *QueryUserRe func (UnimplementedProductServiceServer) QueryUsers(context.Context, *QueryUsersRequest) (*QueryUsersResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryUsers not implemented") } -func (UnimplementedProductServiceServer) QueryNullableFieldsType(context.Context, *QueryNullableFieldsTypeRequest) (*QueryNullableFieldsTypeResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryNullableFieldsType not implemented") -} -func (UnimplementedProductServiceServer) QueryNullableFieldsTypeById(context.Context, *QueryNullableFieldsTypeByIdRequest) (*QueryNullableFieldsTypeByIdResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryNullableFieldsTypeById not implemented") -} -func (UnimplementedProductServiceServer) QueryNullableFieldsTypeWithFilter(context.Context, *QueryNullableFieldsTypeWithFilterRequest) (*QueryNullableFieldsTypeWithFilterResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryNullableFieldsTypeWithFilter not implemented") -} -func (UnimplementedProductServiceServer) QueryAllNullableFieldsTypes(context.Context, *QueryAllNullableFieldsTypesRequest) (*QueryAllNullableFieldsTypesResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryAllNullableFieldsTypes not implemented") -} -func (UnimplementedProductServiceServer) MutationCreateNullableFieldsType(context.Context, *MutationCreateNullableFieldsTypeRequest) (*MutationCreateNullableFieldsTypeResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method MutationCreateNullableFieldsType not implemented") -} -func (UnimplementedProductServiceServer) MutationUpdateNullableFieldsType(context.Context, *MutationUpdateNullableFieldsTypeRequest) (*MutationUpdateNullableFieldsTypeResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method MutationUpdateNullableFieldsType not implemented") -} func (UnimplementedProductServiceServer) mustEmbedUnimplementedProductServiceServer() {} func (UnimplementedProductServiceServer) testEmbeddedByValue() {} @@ -506,82 +696,352 @@ func _ProductService_LookupProductById_Handler(srv interface{}, ctx context.Cont } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: ProductService_LookupProductById_FullMethodName, + FullMethod: ProductService_LookupProductById_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).LookupProductById(ctx, req.(*LookupProductByIdRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_LookupStorageById_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LookupStorageByIdRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).LookupStorageById(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_LookupStorageById_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).LookupStorageById(ctx, req.(*LookupStorageByIdRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_MutationCreateAuthor_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MutationCreateAuthorRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).MutationCreateAuthor(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_MutationCreateAuthor_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).MutationCreateAuthor(ctx, req.(*MutationCreateAuthorRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_MutationCreateBlogPost_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MutationCreateBlogPostRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).MutationCreateBlogPost(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_MutationCreateBlogPost_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).MutationCreateBlogPost(ctx, req.(*MutationCreateBlogPostRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_MutationCreateNullableFieldsType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MutationCreateNullableFieldsTypeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).MutationCreateNullableFieldsType(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_MutationCreateNullableFieldsType_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).MutationCreateNullableFieldsType(ctx, req.(*MutationCreateNullableFieldsTypeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_MutationCreateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MutationCreateUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).MutationCreateUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_MutationCreateUser_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).MutationCreateUser(ctx, req.(*MutationCreateUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_MutationPerformAction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MutationPerformActionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).MutationPerformAction(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_MutationPerformAction_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).MutationPerformAction(ctx, req.(*MutationPerformActionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_MutationUpdateAuthor_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MutationUpdateAuthorRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).MutationUpdateAuthor(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_MutationUpdateAuthor_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).MutationUpdateAuthor(ctx, req.(*MutationUpdateAuthorRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_MutationUpdateBlogPost_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MutationUpdateBlogPostRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).MutationUpdateBlogPost(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_MutationUpdateBlogPost_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).MutationUpdateBlogPost(ctx, req.(*MutationUpdateBlogPostRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_MutationUpdateNullableFieldsType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MutationUpdateNullableFieldsTypeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).MutationUpdateNullableFieldsType(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_MutationUpdateNullableFieldsType_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).MutationUpdateNullableFieldsType(ctx, req.(*MutationUpdateNullableFieldsTypeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_QueryAllAuthors_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAllAuthorsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).QueryAllAuthors(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_QueryAllAuthors_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).QueryAllAuthors(ctx, req.(*QueryAllAuthorsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_QueryAllBlogPosts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAllBlogPostsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).QueryAllBlogPosts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_QueryAllBlogPosts_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).QueryAllBlogPosts(ctx, req.(*QueryAllBlogPostsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_QueryAllNullableFieldsTypes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAllNullableFieldsTypesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).QueryAllNullableFieldsTypes(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_QueryAllNullableFieldsTypes_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).QueryAllNullableFieldsTypes(ctx, req.(*QueryAllNullableFieldsTypesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_QueryAllPets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAllPetsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).QueryAllPets(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_QueryAllPets_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).QueryAllPets(ctx, req.(*QueryAllPetsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_QueryAuthor_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAuthorRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).QueryAuthor(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_QueryAuthor_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).QueryAuthor(ctx, req.(*QueryAuthorRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_QueryAuthorById_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAuthorByIdRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).QueryAuthorById(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_QueryAuthorById_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ProductServiceServer).LookupProductById(ctx, req.(*LookupProductByIdRequest)) + return srv.(ProductServiceServer).QueryAuthorById(ctx, req.(*QueryAuthorByIdRequest)) } return interceptor(ctx, in, info, handler) } -func _ProductService_LookupStorageById_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(LookupStorageByIdRequest) +func _ProductService_QueryAuthorsWithFilter_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAuthorsWithFilterRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ProductServiceServer).LookupStorageById(ctx, in) + return srv.(ProductServiceServer).QueryAuthorsWithFilter(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: ProductService_LookupStorageById_FullMethodName, + FullMethod: ProductService_QueryAuthorsWithFilter_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ProductServiceServer).LookupStorageById(ctx, req.(*LookupStorageByIdRequest)) + return srv.(ProductServiceServer).QueryAuthorsWithFilter(ctx, req.(*QueryAuthorsWithFilterRequest)) } return interceptor(ctx, in, info, handler) } -func _ProductService_MutationCreateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MutationCreateUserRequest) +func _ProductService_QueryBlogPost_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryBlogPostRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ProductServiceServer).MutationCreateUser(ctx, in) + return srv.(ProductServiceServer).QueryBlogPost(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: ProductService_MutationCreateUser_FullMethodName, + FullMethod: ProductService_QueryBlogPost_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ProductServiceServer).MutationCreateUser(ctx, req.(*MutationCreateUserRequest)) + return srv.(ProductServiceServer).QueryBlogPost(ctx, req.(*QueryBlogPostRequest)) } return interceptor(ctx, in, info, handler) } -func _ProductService_MutationPerformAction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MutationPerformActionRequest) +func _ProductService_QueryBlogPostById_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryBlogPostByIdRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ProductServiceServer).MutationPerformAction(ctx, in) + return srv.(ProductServiceServer).QueryBlogPostById(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: ProductService_MutationPerformAction_FullMethodName, + FullMethod: ProductService_QueryBlogPostById_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ProductServiceServer).MutationPerformAction(ctx, req.(*MutationPerformActionRequest)) + return srv.(ProductServiceServer).QueryBlogPostById(ctx, req.(*QueryBlogPostByIdRequest)) } return interceptor(ctx, in, info, handler) } -func _ProductService_QueryAllPets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryAllPetsRequest) +func _ProductService_QueryBlogPostsWithFilter_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryBlogPostsWithFilterRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ProductServiceServer).QueryAllPets(ctx, in) + return srv.(ProductServiceServer).QueryBlogPostsWithFilter(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: ProductService_QueryAllPets_FullMethodName, + FullMethod: ProductService_QueryBlogPostsWithFilter_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ProductServiceServer).QueryAllPets(ctx, req.(*QueryAllPetsRequest)) + return srv.(ProductServiceServer).QueryBlogPostsWithFilter(ctx, req.(*QueryBlogPostsWithFilterRequest)) } return interceptor(ctx, in, info, handler) } @@ -712,6 +1172,60 @@ func _ProductService_QueryNestedType_Handler(srv interface{}, ctx context.Contex return interceptor(ctx, in, info, handler) } +func _ProductService_QueryNullableFieldsType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryNullableFieldsTypeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).QueryNullableFieldsType(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_QueryNullableFieldsType_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).QueryNullableFieldsType(ctx, req.(*QueryNullableFieldsTypeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_QueryNullableFieldsTypeById_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryNullableFieldsTypeByIdRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).QueryNullableFieldsTypeById(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_QueryNullableFieldsTypeById_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).QueryNullableFieldsTypeById(ctx, req.(*QueryNullableFieldsTypeByIdRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProductService_QueryNullableFieldsTypeWithFilter_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryNullableFieldsTypeWithFilterRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProductServiceServer).QueryNullableFieldsTypeWithFilter(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProductService_QueryNullableFieldsTypeWithFilter_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProductServiceServer).QueryNullableFieldsTypeWithFilter(ctx, req.(*QueryNullableFieldsTypeWithFilterRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _ProductService_QueryRandomPet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryRandomPetRequest) if err := dec(in); err != nil { @@ -856,114 +1370,6 @@ func _ProductService_QueryUsers_Handler(srv interface{}, ctx context.Context, de return interceptor(ctx, in, info, handler) } -func _ProductService_QueryNullableFieldsType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryNullableFieldsTypeRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ProductServiceServer).QueryNullableFieldsType(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: ProductService_QueryNullableFieldsType_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ProductServiceServer).QueryNullableFieldsType(ctx, req.(*QueryNullableFieldsTypeRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _ProductService_QueryNullableFieldsTypeById_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryNullableFieldsTypeByIdRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ProductServiceServer).QueryNullableFieldsTypeById(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: ProductService_QueryNullableFieldsTypeById_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ProductServiceServer).QueryNullableFieldsTypeById(ctx, req.(*QueryNullableFieldsTypeByIdRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _ProductService_QueryNullableFieldsTypeWithFilter_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryNullableFieldsTypeWithFilterRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ProductServiceServer).QueryNullableFieldsTypeWithFilter(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: ProductService_QueryNullableFieldsTypeWithFilter_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ProductServiceServer).QueryNullableFieldsTypeWithFilter(ctx, req.(*QueryNullableFieldsTypeWithFilterRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _ProductService_QueryAllNullableFieldsTypes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryAllNullableFieldsTypesRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ProductServiceServer).QueryAllNullableFieldsTypes(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: ProductService_QueryAllNullableFieldsTypes_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ProductServiceServer).QueryAllNullableFieldsTypes(ctx, req.(*QueryAllNullableFieldsTypesRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _ProductService_MutationCreateNullableFieldsType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MutationCreateNullableFieldsTypeRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ProductServiceServer).MutationCreateNullableFieldsType(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: ProductService_MutationCreateNullableFieldsType_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ProductServiceServer).MutationCreateNullableFieldsType(ctx, req.(*MutationCreateNullableFieldsTypeRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _ProductService_MutationUpdateNullableFieldsType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MutationUpdateNullableFieldsTypeRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ProductServiceServer).MutationUpdateNullableFieldsType(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: ProductService_MutationUpdateNullableFieldsType_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ProductServiceServer).MutationUpdateNullableFieldsType(ctx, req.(*MutationUpdateNullableFieldsTypeRequest)) - } - return interceptor(ctx, in, info, handler) -} - // ProductService_ServiceDesc is the grpc.ServiceDesc for ProductService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -979,6 +1385,18 @@ var ProductService_ServiceDesc = grpc.ServiceDesc{ MethodName: "LookupStorageById", Handler: _ProductService_LookupStorageById_Handler, }, + { + MethodName: "MutationCreateAuthor", + Handler: _ProductService_MutationCreateAuthor_Handler, + }, + { + MethodName: "MutationCreateBlogPost", + Handler: _ProductService_MutationCreateBlogPost_Handler, + }, + { + MethodName: "MutationCreateNullableFieldsType", + Handler: _ProductService_MutationCreateNullableFieldsType_Handler, + }, { MethodName: "MutationCreateUser", Handler: _ProductService_MutationCreateUser_Handler, @@ -987,10 +1405,58 @@ var ProductService_ServiceDesc = grpc.ServiceDesc{ MethodName: "MutationPerformAction", Handler: _ProductService_MutationPerformAction_Handler, }, + { + MethodName: "MutationUpdateAuthor", + Handler: _ProductService_MutationUpdateAuthor_Handler, + }, + { + MethodName: "MutationUpdateBlogPost", + Handler: _ProductService_MutationUpdateBlogPost_Handler, + }, + { + MethodName: "MutationUpdateNullableFieldsType", + Handler: _ProductService_MutationUpdateNullableFieldsType_Handler, + }, + { + MethodName: "QueryAllAuthors", + Handler: _ProductService_QueryAllAuthors_Handler, + }, + { + MethodName: "QueryAllBlogPosts", + Handler: _ProductService_QueryAllBlogPosts_Handler, + }, + { + MethodName: "QueryAllNullableFieldsTypes", + Handler: _ProductService_QueryAllNullableFieldsTypes_Handler, + }, { MethodName: "QueryAllPets", Handler: _ProductService_QueryAllPets_Handler, }, + { + MethodName: "QueryAuthor", + Handler: _ProductService_QueryAuthor_Handler, + }, + { + MethodName: "QueryAuthorById", + Handler: _ProductService_QueryAuthorById_Handler, + }, + { + MethodName: "QueryAuthorsWithFilter", + Handler: _ProductService_QueryAuthorsWithFilter_Handler, + }, + { + MethodName: "QueryBlogPost", + Handler: _ProductService_QueryBlogPost_Handler, + }, + { + MethodName: "QueryBlogPostById", + Handler: _ProductService_QueryBlogPostById_Handler, + }, + { + MethodName: "QueryBlogPostsWithFilter", + Handler: _ProductService_QueryBlogPostsWithFilter_Handler, + }, { MethodName: "QueryCalculateTotals", Handler: _ProductService_QueryCalculateTotals_Handler, @@ -1019,6 +1485,18 @@ var ProductService_ServiceDesc = grpc.ServiceDesc{ MethodName: "QueryNestedType", Handler: _ProductService_QueryNestedType_Handler, }, + { + MethodName: "QueryNullableFieldsType", + Handler: _ProductService_QueryNullableFieldsType_Handler, + }, + { + MethodName: "QueryNullableFieldsTypeById", + Handler: _ProductService_QueryNullableFieldsTypeById_Handler, + }, + { + MethodName: "QueryNullableFieldsTypeWithFilter", + Handler: _ProductService_QueryNullableFieldsTypeWithFilter_Handler, + }, { MethodName: "QueryRandomPet", Handler: _ProductService_QueryRandomPet_Handler, @@ -1051,30 +1529,6 @@ var ProductService_ServiceDesc = grpc.ServiceDesc{ MethodName: "QueryUsers", Handler: _ProductService_QueryUsers_Handler, }, - { - MethodName: "QueryNullableFieldsType", - Handler: _ProductService_QueryNullableFieldsType_Handler, - }, - { - MethodName: "QueryNullableFieldsTypeById", - Handler: _ProductService_QueryNullableFieldsTypeById_Handler, - }, - { - MethodName: "QueryNullableFieldsTypeWithFilter", - Handler: _ProductService_QueryNullableFieldsTypeWithFilter_Handler, - }, - { - MethodName: "QueryAllNullableFieldsTypes", - Handler: _ProductService_QueryAllNullableFieldsTypes_Handler, - }, - { - MethodName: "MutationCreateNullableFieldsType", - Handler: _ProductService_MutationCreateNullableFieldsType_Handler, - }, - { - MethodName: "MutationUpdateNullableFieldsType", - Handler: _ProductService_MutationUpdateNullableFieldsType_Handler, - }, }, Streams: []grpc.StreamDesc{}, Metadata: "product.proto", diff --git a/v2/pkg/grpctest/schema.go b/v2/pkg/grpctest/schema.go index fc0248b645..e0516bd974 100644 --- a/v2/pkg/grpctest/schema.go +++ b/v2/pkg/grpctest/schema.go @@ -260,6 +260,94 @@ func GetFieldConfigurations() plan.FieldConfigurations { }, }, }, + { + TypeName: "Query", + FieldName: "blogPostById", + Arguments: []plan.ArgumentConfiguration{ + { + Name: "id", + SourceType: plan.FieldArgumentSource, + }, + }, + }, + { + TypeName: "Query", + FieldName: "blogPostsWithFilter", + Arguments: []plan.ArgumentConfiguration{ + { + Name: "filter", + SourceType: plan.FieldArgumentSource, + }, + }, + }, + { + TypeName: "Query", + FieldName: "authorById", + Arguments: []plan.ArgumentConfiguration{ + { + Name: "id", + SourceType: plan.FieldArgumentSource, + }, + }, + }, + { + TypeName: "Query", + FieldName: "authorsWithFilter", + Arguments: []plan.ArgumentConfiguration{ + { + Name: "filter", + SourceType: plan.FieldArgumentSource, + }, + }, + }, + { + TypeName: "Mutation", + FieldName: "createBlogPost", + Arguments: []plan.ArgumentConfiguration{ + { + Name: "input", + SourceType: plan.FieldArgumentSource, + }, + }, + }, + { + TypeName: "Mutation", + FieldName: "updateBlogPost", + Arguments: []plan.ArgumentConfiguration{ + { + Name: "id", + SourceType: plan.FieldArgumentSource, + }, + { + Name: "input", + SourceType: plan.FieldArgumentSource, + }, + }, + }, + { + TypeName: "Mutation", + FieldName: "createAuthor", + Arguments: []plan.ArgumentConfiguration{ + { + Name: "input", + SourceType: plan.FieldArgumentSource, + }, + }, + }, + { + TypeName: "Mutation", + FieldName: "updateAuthor", + Arguments: []plan.ArgumentConfiguration{ + { + Name: "id", + SourceType: plan.FieldArgumentSource, + }, + { + Name: "input", + SourceType: plan.FieldArgumentSource, + }, + }, + }, } } @@ -305,6 +393,14 @@ func GetDataSourceMetadata() *plan.DataSourceMetadata { "nullableFieldsTypeById", "nullableFieldsTypeWithFilter", "allNullableFieldsTypes", + "blogPost", + "blogPostById", + "blogPostsWithFilter", + "allBlogPosts", + "author", + "authorById", + "authorsWithFilter", + "allAuthors", }, }, { @@ -314,6 +410,10 @@ func GetDataSourceMetadata() *plan.DataSourceMetadata { "performAction", "createNullableFieldsType", "updateNullableFieldsType", + "createBlogPost", + "updateBlogPost", + "createAuthor", + "updateAuthor", }, }, }, @@ -581,6 +681,110 @@ func GetDataSourceMetadata() *plan.DataSourceMetadata { "includeNulls", }, }, + { + TypeName: "BlogPost", + FieldNames: []string{ + "id", + "title", + "content", + "tags", + "optionalTags", + "categories", + "keywords", + "viewCounts", + "ratings", + "isPublished", + "tagGroups", + "relatedTopics", + "commentThreads", + "suggestions", + "relatedCategories", + "contributors", + "mentionedProducts", + "mentionedUsers", + "categoryGroups", + "contributorTeams", + }, + }, + { + TypeName: "Author", + FieldNames: []string{ + "id", + "name", + "email", + "skills", + "languages", + "socialLinks", + "teamsByProject", + "collaborations", + "writtenPosts", + "favoriteCategories", + "relatedAuthors", + "productReviews", + "authorGroups", + "categoryPreferences", + "projectTeams", + }, + }, + { + TypeName: "BlogPostInput", + FieldNames: []string{ + "title", + "content", + "tags", + "optionalTags", + "categories", + "keywords", + "viewCounts", + "ratings", + "isPublished", + "tagGroups", + "relatedTopics", + "commentThreads", + "suggestions", + "relatedCategories", + "contributors", + "categoryGroups", + }, + }, + { + TypeName: "AuthorInput", + FieldNames: []string{ + "name", + "email", + "skills", + "languages", + "socialLinks", + "teamsByProject", + "collaborations", + "favoriteCategories", + "authorGroups", + "projectTeams", + }, + }, + { + TypeName: "BlogPostFilter", + FieldNames: []string{ + "title", + "hasCategories", + "minTags", + }, + }, + { + TypeName: "AuthorFilter", + FieldNames: []string{ + "name", + "hasTeams", + "skillCount", + }, + }, + { + TypeName: "CategoryInput", + FieldNames: []string{ + "name", + "kind", + }, + }, }, } } diff --git a/v2/pkg/grpctest/testdata/products.graphqls b/v2/pkg/grpctest/testdata/products.graphqls index 328ae2eddb..adde3d8ba4 100644 --- a/v2/pkg/grpctest/testdata/products.graphqls +++ b/v2/pkg/grpctest/testdata/products.graphqls @@ -176,6 +176,116 @@ type NullableFieldsType { requiredInt: Int! } +# Blog Post with various list types for testing +type BlogPost { + id: ID! + title: String! + content: String! + + # Single lists with different nullability + tags: [String!]! # Required list, required items + optionalTags: [String!] # Optional list, required items + categories: [String]! # Required list, optional items + keywords: [String] # Optional list, optional items + + # Single lists with different scalar types + viewCounts: [Int!]! # Daily view counts + ratings: [Float] # User ratings (can be null) + isPublished: [Boolean!] # Publication status history + + # Nested lists (one level deep) with different nullability + tagGroups: [[String!]!]! # Required groups, required group content, required tags + relatedTopics: [[String!]]! # Required groups, optional group content, required topics + commentThreads: [[String]!]! # Required threads, required thread content, optional comments + suggestions: [[String]] # Optional groups, optional group content, optional suggestions + + # Single lists with complex types + relatedCategories: [Category!]! # Required list of categories this post belongs to + contributors: [User!]! # Required list of users who contributed + mentionedProducts: [Product] # Optional list of products mentioned + mentionedUsers: [User] # Optional list of users mentioned + + # Nested lists with complex types + categoryGroups: [[Category!]!]! # Required groups of required categories + contributorTeams: [[User!]] # Optional teams of required contributors +} + +# Author with team structure +type Author { + id: ID! + name: String! + email: String + + # Single lists + skills: [String!]! # Required skills + languages: [String]! # Required list, optional languages + socialLinks: [String] # Optional social media links + + # Nested lists for team organization + teamsByProject: [[String!]!]! # Projects -> team members (all required) + collaborations: [[String]] # Past collaborations grouped (all optional) + + # Single lists with complex types + writtenPosts: [BlogPost] # Optional list of blog posts they've written + favoriteCategories: [Category!]! # Required list of their favorite categories + relatedAuthors: [User] # Optional list of related authors/collaborators + productReviews: [Product] # Optional list of products they've reviewed + + # Nested lists with complex types + authorGroups: [[User!]] # Optional groups of required authors they work with + categoryPreferences: [[Category!]!]! # Required groups of required category preferences + projectTeams: [[User]] # Optional groups of optional users for projects +} + +# Input types +input BlogPostInput { + title: String! + content: String! + tags: [String!]! + optionalTags: [String!] + categories: [String]! + keywords: [String] + viewCounts: [Int!]! + ratings: [Float] + isPublished: [Boolean!] + tagGroups: [[String!]!]! + relatedTopics: [[String!]]! + commentThreads: [[String]!]! + suggestions: [[String]] + + # Complex type lists with proper input types + relatedCategories: [CategoryInput] # Single list of categories + contributors: [UserInput] # Single list of contributors + categoryGroups: [[CategoryInput!]] # Nested list of category groups +} + +input AuthorInput { + name: String! + email: String + skills: [String!]! + languages: [String]! + socialLinks: [String] + teamsByProject: [[String!]!]! + collaborations: [[String]] + + # Complex type lists with proper input types + favoriteCategories: [CategoryInput!]! # Single list of favorite categories + authorGroups: [[UserInput!]] # Nested list of author groups + projectTeams: [[UserInput]] # Nested list of project teams (optional) +} + +input BlogPostFilter { + title: String + hasCategories: Boolean + minTags: Int +} + +input AuthorFilter { + name: String + hasTeams: Boolean + skillCount: Int +} + input NullableFieldsInput { name: String! optionalString: String @@ -192,6 +302,11 @@ input NullableFieldsFilter { includeNulls: Boolean } +input CategoryInput { + name: String! + kind: CategoryKind! +} + type Query { _entities(representations: [_Any!]!): [_Entity!]! users: [User!]! @@ -225,6 +340,18 @@ type Query { nullableFieldsTypeById(id: ID!): NullableFieldsType nullableFieldsTypeWithFilter(filter: NullableFieldsFilter!): [NullableFieldsType!]! allNullableFieldsTypes: [NullableFieldsType!]! + + # Blog post queries (testing single and nested lists) + blogPost: BlogPost! + blogPostById(id: ID!): BlogPost + blogPostsWithFilter(filter: BlogPostFilter!): [BlogPost!]! + allBlogPosts: [BlogPost!]! + + # Author queries (testing team structures) + author: Author! + authorById(id: ID!): Author + authorsWithFilter(filter: AuthorFilter!): [Author!]! + allAuthors: [Author!]! } input UserInput { @@ -240,6 +367,14 @@ type Mutation { # Nullable fields mutation createNullableFieldsType(input: NullableFieldsInput!): NullableFieldsType! updateNullableFieldsType(id: ID!, input: NullableFieldsInput!): NullableFieldsType + + # Blog post mutations (testing single and nested lists) + createBlogPost(input: BlogPostInput!): BlogPost! + updateBlogPost(id: ID!, input: BlogPostInput!): BlogPost + + # Author mutations (testing team structures) + createAuthor(input: AuthorInput!): Author! + updateAuthor(id: ID!, input: AuthorInput!): Author } union _Entity = Product | Storage