From 94e695775142e93cf2a0a438fbbe142a871466a9 Mon Sep 17 00:00:00 2001 From: wenchy Date: Mon, 5 Aug 2024 22:10:30 +0800 Subject: [PATCH 1/2] confgen: control field name presence at field-level and sheet-level --- internal/confgen/document_parser.go | 24 +- internal/confgen/parser.go | 41 +-- internal/confgen/util.go | 3 - internal/importer/xml.go | 3 +- internal/importer/yaml.go | 2 + internal/protogen/field_prop.go | 4 + internal/protogen/protogen.go | 2 + proto/tableau/protobuf/metabook.proto | 69 ++--- proto/tableau/protobuf/tableau.proto | 19 +- proto/tableaupb/metabook.pb.go | 218 +++++++++------- proto/tableaupb/tableau.pb.go | 244 ++++++++++-------- .../conf/YamlFieldPropOptionalConf.json | 22 ++ .../proto/xml__metasheet__merger.proto | 4 +- .../proto/yaml__fieldprop__optional.proto | 29 +++ .../testdata/xml/metasheet/Merger.xml | 2 +- test/functest/testdata/yaml/Enum.yaml | 1 - test/functest/testdata/yaml/List.yaml | 1 - test/functest/testdata/yaml/Map.yaml | 1 - test/functest/testdata/yaml/Scalar.yaml | 1 - test/functest/testdata/yaml/Struct.yaml | 1 - .../testdata/yaml/fieldprop/Optional.yaml | 33 +++ 21 files changed, 436 insertions(+), 288 deletions(-) create mode 100644 test/functest/conf/YamlFieldPropOptionalConf.json create mode 100644 test/functest/proto/yaml__fieldprop__optional.proto create mode 100644 test/functest/testdata/yaml/fieldprop/Optional.yaml diff --git a/internal/confgen/document_parser.go b/internal/confgen/document_parser.go index c25a8aef..11bd4e3a 100644 --- a/internal/confgen/document_parser.go +++ b/internal/confgen/document_parser.go @@ -57,19 +57,17 @@ func (sp *documentParser) parseMessage(msg protoreflect.Message, node *book.Node } else { fieldNode = node.FindChild(field.opts.Name) if fieldNode == nil { - // if field.opts.Optional { - // // field not found and is optional, no need to process, just return. - // return nil - // } - // kvs := node.DebugNameKV() - // kvs = append(kvs, - // xerrors.KeyPBFieldType, xproto.GetFieldTypeName(fd), - // xerrors.KeyPBFieldName, fd.FullName(), - // xerrors.KeyPBFieldOpts, field.opts, - // ) - // return xerrors.WrapKV(xerrors.E2014(field.opts.Name), kvs...) - // TODO: return err when required - return nil + if sp.parser.IsFieldOptional(field) { + // field not found and is optional, just return nil. + return nil + } + kvs := node.DebugNameKV() + kvs = append(kvs, + xerrors.KeyPBFieldType, xproto.GetFieldTypeName(fd), + xerrors.KeyPBFieldName, fd.FullName(), + xerrors.KeyPBFieldOpts, field.opts, + ) + return xerrors.WrapKV(xerrors.E2014(field.opts.Name), kvs...) } } fieldPresent, err := sp.parseField(field, msg, fieldNode) diff --git a/internal/confgen/parser.go b/internal/confgen/parser.go index 311d2dbd..58d89575 100644 --- a/internal/confgen/parser.go +++ b/internal/confgen/parser.go @@ -234,6 +234,13 @@ func (sp *sheetParser) GetBookFormat() format.Format { return sp.extInfo.BookFormat } +// IsFieldOptional returns whether this field is optional (field name existence). +// - table formats (Excel/CSV): field's column can be absent. +// - document formats (XML/YAML): field's name can be absent. +func (sp *sheetParser) IsFieldOptional(field *Field) bool { + return sp.opts.GetOptional() || field.opts.GetProp().GetOptional() +} + func (sp *sheetParser) Parse(protomsg proto.Message, sheet *book.Sheet) error { if sheet.Document != nil { docParser := &documentParser{parser: sp} @@ -408,7 +415,7 @@ func (sp *sheetParser) parseMapField(field *Field, msg protoreflect.Message, rc case tableaupb.Layout_LAYOUT_VERTICAL: if valueFd.Kind() == protoreflect.MessageKind { keyColName := prefix + field.opts.Name + field.opts.Key - cell, err := rc.Cell(keyColName, field.opts.Optional) + cell, err := rc.Cell(keyColName, sp.IsFieldOptional(field)) if err != nil { return false, xerrors.WithMessageKV(err, rc.CellDebugKV(keyColName)...) } @@ -456,7 +463,7 @@ func (sp *sheetParser) parseMapField(field *Field, msg protoreflect.Message, rc value := types.DefaultMapValueOptName // default value name // key cell keyColName := prefix + field.opts.Name + key - cell, err := rc.Cell(keyColName, field.opts.Optional) + cell, err := rc.Cell(keyColName, sp.IsFieldOptional(field)) if err != nil { return false, xerrors.WithMessageKV(err, rc.CellDebugKV(keyColName)...) } @@ -468,7 +475,7 @@ func (sp *sheetParser) parseMapField(field *Field, msg protoreflect.Message, rc newMapKey := fieldValue.MapKey() // value cell valueColName := prefix + field.opts.Name + value - cell, err = rc.Cell(valueColName, field.opts.Optional) + cell, err = rc.Cell(valueColName, sp.IsFieldOptional(field)) if err != nil { return false, xerrors.WithMessageKV(err, rc.CellDebugKV(valueColName)...) } @@ -517,7 +524,7 @@ func (sp *sheetParser) parseMapField(field *Field, msg protoreflect.Message, rc // log.Debug("prefix size: ", size) for i := 1; i <= size; i++ { keyColName := prefix + field.opts.Name + strconv.Itoa(i) + field.opts.Key - cell, err := rc.Cell(keyColName, field.opts.Optional) + cell, err := rc.Cell(keyColName, sp.IsFieldOptional(field)) if err != nil { return false, xerrors.WithMessageKV(err, rc.CellDebugKV(keyColName)...) } @@ -574,7 +581,7 @@ func (sp *sheetParser) parseMapField(field *Field, msg protoreflect.Message, rc case tableaupb.Layout_LAYOUT_INCELL: colName := prefix + field.opts.Name - cell, err := rc.Cell(colName, field.opts.Optional) + cell, err := rc.Cell(colName, sp.IsFieldOptional(field)) if err != nil { return false, xerrors.WithMessageKV(err, rc.CellDebugKV(colName)...) } @@ -849,7 +856,7 @@ func (sp *sheetParser) parseListField(field *Field, msg protoreflect.Message, rc if fd == nil { return false, xerrors.ErrorKV(fmt.Sprintf("key field not found in proto definition: %s", keyProtoName), rc.CellDebugKV(keyColName)...) } - cell, err := rc.Cell(keyColName, field.opts.Optional) + cell, err := rc.Cell(keyColName, sp.IsFieldOptional(field)) if err != nil { return false, xerrors.WithMessageKV(err, rc.CellDebugKV(keyColName)...) } @@ -881,7 +888,7 @@ func (sp *sheetParser) parseListField(field *Field, msg protoreflect.Message, rc if field.opts.Span == tableaupb.Span_SPAN_INNER_CELL { // incell-struct list colName := prefix + field.opts.Name - cell, err := rc.Cell(colName, field.opts.Optional) + cell, err := rc.Cell(colName, sp.IsFieldOptional(field)) if err != nil { return false, xerrors.WithMessageKV(err, rc.CellDebugKV(colName)...) } @@ -929,7 +936,7 @@ func (sp *sheetParser) parseListField(field *Field, msg protoreflect.Message, rc if field.fd.Kind() == protoreflect.MessageKind { if field.opts.Span == tableaupb.Span_SPAN_INNER_CELL { // horizontal incell-struct list - cell, err := rc.Cell(colName, field.opts.Optional) + cell, err := rc.Cell(colName, sp.IsFieldOptional(field)) if err != nil { return false, xerrors.WithMessageKV(err, rc.CellDebugKV(colName)...) } @@ -950,7 +957,7 @@ func (sp *sheetParser) parseListField(field *Field, msg protoreflect.Message, rc subMsgName := string(field.fd.Message().FullName()) if types.IsWellKnownMessage(subMsgName) { // built-in message type: google.protobuf.Timestamp, google.protobuf.Duration - cell, err := rc.Cell(colName, field.opts.Optional) + cell, err := rc.Cell(colName, sp.IsFieldOptional(field)) if err != nil { kvs := rc.CellDebugKV(colName) return false, xerrors.WithMessageKV(err, kvs...) @@ -982,7 +989,7 @@ func (sp *sheetParser) parseListField(field *Field, msg protoreflect.Message, rc list.Append(newListValue) } else { // scalar list - cell, err := rc.Cell(colName, field.opts.Optional) + cell, err := rc.Cell(colName, sp.IsFieldOptional(field)) if err != nil { return false, xerrors.WithMessageKV(err, rc.CellDebugKV(colName)...) } @@ -1014,7 +1021,7 @@ func (sp *sheetParser) parseListField(field *Field, msg protoreflect.Message, rc case tableaupb.Layout_LAYOUT_INCELL: // incell list colName := prefix + field.opts.Name - cell, err := rc.Cell(colName, field.opts.Optional) + cell, err := rc.Cell(colName, sp.IsFieldOptional(field)) if err != nil { return false, xerrors.WithMessageKV(err, rc.CellDebugKV(colName)...) } @@ -1113,7 +1120,7 @@ func (sp *sheetParser) parseStructField(field *Field, msg protoreflect.Message, colName := prefix + field.opts.Name if field.opts.Span == tableaupb.Span_SPAN_INNER_CELL { // incell struct - cell, err := rc.Cell(colName, field.opts.Optional) + cell, err := rc.Cell(colName, sp.IsFieldOptional(field)) if err != nil { return false, xerrors.WithMessageKV(err, rc.CellDebugKV(colName)...) } @@ -1129,7 +1136,7 @@ func (sp *sheetParser) parseStructField(field *Field, msg protoreflect.Message, subMsgName := string(field.fd.Message().FullName()) if types.IsWellKnownMessage(subMsgName) { // built-in message type: google.protobuf.Timestamp, google.protobuf.Duration - cell, err := rc.Cell(colName, field.opts.Optional) + cell, err := rc.Cell(colName, sp.IsFieldOptional(field)) if err != nil { return false, xerrors.WithMessageKV(err, rc.CellDebugKV(colName)...) } @@ -1206,7 +1213,7 @@ func (sp *sheetParser) parseUnionField(field *Field, msg protoreflect.Message, r if field.opts.Span == tableaupb.Span_SPAN_INNER_CELL { colName := prefix + field.opts.Name // incell union - cell, err := rc.Cell(colName, field.opts.Optional) + cell, err := rc.Cell(colName, sp.IsFieldOptional(field)) if err != nil { return false, xerrors.WithMessageKV(err, rc.CellDebugKV(colName)...) } @@ -1226,7 +1233,7 @@ func (sp *sheetParser) parseUnionField(field *Field, msg protoreflect.Message, r // parse union type typeColName := prefix + field.opts.Name + unionDesc.TypeName() - cell, err := rc.Cell(typeColName, field.opts.Optional) + cell, err := rc.Cell(typeColName, sp.IsFieldOptional(field)) if err != nil { return false, xerrors.WithMessageKV(err, rc.CellDebugKV(typeColName)...) } @@ -1260,7 +1267,7 @@ func (sp *sheetParser) parseUnionField(field *Field, msg protoreflect.Message, r subField := parseFieldDescriptor(fd, sp.opts.Sep, sp.opts.Subsep) defer subField.release() // incell scalar - cell, err := rc.Cell(colName, subField.opts.Optional) + cell, err := rc.Cell(colName, sp.IsFieldOptional(subField)) if err != nil { return xerrors.WithMessageKV(err, rc.CellDebugKV(colName)...) } @@ -1370,7 +1377,7 @@ func (sp *sheetParser) parseScalarField(field *Field, msg protoreflect.Message, } var newValue protoreflect.Value colName := prefix + field.opts.Name - cell, err := rc.Cell(colName, field.opts.Optional) + cell, err := rc.Cell(colName, sp.IsFieldOptional(field)) if err != nil { return false, xerrors.WithMessageKV(err, rc.CellDebugKV(colName)...) } diff --git a/internal/confgen/util.go b/internal/confgen/util.go index dd65e273..2a44dfd7 100644 --- a/internal/confgen/util.go +++ b/internal/confgen/util.go @@ -52,7 +52,6 @@ func parseFieldDescriptor(fd protoreflect.FieldDescriptor, sheetSep, sheetSubsep layout := tableaupb.Layout_LAYOUT_DEFAULT sep := "" subsep := "" - optional := false var prop *tableaupb.FieldProp // opts := fd.Options().(*descriptorpb.FieldOptions) @@ -65,7 +64,6 @@ func parseFieldDescriptor(fd protoreflect.FieldDescriptor, sheetSep, sheetSubsep layout = fieldOpts.Layout sep = strings.TrimSpace(fieldOpts.Sep) subsep = strings.TrimSpace(fieldOpts.Subsep) - optional = fieldOpts.Optional prop = fieldOpts.Prop } else { // default processing @@ -100,7 +98,6 @@ func parseFieldDescriptor(fd protoreflect.FieldDescriptor, sheetSep, sheetSubsep pooledOpts.Layout = layout pooledOpts.Sep = sep pooledOpts.Subsep = subsep - pooledOpts.Optional = optional pooledOpts.Prop = prop return &Field{ diff --git a/internal/importer/xml.go b/internal/importer/xml.go index 775278ee..03304f74 100644 --- a/internal/importer/xml.go +++ b/internal/importer/xml.go @@ -67,7 +67,8 @@ func NewXMLImporter(filename string, sheets []string, parser book.SheetParser, m Book: book.NewBook(bookName, filename, nil), }, nil } - log.Debugf("newBook:%+v", newBook) + + // log.Debugf("book: %+v", newBook) return &XMLImporter{ Book: newBook, diff --git a/internal/importer/yaml.go b/internal/importer/yaml.go index cc461fc9..6653e38e 100644 --- a/internal/importer/yaml.go +++ b/internal/importer/yaml.go @@ -29,6 +29,8 @@ func NewYAMLImporter(filename string, sheetNames []string, parser book.SheetPars } } + // log.Debugf("book: %+v", book) + return &YAMLImporter{ Book: book, }, nil diff --git a/internal/protogen/field_prop.go b/internal/protogen/field_prop.go index a8541ff3..8d5b871b 100644 --- a/internal/protogen/field_prop.go +++ b/internal/protogen/field_prop.go @@ -23,6 +23,7 @@ func ExtractMapFieldProp(prop *tableaupb.FieldProp) *tableaupb.FieldProp { Fixed: prop.Fixed, Size: prop.Size, Present: prop.Present, + Optional: prop.Optional, } if IsEmptyFieldProp(p) { return nil @@ -42,6 +43,7 @@ func ExtractListFieldProp(prop *tableaupb.FieldProp, isScalarList bool) *tableau Fixed: prop.Fixed, Size: prop.Size, Present: prop.Present, + Optional: prop.Optional, } if isScalarList { p.Range = prop.Range @@ -62,6 +64,7 @@ func ExtractStructFieldProp(prop *tableaupb.FieldProp) *tableaupb.FieldProp { JsonName: prop.JsonName, Form: prop.Form, Present: prop.Present, + Optional: prop.Optional, } if IsEmptyFieldProp(p) { return nil @@ -80,6 +83,7 @@ func ExtractScalarFieldProp(prop *tableaupb.FieldProp) *tableaupb.FieldProp { Refer: prop.Refer, Default: prop.Default, Present: prop.Present, + Optional: prop.Optional, } if IsEmptyFieldProp(p) { return nil diff --git a/internal/protogen/protogen.go b/internal/protogen/protogen.go index 789618f6..a64c578b 100644 --- a/internal/protogen/protogen.go +++ b/internal/protogen/protogen.go @@ -329,6 +329,7 @@ func (gen *Generator) convertDocument(dir, filename string, checkProtoFileConfli Template: sheet.Meta.Template, Mode: sheet.Meta.Mode, Scatter: sheet.Meta.Scatter, + Optional: sheet.Meta.Optional, // Loader options: OrderedMap: sheet.Meta.OrderedMap, Index: parseIndexes(sheet.Meta.Index), @@ -456,6 +457,7 @@ func (gen *Generator) convertTable(dir, filename string, checkProtoFileConflicts Template: sheet.Meta.Template, Mode: sheet.Meta.Mode, Scatter: sheet.Meta.Scatter, + Optional: sheet.Meta.Optional, // Loader options: OrderedMap: sheet.Meta.OrderedMap, Index: parseIndexes(sheet.Meta.Index), diff --git a/proto/tableau/protobuf/metabook.proto b/proto/tableau/protobuf/metabook.proto index 4e25c5a0..3b977682 100644 --- a/proto/tableau/protobuf/metabook.proto +++ b/proto/tableau/protobuf/metabook.proto @@ -20,30 +20,30 @@ message Metabook { } message Metasheet { - string sheet = 1 [(tableau.field) = { name: "Sheet" optional: false }]; - string alias = 2 [(tableau.field) = { name: "Alias" optional: true }]; - int32 namerow = 3 [(tableau.field) = { name: "Namerow" optional: true }]; - int32 typerow = 4 [(tableau.field) = { name: "Typerow" optional: true }]; - int32 noterow = 5 [(tableau.field) = { name: "Noterow" optional: true }]; - int32 datarow = 6 [(tableau.field) = { name: "Datarow" optional: true }]; - int32 nameline = 7 [(tableau.field) = { name: "Nameline" optional: true }]; - int32 typeline = 8 [(tableau.field) = { name: "Typeline" optional: true }]; - bool transpose = 9 [(tableau.field) = { name: "Transpose" optional: true }]; + string sheet = 1 [(tableau.field) = {name:"Sheet"}]; + string alias = 2 [(tableau.field) = {name:"Alias" prop:{optional:true}}]; + int32 namerow = 3 [(tableau.field) = {name:"Namerow" prop:{optional:true}}]; + int32 typerow = 4 [(tableau.field) = {name:"Typerow" prop:{optional:true}}]; + int32 noterow = 5 [(tableau.field) = {name:"Noterow" prop:{optional:true}}]; + int32 datarow = 6 [(tableau.field) = {name:"Datarow" prop:{optional:true}}]; + int32 nameline = 7 [(tableau.field) = {name:"Nameline" prop:{optional:true}}]; + int32 typeline = 8 [(tableau.field) = {name:"Typeline" prop:{optional:true}}]; + bool transpose = 9 [(tableau.field) = {name:"Transpose" prop:{optional:true}}]; // nested naming of namerow - bool nested = 10 [(tableau.field) = { name: "Nested" optional: true }]; - string sep = 11 [(tableau.field) = { name: "Sep" optional: true }]; - string subsep = 12 [(tableau.field) = { name: "Subsep" optional: true }]; + bool nested = 10 [(tableau.field) = {name:"Nested" prop:{optional:true}}]; + string sep = 11 [(tableau.field) = {name:"Sep" prop:{optional:true}}]; + string subsep = 12 [(tableau.field) = {name:"Subsep" prop:{optional:true}}]; // merge multiple sheets with same schema to one. // each element is: // - a workbook name or Glob(https://pkg.go.dev/path/filepath#Glob) to merge (relative to this workbook): , // then the sheet name is the same as this sheet. // - or a workbook name (relative to this workbook) with a worksheet name: #. - repeated string merger = 13 [(tableau.field) = { name: "Merger" optional: true layout: LAYOUT_INCELL }]; + repeated string merger = 13 [(tableau.field) = {name:"Merger" layout:LAYOUT_INCELL prop:{optional:true}}]; // Tableau will merge adjacent rows with the same key. If the key cell is not set, // it will be treated as the same as the most nearest key above the same column. // // This option is only useful for map or keyed-list. - bool adjacent_key = 14 [(tableau.field) = { name: "AdjacentKey" optional: true }]; + bool adjacent_key = 14 [(tableau.field) = {name:"AdjacentKey" prop:{optional:true}}]; // Field presence is the notion of whether a protobuf field has a value. If set as true, // in order to track presence for basic types (numeric, string, bytes, and enums), the // generated .proto will add the `optional` label to them. @@ -51,22 +51,27 @@ message Metasheet { // Singular proto3 fields of basic types (numeric, string, bytes, and enums) which are defined // with the optional label have explicit presence, like proto2 (this feature is enabled by default // as release 3.15). Refer: https://github.com/protocolbuffers/protobuf/blob/main/docs/field_presence.md - bool field_presence = 15 [(tableau.field) = { name: "FieldPresence" optional: true }]; + bool field_presence = 15 [(tableau.field) = {name:"FieldPresence" prop:{optional:true}}]; // declares if sheet is a template config, which only generates protobuf IDL and not generates json data. // NOTE: currently only used for XML protogen. - bool template = 16 [(tableau.field) = { name: "Template" optional: true }]; + bool template = 16 [(tableau.field) = {name:"Template" prop:{optional:true}}]; // Sheet mode. - Mode mode = 17 [(tableau.field) = { name: "Mode" optional: true }]; + Mode mode = 17 [(tableau.field) = {name:"Mode" prop:{optional:true}}]; // Scatter converts sheets separately with same schema. // each element is: // - a workbook name or Glob(https://pkg.go.dev/path/filepath#Glob) which is relative to this workbook: , // then the sheet name is the same as this sheet. // - or a workbook name which is relative to this workbook with a worksheet name: #. - repeated string scatter = 18 [(tableau.field) = { name: "Scatter" optional: true layout: LAYOUT_INCELL }]; + repeated string scatter = 18 [(tableau.field) = {name:"Scatter" layout:LAYOUT_INCELL prop:{optional:true}}]; + // Whether all fields in this sheet are optional (field name existence). + // If set to true, then: + // - table formats (Excel/CSV): field's column can be absent. + // - document formats (XML/YAML): field's name can be absent. + bool optional = 19 [(tableau.field) = {name:"Optional" prop:{optional:true}}]; ////////// Loader related options below ////////// // Generate ordered map accessers - bool ordered_map = 50 [(tableau.field) = { name: "OrderedMap" optional: true }]; + bool ordered_map = 50 [(tableau.field) = {name:"OrderedMap" prop:{optional:true}}]; // Generate index accessers, and multiple index columns are comma-separated. // Format: [@IndexName], if IndexName is not set, it will be this // column’s parent struct type name. @@ -85,7 +90,7 @@ message Metasheet { // C++: // - const std::vector& Find(INDEX_TYPE index) const; // - const STRUCT_TYPE* FindFirst(INDEX_TYPE index); - string index = 51 [(tableau.field) = { name: "Index" optional: true }]; + string index = 51 [(tableau.field) = {name:"Index" prop:{optional:true}}]; } // EnumDescriptor represents enum type definition in sheet. @@ -95,11 +100,11 @@ message EnumDescriptor { datarow: 2 }; - repeated Value values = 1 [(tableau.field) = { layout: LAYOUT_VERTICAL }]; + repeated Value values = 1 [(tableau.field) = {layout:LAYOUT_VERTICAL}]; message Value { - optional int32 number = 1 [(tableau.field) = { name: "Number" optional: true }]; - string name = 2 [(tableau.field) = { name: "Name" }]; - string alias = 3 [(tableau.field) = { name: "Alias" }]; + optional int32 number = 1 [(tableau.field) = {name:"Number" prop:{optional:true}}]; + string name = 2 [(tableau.field) = {name:"Name"}]; + string alias = 3 [(tableau.field) = {name:"Alias"}]; } } @@ -110,10 +115,10 @@ message StructDescriptor { datarow: 2 }; - repeated Field fields = 1 [(tableau.field) = { layout: LAYOUT_VERTICAL }]; + repeated Field fields = 1 [(tableau.field) = {layout:LAYOUT_VERTICAL}]; message Field { - string name = 1 [(tableau.field) = { name: "Name" }]; - string type = 2 [(tableau.field) = { name: "Type" }]; + string name = 1 [(tableau.field) = {name:"Name"}]; + string type = 2 [(tableau.field) = {name:"Type"}]; } } @@ -124,13 +129,13 @@ message UnionDescriptor { datarow: 2 }; - repeated Value values = 1 [(tableau.field) = { layout: LAYOUT_VERTICAL }]; + repeated Value values = 1 [(tableau.field) = {layout:LAYOUT_VERTICAL}]; message Value { - optional int32 number = 1 [(tableau.field) = { name: "Number" optional: true }]; + optional int32 number = 1 [(tableau.field) = {name:"Number" prop:{optional:true}}]; // This is message type name, and the corresponding enum value name // is generated as: "TYPE_" + strcase.ToScreamingSnake(name). - string name = 2 [(tableau.field) = { name: "Name" }]; - string alias = 3 [(tableau.field) = { name: "Alias" }]; - repeated string fields = 4 [(tableau.field) = { name: "Field" layout: LAYOUT_HORIZONTAL }]; + string name = 2 [(tableau.field) = {name:"Name"}]; + string alias = 3 [(tableau.field) = {name:"Alias"}]; + repeated string fields = 4 [(tableau.field) = {name:"Field" layout:LAYOUT_HORIZONTAL}]; } } diff --git a/proto/tableau/protobuf/tableau.proto b/proto/tableau/protobuf/tableau.proto index 0b8bd1a1..e462b9dd 100644 --- a/proto/tableau/protobuf/tableau.proto +++ b/proto/tableau/protobuf/tableau.proto @@ -109,6 +109,11 @@ message WorksheetOptions { // Scatter convert multiple workbook sheets (comma-separated) separately // with same schema. E.g.: Item1.xlsx,Item2.xlsx,ItemAward*.xlsx. repeated string scatter = 18; + // Whether all fields in this sheet are optional (field name existence). + // If set to true, then: + // - table formats (Excel/CSV): field's column can be absent. + // - document formats (XML/YAML): field's name can be absent. + bool optional = 19; ////////// Loader related options below ////////// // Generate OrderedMap accessers or not. @@ -148,7 +153,6 @@ message FieldOptions { Span span = 5; // For list element or map value types. Default: SPAN_CROSS_CELL. string sep = 6; // NOT USED yet. Default: ",". string subsep = 7; // NOT USED yet. Default: ":". - bool optional = 8; // Whether the field is optional. FieldProp prop = 15; // Property of field. } @@ -194,9 +198,18 @@ message FieldProp { // will be used. Otherwise, it's deduced from the field's name by converting // it to camelCase. string json_name = 9; - // Must fill cell data explicitly if present is true, otherwise - // an error will be reported. + // Whether this field value is present (field value existence). + // If set to true, then do the following checks for different field types: + // - scalar/enum: cell data cannot be empty string (TODO: If this field's + // type is string, then how to set empty string explicitly?) + // - struct: check at least one field is present recursively + // - map/list: len(elements) > 0 bool present = 10; + // Whether this field is optional (field name existence). + // If set to true, then: + // - table formats (Excel/CSV): field's column can be absent. + // - document formats (XML/YAML): field's name can be absent. + bool optional = 11; } // Layout of list and map. diff --git a/proto/tableaupb/metabook.pb.go b/proto/tableaupb/metabook.pb.go index 8e810f09..befd8385 100644 --- a/proto/tableaupb/metabook.pb.go +++ b/proto/tableaupb/metabook.pb.go @@ -118,6 +118,11 @@ type Metasheet struct { // then the sheet name is the same as this sheet. // - or a workbook name which is relative to this workbook with a worksheet name: #. Scatter []string `protobuf:"bytes,18,rep,name=scatter,proto3" json:"scatter,omitempty"` + // Whether all fields in this sheet are optional (field name existence). + // If set to true, then: + // - table formats (Excel/CSV): field's column can be absent. + // - document formats (XML/YAML): field's name can be absent. + Optional bool `protobuf:"varint,19,opt,name=optional,proto3" json:"optional,omitempty"` // //////// Loader related options below ////////// // Generate ordered map accessers OrderedMap bool `protobuf:"varint,50,opt,name=ordered_map,json=orderedMap,proto3" json:"ordered_map,omitempty"` @@ -300,6 +305,13 @@ func (x *Metasheet) GetScatter() []string { return nil } +func (x *Metasheet) GetOptional() bool { + if x != nil { + return x.Optional + } + return false +} + func (x *Metasheet) GetOrderedMap() bool { if x != nil { return x.OrderedMap @@ -669,108 +681,114 @@ var file_tableau_protobuf_metabook_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x73, 0x68, 0x65, 0x65, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x12, 0x82, 0xb5, 0x18, 0x0e, 0x0a, 0x08, 0x40, 0x54, 0x41, 0x42, 0x4c, - 0x45, 0x41, 0x55, 0x10, 0x01, 0x28, 0x02, 0x22, 0x81, 0x07, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, + 0x45, 0x41, 0x55, 0x10, 0x01, 0x28, 0x02, 0x22, 0xd7, 0x07, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x73, 0x68, 0x65, 0x65, 0x74, 0x12, 0x21, 0x0a, 0x05, 0x73, 0x68, 0x65, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0x82, 0xb5, 0x18, 0x07, 0x0a, 0x05, 0x53, 0x68, 0x65, 0x65, - 0x74, 0x52, 0x05, 0x73, 0x68, 0x65, 0x65, 0x74, 0x12, 0x23, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x61, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x05, 0x41, - 0x6c, 0x69, 0x61, 0x73, 0x40, 0x01, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x29, 0x0a, - 0x07, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x77, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, 0x0f, - 0x82, 0xb5, 0x18, 0x0b, 0x0a, 0x07, 0x4e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x77, 0x40, 0x01, 0x52, - 0x07, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x77, 0x12, 0x29, 0x0a, 0x07, 0x74, 0x79, 0x70, 0x65, - 0x72, 0x6f, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x42, 0x0f, 0x82, 0xb5, 0x18, 0x0b, 0x0a, - 0x07, 0x54, 0x79, 0x70, 0x65, 0x72, 0x6f, 0x77, 0x40, 0x01, 0x52, 0x07, 0x74, 0x79, 0x70, 0x65, - 0x72, 0x6f, 0x77, 0x12, 0x29, 0x0a, 0x07, 0x6e, 0x6f, 0x74, 0x65, 0x72, 0x6f, 0x77, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x05, 0x42, 0x0f, 0x82, 0xb5, 0x18, 0x0b, 0x0a, 0x07, 0x4e, 0x6f, 0x74, 0x65, - 0x72, 0x6f, 0x77, 0x40, 0x01, 0x52, 0x07, 0x6e, 0x6f, 0x74, 0x65, 0x72, 0x6f, 0x77, 0x12, 0x29, - 0x0a, 0x07, 0x64, 0x61, 0x74, 0x61, 0x72, 0x6f, 0x77, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x42, - 0x0f, 0x82, 0xb5, 0x18, 0x0b, 0x0a, 0x07, 0x44, 0x61, 0x74, 0x61, 0x72, 0x6f, 0x77, 0x40, 0x01, - 0x52, 0x07, 0x64, 0x61, 0x74, 0x61, 0x72, 0x6f, 0x77, 0x12, 0x2c, 0x0a, 0x08, 0x6e, 0x61, 0x6d, - 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x42, 0x10, 0x82, 0xb5, 0x18, - 0x0c, 0x0a, 0x08, 0x4e, 0x61, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x40, 0x01, 0x52, 0x08, 0x6e, - 0x61, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x2c, 0x0a, 0x08, 0x74, 0x79, 0x70, 0x65, 0x6c, - 0x69, 0x6e, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x42, 0x10, 0x82, 0xb5, 0x18, 0x0c, 0x0a, - 0x08, 0x54, 0x79, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x40, 0x01, 0x52, 0x08, 0x74, 0x79, 0x70, - 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, - 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x42, 0x11, 0x82, 0xb5, 0x18, 0x0d, 0x0a, 0x09, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x40, 0x01, 0x52, 0x09, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x42, 0x0e, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x06, 0x4e, 0x65, - 0x73, 0x74, 0x65, 0x64, 0x40, 0x01, 0x52, 0x06, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x12, 0x1d, - 0x0a, 0x03, 0x73, 0x65, 0x70, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0x82, 0xb5, 0x18, - 0x07, 0x0a, 0x03, 0x53, 0x65, 0x70, 0x40, 0x01, 0x52, 0x03, 0x73, 0x65, 0x70, 0x12, 0x26, 0x0a, - 0x06, 0x73, 0x75, 0x62, 0x73, 0x65, 0x70, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0x82, - 0xb5, 0x18, 0x0a, 0x0a, 0x06, 0x53, 0x75, 0x62, 0x73, 0x65, 0x70, 0x40, 0x01, 0x52, 0x06, 0x73, - 0x75, 0x62, 0x73, 0x65, 0x70, 0x12, 0x28, 0x0a, 0x06, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x72, 0x18, - 0x0d, 0x20, 0x03, 0x28, 0x09, 0x42, 0x10, 0x82, 0xb5, 0x18, 0x0c, 0x0a, 0x06, 0x4d, 0x65, 0x72, - 0x67, 0x65, 0x72, 0x20, 0x03, 0x40, 0x01, 0x52, 0x06, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x72, 0x12, - 0x36, 0x0a, 0x0c, 0x61, 0x64, 0x6a, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x0e, 0x20, 0x01, 0x28, 0x08, 0x42, 0x13, 0x82, 0xb5, 0x18, 0x0f, 0x0a, 0x0b, 0x41, 0x64, 0x6a, - 0x61, 0x63, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x40, 0x01, 0x52, 0x0b, 0x61, 0x64, 0x6a, 0x61, - 0x63, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x3c, 0x0a, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, - 0x5f, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x42, - 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, 0x0d, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x50, 0x72, 0x65, 0x73, - 0x65, 0x6e, 0x63, 0x65, 0x40, 0x01, 0x52, 0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x50, 0x72, 0x65, - 0x73, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x2c, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, - 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x42, 0x10, 0x82, 0xb5, 0x18, 0x0c, 0x0a, 0x08, 0x54, - 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x40, 0x01, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, - 0x61, 0x74, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x0d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x4d, 0x6f, 0x64, 0x65, - 0x42, 0x0c, 0x82, 0xb5, 0x18, 0x08, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x40, 0x01, 0x52, 0x04, - 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x73, 0x63, 0x61, 0x74, 0x74, 0x65, 0x72, 0x18, - 0x12, 0x20, 0x03, 0x28, 0x09, 0x42, 0x11, 0x82, 0xb5, 0x18, 0x0d, 0x0a, 0x07, 0x53, 0x63, 0x61, - 0x74, 0x74, 0x65, 0x72, 0x20, 0x03, 0x40, 0x01, 0x52, 0x07, 0x73, 0x63, 0x61, 0x74, 0x74, 0x65, - 0x72, 0x12, 0x33, 0x0a, 0x0b, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x6d, 0x61, 0x70, - 0x18, 0x32, 0x20, 0x01, 0x28, 0x08, 0x42, 0x12, 0x82, 0xb5, 0x18, 0x0e, 0x0a, 0x0a, 0x4f, 0x72, - 0x64, 0x65, 0x72, 0x65, 0x64, 0x4d, 0x61, 0x70, 0x40, 0x01, 0x52, 0x0a, 0x6f, 0x72, 0x64, 0x65, - 0x72, 0x65, 0x64, 0x4d, 0x61, 0x70, 0x12, 0x23, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, - 0x33, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x05, 0x49, 0x6e, 0x64, - 0x65, 0x78, 0x40, 0x01, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0xde, 0x01, 0x0a, 0x0e, - 0x45, 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x3d, - 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, - 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x06, 0x82, - 0xb5, 0x18, 0x02, 0x20, 0x01, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x1a, 0x82, 0x01, - 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x0e, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x06, 0x4e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x40, 0x01, 0x48, 0x00, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x88, 0x01, 0x01, 0x12, 0x1e, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x0a, 0x82, 0xb5, 0x18, 0x06, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x0b, 0x82, 0xb5, 0x18, 0x07, 0x0a, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, - 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x6e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x3a, 0x08, 0x82, 0xb5, 0x18, 0x04, 0x10, 0x01, 0x28, 0x02, 0x22, 0xa6, 0x01, 0x0a, - 0x10, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, - 0x72, 0x12, 0x3f, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x53, 0x74, 0x72, 0x75, - 0x63, 0x74, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x46, 0x69, 0x65, - 0x6c, 0x64, 0x42, 0x06, 0x82, 0xb5, 0x18, 0x02, 0x20, 0x01, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x73, 0x1a, 0x47, 0x0a, 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0x82, 0xb5, 0x18, 0x06, 0x0a, - 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0x82, 0xb5, 0x18, 0x06, 0x0a, - 0x04, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x08, 0x82, 0xb5, 0x18, - 0x04, 0x10, 0x01, 0x28, 0x02, 0x22, 0x87, 0x02, 0x0a, 0x0f, 0x55, 0x6e, 0x69, 0x6f, 0x6e, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x3e, 0x0a, 0x06, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x61, 0x75, 0x2e, 0x55, 0x6e, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x6f, 0x72, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x06, 0x82, 0xb5, 0x18, 0x02, 0x20, - 0x01, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x1a, 0xa9, 0x01, 0x0a, 0x05, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x05, 0x42, 0x0e, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x06, 0x4e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x40, 0x01, 0x48, 0x00, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x88, 0x01, 0x01, - 0x12, 0x1e, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, - 0x82, 0xb5, 0x18, 0x06, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x21, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x0b, 0x82, 0xb5, 0x18, 0x07, 0x0a, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x05, 0x61, 0x6c, - 0x69, 0x61, 0x73, 0x12, 0x25, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x09, 0x42, 0x0d, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, - 0x20, 0x02, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x6e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x3a, 0x08, 0x82, 0xb5, 0x18, 0x04, 0x10, 0x01, 0x28, 0x02, 0x42, - 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x61, 0x75, 0x69, 0x6f, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x70, 0x62, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x52, 0x05, 0x73, 0x68, 0x65, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x61, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0f, 0x82, 0xb5, 0x18, 0x0b, 0x0a, 0x05, 0x41, + 0x6c, 0x69, 0x61, 0x73, 0x7a, 0x02, 0x58, 0x01, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x12, + 0x2b, 0x0a, 0x07, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x77, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, + 0x42, 0x11, 0x82, 0xb5, 0x18, 0x0d, 0x0a, 0x07, 0x4e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x77, 0x7a, + 0x02, 0x58, 0x01, 0x52, 0x07, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x77, 0x12, 0x2b, 0x0a, 0x07, + 0x74, 0x79, 0x70, 0x65, 0x72, 0x6f, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x42, 0x11, 0x82, + 0xb5, 0x18, 0x0d, 0x0a, 0x07, 0x54, 0x79, 0x70, 0x65, 0x72, 0x6f, 0x77, 0x7a, 0x02, 0x58, 0x01, + 0x52, 0x07, 0x74, 0x79, 0x70, 0x65, 0x72, 0x6f, 0x77, 0x12, 0x2b, 0x0a, 0x07, 0x6e, 0x6f, 0x74, + 0x65, 0x72, 0x6f, 0x77, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x42, 0x11, 0x82, 0xb5, 0x18, 0x0d, + 0x0a, 0x07, 0x4e, 0x6f, 0x74, 0x65, 0x72, 0x6f, 0x77, 0x7a, 0x02, 0x58, 0x01, 0x52, 0x07, 0x6e, + 0x6f, 0x74, 0x65, 0x72, 0x6f, 0x77, 0x12, 0x2b, 0x0a, 0x07, 0x64, 0x61, 0x74, 0x61, 0x72, 0x6f, + 0x77, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x42, 0x11, 0x82, 0xb5, 0x18, 0x0d, 0x0a, 0x07, 0x44, + 0x61, 0x74, 0x61, 0x72, 0x6f, 0x77, 0x7a, 0x02, 0x58, 0x01, 0x52, 0x07, 0x64, 0x61, 0x74, 0x61, + 0x72, 0x6f, 0x77, 0x12, 0x2e, 0x0a, 0x08, 0x6e, 0x61, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x05, 0x42, 0x12, 0x82, 0xb5, 0x18, 0x0e, 0x0a, 0x08, 0x4e, 0x61, 0x6d, + 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x7a, 0x02, 0x58, 0x01, 0x52, 0x08, 0x6e, 0x61, 0x6d, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x74, 0x79, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x05, 0x42, 0x12, 0x82, 0xb5, 0x18, 0x0e, 0x0a, 0x08, 0x54, 0x79, 0x70, + 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x7a, 0x02, 0x58, 0x01, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x73, 0x65, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x42, 0x13, 0x82, 0xb5, 0x18, 0x0f, 0x0a, 0x09, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x7a, 0x02, 0x58, 0x01, 0x52, 0x09, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x06, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x42, 0x10, 0x82, 0xb5, 0x18, 0x0c, 0x0a, 0x06, 0x4e, 0x65, + 0x73, 0x74, 0x65, 0x64, 0x7a, 0x02, 0x58, 0x01, 0x52, 0x06, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, + 0x12, 0x1f, 0x0a, 0x03, 0x73, 0x65, 0x70, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0x82, + 0xb5, 0x18, 0x09, 0x0a, 0x03, 0x53, 0x65, 0x70, 0x7a, 0x02, 0x58, 0x01, 0x52, 0x03, 0x73, 0x65, + 0x70, 0x12, 0x28, 0x0a, 0x06, 0x73, 0x75, 0x62, 0x73, 0x65, 0x70, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x10, 0x82, 0xb5, 0x18, 0x0c, 0x0a, 0x06, 0x53, 0x75, 0x62, 0x73, 0x65, 0x70, 0x7a, + 0x02, 0x58, 0x01, 0x52, 0x06, 0x73, 0x75, 0x62, 0x73, 0x65, 0x70, 0x12, 0x2a, 0x0a, 0x06, 0x6d, + 0x65, 0x72, 0x67, 0x65, 0x72, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, 0x42, 0x12, 0x82, 0xb5, 0x18, + 0x0e, 0x0a, 0x06, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x72, 0x20, 0x03, 0x7a, 0x02, 0x58, 0x01, 0x52, + 0x06, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x0c, 0x61, 0x64, 0x6a, 0x61, 0x63, + 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x42, 0x15, 0x82, + 0xb5, 0x18, 0x11, 0x0a, 0x0b, 0x41, 0x64, 0x6a, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, + 0x7a, 0x02, 0x58, 0x01, 0x52, 0x0b, 0x61, 0x64, 0x6a, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x4b, 0x65, + 0x79, 0x12, 0x3e, 0x0a, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x65, + 0x6e, 0x63, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x42, 0x17, 0x82, 0xb5, 0x18, 0x13, 0x0a, + 0x0d, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x7a, 0x02, + 0x58, 0x01, 0x52, 0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, + 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x10, 0x20, + 0x01, 0x28, 0x08, 0x42, 0x12, 0x82, 0xb5, 0x18, 0x0e, 0x0a, 0x08, 0x54, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x7a, 0x02, 0x58, 0x01, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x12, 0x31, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x0d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x42, 0x0e, + 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x7a, 0x02, 0x58, 0x01, 0x52, 0x04, + 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x2d, 0x0a, 0x07, 0x73, 0x63, 0x61, 0x74, 0x74, 0x65, 0x72, 0x18, + 0x12, 0x20, 0x03, 0x28, 0x09, 0x42, 0x13, 0x82, 0xb5, 0x18, 0x0f, 0x0a, 0x07, 0x53, 0x63, 0x61, + 0x74, 0x74, 0x65, 0x72, 0x20, 0x03, 0x7a, 0x02, 0x58, 0x01, 0x52, 0x07, 0x73, 0x63, 0x61, 0x74, + 0x74, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, + 0x13, 0x20, 0x01, 0x28, 0x08, 0x42, 0x12, 0x82, 0xb5, 0x18, 0x0e, 0x0a, 0x08, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x7a, 0x02, 0x58, 0x01, 0x52, 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x12, 0x35, 0x0a, 0x0b, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x6d, + 0x61, 0x70, 0x18, 0x32, 0x20, 0x01, 0x28, 0x08, 0x42, 0x14, 0x82, 0xb5, 0x18, 0x10, 0x0a, 0x0a, + 0x4f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x4d, 0x61, 0x70, 0x7a, 0x02, 0x58, 0x01, 0x52, 0x0a, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x4d, 0x61, 0x70, 0x12, 0x25, 0x0a, 0x05, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x18, 0x33, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0f, 0x82, 0xb5, 0x18, 0x0b, 0x0a, + 0x05, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x7a, 0x02, 0x58, 0x01, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x22, 0xe0, 0x01, 0x0a, 0x0e, 0x45, 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x6f, 0x72, 0x12, 0x3d, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x45, + 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x42, 0x06, 0x82, 0xb5, 0x18, 0x02, 0x20, 0x01, 0x52, 0x06, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x1a, 0x84, 0x01, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2d, 0x0a, + 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x10, 0x82, + 0xb5, 0x18, 0x0c, 0x0a, 0x06, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x7a, 0x02, 0x58, 0x01, 0x48, + 0x00, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x1e, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0x82, 0xb5, 0x18, 0x06, + 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x05, + 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0x82, 0xb5, 0x18, + 0x07, 0x0a, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x42, + 0x09, 0x0a, 0x07, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x3a, 0x08, 0x82, 0xb5, 0x18, 0x04, + 0x10, 0x01, 0x28, 0x02, 0x22, 0xa6, 0x01, 0x0a, 0x10, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x44, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x3f, 0x0a, 0x06, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x75, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x06, 0x82, 0xb5, 0x18, 0x02, + 0x20, 0x01, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x47, 0x0a, 0x05, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x0a, 0x82, 0xb5, 0x18, 0x06, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x0a, 0x82, 0xb5, 0x18, 0x06, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x3a, 0x08, 0x82, 0xb5, 0x18, 0x04, 0x10, 0x01, 0x28, 0x02, 0x22, 0x89, 0x02, + 0x0a, 0x0f, 0x55, 0x6e, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, + 0x72, 0x12, 0x3e, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x55, 0x6e, 0x69, 0x6f, + 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x42, 0x06, 0x82, 0xb5, 0x18, 0x02, 0x20, 0x01, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x1a, 0xab, 0x01, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2d, 0x0a, 0x06, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x10, 0x82, 0xb5, 0x18, + 0x0c, 0x0a, 0x06, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x7a, 0x02, 0x58, 0x01, 0x48, 0x00, 0x52, + 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x1e, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0x82, 0xb5, 0x18, 0x06, 0x0a, 0x04, + 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x05, 0x61, 0x6c, + 0x69, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0x82, 0xb5, 0x18, 0x07, 0x0a, + 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x25, 0x0a, + 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0d, 0x82, + 0xb5, 0x18, 0x09, 0x0a, 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x02, 0x52, 0x06, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x3a, + 0x08, 0x82, 0xb5, 0x18, 0x04, 0x10, 0x01, 0x28, 0x02, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x69, + 0x6f, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( diff --git a/proto/tableaupb/tableau.pb.go b/proto/tableaupb/tableau.pb.go index 21ba1cfc..08d26d54 100644 --- a/proto/tableaupb/tableau.pb.go +++ b/proto/tableaupb/tableau.pb.go @@ -361,6 +361,11 @@ type WorksheetOptions struct { // Scatter convert multiple workbook sheets (comma-separated) separately // with same schema. E.g.: Item1.xlsx,Item2.xlsx,ItemAward*.xlsx. Scatter []string `protobuf:"bytes,18,rep,name=scatter,proto3" json:"scatter,omitempty"` + // Whether all fields in this sheet are optional (field name existence). + // If set to true, then: + // - table formats (Excel/CSV): field's column can be absent. + // - document formats (XML/YAML): field's name can be absent. + Optional bool `protobuf:"varint,19,opt,name=optional,proto3" json:"optional,omitempty"` // //////// Loader related options below ////////// // Generate OrderedMap accessers or not. OrderedMap bool `protobuf:"varint,50,opt,name=ordered_map,json=orderedMap,proto3" json:"ordered_map,omitempty"` @@ -537,6 +542,13 @@ func (x *WorksheetOptions) GetScatter() []string { return nil } +func (x *WorksheetOptions) GetOptional() bool { + if x != nil { + return x.Optional + } + return false +} + func (x *WorksheetOptions) GetOrderedMap() bool { if x != nil { return x.OrderedMap @@ -705,15 +717,14 @@ type FieldOptions struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // Scalar type's variable name or composite type's variable name (prefix). - Note string `protobuf:"bytes,2,opt,name=note,proto3" json:"note,omitempty"` // Field note, maybe in another language (Chinese) other than variable name (English). - Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` // Only set when this field type is map or keyed-list. - Layout Layout `protobuf:"varint,4,opt,name=layout,proto3,enum=tableau.Layout" json:"layout,omitempty"` // For map/list types with cardinality. Default: LAYOUT_DEFAULT. - Span Span `protobuf:"varint,5,opt,name=span,proto3,enum=tableau.Span" json:"span,omitempty"` // For list element or map value types. Default: SPAN_CROSS_CELL. - Sep string `protobuf:"bytes,6,opt,name=sep,proto3" json:"sep,omitempty"` // NOT USED yet. Default: ",". - Subsep string `protobuf:"bytes,7,opt,name=subsep,proto3" json:"subsep,omitempty"` // NOT USED yet. Default: ":". - Optional bool `protobuf:"varint,8,opt,name=optional,proto3" json:"optional,omitempty"` // Whether the field is optional. - Prop *FieldProp `protobuf:"bytes,15,opt,name=prop,proto3" json:"prop,omitempty"` // Property of field. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // Scalar type's variable name or composite type's variable name (prefix). + Note string `protobuf:"bytes,2,opt,name=note,proto3" json:"note,omitempty"` // Field note, maybe in another language (Chinese) other than variable name (English). + Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` // Only set when this field type is map or keyed-list. + Layout Layout `protobuf:"varint,4,opt,name=layout,proto3,enum=tableau.Layout" json:"layout,omitempty"` // For map/list types with cardinality. Default: LAYOUT_DEFAULT. + Span Span `protobuf:"varint,5,opt,name=span,proto3,enum=tableau.Span" json:"span,omitempty"` // For list element or map value types. Default: SPAN_CROSS_CELL. + Sep string `protobuf:"bytes,6,opt,name=sep,proto3" json:"sep,omitempty"` // NOT USED yet. Default: ",". + Subsep string `protobuf:"bytes,7,opt,name=subsep,proto3" json:"subsep,omitempty"` // NOT USED yet. Default: ":". + Prop *FieldProp `protobuf:"bytes,15,opt,name=prop,proto3" json:"prop,omitempty"` // Property of field. } func (x *FieldOptions) Reset() { @@ -797,13 +808,6 @@ func (x *FieldOptions) GetSubsep() string { return "" } -func (x *FieldOptions) GetOptional() bool { - if x != nil { - return x.Optional - } - return false -} - func (x *FieldOptions) GetProp() *FieldProp { if x != nil { return x.Prop @@ -854,9 +858,18 @@ type FieldProp struct { // will be used. Otherwise, it's deduced from the field's name by converting // it to camelCase. JsonName string `protobuf:"bytes,9,opt,name=json_name,json=jsonName,proto3" json:"json_name,omitempty"` - // Must fill cell data explicitly if present is true, otherwise - // an error will be reported. + // Whether this field value is present (field value existence). + // If set to true, then do the following checks for different field types: + // - scalar/enum: cell data cannot be empty string (TODO: If this field's + // type is string, then how to set empty string explicitly?) + // - struct: check at least one field is present recursively + // - map/list: len(elements) > 0 Present bool `protobuf:"varint,10,opt,name=present,proto3" json:"present,omitempty"` + // Whether this field is optional (field name existence). + // If set to true, then: + // - table formats (Excel/CSV): field's column can be absent. + // - document formats (XML/YAML): field's name can be absent. + Optional bool `protobuf:"varint,11,opt,name=optional,proto3" json:"optional,omitempty"` } func (x *FieldProp) Reset() { @@ -961,6 +974,13 @@ func (x *FieldProp) GetPresent() bool { return false } +func (x *FieldProp) GetOptional() bool { + if x != nil { + return x.Optional + } + return false +} + var file_tableau_protobuf_tableau_proto_extTypes = []protoimpl.ExtensionInfo{ { ExtendedType: (*descriptorpb.FileOptions)(nil), @@ -1068,7 +1088,7 @@ var file_tableau_protobuf_tableau_proto_rawDesc = []byte{ 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x25, 0x0a, 0x0f, 0x57, 0x6f, 0x72, 0x6b, 0x62, 0x6f, 0x6f, 0x6b, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x22, 0xac, 0x04, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x68, 0x65, 0x65, 0x74, + 0x6d, 0x65, 0x22, 0xc8, 0x04, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x68, 0x65, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6e, 0x61, @@ -1099,35 +1119,35 @@ var file_tableau_protobuf_tableau_proto_rawDesc = []byte{ 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x63, 0x61, 0x74, 0x74, 0x65, 0x72, 0x18, 0x12, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x07, 0x73, 0x63, 0x61, 0x74, 0x74, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x72, - 0x64, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x32, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0a, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x4d, 0x61, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x18, 0x33, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, - 0x78, 0x22, 0x21, 0x0a, 0x0b, 0x45, 0x6e, 0x75, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x26, 0x0a, 0x10, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x38, 0x0a, 0x0c, - 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, + 0x09, 0x52, 0x07, 0x73, 0x63, 0x61, 0x74, 0x74, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, + 0x64, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x32, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x65, 0x64, 0x4d, 0x61, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x18, 0x33, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x21, 0x0a, + 0x0b, 0x45, 0x6e, 0x75, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x82, 0x02, 0x0a, 0x0c, 0x46, 0x69, 0x65, 0x6c, 0x64, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x6f, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x27, 0x0a, 0x06, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x0f, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x4c, 0x61, 0x79, 0x6f, - 0x75, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x12, 0x21, 0x0a, 0x04, 0x73, 0x70, - 0x61, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x61, 0x75, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x52, 0x04, 0x73, 0x70, 0x61, 0x6e, 0x12, 0x10, 0x0a, - 0x03, 0x73, 0x65, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x65, 0x70, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x75, 0x62, 0x73, 0x65, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x73, 0x75, 0x62, 0x73, 0x65, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x61, 0x6c, 0x12, 0x26, 0x0a, 0x04, 0x70, 0x72, 0x6f, 0x70, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x22, 0x26, 0x0a, 0x10, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x38, 0x0a, 0x0c, 0x4f, 0x6e, 0x65, 0x6f, + 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x22, 0xe6, 0x01, 0x0a, 0x0c, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x27, 0x0a, + 0x06, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x4c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x52, 0x06, + 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x12, 0x21, 0x0a, 0x04, 0x73, 0x70, 0x61, 0x6e, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x53, + 0x70, 0x61, 0x6e, 0x52, 0x04, 0x73, 0x70, 0x61, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x70, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x65, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x75, 0x62, 0x73, 0x65, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x75, 0x62, + 0x73, 0x65, 0x70, 0x12, 0x26, 0x0a, 0x04, 0x70, 0x72, 0x6f, 0x70, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x50, 0x72, 0x6f, 0x70, 0x52, 0x04, 0x70, 0x72, 0x6f, 0x70, 0x22, 0xab, 0x02, 0x0a, 0x09, + 0x64, 0x50, 0x72, 0x6f, 0x70, 0x52, 0x04, 0x70, 0x72, 0x6f, 0x70, 0x22, 0xc7, 0x02, 0x0a, 0x09, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x50, 0x72, 0x6f, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x06, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, @@ -1145,72 +1165,74 @@ var file_tableau_protobuf_tableau_proto_rawDesc = []byte{ 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6a, 0x73, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, - 0x74, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x42, 0x0b, 0x0a, 0x09, - 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x2a, 0x5b, 0x0a, 0x06, 0x4c, 0x61, 0x79, - 0x6f, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x41, 0x59, 0x4f, 0x55, 0x54, 0x5f, 0x44, 0x45, - 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x41, 0x59, 0x4f, 0x55, - 0x54, 0x5f, 0x56, 0x45, 0x52, 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, - 0x4c, 0x41, 0x59, 0x4f, 0x55, 0x54, 0x5f, 0x48, 0x4f, 0x52, 0x49, 0x5a, 0x4f, 0x4e, 0x54, 0x41, - 0x4c, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x41, 0x59, 0x4f, 0x55, 0x54, 0x5f, 0x49, 0x4e, - 0x43, 0x45, 0x4c, 0x4c, 0x10, 0x03, 0x2a, 0x42, 0x0a, 0x04, 0x53, 0x70, 0x61, 0x6e, 0x12, 0x10, - 0x0a, 0x0c, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, - 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x43, 0x52, 0x4f, 0x53, 0x53, 0x5f, 0x43, - 0x45, 0x4c, 0x4c, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x49, 0x4e, - 0x4e, 0x45, 0x52, 0x5f, 0x43, 0x45, 0x4c, 0x4c, 0x10, 0x02, 0x2a, 0x7a, 0x0a, 0x04, 0x4d, 0x6f, - 0x64, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, - 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x45, 0x5f, - 0x43, 0x53, 0x56, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x45, - 0x5f, 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x4f, 0x44, 0x45, 0x5f, - 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x4d, - 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x55, 0x43, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, - 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x49, 0x4f, 0x4e, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x10, 0x05, 0x2a, 0x36, 0x0a, 0x04, 0x46, 0x6f, 0x72, 0x6d, 0x12, 0x10, - 0x0a, 0x0c, 0x46, 0x4f, 0x52, 0x4d, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, - 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x4f, 0x52, 0x4d, 0x5f, 0x54, 0x45, 0x58, 0x54, 0x10, 0x01, 0x12, - 0x0d, 0x0a, 0x09, 0x46, 0x4f, 0x52, 0x4d, 0x5f, 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0x02, 0x3a, 0x54, - 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x62, 0x6f, 0x6f, 0x6b, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, - 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd0, 0x86, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x18, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x62, - 0x6f, 0x6f, 0x6b, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x62, 0x6f, 0x6f, 0x6b, 0x3a, 0x5a, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x68, 0x65, 0x65, - 0x74, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0xd0, 0x86, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x68, 0x65, 0x65, 0x74, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x68, 0x65, 0x65, 0x74, - 0x3a, 0x37, 0x0a, 0x05, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd1, 0x86, 0x03, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x05, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x3a, 0x4c, 0x0a, 0x05, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0xd0, 0x86, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x61, 0x75, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x3a, 0x4a, 0x0a, 0x05, 0x65, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd0, - 0x86, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, - 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x05, 0x65, 0x74, - 0x79, 0x70, 0x65, 0x3a, 0x56, 0x0a, 0x06, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x2e, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x09, 0x0a, + 0x07, 0x5f, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x73, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x63, 0x65, 0x2a, 0x5b, 0x0a, 0x06, 0x4c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x12, + 0x12, 0x0a, 0x0e, 0x4c, 0x41, 0x59, 0x4f, 0x55, 0x54, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, + 0x54, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x41, 0x59, 0x4f, 0x55, 0x54, 0x5f, 0x56, 0x45, + 0x52, 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x4c, 0x41, 0x59, 0x4f, + 0x55, 0x54, 0x5f, 0x48, 0x4f, 0x52, 0x49, 0x5a, 0x4f, 0x4e, 0x54, 0x41, 0x4c, 0x10, 0x02, 0x12, + 0x11, 0x0a, 0x0d, 0x4c, 0x41, 0x59, 0x4f, 0x55, 0x54, 0x5f, 0x49, 0x4e, 0x43, 0x45, 0x4c, 0x4c, + 0x10, 0x03, 0x2a, 0x42, 0x0a, 0x04, 0x53, 0x70, 0x61, 0x6e, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x50, + 0x41, 0x4e, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, + 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x43, 0x52, 0x4f, 0x53, 0x53, 0x5f, 0x43, 0x45, 0x4c, 0x4c, 0x10, + 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x49, 0x4e, 0x4e, 0x45, 0x52, 0x5f, + 0x43, 0x45, 0x4c, 0x4c, 0x10, 0x02, 0x2a, 0x7a, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x10, + 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, + 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x45, 0x5f, 0x43, 0x53, 0x56, 0x10, + 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x45, 0x5f, 0x4a, 0x53, 0x4f, + 0x4e, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x4f, 0x44, 0x45, 0x5f, + 0x53, 0x54, 0x52, 0x55, 0x43, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x04, 0x12, 0x13, 0x0a, + 0x0f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x10, 0x05, 0x2a, 0x36, 0x0a, 0x04, 0x46, 0x6f, 0x72, 0x6d, 0x12, 0x10, 0x0a, 0x0c, 0x46, 0x4f, + 0x52, 0x4d, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, + 0x46, 0x4f, 0x52, 0x4d, 0x5f, 0x54, 0x45, 0x58, 0x54, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x46, + 0x4f, 0x52, 0x4d, 0x5f, 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0x02, 0x3a, 0x54, 0x0a, 0x08, 0x77, 0x6f, + 0x72, 0x6b, 0x62, 0x6f, 0x6f, 0x6b, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd0, 0x86, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x62, 0x6f, 0x6f, 0x6b, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x62, 0x6f, 0x6f, 0x6b, + 0x3a, 0x5a, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x68, 0x65, 0x65, 0x74, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0xd0, 0x86, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x61, 0x75, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x06, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x4f, 0x0a, 0x05, 0x6f, - 0x6e, 0x65, 0x6f, 0x66, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0xd0, 0x86, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x88, 0x01, 0x01, 0x42, 0x75, 0x0a, 0x14, - 0x63, 0x6f, 0x6d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x42, 0x0c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x69, 0x6f, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x61, 0x75, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, - 0x70, 0x62, 0xa2, 0x02, 0x03, 0x54, 0x50, 0x42, 0xaa, 0x02, 0x18, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x61, 0x75, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x61, 0x75, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd0, + 0x86, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, + 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x68, 0x65, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x68, 0x65, 0x65, 0x74, 0x3a, 0x37, 0x0a, 0x05, + 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd1, 0x86, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, + 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x3a, 0x4c, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x1d, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd0, 0x86, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x05, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x3a, 0x4a, 0x0a, 0x05, 0x65, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6e, 0x75, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd0, 0x86, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x45, 0x6e, 0x75, + 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x05, 0x65, 0x74, 0x79, 0x70, 0x65, 0x3a, + 0x56, 0x0a, 0x06, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd0, 0x86, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x45, + 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x06, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x4f, 0x0a, 0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, + 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0xd0, 0x86, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, + 0x75, 0x2e, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x05, + 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x88, 0x01, 0x01, 0x42, 0x75, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x42, 0x0c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x61, 0x75, 0x69, 0x6f, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x70, 0x62, 0xa2, 0x02, + 0x03, 0x54, 0x50, 0x42, 0xaa, 0x02, 0x18, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x2e, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x75, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/test/functest/conf/YamlFieldPropOptionalConf.json b/test/functest/conf/YamlFieldPropOptionalConf.json new file mode 100644 index 00000000..b55378be --- /dev/null +++ b/test/functest/conf/YamlFieldPropOptionalConf.json @@ -0,0 +1,22 @@ +{ + "id": 1, + "num": 0, + "cost": null, + "structMap": { + "1": { + "key": 1, + "name": "apple", + "num": 10 + }, + "2": { + "key": 2, + "name": "orange", + "num": 20 + }, + "3": { + "key": 3, + "name": "banana", + "num": 0 + } + } +} \ No newline at end of file diff --git a/test/functest/proto/xml__metasheet__merger.proto b/test/functest/proto/xml__metasheet__merger.proto index a90023ff..f6e56f54 100644 --- a/test/functest/proto/xml__metasheet__merger.proto +++ b/test/functest/proto/xml__metasheet__merger.proto @@ -1,4 +1,4 @@ -// Code generated by tableau (protogen v0.5.0). DO NOT EDIT. +// Code generated by tableau (protogen v0.6.0). DO NOT EDIT. // clang-format off syntax = "proto3"; @@ -11,7 +11,7 @@ option go_package = "github.com/tableauio/tableau/test/functest/protoconf"; option (tableau.workbook) = {name:"xml/metasheet/Merger.xml"}; message MergerConf { - option (tableau.worksheet) = {name:"MergerConf" merger:"Merger*.xml"}; + option (tableau.worksheet) = {name:"MergerConf" merger:"Merger*.xml" optional:true}; map fuben_map = 1 [(tableau.field) = {name:"Fuben" key:"Id"}]; message Fuben { diff --git a/test/functest/proto/yaml__fieldprop__optional.proto b/test/functest/proto/yaml__fieldprop__optional.proto new file mode 100644 index 00000000..5b22436c --- /dev/null +++ b/test/functest/proto/yaml__fieldprop__optional.proto @@ -0,0 +1,29 @@ +// Code generated by tableau (protogen v0.6.0). DO NOT EDIT. +// clang-format off + +syntax = "proto3"; + +package protoconf; + +import "tableau/protobuf/tableau.proto"; + +option go_package = "github.com/tableauio/tableau/test/functest/protoconf"; +option (tableau.workbook) = {name:"yaml/fieldprop/Optional.yaml"}; + +message YamlFieldPropOptionalConf { + option (tableau.worksheet) = {name:"YamlFieldPropOptionalConf"}; + + uint32 id = 1 [(tableau.field) = {name:"ID"}]; + int32 num = 2 [(tableau.field) = {name:"Num" prop:{optional:true}}]; + Cost cost = 3 [(tableau.field) = {name:"Cost" prop:{optional:true}}]; + message Cost { + string type = 1 [(tableau.field) = {name:"Type"}]; + int32 price = 2 [(tableau.field) = {name:"Price"}]; + } + map struct_map = 4 [(tableau.field) = {name:"StructMap" key:"@key"}]; + message Item { + uint32 key = 1 [(tableau.field) = {name:"@key"}]; + string name = 2 [(tableau.field) = {name:"Name"}]; + int32 num = 3 [(tableau.field) = {name:"Num" prop:{optional:true}}]; + } +} diff --git a/test/functest/testdata/xml/metasheet/Merger.xml b/test/functest/testdata/xml/metasheet/Merger.xml index dd58a4a7..3a459b63 100644 --- a/test/functest/testdata/xml/metasheet/Merger.xml +++ b/test/functest/testdata/xml/metasheet/Merger.xml @@ -1,7 +1,7 @@