<commit_before><%- # the license inside this block applies to this file
# Copyright 2017 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-%>
<%= lines(autogen_notice(:go, pwd)) -%>

package google

import (
<%- # We list all the v2 imports here, because we run 'goimports' to guess the correct
    # set of imports, which will never guess the major version correctly. -%>
  "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
  "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
  "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
  "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
  "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
  "github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure"
  "github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
  "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
  "github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging"
)

<%= lines(compile(pwd + '/' + object.custom_code.constants)) if object.custom_code.constants -%>

<%
    resource_name = product_ns + object.name
    properties = object.all_user_properties
    update_body_properties = object.settable_properties
    update_body_properties = object.settable_properties.reject(&:input) if object.update_verb == :PATCH
    # Handwritten TF Operation objects will be shaped like accessContextManager while the Google Go Client will have a name like accesscontextmanager
    client_name = @config.client_name || product_ns
    client_name_camel = client_name.camelize(:lower)
    client_name_pascal = client_name.camelize(:upper)
    client_name_lower = client_name.downcase
    has_project = object.base_url.include?('{{project}}') || (object.create_url && object.create_url.include?('{{project}}'))
    has_region = object.base_url.include?('{{region}}') && object.parameters.any?{ |p| p.name == 'region' && p.ignore_read }
    # In order of preference, use TF override,
    # general defined timeouts, or default Timeouts
    timeouts = object.timeouts
    timeouts ||= object&.async&.operation&.timeouts
    timeouts ||= Api::Timeouts.new
-%>

func resource<%= resource_name -%>() *schema.Resource {
    return &schema.Resource{
        Create: resource<%= resource_name -%>Create,
        Read: resource<%= resource_name -%>Read,
<%      if updatable?(object, properties) -%>
        Update: resource<%= resource_name -%>Update,
<%      end -%>
        Delete: resource<%= resource_name -%>Delete,
<%      if object.settable_properties.any? {|p| p.unordered_list} && !object.custom_code.resource_definition -%>
        CustomizeDiff: customdiff.All(
<%=
            object.settable_properties.select { |p| p.unordered_list }
                               .map { |p| "resource#{resource_name}#{p.name.camelize(:upper)}SetStyleDiff"}
                               .join(",\n")
-%>
        ),
<%      end -%>

<%      unless object.exclude_import -%>
        Importer: &schema.ResourceImporter{
            State: resource<%= resource_name -%>Import,
        },
<%      end -%>

        Timeouts: &schema.ResourceTimeout {
            Create: schema.DefaultTimeout(<%= timeouts.insert_minutes -%> * time.Minute),
<%      if updatable?(object, properties) -%>
            Update: schema.DefaultTimeout(<%= timeouts.update_minutes -%> * time.Minute),
<%      end -%>
            Delete: schema.DefaultTimeout(<%= timeouts.delete_minutes -%> * time.Minute),
        },

<%      if object.schema_version -%>
        SchemaVersion: <%= object.schema_version -%>,
        StateUpgraders: []schema.StateUpgrader{
<%        for v in 0..object.schema_version-1 -%>
            {
                Type: resource<%= "#{resource_name}ResourceV#{v}" -%>().CoreConfigSchema().ImpliedType(),
                Upgrade: resource<%= "#{resource_name}UpgradeV#{v}" -%>,
                Version: <%= v -%>,
            },
        },
<%        end -%>
<%      end -%>

<%=     lines(compile(pwd + '/' + object.custom_code.resource_definition)) if object.custom_code.resource_definition -%>

        Schema: map[string]*schema.Schema{
<%      order_properties(properties).each do |prop| -%>
<%=       lines(build_schema_property(prop, object, pwd)) -%>
<%      end -%>
<%-     unless object.virtual_fields.empty? -%>
<%-       object.virtual_fields.each do |field| -%>
            "<%= field.name -%>": {
              Type: <%= tf_type(field) -%>,
              Optional: true,
              Default:  <%= go_literal(field.default_value) -%>,
            },
<%        end -%>
<%      end -%>
<%=     lines(compile(pwd + '/' + object.custom_code.extra_schema_entry)) if object.custom_code.extra_schema_entry -%>
<%      if has_project -%>
            "project": {
                Type:     schema.TypeString,
                Optional: true,
                Computed: true,
                ForceNew: true,
            },
<%      end -%>
<%      if object.has_self_link -%>
            "self_link": {
                Type:     schema.TypeString,
                Computed: true,
            },
<%      end -%>
        },
    }
}

