@@ -153,11 +153,7 @@ func parameterDataSource() *schema.Resource {
153153 }
154154
155155 // Validate options
156-
157- // optionType might differ from parameter.Type. This is ok, and parameter.Type
158- // should be used for the value type, and optionType for options.
159- var optionType OptionType
160- optionType , parameter .FormType , err = ValidateFormType (parameter .Type , len (parameter .Option ), parameter .FormType )
156+ _ , parameter .FormType , err = ValidateFormType (parameter .Type , len (parameter .Option ), parameter .FormType )
161157 if err != nil {
162158 return diag .FromErr (err )
163159 }
@@ -166,60 +162,11 @@ func parameterDataSource() *schema.Resource {
166162 // is used and saved.
167163 rd .Set ("form_type" , parameter .FormType )
168164
169- if len (parameter .Option ) > 0 {
170- names := map [string ]interface {}{}
171- values := map [string ]interface {}{}
172- for _ , option := range parameter .Option {
173- _ , exists := names [option .Name ]
174- if exists {
175- return diag .Errorf ("multiple options cannot have the same name %q" , option .Name )
176- }
177- _ , exists = values [option .Value ]
178- if exists {
179- return diag .Errorf ("multiple options cannot have the same value %q" , option .Value )
180- }
181- err := valueIsType (optionType , option .Value )
182- if err != nil {
183- return err
184- }
185- values [option .Value ] = nil
186- names [option .Name ] = nil
187- }
188-
189- if parameter .Default != "" {
190- if parameter .Type == OptionTypeListString && optionType == OptionTypeString {
191- // If the type is list(string) and optionType is string, we have
192- // to ensure all elements of the default exist as options.
193- var defaultValues []string
194- // TODO: We do this unmarshal in a few spots. It should be standardized.
195- err = json .Unmarshal ([]byte (parameter .Default ), & defaultValues )
196- if err != nil {
197- return diag .Errorf ("default value %q is not a list of strings" , parameter .Default )
198- }
199-
200- // missing is used to construct a more helpful error message
201- var missing []string
202- for _ , defaultValue := range defaultValues {
203- _ , defaultIsValid := values [defaultValue ]
204- if ! defaultIsValid {
205- missing = append (missing , defaultValue )
206- }
207- }
208-
209- if len (missing ) > 0 {
210- return diag .Errorf (
211- "default value %q is not a valid option, values %q are missing from the option" ,
212- parameter .Default , strings .Join (missing , ", " ),
213- )
214- }
215- } else {
216- _ , defaultIsValid := values [parameter .Default ]
217- if ! defaultIsValid {
218- return diag .Errorf ("%q default value %q must be defined as one of options" , parameter .FormType , parameter .Default )
219- }
220- }
221- }
165+ diags := parameter .Valid ()
166+ if diags .HasError () {
167+ return diags
222168 }
169+
223170 return nil
224171 },
225172 Schema : map [string ]* schema.Schema {
@@ -459,6 +406,76 @@ func valueIsType(typ OptionType, value string) diag.Diagnostics {
459406 return nil
460407}
461408
409+ func (v * Parameter ) Valid () diag.Diagnostics {
410+ // optionType might differ from parameter.Type. This is ok, and parameter.Type
411+ // should be used for the value type, and optionType for options.
412+ optionType , formType , err := ValidateFormType (v .Type , len (v .Option ), v .FormType )
413+ if err != nil {
414+ return diag .FromErr (err )
415+ }
416+
417+ if formType != v .FormType {
418+ return diag .FromErr (fmt .Errorf ("form_type %q is not valid for type %q" , v .FormType , v .Type ))
419+ }
420+
421+ optionNames := map [string ]interface {}{}
422+ optionValues := map [string ]interface {}{}
423+ if len (v .Option ) > 0 {
424+ for _ , option := range v .Option {
425+ _ , exists := optionNames [option .Name ]
426+ if exists {
427+ return diag .FromErr (fmt .Errorf ("multiple options cannot have the same name %q" , option .Name ))
428+ }
429+ _ , exists = optionValues [option .Value ]
430+ if exists {
431+ return diag .FromErr (fmt .Errorf ("multiple options cannot have the same value %q" , option .Value ))
432+ }
433+ diags := valueIsType (optionType , option .Value )
434+ if diags .HasError () {
435+ return diags
436+ }
437+ optionValues [option .Value ] = nil
438+ optionNames [option .Name ] = nil
439+ }
440+ }
441+
442+ if v .Default != "" {
443+ if v .Type == OptionTypeListString && optionType == OptionTypeString {
444+ // If the type is list(string) and optionType is string, we have
445+ // to ensure all elements of the default exist as options.
446+ var defaultValues []string
447+ // TODO: We do this unmarshal in a few spots. It should be standardized.
448+ err = json .Unmarshal ([]byte (v .Default ), & defaultValues )
449+ if err != nil {
450+ return diag .FromErr (fmt .Errorf ("default value %q is not a list of strings" , v .Default ))
451+ }
452+
453+ // missing is used to construct a more helpful error message
454+ var missing []string
455+ for _ , defaultValue := range defaultValues {
456+ _ , defaultIsValid := optionValues [defaultValue ]
457+ if ! defaultIsValid {
458+ missing = append (missing , defaultValue )
459+ }
460+ }
461+
462+ if len (missing ) > 0 {
463+ return diag .FromErr (fmt .Errorf (
464+ "default value %q is not a valid option, values %q are missing from the option" ,
465+ v .Default , strings .Join (missing , ", " ),
466+ ))
467+ }
468+ } else {
469+ _ , defaultIsValid := optionValues [v .Default ]
470+ if ! defaultIsValid {
471+ return diag .FromErr (fmt .Errorf ("%q default value %q must be defined as one of options" , v .FormType , v .Default ))
472+ }
473+ }
474+ }
475+
476+ return nil
477+ }
478+
462479func (v * Validation ) Valid (typ OptionType , value string ) error {
463480 if typ != OptionTypeNumber {
464481 if ! v .MinDisabled {
0 commit comments