<% properties.each do |prop| -%>
<%= lines(build_subresource_schema(prop, object, pwd), 1) -%>
<% end -%>

<% object.settable_properties.select {|p| p.unordered_list}.each do |prop| -%>
func resource<%= resource_name -%><%= prop.name.camelize(:upper) -%>SetStyleDiff(_ context.Context, diff *schema.ResourceDiff, meta interface{}) error {
<%=
    compile_template(pwd + '/templates/terraform/unordered_list_customize_diff.erb',
                     prop: prop,
                     resource_name: resource_name)
-%>
}
<% end -%>

func resource<%= resource_name -%>Create(d *schema.ResourceData, meta interface{}) error {
    var m providerMeta

    err := d.GetProviderMeta(&m)
    if err != nil {
        return err
    }

    config := meta.(*Config)
    config.userAgent = fmt.Sprintf("%s %s", config.userAgent, m.ModuleName)

<%  if object.custom_code.custom_create -%>
    <%= lines(compile(pwd + '/' + object.custom_code.custom_create))  -%>
<%  else  -%>
    obj := make(map[string]interface{})
<%  object.settable_properties.each do |prop| -%>
    <% schemaPrefix = prop.flatten_object ? "nil" : "d.Get( \"#{prop.name.underscore}\" )" -%>
    <%= prop.api_name -%>Prop, err := expand<%= "Nested" if object.nested_query -%><%= resource_name -%><%= titlelize_property(prop) -%>(<%= schemaPrefix -%>, d, config)
    if err != nil {
        return err
<%    if prop.send_empty_value -%>
    } else if v, ok := d.GetOkExists("<%= prop.name.underscore -%>"); ok || !reflect.DeepEqual(v, <%= prop.api_name -%>Prop) {
<%    elsif prop.flatten_object -%>
    } else if !isEmptyValue(reflect.ValueOf(<%= prop.api_name -%>Prop)) {
<%    else -%>
    } else if v, ok := d.GetOkExists("<%= prop.name.underscore -%>"); !isEmptyValue(reflect.ValueOf(<%= prop.api_name -%>Prop)) && (ok || !reflect.DeepEqual(v, <%= prop.api_name -%>Prop)) {
<%    end -%>
        obj["<%= prop.api_name -%>"] = <%= prop.api_name -%>Prop
    }
<%  end -%>

<%  if object.custom_code.encoder -%>
    <%= "var err error"  if object.settable_properties.size == 0 %>
    obj, err = resource<%= resource_name -%>Encoder(d, meta, obj)
    if err != nil {
        return err
    }
<%  end -%>

<%  if object.mutex -%>
    lockName, err := replaceVars(d, config, "<%= object.mutex -%>")
    if err != nil {
        return err
    }
    mutexKV.Lock(lockName)
    defer mutexKV.Unlock(lockName)
<%  end -%>

    url, err := replaceVars(d, config, "<%= "{{#{object.__product.name}BasePath}}#{object.create_uri}" -%>")
    if err != nil {
        return err
    }

    log.Printf("[DEBUG] Creating new <%= object.name -%>: %#v", obj)
<%  if object.nested_query&.modify_by_patch -%>
<%# Keep this after mutex - patch request data relies on current resource state %>
    obj, err = resource<%= resource_name -%>PatchCreateEncoder(d, meta, obj)
    if err != nil {
        return err
    }<commit_msg>Remove unneeded err declaration (#4010)<commit_after><%- # the license inside this block applies to this file
# Copyright 2017 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-%>
<%= lines(autogen_notice(:go, pwd)) -%>

package google

import (
<%- # We list all the v2 imports here, because we run 'goimports' to guess the correct
    # set of imports, which will never guess the major version correctly. -%>
  "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
  "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
  "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
  "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
  "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
  "github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure"
  "github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
  "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
  "github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging"
)

<%= lines(compile(pwd + '/' + object.custom_code.constants)) if object.custom_code.constants -%>

<%
    resource_name = product_ns + object.name
    properties = object.all_user_properties
    update_body_properties = object.settable_properties
    update_body_properties = object.settable_properties.reject(&:input) if object.update_verb == :PATCH
    # Handwritten TF Operation objects will be shaped like accessContextManager while the Google Go Client will have a name like accesscontextmanager
    client_name = @config.client_name || product_ns
    client_name_camel = client_name.camelize(:lower)
    client_name_pascal = client_name.camelize(:upper)
    client_name_lower = client_name.downcase
    has_project = object.base_url.include?('{{project}}') || (object.create_url && object.create_url.include?('{{project}}'))
    has_region = object.base_url.include?('{{region}}') && object.parameters.any?{ |p| p.name == 'region' && p.ignore_read }
    # In order of preference, use TF override,
    # general defined timeouts, or default Timeouts
    timeouts = object.timeouts
    timeouts ||= object&.async&.operation&.timeouts
    timeouts ||= Api::Timeouts.new
-%>

func resource<%= resource_name -%>() *schema.Resource {
    return &schema.Resource{
        Create: resource<%= resource_name -%>Create,
        Read: resource<%= resource_name -%>Read,
<%      if updatable?(object, properties) -%>
        Update: resource<%= resource_name -%>Update,
<%      end -%>
        Delete: resource<%= resource_name -%>Delete,
<%      if object.settable_properties.any? {|p| p.unordered_list} && !object.custom_code.resource_definition -%>
        CustomizeDiff: customdiff.All(
<%=
            object.settable_properties.select { |p| p.unordered_list }
                               .map { |p| "resource#{resource_name}#{p.name.camelize(:upper)}SetStyleDiff"}
                               .join(",\n")
-%>
        ),
<%      end -%>

<%      unless object.exclude_import -%>
        Importer: &schema.ResourceImporter{
            State: resource<%= resource_name -%>Import,
        },
<%      end -%>

        Timeouts: &schema.ResourceTimeout {
            Create: schema.DefaultTimeout(<%= timeouts.insert_minutes -%> * time.Minute),
<%      if updatable?(object, properties) -%>
            Update: schema.DefaultTimeout(<%= timeouts.update_minutes -%> * time.Minute),
<%      end -%>
            Delete: schema.DefaultTimeout(<%= timeouts.delete_minutes -%> * time.Minute),
        },

<%      if object.schema_version -%>
        SchemaVersion: <%= object.schema_version -%>,
        StateUpgraders: []schema.StateUpgrader{
<%        for v in 0..object.schema_version-1 -%>
            {
                Type: resource<%= "#{resource_name}ResourceV#{v}" -%>().CoreConfigSchema().ImpliedType(),
                Upgrade: resource<%= "#{resource_name}UpgradeV#{v}" -%>,
                Version: <%= v -%>,
            },
        },
<%        end -%>
<%      end -%>

<%=     lines(compile(pwd + '/' + object.custom_code.resource_definition)) if object.custom_code.resource_definition -%>

        Schema: map[string]*schema.Schema{
<%      order_properties(properties).each do |prop| -%>
<%=       lines(build_schema_property(prop, object, pwd)) -%>
<%      end -%>
<%-     unless object.virtual_fields.empty? -%>
<%-       object.virtual_fields.each do |field| -%>
            "<%= field.name -%>": {
              Type: <%= tf_type(field) -%>,
              Optional: true,
              Default:  <%= go_literal(field.default_value) -%>,
            },
<%        end -%>
<%      end -%>
<%=     lines(compile(pwd + '/' + object.custom_code.extra_schema_entry)) if object.custom_code.extra_schema_entry -%>
<%      if has_project -%>
            "project": {
                Type:     schema.TypeString,
                Optional: true,
                Computed: true,
                ForceNew: true,
            },
<%      end -%>
<%      if object.has_self_link -%>
            "self_link": {
                Type:     schema.TypeString,
                Computed: true,
            },
<%      end -%>
        },
    }
}

<% properties.each do |prop| -%>
<%= lines(build_subresource_schema(prop, object, pwd), 1) -%>
<% end -%>

<% object.settable_properties.select {|p| p.unordered_list}.each do |prop| -%>
func resource<%= resource_name -%><%= prop.name.camelize(:upper) -%>SetStyleDiff(_ context.Context, diff *schema.ResourceDiff, meta interface{}) error {
<%=
    compile_template(pwd + '/templates/terraform/unordered_list_customize_diff.erb',
                     prop: prop,
                     resource_name: resource_name)
-%>
}
<% end -%>

func resource<%= resource_name -%>Create(d *schema.ResourceData, meta interface{}) error {
    var m providerMeta

    err := d.GetProviderMeta(&m)
    if err != nil {
        return err
    }

    config := meta.(*Config)
    config.userAgent = fmt.Sprintf("%s %s", config.userAgent, m.ModuleName)

<%  if object.custom_code.custom_create -%>
    <%= lines(compile(pwd + '/' + object.custom_code.custom_create))  -%>
<%  else  -%>
    obj := make(map[string]interface{})
<%  object.settable_properties.each do |prop| -%>
    <% schemaPrefix = prop.flatten_object ? "nil" : "d.Get( \"#{prop.name.underscore}\" )" -%>
    <%= prop.api_name -%>Prop, err := expand<%= "Nested" if object.nested_query -%><%= resource_name -%><%= titlelize_property(prop) -%>(<%= schemaPrefix -%>, d, config)
    if err != nil {
        return err
<%    if prop.send_empty_value -%>
    } else if v, ok := d.GetOkExists("<%= prop.name.underscore -%>"); ok || !reflect.DeepEqual(v, <%= prop.api_name -%>Prop) {
<%    elsif prop.flatten_object -%>
    } else if !isEmptyValue(reflect.ValueOf(<%= prop.api_name -%>Prop)) {
<%    else -%>
    } else if v, ok := d.GetOkExists("<%= prop.name.underscore -%>"); !isEmptyValue(reflect.ValueOf(<%= prop.api_name -%>Prop)) && (ok || !reflect.DeepEqual(v, <%= prop.api_name -%>Prop)) {
<%    end -%>
        obj["<%= prop.api_name -%>"] = <%= prop.api_name -%>Prop
    }
<%  end -%>

<%  if object.custom_code.encoder -%>
    obj, err = resource<%= resource_name -%>Encoder(d, meta, obj)
    if err != nil {
        return err
    }
<%  end -%>

<%  if object.mutex -%>
    lockName, err := replaceVars(d, config, "<%= object.mutex -%>")
    if err != nil {
        return err
    }
    mutexKV.Lock(lockName)
    defer mutexKV.Unlock(lockName)
<%  end -%>

    url, err := replaceVars(d, config, "<%= "{{#{object.__product.name}BasePath}}#{object.create_uri}" -%>")
    if err != nil {
        return err
    }

    log.Printf("[DEBUG] Creating new <%= object.name -%>: %#v", obj)
<%  if object.nested_query&.modify_by_patch -%>
<%# Keep this after mutex - patch request data relies on current resource state %>
    obj, err = resource<%= resource_name -%>PatchCreateEncoder(d, meta, obj)
    if err != nil {
        return err
    }
{'fraction_non_alphanumeric': 0.15982439487422875, 'fraction_numerical': 0.002788324632178453, 'mean_word_length': 2.867171369580179, 'pattern_counts': {'":': 6, '<': 184, '<?xml version=': 0, '>': 184, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4532420', 'n_tokens_mistral': 5648, 'n_tokens_neox': 5414, 'n_words': 1104}